conan

什么是conan

image-20241005202849758

从官网的介绍上来看,它是一个为C和C++开发者设计的软件包管理器。开源、去中心化和多平台的软件包管理器,用来创建和共享所有本地二进制文件。现在官网上的版本已经是2.0,1.x的版本就不建议学了。

目前最新版本:

image-20241005210645268

为什么使用conan

从官网上来看,可以分为以下几点:

  1. 最佳二进制管理,为开发人员和 CI 节省时间和资源
  2. 真正的通用性,适用于任何平台、任何构建系统、任何编译器
  3. 全球最先进企业所需的可扩展性
  4. 管理工具,改进本地、嵌入式和交叉构建流程
  5. 快速响应,大规模整合变更
  6. 自动存储开源第三方,管理元数据。
  7. 自由开放的源代码 由专业团队提供稳定支持
  8. 从 ConanCenter 到您自己的服务器,完全去中心化,拥有自己的供应链,提高安全性
  9. 庞大而广泛的conan社区和生态系统

什么地方在使用conan

就如官网介绍的一样,这是为C和C++开发者服务的包管理器。

image-20241005211032085

2024CPP调研报告

上图为管理C++库工具的排行榜,除去自己编译、使用别人编译好的之外,conan是最受欢迎的包管理工具(毕竟其他的都没有用到包管理工具),除此之外,比如ROS2,在线查看汇编工具:https://godbolt.org/都是使用的conan作为库管理工具。

image-20241005211619844

查看包

前往ConanCenter搜索你想要的包

image-20241005211816868这里以boost举个栗子:

image-20241005211946018

image-20241005212428835

image-20241005212639160初识conan

安装conan

前往官网首页,点击downloads

image-20241005212912158

推荐使用python安装(或者安装包安装),安装完之后,使用conan --version查看conan版本

image-20241005213422489

卸载使用pip uninstall conan即可。

配置conan

查看conan配置文件位置

1
conan config home

image-20250114165849605

进入该文件夹下,使用下面命令生成profiles->default文件

1
conan profile detect

文件内容大致如下:

1
2
3
4
5
6
7
8
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=12
os=Linux

不同系统环境内容可能不同!!!

Hello Conan2

把环境配置好以后,让我们开始编写第一个项目吧!(以gcc为例)

项目目录结构如下:

1
2
3
4
5
6
demo # 项目名
├── build.sh # 构建脚本
├── clear.sh # 清除构建产物脚本
├── CMakeLists.txt
├── conanfile.txt
└── main.cpp
  • main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <cstring>

#include "zlib.h"

void test_env()
{
std::cout << ">>>" << __func__ << "<<<" << std::endl;
std::cout << "sizeof(void*) = " << sizeof(void *) << std::endl;
#if defined(__VERSION__)
std::cout << "__VERSION__ = " << __VERSION__ << std::endl;
#elif defined(_MSC_VER)
std::cout << "_MSC_VER = " << __MSC_VER__ << std::endl;
#endif
}

void test_zlib(void)
{
std::cout << ">>>" << __func__ << "<<<" << std::endl;
char buffer_in[256] = {
"Conan is a C/C++ package manager for C/C++ projects. Conan is a "
"toolchain that can be used to build and package projects. It is a "
"toolchain that can be used to build and package projects. It is a "};

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());
}

int main(void)
{
test_env();
test_zlib();
return 0;
}
  • conanfile.txt
1
2
3
4
5
6
[requires]
zlib/1.3.1

[generators]
CMakeDeps
CMakeToolchain
  • CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
cmake_minimum_required(VERSION 3.15)
project(demo CXX)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)

find_package(ZLIB REQUIRED)

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

# conan install . --output-folder=build --build missing --profile:host=default --profile:build=default
# host:目标平台的配置,build:构建平台的配置(交叉编译)
conan install . --output-folder=build --build missing

cd build

cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release

cmake --build . --config Release

cd ../bin

