Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake library linking order

Tags:

gcc

cmake

I have following libraries lib_A, lib_B, lib_C, lib_D. I am doing something like this in my CMake files (order is important):

  1. ADD_LIBRARY(lib_A)
  2. ADD_LIBRARY(lib_B)
  3. ADD_LIBRARY(lib_C)
  4. ADD_LIBRARY(lib_D)
  5. TARGET_LINK_LIBRARIES(lib_B lib_C)
  6. TARGET_LINK_LIBRARIES(lib_A lib_B)
  7. ADD_EXECUTABLE(Exec)
  8. TARGET_LINK_LIBRARIES(exec lib_A)
  9. TARGET_LINK_LIBRARIES(exec lib_D)

This results in following linker command.

linker -llib_A -llib_D -llib_B -llib_C

Q1. Why are lib_B and lib_C after lib_D?

Q2. When I change CMake a little bit and do something like this:

  1. TARGET_LINK_LIBRARIES(lib_A lib_D)
  2. TARGET_LINK_LIBRARIES(exec lib_A)

then linking order is like this:

linker -llib_A -llib_B -llib_C -llib_D

Here, lib_B and lib_C are before lib_D. It means that target_link_libraries works differently for executable targets and library targets. Am I right?

The problem here is that lib_B and lib_C also depend on lib_D, but I don't want to make target_link_libraries(lib_B lib_D) and target_link_libraries(lib_C lib_D), because I have more of such cases, and I would have to do it manually for each library. Of course doing like in Q2 solves the problem but:

Q3 - Is this order guaranteed somehow by CMake or it is just a fortuity?

Thank you

like image 568
user2301299 Avatar asked Jul 17 '13 22:07

user2301299


People also ask

Does order matter in CMake?

The order of target creation does not affect the order of command execution. Only dependency order matters. It's just that you can't call certain functions on targets in the scripting language until they've been created.

Does linking order matter?

Link order certainly does matter, at least on some platforms. I have seen crashes for applications linked with libraries in wrong order (where wrong means A linked before B but B depends on A).

How do I link libraries in CMakeLists?

Linking libraries to executables with CMake Let's start by adding the library's directory as a subdirectory to our myapp project. add_subdirectory makes the library test defined in libtestproject available to the build. In target_link_libraries we tell CMake to link it to our executable.


1 Answers

Just link lib_B and lib_C to lib_D, it's worth the effort (I can tell by experience), otherwise you will have big troubles, for example if you try to install your program. lib_C and lib_D should have all their symbols solved when you are finished creating their library files, before linking them to any other library.

By the way, you can compact your target_link_libraries in one line per target, like:

TARGET_LINK_LIBRARIES(exec lib_A lib_D)

And, if exec doesn't depend directly on lib_D, you can avoid linking it if you have correctly linked lib_A to lib_D.

Anyway, regarding Q1: even if the order is guaranteed by CMake, it is not guaranteed the way your linker will treat it, you are going to suffer pain if you rely on that

like image 87
Antonio Avatar answered Oct 01 '22 03:10

Antonio