Retrieve all link flags in CMake

2019-01-09 13:49发布

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.

标签: cmake
1条回答
\"骚年 ilove
2楼-- · 2019-01-09 14:30

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

查看更多
登录 后发表回答