5

I have a static link library (say libfoo).

 add_library(foo STATIC foo.cpp)

There are many executables that links(uses) this library.

 add_executable(myexe1 myexe1.cpp)
 link_target_libraries(myexe1 foo)
 add_executable(myexe2 myexe2.cpp)
 link_target_libraries(myexe2 foo)
 add_executable(myexe3 myexe3.cpp)
 link_target_libraries(myexe3 foo)
 #... and so on. (These definitions are actually scattered in the project)

Now I would like to use -Wl,--whole-archive flag to the library. It seems one solution is to add the flags in the executable side.

 add_executable(myexe1 myexe1.cpp)
 link_target_libraries(myexe1 -Wl,--whole-archive foo -Wl,--no-whole-archive)

But in this way I have to write this every time I define executable that links to this library.

Is there any way to add this flag to the library definition side so that the flag is always used when linking the executables that depend on the library?

Shu Suzuki
  • 1,164
  • 11
  • 19

2 Answers2

4

I had the same problem, but could not stop CMAKE from reordering the flags and my library. I ended up doing something like this:

add_library(foo_actual STATIC foo.cpp)
add_library(foo INTERFACE)
set_property(TARGET foo PROPERTY INTERFACE_LINK_LIBRARIES
  -Wl,--whole-archive,$<TARGET_FILE:foo_actual>,--no-whole-archive)

Couple differences with your answer:

  • My version of CMake (3.7) didn't allow the get_property, but $<TARGET_FILE> worked well and ensures the dependency is propagated.
  • I used commas to put the --whole-archive, library, and --no-whole-archive all in one argument, so CMake wouldn't reorder them. I could not get CMake not to wildly reorder them, otherwise.
David Ghandehari
  • 534
  • 3
  • 12
  • I'm guessing if you tried to also do something like: target_include_directories(foo_actual PUBLIC .) that it would fail. It did for me. It seems CMake can't do both: if you stick your file inside the --whole-archive piece then foo_actual is treated just like a flag. You can't also get his usage requirements (i.e. what include folders he PUBLICly brings to the table). This seems to be one area where mixing flags and dependencies together with one command: target_link_libraries is a bad design by cmake. – Rich von Lehe Oct 30 '18 at 22:52
2

I solved this with the following solution.

add_library(foo STATIC foo.cpp)
get_property(foo_location TARGET foo PROPERTY LOCATION)     
target_link_libraries(foo -Wl,--whole-archive ${foo_location} -Wl,--no-whole-archive) 
Shu Suzuki
  • 1,164
  • 11
  • 19
  • `c++: error: unrecognized command-line option ‘-Wl’; did you mean ‘-W’?` `c++: error: unrecognized command-line option ‘--whole-archive’; did you mean ‘--whole-file’?` (CMake 3.23.2) – MiloDC Jul 13 '22 at 01:08