Conan 默认支持 Debug/Release,但必须在 conanfile.py 的 settings 中显式声明 build_type,否则其不参与 package ID 计算,导致二进制混用;install 时须用 -s build_type=Debug/Release 显式指定,并与 CMake 构建类型严格对齐。

Conan 默认就支持 Debug 和 Release,不需要额外“开启”,但必须让 build_type 正确参与 package ID 计算,并在构建、安装、消费全流程保持一致 —— 否则你会拿到错的二进制,或者链接失败。
conanfile.py 中必须声明 build_type 在 settings
如果你没显式写,Conan 2.x 会从 profile 继承,但 package ID 不会包含它(除非你把它放进 settings)。后果是:Debug 和 Release 二进制被塞进同一个 package ID,互相覆盖或静默混用。
正确写法(必须):
from conan import ConanFile <p>class HelloConan(ConanFile): name = "hello" version = "1.0"</p><h1>✅ 必须包含 build_type</h1><pre class="brush:php;toolbar:false;">settings = "os", "arch", "compiler", "build_type" # ❌ 不要省略,也不要只写在 profile 里而不在 recipe 中
-
build_type是settings,不是options,不能用self.options.build_type访问 - 一旦声明,Conan 会自动把
build_type=Debug和build_type=Release视为两个完全不同的 package ID - 如果项目同时需要静态/动态库,还要加上
shared选项,否则shared=True和shared=False也会被当成同一包
conan install 时必须传 --settings build_type=Debug
很多人以为 profile 里写了 build_type=Debug 就够了,其实 conan install 命令本身不读取 profile 的 build_type 来决定拉哪个包 —— 它只用来推导默认值;真正决定 package ID 的,是命令行显式传入的 --settings。
错误示例(profile 有 build_type=Debug,但没传):
conan install . -pr:h my-win-profile -if build
这会 fallback 到 profile 默认值,但更危险的是:如果远端没有该 build_type 对应的二进制,Conan 默认不会报错,而是尝试源码构建 —— 可能构建出 Release 版本却声称是 Debug。
正确做法(显式指定):
conan install . -s build_type=Debug -pr:h my-win-profile -if build conan install . -s build_type=Release -pr:h my-win-profile -if build
- Linux/macOS(单配置生成器如 Ninja):
-s build_type=Debug+ CMake 的-DCMAKE_BUILD_TYPE=Debug必须严格一致 - Windows/MSVC(多配置生成器如 Visual Studio):
-s build_type=Debug决定拉哪个包,但 CMake 生成时不传DCMAKE_BUILD_TYPE;链接时靠--config Debug区分 - 不要依赖
conan config set general.default_build_type=Debug,它只影响新 profile 初始化,不参与 package ID 计算
CMake 集成时,build_type 和 CMAKE_BUILD_TYPE 易混淆
Conan 的 build_type 和 CMake 的 CMAKE_BUILD_TYPE 不是同一个东西,但必须对齐。错位会导致:CMake 用 Debug 模式编译,却链接了 Release 的 Conan 包(或反之),典型报错如 LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL'(MSVC)或 undefined reference to `__assert_fail'(GCC)。
对齐方式取决于生成器类型:
- 单配置(Ninja / Makefiles):
conan install -s build_type=Debug→ CMake 必须同步-DCMAKE_BUILD_TYPE=Debug - 多配置(Visual Studio / Xcode / Ninja Multi-Config):
conan install -s build_type=Debug→ CMake 生成时不设CMAKE_BUILD_TYPE,构建时用--config Debug或 IDE 切换配置 -
CMakeDeps生成器会为每个build_type生成独立的xxx-release-config.cmake和xxx-debug-config.cmake,但前提是build_type真正参与了 package ID
为什么 package_info() 里不能硬编码库名后缀?
有人会在 package_info() 里写 self.cpp_info.libs = ["hello_d"](Debug)或 ["hello"](Release),这是错的 —— 它破坏了 Conan 的条件逻辑,导致 consumer 无法自动适配。
正确做法是让 package_info() 根据当前 self.settings.build_type 动态设置:
def package_info(self):
if self.settings.build_type == "Debug":
self.cpp_info.libs = ["hello_d"]
else:
self.cpp_info.libs = ["hello"]
# 还可加调试宏
if self.settings.build_type == "Debug":
self.cpp_info.defines.append("DEBUG_MODE")
- 不要在
conan create时手动改库文件名;Conan 会按build_type自动区分目录结构 - 如果用了
cmake_find_package生成器,它不支持这种动态库名,建议迁移到CMakeDeps - 最易忽略的一点:
conan upload时,必须确保上传的是带完整build_type的 package ID,否则远端仓库里 Debug/Release 会丢失维度

















