工具学习_CONAN_Consuming Packages

1. Build a simple CMake project using Conan

首先创建一个使用最流行的 C++ 库之一 Zlib 的字符串压缩器应用程序,教程将使用 CMake 构建系统,但需要注意 Conan 适用于任何系统构建方式。 为了完成教程,首先下载对应的项目:

git clone https://github.com/conan-io/examples2.git
cd examples2/tutorial/consuming_packages/simple_cmake_project

教程从一个非常简单的C语言项目开始,其结构如下:

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

项目包含一个基本的 CMakeLists.txt(包括 zlib 依赖项)与 main.c(字符串程序源码),main.c 代码如下所示:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <zlib.h>

int main(void) {
    char buffer_in [256] = {"Conan is a MIT-licensed, Open Source package manager for C and C++ development "
                            "for C and C++ development, allowing development teams to easily and efficiently "
                            "manage their packages and dependencies across platforms and build systems."};
    char buffer_out [256] = {0};

    z_stream defstream;
    defstream.zalloc = Z_NULL;
    defstream.zfree = Z_NULL;
    defstream.opaque = Z_NULL;
    defstream.avail_in = (uInt) strlen(buffer_in);
    defstream.next_in = (Bytef *) buffer_in;
    defstream.avail_out = (uInt) sizeof(buffer_out);
    defstream.next_out = (Bytef *) buffer_out;

    deflateInit(&defstream, Z_BEST_COMPRESSION);
    deflate(&defstream, Z_FINISH);
    deflateEnd(&defstream);

    printf("Uncompressed size is: %lu\n", strlen(buffer_in));
    printf("Compressed size is: %lu\n", strlen(buffer_out));

    printf("ZLIB VERSION: %s\n", zlibVersion());

    return EXIT_SUCCESS;
}

CMakeLists.txt 代码如下所示:

cmake_minimum_required(VERSION 3.15)
project(compressor C)

find_package(ZLIB REQUIRED)

add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${PROJECT_NAME} ZLIB::ZLIB)

项目的应用程序依赖于 Zlib 库,Conan 会尝试从远程服务器安装对应的库。安装 Zlib 库并从项目中找到它的最简单方法是使用 conan.txt 文件,文件内容如下所示:

# 声明使用的库
[requires]
zlib/1.2.11

# 指定生成器
[generators]
CMakeDeps
CMakeToolchain

除了 connfile.txt,项目还需要一个 Conan 配置文件来构建项目。Conan 配置文件允许用户为编译器、构建配置、架构、共享或静态库等定义配置集。默认情况下,Conan 不会尝试自动检测配置文件,因此需要创建一个。为了让 Conan 根据当前的操作系统和安装的工具猜测配置文件,需要运行下面的代码:

conan profile detect --force

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

项目将使用 Conan 安装 Zlib 并生成 CMake 查找此库和构建项目所需的文件。为了在 build 文件夹中生成这些文件需要运行下面的代码:

conan install . --output-folder=build --build=missing

从输出中可以发现:(1)Conan 从远程服务器下载了 Zlib 库,此服务器存储 Conan recipes 和可重用的二进制文件,因此不需要每次都从源代码构建;(2)Conan 再 build 文件夹下生成了几个文件,这些文件是由 conanfile.txt 中设置的 CMakeToolchain 和 CMakeDeps 生成的。

完成应用程序 TPL 的安装后,可以对应用程序进行构建和运行,对于 Linux 构建和运行代码如下所示:

cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .

执行 compressor 可得到下面的结果:

2. Using build tools as Conan packages

上一个示例构建了一个 CMake 项目,并使用Conan 安装和定位 Zlib 库。上一个示例使用已经安装在系统中的 CMake 来构建项目,本示例将通过特定版本的 CMake 来构建项目。在这种情况下,Conan 可以是哟个名为 tool_requires 的需求类型声明此依赖关系,下面将通过本示例进行说明该用法。

首先创建一个使用最流行的 C++ 库之一 Zlib 的字符串压缩器应用程序,教程将使用 CMake 构建系统,但需要注意 Conan 适用于任何系统构建方式。 为了完成教程,首先下载对应的项目:

git clone https://github.com/conan-io/examples2.git
cd examples2/tutorial/consuming_packages/tool_requires

