conan 2.0 Getting Started

系列文章目录



前言

C++包管理工具conan简介。
conan实际上是用python编写的一个python module,用于C/C++的包管理,基于C/S模式,client向server端请求二进制包。

构建工具栈:

+-------------------------+
| conan                   |
+-------------------------+
| cmake(or others)        |
+-------------------------+
| make(or others)         |
+-------------------------+
| gcc(or others)          |
+-------------------------+

0、安装

# 安装python虚拟环境管理模块
pip install venv
# 创建虚拟环境
# 这里会在当前目录下创建一个.venv目录,
python3 -m venv ./.venv
# 激活虚拟环境。 激活虚拟环境后所有通过pip安装的模块都会在该目录下,不会与全局环境冲突
source .venv/bin/activate
# 在虚拟环境中安装conan
pip install conan

分享依赖给他人

# 导出当前依赖
pip freeze > requirements.txt
# 安装所有需要的模块
pip install -r requirements.txt

一、使用conan管理项目依赖

使用conan构建一个简单的CMake项目

├── CMakeLists.txt
├── conanfile.txt
└── src
    └── main.c

CMakeLists.txt

find_package(ZLIB REQUIRED)

conanfile.txt
[requires] 段用于声明项目中需要用到的库
[generators] 段告诉 Conan 生成一个文件,该文件将用于编译器或构建系统查找依赖项和构建项目。在本例中,由于我们的项目基于 CMake,我们将使用 CMakeDeps 来生成有关 Zlib 库文件安装位置的信息,并使用 CMakeToolchain 通过 CMake 工具链文件将构建信息传递给 CMake。

[requires]
zlib/1.3.1

[generators]
CMakeDeps
CMakeToolchain

Conan profile 允许用户定义配置,如,指定编译器、构建选项、架构、共享或静态库等。Conan默认不自动检测profile

# 该指令
conan profile detect --force

这将根据环境检测操作系统、构建架构和编译器设置。它还会默认将构建配置设置为“Release”。生成的配置文件将以“default”的名称存储在Conan的主文件夹中,除非通过命令行指定了其他配置文件,否则Conan在所有命令中都会默认使用该配置文件。

conan install . --output-folder=build --build=missing
  • Conan从远程服务器安装了Zlib库,如果该库可用,默认情况下该服务器应为Conan Center服务器。此服务器既存储Conan配方(定义如何构建库的文件),也存储可重用的二进制文件,这样我们就不必每次都从源代码构建。
  • Conan在build文件夹下生成了几个文件。这些文件是由我们在conanfile.txt中设置的CMakeToolchain和CMakeDeps生成器生成的。CMakeDeps生成文件,以便CMake能够找到我们刚刚下载的Zlib库。另一方面,CMakeToolchain为CMake生成一个工具链文件,这样我们就可以使用为默认配置文件检测到的相同设置,通过CMake透明地构建我们的项目。
  • –build=missing:当预编译包缺失时自动从源码构建
  • –install-folder:指定生成文件的输出目录
  • –settings、–options:指定构建配置(如编译器版本、架构等)

conan install的核心作用:准备cmake环境

  • 依赖解析与获取
    • 读取项目根目录下的 conanfile.txt或 conanfile.py
    • 解析依赖图(包括传递依赖)
    • 从配置的远程仓库(如 conancenter)下载预编译的二进制包
    • 如果预编译包不可用,则根据 settings和 options在本地从源码构建
  • 环境配置与集成文件生成
    • 为每个依赖包生成对应的 .cmake或 .pc文件
    • 创建 conanbuildinfo.cmake(旧版本)或 conan_toolchain.cmake(新版本)
    • 设置编译器和链接器所需的路径、定义、库文件、脚本等信息
$ cd build
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
$ cmake --build .

Conan 命令行

$ conan config home

$ conan install . --build=missing --profile=default

$ conan install . --output-folder=build --build=missing --settings=build_type=Debug

$ conan install . --output-folder=build --build=missing --options=zlib/1.3.1:shared=True

conan编译会自动生成程序的运行环境:

source conanrun.sh

source deactivate_conanrun.sh

conanfile.py文件

conanfile.txt

[requires]
zlib/1.3.1

[tool_requires]
cmake/3.27.9

[generators]
CMakeDeps
CMakeToolchain

conanfile.py