./demo
1
2
3
4
5
#!/bin/bash

rm -rf build
rm -rf bin
rm -rf CMakeUserPresets.json

main.cpptest_env()函数主要功能是输出当前编译环境的一些信息;test_zlib(void)函数是测试 zlib 库的压缩功能。

运行:

1
2
chmod +x ./build.sh
./build.sh

出现下面的结果就说明成功了!

image-20250114173041638

如果你要测试MSVC(Windows系统),你需要添加或者修改配置文件default,修改后的文件大概如下:

1
2
3
4
5
6
7
8
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=14
compiler.runtime=dynamic
compiler.version=192
os=Linux

同时需要修改build.sh

1
2
3
4
5
6
7
8
9
10
11
conan install . --output-folder=build --build missing

cd build

cmake .. -G "Visual Studio 16 2019" -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake"

cmake --build . --config Release

cd ../bin/Release

demo.exe

gccmsvc配置项描述如下:

image-20250117213836173

更多配置详情请参考执行conan config home命令后得到目录下的settings.yml文件。

推荐使用GCC

Debug&Release 静态库&动态库

以下代码均使用gcc测试。重新创建一个新项目json_cpp,项目结构跟之前一样。

  • main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <json/json.h>

#include <iostream>

void test_env()
{
std::cout << ">>>" << __func__ << "<<<" << std::endl;
std::cout << "sizeof(void*) = " << sizeof(void *) << std::endl;
#if defined(__VERSION__)
#ifdef DEBUG
std::cout << "Debug version" << std::endl;
#else
std::cout << "Release version" << std::endl;
#endif
std::cout << "__VERSION__ = " << __VERSION__ << std::endl;
#endif
}

void test_jsoncpp(void)
{
std::cout << ">>>" << __func__ << "<<<" << std::endl;

Json::Value up;
up["name"] = "yuanyuan";
up["github"] = "https://github.com/liaojie1314";

std::cout << "up:" << up << std::endl;
}

int main(void)
{
test_env();
test_jsoncpp();
return 0;
}
  • conanfile.txt
1
2
3
4
5
6
7
8
9
[requires]
jsoncpp/1.9.5

[generators]
CMakeDeps
CMakeToolchain

[options]
jsoncpp*:shared=False

jsoncpp*:shared=True表示生成动态库,默认为False,即生成静态库。

  • CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
cmake_minimum_required(VERSION 3.15)
project(json_cpp CXX)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)

find_package(jsoncpp REQUIRED)

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} JsonCpp::JsonCpp)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

# conan install . --output-folder=build --build missing --profile:host=default --profile:build=default
# host:目标平台的配置,build:构建平台的配置(交叉编译)
conan install . --output-folder=build --build missing

cd build

cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release

cmake --build . --config Release

cd ../bin

./json_cpp
  • clear.sh不变

运行结果如下:

image-20250117220646382

可以发现当前代码是Release模式。

那么怎么变成Debug模式呢?

  1. 修改default配置文件,将build_type=Release改为build_type=Debug
  2. 修改build.sh文件
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

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

cd build

cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Debug

cmake --build . --config Debug

cd ../bin

./json_cpp

conanfile.py

下面的conanfile.py可以完全替换上一小节中的conanfile.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import os
from conan import ConanFile
from conan.tools.files import copy

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

options = {
"shared": [True, False],
}
default_options = {
"shared": False,
}

def requirements(self):
self.requires("jsoncpp/1.9.5")

def generate(self):
if not self.options.shared:
return
# 复制动态链接库(windows)
for dep in self.dependencies.values():
for depDll in dep.cpp_info.binaries:
print(">>>")
print(">>>",depDll)
print(">>>")
copy(self,"*.dll",depDll,os.path.join(self.source_folder,"bin"))

并且可以在conan install . --output-folder=build --build missing后面指定-o jsoncpp*:shared=True生成动态库。

conanfile.py和conanfile.txt不能同时存在,否则会发生冲突。