教程从一个非常简单的C语言项目开始,其结构如下:

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

该示例与上一个示例的主要区别在于 conanfile.txt 文件中添加了 [tool_requires] 部分,该文件内容如下所示:

[requires]
zlib/1.2.11

[tool_requires]
cmake/3.22.6

[generators]
CMakeDeps
CMakeToolchain

该实例在 CMakeLists.txt 中添加一条消息,以输出 CMake 版本,该文件内容如下所示:

cmake_minimum_required(VERSION 3.15)
project(compressor C)

find_package(ZLIB REQUIRED)

message("Building with CMake version: ${CMAKE_VERSION}")

add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${PROJECT_NAME} ZLIB::ZLIB)

与上一个示例类似,本示例将使用 Conan 安装 Zlib 和 CMake 3.22.6,并生成可执行文件,这一步需要执行的代码如下:

conan install . --output-folder=build --build=missing

通过上述指令, Conan 成功生成一个名为 conanbuild.sh/bat 的新文件,该文件为 conan.txt 中声明 tool_requires 时自动调用 VirtualBuildEnv 生成器的结果。此文件设置了一些环境变量,例如一个新的PATH。为了使用特定版本的 CMake,需要执行下面的代码:

cd build
source conanbuild.sh

执行上述指令后,检查 CMake 版本如下图所示:

可以发现,在激活环境后,CMake v3.22.6 二进制文件夹被添加到路径中,现在是当前活动的版本。这时可以直接通过这个版本的 CMake 来构建项目,需要执行的指令如下所示:

cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .

如果需要恢复到默认的 CMake 版本,需要执行 build 目录下的 deactivate_conanbuild.sh/bat 脚本,需要执行的代码如下所示:

source deactivate_conanbuild.sh

执行上述指令后,检查 CMake 版本如下图所示:

3. Building for multiple configurations: Release, Debug, Static and Shared

首先创建一个使用最流行的 C++ 库之一 Zlib 的字符串压缩器应用程序,教程将使用 CMake 构建系统,但需要注意 Conan 适用于任何系统构建方式。 为了完成教程,首先下载对应的项目:

git clone https://github.com/conan-io/examples2.git
cd examples2/tutorial/consuming_packages/different_configurations

之前的示例介绍了如何构建一个依赖于 zlib 库的简单 CMake 项目,并了解了 tool_requires。这两个示例都没有指定要在发布或调试模式下构建应用程序,也没有指定是否要静态链接或共享库。如果没有另行指示,Conan 将使用默认配置文件中声明的默认配置。可以通过指令 "conan config home" 定位 Conan 用户主页:

 Conan 主页中的 profile 目录下的 default 文件如下所示:

