C/C++包管理工具:Conan

Conan是一个专为C/C++设计的开源、去中心化、跨平台的包管理器,致力于简化依赖管理和二进制分发流程。Conan基于Python进行开发,支持与主流的构建系统集成,提供了强大的跨平台和交叉编译能力。通过Conan,开发者可以高效的创建、共享和使用预编译的二进制包,提升开发效率和协作体验,尤其适合于复杂项目和多环境部署的场景。

下文将结合一个cmake构建系统的C++ Demo工程介绍conan安装、基本概念及简单使用,更多的示例和更复杂的应用需求建议查询Conan用户文档。

Conan用户文档:https://docs.conan.io/2/index.html

一、安装

pipx install conan

验证安装结果:

$ conan -v
Conan version 2.20.0

Conan1.x和Conan2.x不兼容,默认是conan2.x,如果使用Conan1.x可以指定版本安装

pipx install conan==1.66.0

二、概念和配置

1、常用命令(commands)
  • conan config: 管理conan的配置(远程、设置、插件等)
    # 指定目录安装conan配置文件: 
    conan config install <config_path> 
    
  • conan profile: 显示和管理profile文件
    # 查看所有的profile文件
    conan profile list
    
  • conan remove: 移除包从本地缓存或远程
    # 移除指定的包
    conan remove <name>
    # 移除指定版本的包
    conan remove <name>/<version>
    
  • conan version: 查看conan客户端的版本信息
    $ conan version
    version: 2.20.0
    conan_path: /root/.local/bin/conan
    pythonversion: 3.12.3sys_version: 3.12.3 (main, Aug 14 2025, 17:47:21) [GCC 13.3.0]sys_executable: /root/.local/share/pipx/venvs/conan/bin/pythonis_frozen: Falsearchitecture: x86_64
    systemversion: #149~20.04.1-Ubuntu SMP Wed Apr 16 08:29:56 UTC 2025platform: Linux-5.15.0-139-generic-x86_64-with-glibc2.39system: Linuxrelease: 5.15.0-139-genericcpu: x86_64
    
  • conan create: 从一个配方文件创建一个包
    # 当二进制不存在时构建
    conan create <project_path> -pr=<profile_file> --build=missing
    
2、配方文件(conanfile.py)

conanfile.py是一个包的配方,负责定义怎么定义和消费一个包。

from conan import ConanFileclass HelloConan(ConanFile):...

conanfile.py使用了多种属性(attributes)和方法(methods)用于操作。为了避免冲突,请遵循一下规则:

  • 公共属性和方法,像build(),self.package_folder,是conan保留的。不要在配方中使用这些公共成员作为自定义属性或方法。
  • 对你自己的成员使用“protected”访问,像self._my_data或def _my_helper(self):。Conan只保留“_conan”作为保护成员的开始。
(1)属性(attributes)

conanfile.py Attributes文档:https://docs.conan.io/2/reference/conanfile/attributes.html

Attribute说明
name包的名字
version包的版本
description包的描述信息
license包的license信息
author包的作者信息
setting列举第一层的配置信息(来自setting.yml),这些值将被用于计算package id
options定义option的名字及允许的值,默认任何值改变都将影响package id
default_options定义options的默认值
generators描述所需的生成器名字

注:Attribute一般提供简单的功能,对于复杂的需求可以使用功能相似的Method实现。

(2)方法(methods)

conanfile.py Methods文档:https://docs.conan.io/2/reference/conanfile/methods.html

Mathod说明
build()包含了从源码构建包的构建指令
build_requirements()定义了tool_requirestest_requires
configure()允许在计算依赖时进行配置和选择
deploy()从package中复制指定文件到特定目录
generate()生成构建包时所必须的文件
layout()定义工程相关的源文件夹、build文件夹等
package()从build文件夹copy文件到package文件夹
requirements()定义依赖的包
set_name()动态定义包的名字
set_version()动态定义包的版本
system_requirements()调用系统包管理(比如apt)安装系统包
test()运行简单的包测试
(3)Running命令

对于系统命令,Conan提供了self.run()方法,支持在指定环境中运行相应的系统命令,并且当命令执行错误时,支持抛出异常以便错误能够被及时发现。

