compiler.runtime 是 conan profile 中控制 c++ 运行时链接方式的关键设置,决定静态(static)或动态(dynamic)链接 msvcrt(windows),需与 visual studio 项目属性中“运行库”选项严格一致(如 /md→dynamic,/mt→static),且必须显式声明,conan profile detect 不自动设置;linux/macos 对应项为 compiler.libcxx,须匹配实际标准库 abi(如 libc++ 或 libstdc++11)。

conan profile 里 compiler.runtime 是什么
compiler.runtime 是 Conan profile 中控制 C++ 运行时链接方式的关键设置,它直接决定生成的库或可执行文件是静态链接(static)还是动态链接(dynamic)MSVCRT(Windows)或 libc++/libstdc++(Linux/macOS)。这个值不参与编译器自动检测,必须显式声明,否则默认行为因 Conan 版本和 profile 来源而异(v2 默认常为 dynamic,但不可依赖)。
常见取值只有两个:dynamic 对应 /MD(Release)或 /MDd(Debug),static 对应 /MT 或 /MTd。一旦设错,轻则 LNK2038 运行时版本不匹配,重则运行时崩溃(如 malloc/free 跨 DLL 边界)。
如何正确设置 compiler.runtime 值
不能靠猜测,必须和你实际用的 Visual Studio 工程配置完全一致。打开 VS 项目属性 → C/C++ → 代码生成 → 运行库,看显示的是 /MD、/MDd、/MT 还是 /MTd,再映射到 profile:
-
/MD→compiler.runtime=dynamic -
/MDd→compiler.runtime=dynamic+build_type=Debug -
/MT→compiler.runtime=static -
/MTd→compiler.runtime=static+build_type=Debug
例如,VS2019 默认新建项目用 /MD,那 profile 就该写:
[settings] os=Windows arch=x86_64 compiler=msvc compiler.version=192 compiler.runtime=dynamic compiler.cppstd=17 build_type=Release
注意:compiler.runtime 必须和 build_type 搭配使用——Debug 构建下即使 runtime=dynamic,Conan 也会拉取带 d 后缀的 debug 版本二进制(如 vcruntimed.lib),前提是远程仓库有对应包。
为什么 conan profile detect 不设 compiler.runtime
conan profile detect 只读取系统环境变量和编译器可执行路径,它无法知道你工程里选的是 /MD 还是 /MT——这是项目级配置,不是系统级。所以它永远不写 compiler.runtime 行,留给你手动补全。漏掉这行,Conan 会按内部默认策略选(v2 多数情况 fallback 到 dynamic),但你无法保证所有依赖包都提供了你想要的 runtime 变体。
验证是否生效:运行 conan install . -pr=myprofile --build=missing 后,检查输出中是否出现类似 ffmpeg/4.4.3: Package 'xxx' built 的构建日志;如果看到 ERROR: Missing prebuilt package,大概率就是 compiler.runtime 和远程包提供的变体不匹配(比如你要 static,但 conancenter 只有 dynamic 二进制)。
跨平台项目要注意 libcxx 设置
Linux/macOS 下没有 compiler.runtime,但等效的是 compiler.libcxx。它控制标准库实现链接方式:
-
libstdc++(GCC 默认) -
libstdc++11(C++11 ABI) -
libc++(Clang 默认)
这个值必须和你的编译器实际使用的标准库 ABI 一致。例如 Clang + libc++ 项目若设成 libstdc++11,链接时大概率报 undefined reference to std::string::...。macOS 上尤其敏感,因为系统 libc++ 和 Homebrew GCC 的 libstdc++ ABI 不兼容。
简单判断方法:在终端运行 $CXX --version,看输出含 “clang” 还是 “gcc”;再运行 $CXX -x c++ -E -v /dev/null 2>&1 | grep "c\+\+",确认实际 include 路径指向 libc++ 还是 libstdc++。然后在 profile 里明确写死,不要省略。











