Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve all link flags in CMake

Tags:

cmake

In CMake, is it possible to programmatically retrieve the complete list of linker flags that will be used for a given target? The only way I can see to do this is to inspect the link.txt file in the target's CMakeFiles directory. Not ideal.

The use case that I'm interested in is to collect the data to include in something like a pkg-config file. I'm writing a library, and it includes a couple executable utilities that use the library. Building the executables (especially when the library is build statically) requires a non-trivial link line to link to my library and its dependencies. So I'd like to write out the link line necessary for building these executables to a data file included with the package such that other clients can know how to link.

like image 613
Robert T. McGibbon Avatar asked Dec 08 '15 20:12

Robert T. McGibbon


1 Answers

As @Tsyvarev has commented there is no build-in command or property "to programmatically retrieve the complete list of linker flags" in CMake.

But inspired by your hint "so I'd like to write out the link line necessary for building these executables to a data file" I think I found a feasible solution (at least for makefile generators).

And if I understand your request correctly, we are not talking about simple verbose outputs like you get with e.g. CMAKE_VERBOSE_MAKEFILE, which would still need you to copy things manually.

So taking the following into account:

  • You need to run the generator first to get the real link line
  • CMake allows you to invent any linker language by name
  • You can define the link line with CMAKE_>LANG<_LINK_EXECUTABLE using variables and expansion rules

I came up with adding an LinkLine executable using my ECHO "linker" with the single purpose to create a link line file of my choosing:

set(CMAKE_ECHO_STANDARD_LIBRARIES ${CMAKE_CXX_STANDARD_LIBRARIES})
set(CMAKE_ECHO_FLAGS ${CMAKE_CXX_FLAGS})
set(CMAKE_ECHO_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS})
set(CMAKE_ECHO_IMPLICIT_LINK_DIRECTORIES ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
set(
    CMAKE_ECHO_LINK_EXECUTABLE 
    "<CMAKE_COMMAND> -E echo \"<FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>\" > <TARGET>"
)

add_executable(LinkLine "")
target_link_libraries(LinkLine MyLibraryTarget)

set_target_properties(
    LinkLine 
        PROPERTIES
            LINKER_LANGUAGE ECHO
            SUFFIX          ".txt"
)

The nice thing about this approach is, that the output of my LinkLine target can be used as any other "officially generated" executable output (e.g. in install() commands or post-build steps with generator expressions):

add_custom_command(
    TARGET LinkLine
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:LinkLine> PackageCfg/$<TARGET_FILE_NAME:LinkLine>
)

References

  • Recursive list of LINK_LIBRARIES in CMake
  • add_custom_command is not generating a target
like image 190
Florian Avatar answered Oct 21 '22 00:10

Florian