run(self, command: str, stdout=None, cwd=None, ignore_errors=False, env='', quiet=False, shell=True, scope='build', stderr=None)
  • command – 待运行的命令字符串.
  • stdout – 支持将标准输出重定向,默认输出到标准输出流。
  • stderr – 支持将错误输出重定向,默认输出到标准错误流。
  • cwd – 指定运行命令的工作空间。
  • ignore_errors – 如果为Ture,命令执行错误也将不抛出异常。
  • env – 要使用的环境文件,当scope为build时默认为conanbuild,否则scope为run默认使用conanrun。如果明确设置为None则不会使用任何环境文件。
  • quiet – 如果为True,将屏蔽该命令的输出。
  • shell – 如果为True,将在一个shell中运行该命令。这将会被传递给底层的popen函数。
  • scope – 这个命令的范围,只能是“build”或者“run”。用于指定命令执行时所处的环境作用域。它们决定了命令执行时使用的环境变量集合。(这些环境变量通常在generate()阶段生成并保存在相应脚本中)
(4)从配方输出文本

Conan建议使用self.output代替print()从配方中输出文本信息。self.output下的成员方法有:

error(self, msg:str, error_type:str=None)
warning(self, msg:str, warn_tag:str=None)
info(self, msg:str, fg:str=None, bg:str=None)status(self, msg:str, fg:str=None, bg:str=None)
verbose(self, msg:str, fg:str=None, bg:str=None)
debug(self, msg:str, fg:str='\x1b[35m',bg:str=None)
trace(self, msg:str)success(self, msg:str)
highlight(self, msg:str)
(5)配方工具

配方工具文档:https://docs.conan.io/2/reference/tools.html

配方工具是指能够在conan配方中引用的工具,比如:

from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake, cmake_layout
from conan.tools.env import Environment, EnvVars, VirtualBuildEnv, VirtualRunEnv
from conan.tools.files import *
from conan.tools.scm import Git, Version
from conan.tools.system import Apt

注:conanfile.py还有一个对功能简单的版本:conanfile.txt,便于对依赖项的简单管理使用,不能用于创建软件包。

3、配置文件
(1)global.conf

global.conf文件位于Conan的家目录,~/.conan2/global.conf。如果不存在将自动创建一个。global.conf文件的目标是存在一些核心(core)、工具(tool)及用户(user)的配置变量,这些变量也将会被Conan使用。

  • core.*:旨在配置 Conan 核心行为的参数(下载重试次数、包标识模式等)。仅能在global.conf文件中进行定义。
  • tool.*: 旨在配置 Conan 工具(工具链、构建辅助程序等)在您的配方中所使用的值。可在global.conf和配置文件中进行定义。
  • user.*: 旨在定义个人用户配置。用户可以自行设定任何所需内容。这些配置可在global.conf文件和配置文件中进行设定。

使用命令conan config list可以查看当前的所有配置。

(2)profiles

Conan配置文件允许用户在文件中为设置、选项、环境变量(包括构建时和运行时环境)以及工具需求和配置变量设定一个完整的配置集。

