7

We have set up a cmake project with external shared library dependencies. We want to package the binaries and dependencies of our project using CPack. However we are getting different results on windows and linux systems when trying to find dependencies of our targets.

We had a look at the GetPrerequisites Module of CMake (2.8.12).We have successfully used the following CMake code to get the full path of a CMake target (BINARY) dependency (_libFile) on linux, however we don't get a the full path of the dependency on windows. On Windows the variable dependency_realpath holds something like ${CMAKE_SOURCE_DIR}/DEPENDENCY_FILE, which is not the correct path to the dependency.

string(TOUPPER "${CMAKE_BUILD_TYPE}" CONFIG)
GET_TARGET_PROPERTY(MY_BINARY_LOCATION ${BINARY} LOCATION_${CONFIG} )
GET_PREREQUISITES(${MY_BINARY_LOCATION} DEPENDENCIES 0 0 "" "")

foreach( DEPENDENCY_FILE ${DEPENDENCIES})
    get_filename_component( dependency_realpath ${DEPENDENCY_FILE} REALPATH)

So the question would be: Why are we getting different results for the dependency locations on windows and linux?

tisch
  • 1,098
  • 3
  • 13
  • 30
  • What results do you actually get? What results do you expect? I would like to see the output of the loop "foreach(d ${DEPENDENCIES}) message("d='${d}'") endforeach()" There should be no need to do REALPATH, the results of get_prerequisites should already be full paths... – DLRdave Jun 24 '14 at 09:54
  • I have printed the result of one of my targets. It seems the list only contains the filenames, not the full paths: d='ITKCommon-4.4.dll' d='KERNEL32.dll' d='MSVCP100.dll' d='MSVCR100.dll' d='RPCRT4.dll' d='VCOMP100.DLL' d='liblinear.dll' d='libsvm.dll' d='vtkCommon.dll' d='vtkFiltering.dll' d='vtkGraphics.dll' d='vtkHybrid.dll' d='vtkIO.dll' d='vtkImaging.dll' d='vtkRendering.dll' – tisch Jun 24 '14 at 10:12
  • Could this be related to dumpbin, which is the gp_cmd? – tisch Jun 24 '14 at 10:20
  • Yes, of course. Sorry for the "REALPATH" part of my first comment. The results of get_prerequisites are obviously NOT already full paths. But you still can't use REALPATH to get the right result. See my answer... and use gp_resolve_item instead. – DLRdave Jun 24 '14 at 14:22

1 Answers1

9

The references that get_prerequisites returns are not absolute full path references, and they are also not resolve-able to absolute references via a simple get_filename_component call. (On Mac, they may contain @executable_path, for instance.)

However, there is another function in the GetPrerequisites.cmake module called gp_resolve_item that can help you here.

Try this:

get_prerequisites(${MY_BINARY_LOCATION} DEPENDENCIES 0 0 "" "")

foreach(DEPENDENCY_FILE ${DEPENDENCIES})
  gp_resolve_item("${MY_BINARY_LOCATION}" "${DEPENDENCY_FILE}" "" "" resolved_file)
  message("resolved_file='${resolved_file}'")
endforeach()

That should convert DLL names into full path locations of the DLLs, assuming they are in your PATH. If they are in some other directories, you may need to provide those as the "dirs" arguments to get_prerequisites and gp_resolve_item.

The documentation for the GetPrerequisites.cmake module is here: http://www.cmake.org/cmake/help/v3.0/module/GetPrerequisites.html

Also, possibly dig into the BundleUtilities.cmake module to see how it uses GetPrerequisites.

DLRdave
  • 13,876
  • 4
  • 53
  • 70
  • 3
    Note that starting with CMake 3.16, [`file(GET_RUNTIME_DEPENDENCIES ...)`](https://cmake.org/cmake/help/v3.16/command/file.html#get-runtime-dependencies) has superseded `get_prerequisites`. The latter is now officially deprecated. – ComicSansMS Nov 30 '19 at 05:43