能否在CMake中unset导入库目标以适配不同第三方库版本?
问题分析与解决方案
首先明确:没法通过unset导入库目标实现你的需求。CMake里的目标是全局作用域的,一旦用add_library创建了导入目标,unset(third-party-lib)根本没用——这个命令只能清除变量,动不了CMake已经注册的目标对象,所以你才会一直报“目标已存在”的错。
针对你的场景,给两个可行的解决思路:
1. 给不同版本的库创建独立目标
别复用同一个目标名,给每个编译器版本的库单独起名字,比如third-party-lib-gcc、third-party-lib-clang。对应你的最小示例,修改后代码如下:
根目录CMakeLists.txt:
set(MY_DIR "/path/one") add_library(third-party-lib-one INTERFACE IMPORTED) set_target_properties(third-party-lib-one PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${MY_DIR}/usr/local/include) add_executable(foo main.cpp) target_link_libraries(foo third-party-lib-one) add_subdirectory(bar)
bar子目录CMakeLists.txt:
set(MY_DIR "/path/two") add_library(third-party-lib-two INTERFACE IMPORTED) set_target_properties(third-party-lib-two PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${MY_DIR}/usr/local/include) add_executable(bar main.cpp) target_link_libraries(bar third-party-lib-two)
2. 针对find_package的场景处理
如果是用第三方库的config.cmake文件,你可以:
- 先设置对应版本的路径变量(比如指定编译器相关的路径前缀)
- 调用
find_package时,清理缓存并避免复用已有配置,给每个版本的库指定不同的目标别名:
# 导入gcc版本 set(MY_DIR "/path/gcc-version") find_package(ThirdParty NO_CMAKE_CURRENT_DIR) add_library(third-party-lib-gcc ALIAS ThirdParty::ThirdParty) # 导入clang版本 unset(ThirdParty_DIR CACHE) # 清除缓存的路径变量 set(MY_DIR "/path/clang-version") find_package(ThirdParty NO_CMAKE_CURRENT_DIR) add_library(third-party-lib-clang ALIAS ThirdParty::ThirdParty)
之后让不同的目标分别链接third-party-lib-gcc或third-party-lib-clang即可。
内容的提问来源于stack exchange,提问作者user3667089
相关产品推荐
相关产品推荐