[settings]
arch=x86_64
build_type=Release
os=Macos[options]
mylib/*:shared=True[tool_requires]
tool1/0.1@user/channel
*: tool4/0.1@user/channel[buildenv]
VAR1=value[runenv]
EnvironmentVar1=My Value[conf]
tools.build:jobs=2[replace_requires]
zlib/1.2.12: zlib/[*][replace_tool_requires]
7zip/*: 7zip/system[platform_requires]
dlib/1.3.22[platform_tool_requires]
cmake/3.24.2

注:对不需要特定设置section,可以不在profile中声明。

(3)settings.yml
# This file was generated by Conan. Remove this comment if you edit this file or Conan
# will destroy your changes.
os:Windows:subsystem: [null, cygwin, msys, msys2, wsl]WindowsStore:version: ["8.1", "10.0"]WindowsCE:platform: [ANY]version: ["5.0", "6.0", "7.0", "8.0"]Linux:iOS:version: &ios_version["7.0", "7.1", "8.0", "8.1", "8.2", "8.3", "8.4", "9.0", "9.1", "9.2", "9.3","10.0", "10.1", "10.2", "10.3","11.0", "11.1", "11.2", "11.3", "11.4","12.0", "12.1", "12.2", "12.3", "12.4", "12.5","13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7","14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7", "14.8","15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6", "15.7", "15.8","16.0", "16.1", "16.2", "16.3", "16.4", "16.5", "16.6", "16.7","17.0", "17.1", "17.2", "17.3", "17.4", "17.5", "17.6", "17.8","18.0", "18.1", "18.2", "18.3", "18.4", "18.5", "18.6"]sdk: ["iphoneos", "iphonesimulator"]sdk_version: [null, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4","13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7","14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "15.0", "15.2", "15.4","15.5", "16.0", "16.1", "16.2", "16.4", "17.0", "17.1", "17.2", "17.4", "17.5","18.0", "18.1", "18.2", "18.4", "18.5"]watchOS:version: ["4.0", "4.1", "4.2", "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2", "6.3","7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6","8.0", "8.1", "8.3", "8.4", "8.5", "8.6", "8.7","9.0","9.1", "9.2", "9.3", "9.4", "9.5", "9.6","10.0", "10.1", "10.2", "10.3", "10.4", "10.5", "10.6","11.0", "11.1", "11.2", "11.3", "11.4", "11.5", "11.6"]sdk: ["watchos", "watchsimulator"]sdk_version: [null, "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2","7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.0.1", "8.3", "8.5", "9.0", "9.1","9.4", "10.0", "10.1", "10.2", "10.4", "10.5","11.0", "11.1", "11.2", "11.4", "11.5"]tvOS:version: ["11.0", "11.1", "11.2", "11.3", "11.4","12.0", "12.1", "12.2", "12.3", "12.4","13.0", "13.2", "13.3", "13.4","14.0", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7","15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6","16.0", "16.1", "16.2", "16.3", "16.4", "16.5", "16.6","17.0", "17.1", "17.2", "17.3", "17.4", "17.5", "17.6","18.0", "18.1", "18.2", "18.3", "18.4", "18.5", "18.6"]sdk: ["appletvos", "appletvsimulator"]sdk_version: [null, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4","13.0", "13.2", "13.3", "13.4", "14.0", "14.2", "14.3", "14.4", "14.5", "15.0","15.2", "15.4", "15.5", "16.0", "16.1", "16.4", "17.0", "17.1", "17.2", "17.4", "17.5","18.0", "18.1", "18.2", "18.4", "18.5"]visionOS:version: ["1.0", "1.1", "1.2", "1.3", "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6"]sdk: ["xros", "xrsimulator"]sdk_version: [null, "1.0", "1.1", "1.2", "1.3", "2.0", "2.1", "2.2", "2.4", "2.5"]Macos:version: [null, "10.6", "10.7", "10.8", "10.9", "10.10", "10.11", "10.12", "10.13", "10.14", "10.15","11.0", "11.1", "11.2", "11.3", "11.4", "11.5", "11.6", "11.7","12.0", "12.1", "12.2", "12.3", "12.4", "12.5", "12.6", "12.7","13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7","14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7","15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6"]sdk_version: [null, "10.13", "10.14", "10.15", "11.0", "11.1", "11.2", "11.3", "12.0", "12.1","12.3", "12.4", "13.0", "13.1", "13.3", "14.0", "14.2", "14.4", "14.5","15.0", "15.1", "15.2", "15.4", "15.5"]subsystem:null:catalyst:ios_version: *ios_versionAndroid:api_level: [ANY]ndk_version: [null, ANY]FreeBSD:SunOS:AIX:Arduino:board: [ANY]Emscripten:Neutrino:version: ["6.4", "6.5", "6.6", "7.0", "7.1"]baremetal:VxWorks:version: ["7"]
arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64,armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, arm64ec,sparc, sparcv9,mips, mips64, avr, s390, s390x, asm.js, wasm, wasm64, sh4le,e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7,riscv64, riscv32,xtensalx6, xtensalx106, xtensalx7,tc131, tc16, tc161, tc162, tc18]
compiler:sun-cc:version: ["5.10", "5.11", "5.12", "5.13", "5.14", "5.15"]threads: [null, posix]libcxx: [libCstd, libstdcxx, libstlport, libstdc++]gcc:version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9","5", "5.1", "5.2", "5.3", "5.4", "5.5","6", "6.1", "6.2", "6.3", "6.4", "6.5","7", "7.1", "7.2", "7.3", "7.4", "7.5","8", "8.1", "8.2", "8.3", "8.4", "8.5","9", "9.1", "9.2", "9.3", "9.4", "9.5","10", "10.1", "10.2", "10.3", "10.4", "10.5","11", "11.1", "11.2", "11.3", "11.4", "11.5","12", "12.1", "12.2", "12.3", "12.4", "12.5","13", "13.1", "13.2", "13.3", "13.4","14", "14.1", "14.2", "14.3","15", "15.1", "15.2"]libcxx: [libstdc++, libstdc++11]threads: [null, posix, win32, mcf]  # Windows MinGWexception: [null, dwarf2, sjlj, seh]  # Windows MinGWcppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]msvc:version: [170, 180, 190, 191, 192, 193, 194]update: [null, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]runtime: [static, dynamic]runtime_type: [Debug, Release]cppstd: [null, 14, 17, 20, 23]toolset: [null, v110_xp, v120_xp, v140_xp, v141_xp]cstd: [null, 11, 17]clang:version: ["3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0","5.0", "6.0", "7.0", "7.1","8", "9", "10", "11", "12", "13", "14", "15", "16", "17","18", "19", "20", "21"]libcxx: [null, libstdc++, libstdc++11, libc++, c++_shared, c++_static]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]runtime: [null, static, dynamic]runtime_type: [null, Debug, Release]runtime_version: [null, v140, v141, v142, v143, v144]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]apple-clang:version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", "9.1","10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", "14.0", "15", "15.0","16", "16.0", "17", "17.0"]libcxx: [libstdc++, libc++]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]intel-cc:version: ["2021.1", "2021.2", "2021.3", "2021.4", "2022.1", "2022.2","2022.3", "2023.0", "2023.1", "2023.2", "2024.0", "2024.1","2025.0", "2025.1"]update: [null, ANY]mode: ["icx", "classic", "dpcpp"]libcxx: [null, libstdc++, libstdc++11, libc++]cppstd: [null, 98, gnu98, "03", gnu03, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]runtime: [null, static, dynamic]runtime_type: [null, Debug, Release]qcc:version: ["4.4", "5.4", "8.3"]libcxx: [cxx, gpp, cpp, cpp-ne, accp, acpp-ne, ecpp, ecpp-ne]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17]mcst-lcc:version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]libcxx: [libstdc++, libstdc++11]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]emcc:# From https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md# There is no ABI compatibility guarantee between versionsversion: [ANY]libcxx: [null, libstdc++, libstdc++11, libc++]threads: [null, posix, wasm_workers]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]build_type: [null, Debug, Release, RelWithDebInfo, MinSizeRel]

通过settings.yml文件,设置的可能值都在同一个文件中定义。这样做是为了确保名称和拼写的一致性,并在用户和开源软件社区之间建立一个统一的设置模型。
对于设置的一些特殊信息:

  • 如果某个设置允许设置为任意值,那么就可以使用“ANY”这个选项。
  • 如果某个设置允许设置为任意值,或者也可以不进行设置,那么您可以使用 [null, ANY] 这种组合。
    这个配置文件可以根据任何需求进行修改,包括添加新的设置或子设置及其值。如果希望使用工程中的settings.yml文件,可以使用conan config install命令将指定的setting.yml文件安装(覆盖)到Conan家目录。
4、环境变量

可用于配置 Conan 某些行为的环境变量非常少。这些环境变量属于例外情况,对于自定义和配置控制,Conan使用global.conf配置以及profile文件的[conf]部分。

环境变量说明
CONAN_HOME控制Conan的家目录,默认没有定义,使用~/.conan2
CONAN_DEFAULT_PROFILE指定一个不同于“default”的默认profile名
5、二进制模型

二进制模型是Conan包管理的核心。它通过对profile配置(setting + options + dependencies versions)进行哈希运算获取package_id,确定了包的唯一性。
而profile中,各配置项保证了C/C++ API接口的兼容性,ABI接口的兼容性,从而实现对二进制文件的管理和分发。
另外Conan二进制模型具有可扩展性,用户可以定义自定义设置、选项和配置,以塑造其自身二进制文件的特性。

在这里插入图片描述
在这里插入图片描述

三、一个完整的工程demo

1、创建cmake工程
(1)创建工程
  • C++源文件
// source/main.cpp
#include <iostream>
#include <cstdint>std::int32_t main(void)
{std::cout << "Hello World!" << std::endl;return 0;
}
  • C++测试文件
// test/main.cpp
#include <gtest/gtest.h>TEST(ExampleTest, StringTest) {std::string str = "Hello";EXPECT_EQ(str, "Hello");EXPECT_NE(str, "World");
}int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
  • cmake文件
# CMakeLists.txt
cmake_minimum_required(VERSION 3.28)project(ConanDemo VERSION 1.0.0 LANGUAGES CXX)set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME}PRIVATEsource/main.cpp
)set_target_properties(${PROJECT_NAME}PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)find_package(GTest)add_executable(${PROJECT_NAME}_test)
target_sources(${PROJECT_NAME}_testPRIVATEtest/main.cpp
)target_link_libraries(${PROJECT_NAME}_testPRIVATEGTest::gtest_main
)set_target_properties(${PROJECT_NAME}_testPROPERTIESRUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)enable_testing()
add_test(NAME ${PROJECT_NAME}_testCOMMAND ${PROJECT_NAME}_test
)
  • 当前工程结构
$ tree
.
|-- CMakeLists.txt
|-- source
|   `-- main.cpp
`-- test`-- main.cpp
(2)基于cmake构建验证
# 配置cmake
cmake -S . -B build
# 构建目标
cmake --build build
# 运行test
cmake --build build --target test
2、添加conan管理
(1)设计conan配置文件
  • setting.yml文件
os:Linux:platform: [null, host, pi4]
arch: [x86_64, armv7, armv7hf, armv8, armv8_32, riscv64, riscv32]
compiler:gcc:version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9","5", "5.1", "5.2", "5.3", "5.4", "5.5","6", "6.1", "6.2", "6.3", "6.4", "6.5","7", "7.1", "7.2", "7.3", "7.4", "7.5","8", "8.1", "8.2", "8.3", "8.4", "8.5","9", "9.1", "9.2", "9.3", "9.4", "9.5","10", "10.1", "10.2", "10.3", "10.4", "10.5","11", "11.1", "11.2", "11.3", "11.4", "11.5","12", "12.1", "12.2", "12.3", "12.4", "12.5","13", "13.1", "13.2", "13.3", "13.4","14", "14.1", "14.2", "14.3","15", "15.1", "15.2"]libcxx: [libstdc++, libstdc++11]threads: [null, posix, win32, mcf]  # Windows MinGWexception: [null, dwarf2, sjlj, seh]  # Windows MinGWcppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]clang:version: ["3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0","5.0", "6.0", "7.0", "7.1","8", "9", "10", "11", "12", "13", "14", "15", "16", "17","18", "19", "20", "21"]libcxx: [null, libstdc++, libstdc++11, libc++, c++_shared, c++_static]cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]runtime: [null, static, dynamic]runtime_type: [null, Debug, Release]runtime_version: [null, v140, v141, v142, v143, v144]cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]build_type: [null, Debug, Release, RelWithDebInfo]
  • profile文件
# host_x86_64
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux
os.platform=host
# pi4_aarch64
[settings]
arch=armv8
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux
os.platform=pi4
(2)添加conanfile.py文件
# conanfile.py
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDepsclass ConanDemo(ConanFile):name = "hello"version = "1.0"# Optional metadatalicense = "<Put the package license here>"author = "<Put your name here> <And your email here>"url = "<Package recipe repository url here, for issues about the package>"description = "<Description of hello package here>"topics = ("<Put some tag here>", "<here>", "<and here>")# Binary configurationsettings = "os", "compiler", "build_type", "arch"options = {"shared": [True, False], "fPIC": [True, False]}default_options = {"shared": False, "fPIC": True}# Sources are located in the same place as this recipe, copy them to the recipeexports_sources = "CMakeLists.txt", "source/*", "test/*"def config_options(self):passdef layout(self):cmake_layout(self)def generate(self):deps = CMakeDeps(self)deps.generate()tc = CMakeToolchain(self)tc.generate()def build(self):cmake = CMake(self)cmake.configure()cmake.build()def package(self):cmake = CMake(self)cmake.install()def package_info(self):self.cpp_info.libs = ["hello"]
(3)安装配置文件
  • 当前的工程结构
$ tree
.
|-- CMakeLists.txt
|-- conan
|   |-- profiles
|   |   |-- host_x86_64
|   |   `-- pi4_aarch64
|   `-- settings.yml
|-- conanfile.py
|-- source
|   `-- main.cpp
`-- test`-- main.cpp
  • 安装Conan配置
# 创建默认的profile
conan profile detect
# 安装指定的conan配置
conan config install conan

注:conan config install conan会将conan文件下的所有文件复制到Conan的家目录。

  • 检查安装的profile
$ conan profile list
Profiles found in the cache:
default
host_x86_64
pi4_aarch64
(4)基于conan创建包
  • 执行命令
# 清除已有构建
conan remove hello# 使用默认的profile创建包
conan create . 
# 使用host_x86_64创建包
conan create . -pr=host_x86_64
# 使用pi4_aarch64创建包
conan create . -pr=pi4_aarch64
  • 检查conan包
$ tree ~/.conan2/p -L 2
/root/.conan2/p
|-- b
|   |-- hello97f3ea6988f96
|   |-- hello9cf30133a2f6d
|   `-- hellob394c1d27f95b
|-- cache.sqlite3
|-- hello066c562205912
|   |-- d
|   |-- e
|   |-- es
|   `-- s
`-- t

conan cache中还是包含挺多文件:工程的源码文件、conan的生成文件、构建后的输出文件等,可以在自己本地搭建环境运行后自行查看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95524.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

核心高并发复杂接口重构方案

核心高并发复杂接口重构方案 一、重构目标与原则 核心目标 提升接口性能:降低响应时间,提高吞吐量,降低资源使用 增强可维护性:拆解复杂逻辑,模块化设计,降低后续迭代成本 保障稳定性:通过架构优化和灰度策略,确保重构过程无服务中断 提升扩展性:设计灵活的扩展点,…

C++容器内存布局与性能优化指南

C容器的内存布局和缓存友好性对程序性能有决定性影响。理解这些底层机制&#xff0c;能帮你写出更高效的代码。 一、容器内存布局概述 不同容器在内存中的组织方式差异显著&#xff0c;这直接影响了它们的访问效率和适用场景。容器类型内存布局特点元数据位置元素存储位置std::…

Beautiful.ai:AI辅助PPT工具高效搞定排版,告别熬夜做汇报烦恼

你是不是每次做 PPT 都头大&#xff1f;找模板、调排版、凑内容&#xff0c;熬大半夜出来的东西还没眼看&#xff1f;尤其是遇到 “明天就要交汇报” 的紧急情况&#xff0c;打开 PPT 软件半天&#xff0c;光标在空白页上晃来晃去&#xff0c;连标题都想不出来 —— 这种抓瞎的…

阿里云携手MiniMax构建云原生数仓最佳实践:大模型时代的 Data + AI 数据处理平台

MiniMax简介MiniMax是全球领先的通用人工智能科技公司。自2022年初成立以来&#xff0c;MiniMax以“与所有人共创智能”为使命&#xff0c;致力于推动人工智能科技前沿发展&#xff0c;实现通用人工智能(AGI&#xff09;。MiniMax自主研发了一系列多模态通用大模型&#xff0c;…

一键生成PPT的AI工具排名:2025年能读懂你思路的AI演示工具

人工智能正在重塑PPT制作方式&#xff0c;让专业演示变得触手可及。随着人工智能技术的飞速发展&#xff0c;AI生成PPT工具已成为职场人士、学生和创作者提升效率的得力助手。这些工具通过智能算法&#xff0c;能够快速将文本、数据或创意转化为结构化、视觉化的演示文稿&#…

数据库基础知识——聚合函数、分组查询

目录 一、聚合函数 1.1 count 1.1.1 统计整张表中所有记录的总条数 1.1.2 统计单列的数据 1.1.3 统计单列记录限制条件 1.2 sum 1.3 avg 1.4 max, min 二、group by 分组查询 2.1 语法 2.2 示例 2.3 having 一、聚合函数 常用的聚合函数 函数说明count ([distinc…

改 TDengine 数据库的时间写入限制

一 sql连数据库改 改 TDengine 数据库的时间写入限制 之前默认了可写入时间为一个月&#xff0c;调整为10年&#xff0c;方便测试&#xff1a; SHOW DATABASES;use wi; SELECT CONCAT(ALTER TABLE , table_name, KEEP 3650;) FROM information_schema.ins_tables WHERE db_…

数码视讯TR100-OTT-G1_国科GK6323_安卓9_广东联通原机修改-TTL烧录包-可救砖

数码视讯TR100-OTT-G1_国科GK6323_安卓9_广东联通原机修改-TTL烧录包-可救砖刷机教程数码视讯 TR100-G1 TTL 烧录刷机教程固件由广东联通 TR100-G1 28 原版修改&#xff0c;测试一切正常1、把刷机文件解压出 备用&#xff0c;盒子主板接好 TTL&#xff0c;不会接自行查找 TTl 接…

TVS防护静电二极管选型需要注意哪些参数?-ASIM阿赛姆

TVS防护静电二极管选型关键参数详解TVS(Transient Voltage Suppressor)二极管作为电路防护的核心器件&#xff0c;在电子设备静电防护(ESD)、浪涌保护等领域发挥着重要作用。本文将系统性地介绍TVS二极管选型过程中需要重点关注的参数指标&#xff0c;帮助工程师做出合理选择。…

项目经理为什么要有一张PMP®认证?

在项目管理日益成为企业核心竞争力的今天&#xff0c;PMP已成为项目经理职业发展的重要“通行证”。这张由美国项目管理协会&#xff08;PMI&#xff09;颁发的全球公认证书&#xff0c;不仅是专业能力的象征&#xff0c;更在职业竞争力、项目成功率、团队协作等多个维度为项目…

Qt中QSettings的键值使用QDataStream进行存储

1. QDataStream介绍 数据流是编码信息的二进制流&#xff0c;与主机的操作系统、CPU 或字节顺序完全无关。例如&#xff0c;Windows 系统下 PC 写入的数据流可由运行 Solaris 的 Sun SPARC 读取。 您还可以使用数据流读/写raw unencoded binary data 。如果需要 "解析 &…

Typer 命令行工具使用示例

Typer 命令行工具使用示例 示例1&#xff1a;简单问候程序 代码 import typerapp typer.Typer()app.command() def greet(name: str):"""简单的问候命令"""typer.echo(f"Hello {name}!")if __name__ "__main__":app()使用…

关于CAN总线bus off 理论标准 vs 工程实践

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

CAN堆栈

PDU映射到HOH将硬件对象句柄HOH抽象成为硬件抽象层CanIf将pdu映射到硬件对象句柄上一个HOH代表一个Can控制器的一个消息缓冲区发送缓存区当所有Can硬件资源被占用时&#xff0c;LPDU存储在缓冲区中。发送取消为了解决优先级反转的问题&#xff0c;高优先级L-PDU会请求取消低优先…

sub3G和sub6G的区别和联系

Sub-3G 和 Sub-6G 的区别与联系Sub-3G 和 Sub-6G 是无线通信中频段的不同分类&#xff0c;尤其在4G LTE和5G网络中&#xff0c;定义了无线信号传输的不同频率范围。具体来说&#xff0c;Sub-3G 通常指的是低于3 GHz的频段&#xff0c;而 Sub-6G 是指低于6 GHz的频段。这些频段的…

【数据可视化-106】华为2025上半年财报分析:用Python和Pyecharts打造炫酷可视化大屏

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

Scikit-learn Python机器学习 - 特征预处理 - 归一化 (Normalization):MinMaxScaler

锋哥原创的Scikit-learn Python机器学习视频教程&#xff1a; 2026版 Scikit-learn Python机器学习 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 课程介绍 本课程主要讲解基于Scikit-learn的Python机器学习知识&#xff0c;包括机器学习概述&#xff0c;特征工程(数据…

LINUX_Ubunto学习《2》_shell指令学习、gitee

0、前言&#xff1a; 0.1、为什么学习shell脚本 学习Shell&#xff08;Shell脚本编程&#xff09;是提升系统管理和开发效率的重要技能&#xff0c;尤其在Linux/Unix环境中作用显著。Shell是用户与操作系统内核的接口&#xff0c;学习Shell有助于掌握系统工作原理。shell的核心…

系统安装与迁移工具,一键下载系统并制作U盘启动盘

大家好&#xff0c;今天想跟大家分享一款非常实用的软件——Hasleo WinToUSB 下载地址获取 点击获取&#xff1a;WinToUSB启动盘 打开后的界面&#xff1b; image Windows To Go USB 可以安装或克隆 Windows 到 USB 设备&#xff0c;作为便携式 Windows 使用 可以选择直接用…

日语学习-日语知识点小记-构建基础-JLPT-N3阶段(26):文法+单词第8回3 复习 +考え方6

日语学习-日语知识点小记-构建基础-JLPT-N3阶段&#xff08;&#xff12;6&#xff09;&#xff1a;文法单词第8回3 复习1、前言&#xff08;1&#xff09;情况说明&#xff08;2&#xff09;工程师的信仰2、知识点1ー V辞書形 &#xff0b; ことができます。2ーこの橋、&am…