Joakim Thorén
Joakim Thorén

Reputation: 1281

Use CMake generator expression to conditionally link towards list of libraries

cmake-genex can be used to conditionally link libraries based on information only available at CMake build-time:

Example 1: Using one genex per lib

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>
)

This works as intended, however is a bit verbose. It'd be neat to use a single genex for all libs:

Example 2: Using one genex for all libs

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}>
)

However, Example2 fails. In my case I used ninja as generator. ninja.build shows this:

ninja.build (excerpt)

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

I expected the following:

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

How can one genex decide whether to conditionally link towards several libraries or not?

Upvotes: 2

Views: 1524

Answers (1)

Joakim Thor&#233;n
Joakim Thor&#233;n

Reputation: 1281

It's possible to use one genex for all libs if the genex is quoted:

Working example with one genex for all libs

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}>"
)

This will generate the expected output:

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

I don't know why quoting works. Maybe someone else can explain this.

Upvotes: 2

Related Questions