Conan未正确传递compiler.libcxx等编译配置问题求助
问题描述
我的默认Conan配置文件如下:
$ conan profile show default Configuration for profile default: [settings] os=Linux os_build=Linux arch=x86_64 arch_build=x86_64 compiler=gcc compiler.version=11 compiler.cppstd=20 compiler.libcxx=libstdc++ build_type=Release [options] [conf] [build_requires] [env]
注:compiler.libcxx特意设置为旧ABI的libstdc++而非新ABI的libstdc++11,同时指定了cppstd=20。
我为fmt 9.0.0编写了自定义conanfile.py:
from conans import ConanFile, CMake, tools from conan.tools.cmake import CMakeToolchain, cmake_layout class ConanFmt(ConanFile): name = "fmt" version = "9.0.0" settings = "os", "compiler", "cppstd", "build_type", "arch" def source(self): git = tools.Git(folder="fmt") git.clone("https://github.com/fmtlib/fmt.git", "9.0.0", shallow=True) def layout(self): cmake_layout(self) def generate(self): tc = CMakeToolchain(self) tc.generate() def build(self): cmake = CMake(self) cmake.definitions["FMT_DOC"] = False cmake.definitions["FMT_TEST"] = False cmake.definitions["FMT_INSTALL"] = True cmake.definitions["CMAKE_EXPORT_COMPILE_COMMANDS"] = True cmake.configure(source_folder="fmt") cmake.build() def package(self): cmake = CMake(self) cmake.install() def package_info(self): self.cpp_info.libs = ["fmt"]
执行$ conan create . demo/testing -s build_type=Release后,Conan能正常克隆仓库并打包,但存在三个问题:
- 未设置
_GLIBCXX_USE_CXX11_ABI定义(与Conan官方文档描述不符); - fmt实际以C11而非C20编译;
- 仅Release构建模式的编译选项(
-O3 -DNDEBUG)生效,其他配置未传递。
Conan提供的CONAN_CMAKE_CXX_STANDARD=20、CONAN_STD_CXX_FLAG=-std=c++2a、CONAN_LIBCXX=libstdc++等变量未被fmt构建使用,请问如何让Conan正确传递这些配置?是否必须在conanfile.py中显式指定?
解决方案
1. 补全settings声明
当前settings列表缺少compiler.libcxx,Conan无法识别并传递该配置项,先修正类的settings定义:
settings = "os", "compiler", "compiler.version", "compiler.cppstd", "compiler.libcxx", "build_type", "arch"
2. 强化CMakeToolchain的配置传递
在generate方法中,显式传递C++标准与ABI相关定义,确保CMake能正确接收:
def generate(self): tc = CMakeToolchain(self) # 强制传递C++标准,要求CMake严格遵循 tc.variables["CMAKE_CXX_STANDARD"] = self.settings.compiler.cppstd tc.variables["CMAKE_CXX_STANDARD_REQUIRED"] = True tc.variables["CMAKE_CXX_EXTENSIONS"] = False # 根据libcxx设置_GLIBCXX_USE_CXX11_ABI宏 if self.settings.compiler == "gcc": if self.settings.compiler.libcxx == "libstdc++": tc.variables["CMAKE_CXX_FLAGS"] = "-D_GLIBCXX_USE_CXX11_ABI=0" elif self.settings.compiler.libcxx == "libstdc++11": tc.variables["CMAKE_CXX_FLAGS"] = "-D_GLIBCXX_USE_CXX11_ABI=1" tc.generate()
3. 优化build方法的CMake调用
借助cmake_layout的自动路径管理,去掉手动指定source_folder,确保工具链文件被正确加载:
def build(self): cmake = CMake(self) cmake.definitions["FMT_DOC"] = False cmake.definitions["FMT_TEST"] = False cmake.definitions["FMT_INSTALL"] = True cmake.definitions["CMAKE_EXPORT_COMPILE_COMMANDS"] = True # 现代CMake API会自动读取toolchain文件,无需手动指定源码路径 cmake.configure() cmake.build()
4. 验证配置有效性(可选)
可以在build方法中添加调试输出,确认配置是否被正确读取:
def build(self): self.output.info(f"当前使用C++标准: {self.settings.compiler.cppstd}") self.output.info(f"当前使用libcxx: {self.settings.compiler.libcxx}") # ... 原有build代码
关键说明
- 无需手动调用
CONAN_*系列环境变量,CMakeToolchain会自动处理大部分常规配置,但ABI宏这类编译器特定定义需要显式设置; - 必须在
settings中声明所有需要传递的配置项,否则Conan不会将其纳入构建上下文; - fmt的官方CMakeLists.txt会尊重
CMAKE_CXX_STANDARD参数,只要该变量正确传递,就能以指定的C++版本编译。
内容的提问来源于stack exchange,提问作者Barry
相关产品推荐
相关产品推荐