from conan import ConanFile
class CompressorRecipe(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeToolchain", "CMakeDeps"

    def requirements(self):
        self.requires("zlib/1.3.1")

    def build_requirements(self):
        self.tool_requires("cmake/3.27.9")
  • settings: 类属性,定义项目维度的变量,如编译器、它的版本、OS
  • generators: 类属性,说明调用conan install命令时,哪个Conan生成器会运行
  • requirements() 方法,使用self.requires()方法声明 zlib/1.3.1 依赖
  • build_requirements() 方法,使用self.tool_requires() 方法声明 cmake/3.27.9 依赖
$ conan install . --output-folder build --build=missing
$ cd build
$ source conanbuild.sh
Capturing current environment in deactivate_conanbuildenv-release-x86_64.sh
Configuring environment variables
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
$ cmake --build .

layout() 方法
如:通过layout()方法,可以直接根据CMake generator的类型指定输出目录名

    def layout(self):
        # We make the assumption that if the compiler is msvc the
        # CMake generator is multi-config
        multi = True if self.settings.get_safe("compiler") == "msvc" else False
        if multi:
            self.folders.generators = os.path.join("build", "generators")
            self.folders.build = "build"
        else:
            self.folders.generators = os.path.join("build", str(self.settings.build_type), "generators")
            self.folders.build = os.path.join("build", str(self.settings.build_type))

self.folders.generators=指定生成目录
self.folders.build=Makefile所在目录
这里有一些预定义的layouts以供import和直接使用,如,cmake_layout()

from conan.tools.cmake import cmake_layout

	def layout(self):
	  cmake_layout(self)

使用 validate() 方法对不支持的配置抛出错误

from conan.errors import ConanInvalidConfiguration
class CompressorRecipe(ConanFile):
  ...
  def validate(self):
    if self.settings.os == "Macos" and self.settings.arch == "armv8":
      raise ConanInvalidConfiguration("ARM v8 not supported in Macos")

条件requirements
向requirements()方法中添加或移除requirements

from conan import ConanFile
class CompressorRecipe(ConanFile):
  # binary configuration
  settings = "os", "compiler", "build_type", "arch"
  generators = "CMakeToolchain", "CMakeDeps"
  
  def requirements(self):
    self.requires("zlib/1.3.1")
    if self.settings.os == "Windows":
      self.requires("base64/0.4.0")
   
  def build_requirements(self):
    if self.settings.os != "Windows":
      self.tool_requires("cmake/3.27.9")

使用 generate() 方法从packages中拷贝资源

import os
from conan import ConanFile
from conan.tools.files import copy
class Recipe(ConanFile):
  ...
  def generate(self):
    # Copy all resources from the dependency's resource directory
    # to the "assets" folder in the source directory of your project
    dep = self.dependencies["dep_name"]
    copy(self, "*", dep.cpp_info.resdirs[0], os.path.join(self.source_folder, "assets"))

conan install 就会拷贝资源文件

** 使用build() 方法和conan build命令 **
如果Conan配方里实现了build()方法,那么一条conan build命令就可以实现conan install + cmake <configure> + cmake <build>

from conan import ConanFile
from conan.tools.cmake import CMake
class CompressorRecipe(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeToolchain", "CMakeDeps"
    ...
    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

交叉编译

build profile: 编译主机
host profile: 运行编译产物的主机

conan install . --build=missing --profile=someprofile
# 等价于
conan install . --build=missing --profile:host=someprofile --profile:build=default
conan install . --build missing -pr:b=default -pr:h=./profiles/raspberry

<local folder>/profiles/raspberry

[settings]
os=Linux
arch=armv7hf
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=12
[buildenv]
CC=arm-linux-gnueabihf-gcc-12
CXX=arm-linux-gnueabihf-g++-12
LD=arm-linux-gnueabihf-ld

[buildenv] 用于设置环境变量。将该段添加到profile文件后,执行 conan install 将会调用VirtualBuildEnv生成器,该生成器将会把环境信息添加到 conanbuild.sh 脚本中,该脚本会在CMake之前source一下以使用交叉构建工具链。

host context 是编译产物时用到的,通过self.requires()添加
build context 包含[tool requirements],在build machine中使用
两个context互不影响

versioning

def requirements(self):
  self.requires("zlib/[~1.2]")  # 1.2.X的最新版
                "zlib/[<1.2.12]"  # zlib版本小于1.2.12的最新版
def build_requirements(self):
  self.tool_requires("cmake/[>3.10]")  # 至少是cmake3.11的版本

pkgname/version#recipe_reversion  
or
pkgname/version#user/channel#recipe_revision

# 查看修订的版本
conan list "zlib/1.2.12#*" -r=conancenter

self.requires("zlib/1.2.12#87a7211557b6690ef5bf7fc599dd8349")

Lockfiles 是指包含固定依赖的列表,该列表指明了依赖的固定版本
lockfile可以被认为是某个时间点的依赖图的快照

conan lock create .

# then
conan install .   等价于  conan install . --lockfile=conan.lock
此时会强制使用conan.lock中的配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值