cmake-conan 2.0 接入指南

一月 11, 2024 更新: 一月 14, 2024 [C/C++] #obsidian #编译链接

cmake-conan 2.0 接入指南

conan 教程

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

上面这个包名包含四个部分:

虽然它们出现在同一个名字中,但它们不在同一个位置设置。前面两个通常写在配置文件中,而后面两个在命令行中指定。

包的创建步骤

创建一个包,实际上就是编译一个包的过程,只不过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这几条命名。它之所以慢是因为每次都需要重新执行这些命令,如果我们手动创建包,我们可以有下面这些改进:

需要注意的是,****export-pkg包含两种不同的执行模式,如果我们在build这个步骤中使用了cmake.install() 创建了包,我们只需要指定**package-folder就可以了(这种情况通常我们不写package函数),否则我们需要指定source-folder和build-folder** ,以便执行**package**函数打包。