Conan为Windows生成二进制包的核心在于选择正确方式:conan create从源码构建(需完整settings和CRT控制),conan export-pkg打包已有二进制(需显式指定Windows settings且package()路径准确),二者不可混用,否则导致不可复现或ABI不兼容。

Conan 为 Windows 生成二进制包,核心不是“能不能”,而是“用什么方式生成”——conan create 从源码构建,conan export-pkg 打包已有二进制,二者适用场景完全不同,选错直接导致包不可复现或 ABI 不兼容。
用 conan create 从源码构建 Windows 二进制包
这是最常见、也最推荐的流程,尤其当你控制源码且需要跨配置(如 Visual Studio 2022 / MD / x64 / Release)生成不同二进制时。
- 确保
conanfile.py中settings包含"os", "compiler", "build_type", "arch",Windows 下compiler必须显式声明(如msvc或clang),不能省略 - Windows 上默认不启用
fPIC,但若目标是动态库(shared=True)且后续要被其他 DLL 加载,建议在options中添加"fPIC": [True, False]并在configure()中校验 - MSVC 下必须处理 CRT 链接:在
CMake配置阶段传入-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$:Debug>,否则生成的.lib和.dll可能混用/MD与/MT,链接时报LNK2038 - 执行命令时必须指定 profile 或完整 settings,例如:
conan create . --profile:build=default --profile:host=msvc2022-x64-release,仅靠--build=missing无法保证 Windows 下编译器版本和运行时一致
用 conan export-pkg 打包已存在的 Windows 二进制
适用于你已有预编译好的 .lib + .dll(比如第三方闭源 SDK),或者本地调试后想快速导出当前构建产物到 Conan 缓存,跳过重复编译。
- 必须先运行
conan build或手动构建,确保二进制文件已存在于工作目录(如build/Release/下有mylib.lib和mylib.dll) -
conan export-pkg不执行build()方法,所以conanfile.py中的build()可以为空,但package()必须正确描述文件来源路径,例如:self.copy("*.lib", dst="lib", src=os.path.join(self.build_folder, "Release")) - 必须显式传入
--settings,否则 Conan 会按默认(通常是 Linux)推断,导致包元数据中os=Windows缺失,下游conan install时匹配失败 - 命令示例:
conan export-pkg . mypkg/1.0@user/channel -s os=Windows -s arch=x86_64 -s compiler=msvc -s compiler.version=193 -s compiler.runtime=dynamic -s build_type=Release
Windows 下容易踩的坑:CRT、路径、大小写
Windows 环境下 Conan 的行为和 Linux 差异明显,很多问题不是 Conan 本身 bug,而是 Windows 构建生态固有约束。
-
conanfile.py中用tools.replace_in_file()修改 CMakeLists.txt 时,Windows 默认换行符是,正则匹配需加re.DOTALL,否则替换失败静默忽略 - MSVC 工具链路径含空格(如
Program Files)时,CMake 命令行必须用双引号包裹路径,CMake(self)类默认处理了这点,但手写self.run("cmake ...")时极易漏掉 - Conan 缓存路径(
~/.conan2)在 Windows 上可能落在 OneDrive 同步目录里,导致conan create过程中文件被后台同步锁住,报错PermissionError: [WinError 32]—— 直接把缓存迁移到非同步盘即可 - 包内头文件路径写成
self.copy("*.h", dst="include", src="src\public")是错的:src参数路径分隔符必须用正斜杠/或os.path.join(),反斜杠会被当成转义字符解析失败
真正麻烦的从来不是“怎么打包”,而是“怎么让这个包在别人的 VS 工程里不报 LNK2019、不崩在 DLL 加载时、不因为一个 runtime 设置错就全链路失效”——Windows 下每个 settings 组合都对应真实可执行的二进制,少设一个,下游就多一分不可控。


















