8

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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Robert T. McGibbon
  • 5,075
  • 3
  • 37
  • 45
  • 1
    If you want more than target's property `LINK_FLAGS` gives, you probably will face with listing all link targets. See, e.g., [this question](http://stackoverflow.com/questions/32756195/recursive-list-of-link-libraries-in-cmake). And this problem seems cannot be resolved within CMake script. But you may try generator expression with this property. It may work as using `INCLUDE_DIRECTORIES` one. – Tsyvarev Dec 08 '15 at 20:55
  • The possible answers really depend on your motivation. Can you please go a little more into details what you want to do with the flags? E.g. documentation, error tracking, reuse elsewhere, ... – Florian Dec 09 '15 at 12:04
  • @Florian: okay, I updated the question with my use case. – Robert T. McGibbon Dec 09 '15 at 22:38

1 Answers1

5

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

Community
  • 1
  • 1
Florian
  • 39,996
  • 9
  • 133
  • 149