Link line dependency order using target_link_libraries

Hello,

I am trying to create a set of libraries that are not linked until the application definition. This is to allow the selection of functionality, in this case some log features, by the user. However I am seeing that cmake does not honor the library dependency order that I specify using ‘target_link_libraries’, It seems any transitive libraries are listed after those listed in the ‘target_link_libraries’ call. Please see the comments in the following example. Is there anyway to enforce a library ordering here?

Thanks.

cmake_minimum_required(VERSION 3.18)
set(CMAKE_CXX_STANDARD 11)
project(Test
    VERSION 0.0.0.0
    LANGUAGES C CXX ASM
)

###########################################
## Create a library with option1 for logging
## This is definition of a function found in log.hxx
## No link libraries required
###########################################
add_library(logOption1
   ${PROJECT_SOURCE_DIR}/logOption1.cxx
)
target_include_directories(logOption1
   PUBLIC
      ${PROJECT_SOURCE_DIR}
)

###########################################
## Create a library with option2 for logging
## This is another definition of the function found in log.hxx
## No link libraries required
###########################################
add_library(logOption2
   ${PROJECT_SOURCE_DIR}/logOption2.cxx
)
target_include_directories(logOption2
   PUBLIC
      ${PROJECT_SOURCE_DIR}
)

###########################################
## Create a library that defines a doSomething() function that calls the log() function
## This includes the log.hxx file
## Do not specify a logOption# link library as we do not want a dependency yet
###########################################
add_library(core
   ${PROJECT_SOURCE_DIR}/core.cxx
)
target_include_directories(core
   PUBLIC
      ${PROJECT_SOURCE_DIR}
)

###########################################
## Create a library that defines a doSomething2() function that calls the doSomething() function
## This includes the core.hxx file
## Link against the core library to bring in its include directories
###########################################
add_library(core2
   ${PROJECT_SOURCE_DIR}/core2.cxx
)
target_link_libraries(core2
   PUBLIC
      core
)

###########################################
## Create an executable that calls the doSomething2()
## This includes the core2.hxx file
## Link against the core2 library and we wish to use the option1 for logging
## However, the link line lists the dependencies as:
##    libcore2.a  logOption1.a  libcore.a
## This fails because libcore.a calls the log() function defined in liblogOption1.a
## but since the log library does not follow, we hit an undefined reference
###########################################
add_executable(main
   ${PROJECT_SOURCE_DIR}/main.cxx
)
target_link_libraries(main
   PRIVATE
      core2
      logOption1
)
``

Tell CMake that core depends on logOption1. I think even an INTERFACE link will do this (to make it not actually link core to it).

Thanks for the reply, however this also does not work. It seems cmake builds the link line in a particular manner where the immediate dependencies are listed first, and then the transitive dependencies are listed. My assumption (perhaps incorrect) would be that each immediate dependency would have its transitive dependencies listed directly after it, followed by the next immediate dependency and its transitive dependencies, and so on.

To get around this, I was able to create an INTERFACE library with my desired ordering and then have my executable depend on this new interface library.

###########################################
## Create an interface library to wrap the
## dependencies so that the desired link line
## order is maintained
###########################################
add_library(mainInterfaceLib
   INTERFACE
)
target_link_libraries(mainInterfaceLib
   INTERFACE
      core2
      logOption1
)
add_executable(main
   ${PROJECT_SOURCE_DIR}/main.cxx
)
target_link_libraries(main
   PRIVATE
      mainInterfaceLib
)