Conan 1.x迁移至2.x后静态库构建异常求助
Conan 2.x升级后静态库生成异常的修复方案
核心问题排查与修复步骤
1. 修正BUILD_SHARED_LIBS赋值类型
你在generate方法中将BUILD_SHARED_LIBS设为字符串"OFF",CMake对布尔变量的处理更兼容布尔值,改为False即可确保静态库生成逻辑生效:
def generate(self): tc = CMakeToolchain(self) tc.variables["BUILD_SHARED_LIBS"] = False # 替换字符串为布尔值 tc.generate()
2. 修复Layout与源码目录的不匹配
你的layout指定了src_folder="src",但实际源码被克隆到my-api目录,导致Conan路径上下文混乱,CMakeToolchain配置无法正确传递。两种修复方案:
- 方案一:调整源码目录到layout指定路径
def source(self): self.run(f"git clone --depth 1 --branch {BRANCH_NAME} git@github.com:EMCP/my-api.git") # 将my-api内容移动到src目录 self.run("mv my-api/* src/ && rm -rf my-api") # 修改CMakeLists.txt的路径为src/CMakeLists.txt files.replace_in_file(self, file_path="src/CMakeLists.txt", search="project( IBKR LANGUAGES CXX )", replace='''project( MYAPI LANGUAGES CXX ) add_compile_options(-std=c++17)''')
- 方案二:修改layout匹配源码目录
def layout(self): basic_layout(self, src_folder="my-api") def build(self): cmake = CMake(self) cmake.configure() # 无需再指定build_script_folder,layout已关联源码目录 cmake.build()
3. 强制覆盖原库CMakeLists的动态库设置
原第三方库的CMakeLists.txt可能硬编码了动态库生成逻辑,需在source阶段额外添加替换:
# 替换显式的SHARED库定义 files.replace_in_file(self, file_path="my-api/CMakeLists.txt", search="add_library(twsapi SHARED", replace="add_library(twsapi STATIC)") # 覆盖原库的BUILD_SHARED_LIBS设置(如果存在) files.replace_in_file(self, file_path="my-api/CMakeLists.txt", search="set(BUILD_SHARED_LIBS ON)", replace="set(BUILD_SHARED_LIBS OFF)")
4. 修正Conan选项定义格式
你的选项定义写法不符合Conan 2.x规范,需明确列出所有可选值:
options = {"shared": [True, False]} default_options = {"shared": False}
5. 优化package阶段的文件复制逻辑
当前package阶段同时复制动态库和静态库,可能误打包生成的动态文件,可根据shared选项过滤:
def package(self): cmake = CMake(self) cmake.install() copy(self, "*.h", self.source_folder, dst=join(self.package_folder, "include"), keep_path=False) if self.options.shared: copy(self, "*.lib", self.source_folder, dst=join(self.package_folder, "lib"), keep_path=False) copy(self, "*.dll", self.source_folder, dst=join(self.package_folder, "bin"), keep_path=False) copy(self, "*.so", self.source_folder, dst=join(self.package_folder, "lib"), keep_path=False) copy(self, "*.so", src=join(self.build_folder, "lib"), dst=join(self.package_folder, "lib"), keep_path=False) copy(self, "*.dylib", self.source_folder, dst=join(self.package_folder, "lib"), keep_path=False) else: copy(self, "*.lib", self.source_folder, dst=join(self.package_folder, "lib"), keep_path=False) copy(self, "*.a", self.source_folder, dst=join(self.package_folder, "lib"), keep_path=False) copy(self, "*.a", src=join(self.build_folder, "lib"), dst=join(self.package_folder, "lib"), keep_path=False) # 系统库复制逻辑保留 lib_paths = ["/usr/lib/x86_64-linux-gnu/libbidgcc000.a"] for lib_path in lib_paths: if os.path.isfile(lib_path): self.output.info(f"Found library: {lib_path}") copy(self, pattern="libbidgcc000*.a", dst="lib", keep_path=False, src="/usr/lib/x86_64-linux-gnu/") else: self.output.warn(f"Library not found: {lib_path}")
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

