2

I need to get a list of all linked libraries in form as they will be passed to the linker in my CMake script.

For example, in my CMake project file, I define the target, which represents the build of a dynamic library. I call the functions from another CMake file's to include in my target all necessary static libraries, and finally if I

set(CMAKE_VERBOSE_MAKEFILE ON)

I see the output something like this: "clang++ -o /path/to/program.p /path/to/library1.a /path/to/library2.a" and so on.

I need to get the string that will contain the list of all static libraries linked to my dynamic library in my CMake script. I tried to do that like:

get_target_property(l_libs2 ${target} LINK_LIBRARIES)
message("!!!LINK_LIBRARIES: ${l_libs2}")

But it contains the string in the format like a: "Library::Library1;Library::Library2". I tried to get the same information from the properties: INTERFACE_LINK_LIBRARIES, LDFLAGS, LIBS, LINK_FLAGS, LINK_WHAT_YOU_USE, LINK_OPTIONS,...

Is it possible in principle? How to CMake engine "build" this argument for the linker?

Why I need that:

I need to exclude export from all libraries except one. If I pass to the linker option

"-Wl,--exclude-libs,ALL" 

it leads to SEGFAULT when my dynamic library (python extension module) loads into python. I played with compiler flags and found that it happens because

"--exclude-libs,ALL" 

exclude export from "python.a" library. So if I set the exclusion list more precisely i.e.

"-Wl,--exclude-libs,library1.a -Wl,--exclude-libs,library2.a" 

and so on, i.e. all libraries except "python.a", the module load to python without any problem. So I decided to generate this compiler option dynamically to get the libraries list and then, process it with regex. The best way to solve that is if clang will have the opposite option to "--exclude-libs" for example "--exclude-libs-except" (or something like that) but unfortunately I do not find it in clang documentation.

nen777w
  • 87
  • 1
  • 1
  • 6
  • This list of *linker arguments* is computed by the build system generator. Are you allowed and willing to invoke `cmake -G "Unix Makefiles"` or does this all have to happen inside CMake? – Botje Jan 25 '23 at 10:17
  • Maybe you have to explain why you want to do that. There is no obvious need for what you try to do. cmake can do linking all by itself with no further tricks. For checking you can use CMAKE_VERBOSE_MAKEFILE, as you suggest. Post-link, you can do `ldd`... – Ralf Ulrich Jan 25 '23 at 11:07
  • Added explanation to the question. – nen777w Jan 25 '23 at 13:41
  • @nen777w I've added an answer on how you can do this. However if I'm not mistaken you can achieve what you wish to achieve (in a clean way) via `set_target_properties` – Milan Š. Jan 25 '23 at 14:22
  • How do you add the dependencies to your target? I'm not sure if I fully understand your whole setup but perhaps you should add them as private dependencies? The thing I'm talking about is something like this: `target_link_libraries(${target} PRIVATE static_lib.a)` – tomdol Jan 25 '23 at 14:25

1 Answers1

1

Yes it is possible - I know of a way on how to get this once the files are generated, however I do not think it is possible (at least not in a straight forward way within the CMakeLists.txt file itself.).

I was once debugging a link dependency issue and had to "figure out" what is being passed to the linker. This is what I did:

  • Generated build files through CMake via cmake -S. -Bbuild
  • Greped the build folder e.g. grep -Ri "[-]lmylibrary*" ./build

The result was that only one specific file became of interest i.e.:

./build/CMakeFiles/target_name.dir/link.txt

This one file will contain what is being fed to your linker/compiler.

EDIT: I'll maybe also add that changing this file will truly affect the build. So if you want to make a "hack" to fix your issues you could always run a script on this file before building.

However I do believe that CMake can handle your issues well if configured correctly. For example via set_target_properties

Milan Š.
  • 1,353
  • 1
  • 2
  • 11