How do I find the dll/so files used when linking an executable?

Setup:

Repository A creates a shared library that we have a relocatable packages for.

Repository B creates a shared library that we have a relocatable package for. Moreover, Repo-B uses Repo-A, therefore Repo-A appears in the interface listing of Repo-B.

Finally, we have an application C that links with/uses Repo-B and because of the interface automatically finds and links with Repo-A too.

Yay!

Problem:

The problem I’m having is that I want the Repo-A and Repo-B dll files copied into the same folder as the executable from the application.

Is there an easy way to do this?

I did some reading, and I thought I figured out a way to do this using install(...RUNTIME_DEPENDENCIES...) and it worked for some of our applications, but not all of them.

What I found was if the application only uses code from Repo-B, then Repo-B appears as a dependency of the application, but Repo-A does not. However, using a dependency tool I see that Repo-B does appear as dependency of Repo-A – a grandchild dependency for the application – which doesn’t appear to be available via RUNTIME_DEPENDENCIES. (or maybe I have my regular expressions wrong)

How can I easily determine the dependent libraries that my executable is using? Is there property or other method that I can use?

I feel that CMake must have this information because if I look at the link information in Visual Studio it will show the path to the shared and static libraries that it’s going to use. I just don’t know how to do it myself in the CMake code.

install(IMPORTED_RUNTIME_ARTIFACTS ${PROJECT_NAME} RUNTIME_DEPENDENCY_SET _dependency_set)

install(
    RUNTIME_DEPENDENCY_SET _dependency_set
    POST_EXCLUDE_REGEXES "${CMAKE_INSTALL_PREFIX}/lib"
    RUNTIME DESTINATION lib
  )

Works at least on linux

Thank you for the feedback @ClausKlein. I should have mentioned this is a Windows only problem. I don’t see this problem on Linux.

For additional input, when IN invoke install_TARGETS ${TARGET} RUNTIME_DPENDENCIES...)

I removed all the regexes variables so that when it fails it prints the message of all the libraries it couldn’t find.

This output only shows the child dependency on B, but does not show the grandchild dependency of A (which B depends upon.)

I suspect this is a limitation of whatever Windows tool is being used to analyze the executable. However, this puts us into a platform incompatibility issue with CMake.

It works for Linux and doesn’t work for Windows.

I fall back onto my original question, is there some other way to get a list of all the libraries that a compilation unit will use? I know CMake has this information because it creates a functioning Visual Studios solution file with it. But I don’t know the CMake user interface to obtain that information. The install(... RUNTIME_DEPENDENCIES...) functionality doesn’t provide a complete answer.

I believe CMake is using dumpbin under the sheets to get the desired output. So I ran it on my test executable and on the parent library to provide more information on all of this.

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>dumpbin /DEPENDENTS C:\path-to-target\OPSLPlugins\PluginManager\INSTALL\Win-VS2017\tests\TestOPSLPluginMgr_64R.exe
Microsoft (R) COFF/PE Dumper Version 14.16.27051.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\path-to-target\OPSLPlugins\PluginManager\INSTALL\Win-VS2017\tests\TestOPSLPluginMgr_64R.exe

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    OPSL_64R.dll
    KERNEL32.dll
    MSVCP140.dll
    VCRUNTIME140.dll
    api-ms-win-crt-heap-l1-1-0.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-convert-l1-1-0.dll
    api-ms-win-crt-environment-l1-1-0.dll
    api-ms-win-crt-stdio-l1-1-0.dll
    api-ms-win-crt-string-l1-1-0.dll
    api-ms-win-crt-filesystem-l1-1-0.dll
    api-ms-win-crt-time-l1-1-0.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-locale-l1-1-0.dll

  Summary

        2000 .data
        2000 .pdata
       10000 .rdata
        1000 .reloc
        1000 .rsrc
       25000 .text

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>dumpbin /DEPENDENTS C:\path-to-target\OPSL\Library\INSTALL\Win-VS2017\lib\OPSL_64R.dll
Microsoft (R) COFF/PE Dumper Version 14.16.27051.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\path-to-target\OPSL\Library\INSTALL\Win-VS2017\lib\OPSL_64R.dll

File Type: DLL

  Image has the following dependencies:

    OPSLTools_64R.dll
    WS2_32.dll
    KERNEL32.dll
    SHELL32.dll
    ole32.dll
    ADVAPI32.dll
    MSVCP140.dll
    VCRUNTIME140.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-convert-l1-1-0.dll
    api-ms-win-crt-time-l1-1-0.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-stdio-l1-1-0.dll
    api-ms-win-crt-locale-l1-1-0.dll
    api-ms-win-crt-utility-l1-1-0.dll
    api-ms-win-crt-filesystem-l1-1-0.dll
    api-ms-win-crt-string-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll
    api-ms-win-crt-environment-l1-1-0.dll

  Summary

       35000 .data
       73000 .pdata
      447000 .rdata
        7000 .reloc
        1000 .rsrc
      7E4000 .text

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>

Found the following generator expression via a stack overflow article, and early investigations are hopeful!

$<TARGET_RUNTIME_DLLS:tgt>

Reference

I was able to resolve this problem using

    install(FILES
        "$<TARGET_RUNTIME_DLLS:${TARGET}>"
        DESTINATION ${DIR}
        )

A very simple solution, now. So many web hits point you to RUNTIME_DEPENDENCIES, which I couldn’t get to work, but this does what I expected/wanted.


update

Well poop! This only works for Windows – which the documentation states, but now it means I need to have platform specific logic to get this to work… :frowning: