cmake-conan 2.0 接入指南
一月 11, 2024 更新: 一月 14, 2024 [C/C++] #obsidian #编译链接cmake-conan 2.0 接入指南
pip install conan
# 甚至可以不提供conanfile.txt文件,直接使用命令行完成包的安装
conan install zlib/1.2.11@conan/stable -g cmake -s build_type=Debug -o 'zlib/*:shared=True' --build=missing
profile
其实和option一样,setting既可以用命令行参数指定,也可以通过配置文件指定,只不过setting是写在profile而不是conanfile.txt中。conan安装完之后会有一个默认的profile:$HOME/.conan2/profiles/default【3】。如果你想要系统默认都下载Debug包,你可以修改这个文件,把build_type改成Debug。
如果你不想影响全局,又不想频繁的输入命令行参数,你可以在$HOME/.conan2/profiles/下新建一个profile,比如debug,然后使用下面命令安装依赖包:
conan install . --profile=debug
这种方式在对于简单的参数来说没有太大的意义,但是对于交叉编译的中特别有用,可以避免大量的参数的输入工作。
理解conan的包名
在实际创建一个包之前,我们先来理解一下conan包的包名。
zlib/1.2.11@conan/stable
上面这个包名包含四个部分:
- zlib 名字
- 1.2.11 版本
- conan 用户
- stable 通道(channel)
虽然它们出现在同一个名字中,但它们不在同一个位置设置。前面两个通常写在配置文件中,而后面两个在命令行中指定。
包的创建步骤
创建一个包,实际上就是编译一个包的过程,只不过conan把这个过程脚本化来而已。所以在创建一个包之前,我们先整理一下编译一个包需要的步骤:
- 重复下面这三个步骤,直到所有依赖编译完成,后然执行下面三个步骤编译自身
- 下载源码
- 编译
- 安装
所以创建一个conan包大概也就是把这几个步骤自动化而已,自动化这些操作的脚本叫做:conanfile.py,官方称之为recipe。recipe是菜谱的意思,这个词非常好的体现了conanfile.py的功能,引导conan一步一步的创建一个包。
conanfile.py
一个 conanfile.py 通常的像下面这个样子:
from conans import ConanFile, CMake, tools
class HelloConan(ConanFile):
name = "Hello"
version = "0.0.1"
license = "MIT"
url = "https://github.com/hello/hello.git"
description = "Hello conan"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False]}
default_options = "shared=False"
generators = "cmake"
def source(self):
self.run("git clone https://github.com/hello/hello.git")
def build(self):
cmake = CMake(self)
cmake.configure(source_folder="hello")
cmake.build()
def package(self):
self.copy("*.h", dst="include", src="hello")
self.copy("*hello.lib", dst="lib", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.dylib", dst="lib", keep_path=False)
self.copy("*.a", dst="lib", keep_path=False)
def package_info(self):
self.cpp_info.libs = ["hello"]
你可以使用下面的命令来创建这个脚本:
conan new Hello/0.0.1
手动创建包,避免每次更新都重新编译整包
conan create这条命令的背后实际上执行了整个打包流程【5】,这条命令很方便,但是 会导致所有的包都重新编译一遍,而很多时候其实我们只是做了非常小的一个改动而已。 为了充分的利用编译缓存,我们可以手动的执行打包流程,也就是手动执行conan create背后的指令:
conan install . --install-folder=./build
conan build . --source-folder=./ --build-folder=./build
conan export-pkg . HelloConan/0.1.0@conan/testing --package-folder=./build/package
conan create实际上依次执行了conan source,conan install,conan build,conan package,conan export-pkg这几条命名。它之所以慢是因为每次都需要重新执行这些命令,如果我们手动创建包,我们可以有下面这些改进:
- 不执行
source,因为源码就在我们手上,可能就是当前这个目录 - 选择性执行
conan install,依赖项实际上我们可以只安装一次,后续的编译不需要重复执行 - 指定同一个编译目录,这个是最见效的方式,我们可以把编译目录手动设置为固定的目录,这样可以充分的利用编译缓存来极大是缩短编译时间。
- 不执行
conan package,因为conan export-pkg会执行package()函数,也就是conan package命令做的事情。
需要注意的是,****export-pkg包含两种不同的执行模式,如果我们在build这个步骤中使用了cmake.install() 创建了包,我们只需要指定**package-folder就可以了(这种情况通常我们不写package函数),否则我们需要指定source-folder和build-folder** ,以便执行**package**函数打包。