[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu14
compiler.libcxx=libstdc++11
compiler.version=7
os=Linux

其中,setting 部分包含有关操作系统、体系结构、编译器以及构建配置等信息。当调用设置-- profile 参数的 Conan 命令时,Conan 将从配置文件中获取所有信息,并将其应用于要构建或安装的包。如果不指定该参数,则相当于使用--profile=default调用它,即下面两个命令的效果是相同的:

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

可以存储不同的配置文件,并使用它们为不同的设置进行构建,首先要创建对应的配置文件,其内容如下所示:

[settings]
arch=x86_64
build_type=Debug
compiler=gcc
compiler.cppstd=gnu14
compiler.libcxx=libstdc++11
compiler.version=7
os=Linux

修改上述文件之后,可以通过下面的指令来安装应用程序的依赖:

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

这时可以直接通过这个版本的 CMake 来构建项目,需要执行的指令如下所示:

cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug
cmake --build .

到目前位置,示例一直在应用程序中静态链接 zlib。可以通过使用 --option 参数将共享选项设置为 true,如下所示:

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

通过上述代码,Conan 将安装 zlib 共享库,生成使用它们构建的文件,以及在运行应用程序时定位的这些动态库所需的文件。这时可以直接通过这个版本的 CMake 来构建项目,需要执行的指令如下所示:

cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug
cmake --build .

在运行可执行文件之前需要首先运行下面的脚本:

source conanrun.sh

运行可执行文件之后需要运行下面的脚本:

source deactivate_conanrun.sh

4. Understanding the flexibility of using conanfile.py vs conanfile.txt

之前的示例通过 conanfile.txt 来声明依赖关系。对于更复杂的依赖关系,可以通过 conanfile.py 来声明依赖关系,本实例将介绍如何完成这一的依赖声明。

首先创建一个使用最流行的 C++ 库之一 Zlib 的字符串压缩器应用程序,教程将使用 CMake 构建系统,但需要注意 Conan 适用于任何系统构建方式。 为了完成教程,首先下载对应的项目:

git clone https://github.com/conan-io/examples2.git
cd examples2/tutorial/consuming_packages/conanfile_py

教程从一个非常简单的C语言项目开始,其结构如下:

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

与 conanfile.txt 等价的 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.2.11")

    def build_requirements(self):
        self.tool_requires("cmake/3.22.6")

这时可以直接通过这个版本的 CMake 来构建项目,需要执行的指令如下所示:

conan install . --output-folder=build --build=missing
cd build
source conanbuild.sh
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .

conanfile.py 除了可以完成 conan.txt 可以完成的任务,还能进一步实现项目结构的定义。

5. How to cross-compile your applications using Conan: host and build contexts

首先创建一个使用最流行的 C++ 库之一 Zlib 的字符串压缩器应用程序,教程将使用 CMake 构建系统,但需要注意 Conan 适用于任何系统构建方式。 为了完成教程,首先下载对应的项目:

git clone https://github.com/conan-io/examples2.git
cd examples2/tutorial/consuming_packages/cross_building

Conan 可以使用两个不同的配置文件构建应用于不同普通的应用程序,例如,一个应用于 Ubuntu Linux,另一个应用于 Raspberry Pi。为了实现上述目的,需要准备两个 profiles 。

# default
[settings]
os=Linux
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu14
compiler.libcxx=libstdc++11
compiler.version=9
# raspberry
[settings]
os=Linux
arch=armv7hf
compiler=gcc
build_type=Release
compiler.cppstd=gnu14
compiler.libcxx=libstdc++11
compiler.version=9
[buildenv]
CC=arm-linux-gnueabihf-gcc
CXX=arm-linux-gnueabihf-g++
LD=arm-linux-gnueabihf-ld

之后需要 修改conanfile.py,如下所示:

from conan import ConanFile
from conan.tools.cmake import cmake_layout

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

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

    def build_requirements(self):
        self.tool_requires("cmake/3.22.6")

    def layout(self):
        cmake_layout(self)

除此之外,为了实现 ARM 应用程序的顺利构建,需要在 Ubuntu 机器上安装 arm-linux-gnueabihf 工具链。

sudo apt update
sudo apt install gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-gcc --version

至此可以进行应用程序的构建,首先使用构建平台和主机平台的配置文件调用 conan install。这将安装为 armv7hf 架构构建的 zlib/1.2.11 依赖项和为 64 位架构运行的 cmake/3.22.6 版本。指令如下所示:

conan install . --build missing -pr:b=default -pr:h=./profiles/raspberry

这时可以直接通过这个版本的 CMake 来构建项目,需要执行的指令如下所示:

cd build
source Release/generators/conanbuild.sh
cmake .. -DCMAKE_TOOLCHAIN_FILE=Release/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .

最后通过 file 对生成的应用程序进行检查,如下图所示:

6. Introduction to versioning

之前的示例一直在使用带有固定版本的依赖,例如,requires="zlib/1.2.12"。但有时依赖关系会演变,新版本会发布,消费者希望尽可能容易地更新到这些新版本。始终可以编辑connfiles并明确地将版本更新为新版本,但Conan中有机制允许在不修改配方的情况下进行此类更新。

首先创建一个使用最流行的 C++ 库之一 Zlib 的字符串压缩器应用程序,教程将使用 CMake 构建系统,但需要注意 Conan 适用于任何系统构建方式。 为了完成教程,首先下载对应的项目:

git clone https://github.com/conan-io/examples2.git
cd examples2/tutorial/consuming_packages/versioning

该项目的 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.2]")

其中,zlib 的版本被设置为 "1.2" 版本附近,该配置对应 zlib/1.2.8、zlib/1.211 等,但不会对应 zlib/1.3.0。如果执行 conan install 会出现:

如果将对应的设置更改为 zlib/[>1.2.12] 并执行 conan install 则会出现:

同样的思想也可以应用在 tool_requires。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值