使用 CMake 生成器表达式有条件地链接到库列表

Posted

技术标签:

【中文标题】使用 CMake 生成器表达式有条件地链接到库列表【英文标题】:Use CMake generator expression to conditionally link towards list of libraries 【发布时间】:2021-12-05 09:01:20 【问题描述】:

cmake-genex 可用于根据仅在 CMake 构建时可用的信息有条件地链接库:

示例 1:每个库使用一个genex

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>
    $<$<PLATFORM_ID:Linux>:lib2>
    $<$<PLATFORM_ID:Linux>:lib3>
)

这按预期工作,但是有点冗长。为所有库使用单个基因会很整洁:

示例 2:对所有库使用一个genex

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>:$linux_libs>
)

但是,Example2 失败。就我而言,我使用 ninja 作为生成器。 ninja.build 显示:

ninja.build(摘录)

LINK_LIBRARIES = -Wl,-rpath,/mnt/c/Users/joakim.thoren/programming/cmake-genex/build  $<1:lib1  liblib2.so  -llib3>

我预计会出现以下情况:

LINK_LIBRARIES = -Wl,-rpath,/mnt/c/Users/joakim.thoren/programming/cmake-genex/build  liblib1.so  liblib2.so  liblib3.so

一个genex如何决定是否有条件地链接到几个库?

【问题讨论】:

为什么在这里使用生成器表达式?我认为if(UNIX) target_link_libraries(main lib1 lib2 lib3) endif() 更容易理解...... @f*** 这只是一个 SSCCE,而不是我的实际用例。你当然可以像以前那样做,完全避免基因。 【参考方案1】:

如果引用了genex,则可以对所有库使用一个genex:

所有库都使用一个基因的工作示例

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>:$linux_libs>"
)

这将产生预期的输出:

LINK_LIBRARIES = -Wl,-rpath,/mnt/c/Users/joakim.thoren/programming/cmake-genex/build  liblib1.so  liblib2.so  liblib3.so

我不知道为什么引用有效。也许其他人可以解释这一点。

【讨论】:

以上是关于使用 CMake 生成器表达式有条件地链接到库列表的主要内容,如果未能解决你的问题,请参考以下文章

CMake:从“make install [all]”中排除自定义安装目标

cmake基础教程(40)生成器表达式

cmake基础教程(40)生成器表达式

CMake条件库链接取决于平台

CMake:如何添加仅针对一种配置执行的自定义命令?

三元表达式,列表推导式,生成器表达式