如何使用单个CMake生成器表达式实现多依赖库的条件链接
问题原因
示例2报错的核心原因是CMake原生列表以分号作为分隔符,直接把列表变量放入生成器表达式时,CMake会在配置阶段就将列表的分号识别为参数分隔符,破坏生成器表达式的完整结构,最终导致生成的编译配置文件格式错乱。
可行解决方案
方案1:用$处理分隔符
依赖数量少的场景下,可以直接在生成器表达式中用$<SEMICOLON>替代普通分号分隔库名,避免配置阶段参数被拆分:
cmake_minimum_required(VERSION 3.20.0) project(cmake-genex) add_library(lib1 SHARED source1.hpp source1.cpp) add_library(lib2 SHARED source2.hpp source2.cpp) add_library(lib3 SHARED source3.hpp source3.cpp) add_executable(main main.cpp) target_link_libraries(main $<$<PLATFORM_ID:Linux>:lib1$<SEMICOLON>lib2$<SEMICOLON>lib3> )
如果依赖较多已经存为列表变量,可以配合$<LIST:JOIN>(CMake 3.15+支持)自动处理分隔符:
cmake_minimum_required(VERSION 3.20.0) project(cmake-genex) add_library(lib1 SHARED source1.hpp source1.cpp) add_library(lib2 SHARED source2.hpp source2.cpp) add_library(lib3 SHARED source3.hpp source3.cpp) set(linux_libs lib1 lib2 lib3 ) add_executable(main main.cpp) target_link_libraries(main $<$<PLATFORM_ID:Linux>:$<LIST:JOIN,${linux_libs},$<SEMICOLON>>> )
方案2:通过INTERFACE库打包依赖
如果需要复用这组依赖,或者希望代码可读性更高,可以把平台专属依赖打包为一个INTERFACE库,再用生成器表达式控制是否链接:
cmake_minimum_required(VERSION 3.20.0) project(cmake-genex) add_library(lib1 SHARED source1.hpp source1.cpp) add_library(lib2 SHARED source2.hpp source2.cpp) add_library(lib3 SHARED source3.hpp source3.cpp) # 打包Linux平台专属依赖 add_library(linux_deps INTERFACE) target_link_libraries(linux_deps INTERFACE lib1 lib2 lib3) add_executable(main main.cpp) target_link_libraries(main $<$<PLATFORM_ID:Linux>:linux_deps> )
以上两种方案最终生成的构建配置都会符合预期的链接逻辑。
内容的提问来源于stack exchange,提问作者Joakim Thorén
相关产品推荐
相关产品推荐

