conan 什么是conan
从官网的介绍上来看,它是一个为C和C++开发者设计的软件包管理器。开源、去中心化和多平台的软件包管理器,用来创建和共享所有本地二进制文件。现在官网上的版本已经是2.0,1.x的版本就不建议学了。
目前最新版本:
为什么使用conan 从官网上来看,可以分为以下几点:
最佳二进制管理,为开发人员和 CI 节省时间和资源 真正的通用性,适用于任何平台、任何构建系统、任何编译器 全球最先进企业所需的可扩展性 管理工具,改进本地、嵌入式和交叉构建流程 快速响应,大规模整合变更 自动存储开源第三方,管理元数据。 自由开放的源代码 由专业团队提供稳定支持 从 ConanCenter 到您自己的服务器,完全去中心化,拥有自己的供应链,提高安全性 庞大而广泛的conan社区和生态系统 什么地方在使用conan 就如官网介绍的一样,这是为C和C++开发者服务的包管理器。
2024CPP调研报告
上图为管理C++库工具的排行榜,除去自己编译、使用别人编译好的之外,conan是最受欢迎的包管理工具(毕竟其他的都没有用到包管理工具),除此之外,比如ROS2,在线查看汇编工具:https://godbolt.org/都是使用的conan作为库管理工具。
查看包 前往ConanCenter搜索你想要的包
这里以boost
举个栗子:
初识conan安装conan 前往官网首页,点击downloads
推荐使用python安装(或者安装包安装),安装完之后,使用conan --version
查看conan版本
卸载使用pip uninstall conan
即可。
配置conan 查看conan
配置文件位置
进入该文件夹下,使用下面命令生成profiles->default文件
文件内容大致如下:
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
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 ; }
1 2 3 4 5 6 [requires] zlib/1.3.1 [generators] CMakeDeps CMakeToolchain
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.cpp :test_env()
函数主要功能是输出当前编译环境的一些信息;test_zlib(void)
函数是测试 zlib
库的压缩功能。
运行:
1 2 chmod +x ./build.sh ./build.sh
出现下面的结果就说明成功了!
如果你要测试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
gcc 和msvc 配置项描述如下:
更多配置详情请参考执行conan config home
命令后得到目录下的settings.yml
文件。
Debug&Release 静态库&动态库 以下代码均使用gcc 测试。重新创建一个新项目json_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 ; }
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,即生成静态库。
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
运行结果如下:
可以发现当前代码是Release模式。
那么怎么变成Debug 模式呢?
修改default 配置文件,将build_type=Release
改为build_type=Debug
修改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.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 osfrom conan import ConanFilefrom conan.tools.files import copyclass 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 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不能同时存在,否则会发生冲突。