Static library dependency problem

I have a project where there is 1 static library (A) and 1 executable (E)

Linux, Ubuntu 24.04, cmake 3.28.3

The static library (A) itself links some system provided static libraries like this

target_link_libraries(A PUBLIC
  -Wl,-Bstatic
  ${YAML_STATIC_LIBRARIES} ${MINIZIP_STATIC_LIBRARIES} ${PCAP_STATIC_LIBRARIES} ${SLIRP_STATIC_LIBRARIES}
  -Wl,-Bdynamic
  )

these have been found via pkg_search_module.

Later in E, I do

target_link_libraries(E PUBLIC
  -Wl,-Bstatic
  ${NCURSES_STATIC_LIBRARIES} ${LIBEVDEV_STATIC_LIBRARIES}
  -Wl,-Bdynamic
  A
  )

so you can see that all system libraries are always inside the static / dynamic linker commands.

In the final linker command for E, cmake rearranges the libraries needed by A breaking this invariant.

This is a snippet of the final link command

-o E  -Wl,-Bstatic  -lncursesw  -ltinfo  -ldl  -levdev
-Wl,-Bdynamic  libA.a  -Wl,-Bstatic  -Wl,-Bdynamic
-lyaml  -lminizip  -lz  -lslirp  -lglib-2.0  -lm  -lpcre2-8

As you see it has moved A’s needed libraries outside the static / dynamic pair.

The obvious solution is to move all libraries to E, but this causes information leakage and duplication (I still need the header files in A).

It looks like cmake is trying to interpret A’s dependencies and decided to rearrange the tokens.

Thanks

Andrea

In the first place, why do you want to specify -Bstatic and -Bdynamic flags? Is there both variants of the libraries (i.e. static and dynamic)?

If yes, you can use $<LINK_LIBRARY> genex (example assumes the C language):

set(CMAKE_C_LINK_LIBRARY_USING_STATIC "LINKER:-Bstatic" <LINK_ITEM> "LINKER:-Bdynamic")
set(CMAKE_C_LINK_LIBRARY_USING_STATIC_SUPPORTED TRUE)

target_link_libraries(A PUBLIC
  "$<LINK_LIBRARY:STATIC,${YAML_STATIC_LIBRARIES},${MINIZIP_STATIC_LIBRARIES},${PCAP_STATIC_LIBRARIES},${SLIRP_STATIC_LIBRARIES}>"
  )

target_link_libraries(E PUBLIC
  "$<LINK_LIBRARY:STATIC,${NCURSES_STATIC_LIBRARIES},${LIBEVDEV_STATIC_LIBRARIES}>"
  A
  )

I did not know about this one. I was trying to use another thing as well LINK_SEARCH_START_STATIC and END which I struggle to understand.

Anyway, I need to link some (other) libraries dynamic as they either don’t exist or don’t work (lack of -fPIC since I need to generate some .so too).

I will try this too, thanks

It might be obvious, but I cannot find any documentation about the above syntax in that page.

This is the close it gets to: https://cmake.org/cmake/help/git-master/manual/cmake-generator-expressions.7.html#link-features

But STATIC is not a listed feature.

The STATIC feature is not provided as default. This is why, in the example, I also defined CMAKE_C_LINK_LIBRARY_USING_STATIC and CMAKE_C_LINK_LIBRARY_USING_STATIC_SUPPORTED variables.

The user is perfectly allowed to define new features to use with the $<LINK_LIBRARY> genex.