[CMake] fixup-bundle usability

Andreas Naumann Andreas-Naumann at gmx.net
Mon Feb 18 12:44:22 EST 2019


Thank you very much for your explaination. At the moment, I link only to 
boost and some in-house libraries. When experimenting with CMake and 
reading the docs, I got the same impression as you described. And I 
hoped to miss something obvious.

When I understand you correctly, one have to set the directories from 
hand. Furthermore there are additional variables (in case of VTK), which 
contain the library directories. But modern CMake works with targets and 
properties and let the dependencies propagate.

To test the idea a little bit, I startet with the following function

function(setBundle targetName dest)
   install(TARGETS ${targetName} DESTINATION ${dest})

   get_target_property(targtDeps ${targetName} LINK_LIBRARIES)
   file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" instPref)
   set(depDirs )
   foreach(t IN LISTS targtDeps)
     #disable the INTERFACE target due to error later.
     if(TARGET ${t} AND NOT ("${t}" STREQUAL "Boost::disable_autolinking"))
       get_target_property(isImported ${t} IMPORTED)
       if(isImported)
         get_target_property(depFile ${t} IMPORTED_LOCATION_DEBUG)
         if(depFile)
           get_filename_component(cdepDir ${depFile} DIRECTORY)
           list(APPEND depDirs ${cdepDir})
         endif()
       endif()
     endif()
   endforeach()
   install(CODE "include(BundleUtilities)
fixup_bundle(\"${instPref}/${dest}/$<TARGET_FILE_NAME:${targetName}>\" 
\"\" \"${depDirs}\")")
endfunction()

It is far away from optimal and has some drawbacks, especially the 
detection of interface libraries and the location of the imported target 
should be more fail proof.

How can I ask for feature requests on gitlab? I found the issue tracker, 
but nothing in regard for a feature or improvement.

Andreas

Am 18.02.19 um 15:56 schrieb Francis Giraldeau:
> You are right, the fixup bundle is difficult to use. Here are some 
> undocumented tips:
>
> Put the install(CODE) with the fixup_bundle() call in a CMakeLists.txt 
> in its own directory. In your main CMakeLists.txt file, add this 
> directory with add_subdirectory() last. This install(CODE) will run 
> after all the other install directive, otherwise the fixup_bundle() 
> might run before other targets are installed.
>
> The main thing is to build the library path variable. Yes, this 
> information can be recovered from the target itself, but 
> fixup_bundle() won't gather that info for you. Here is an example with 
> Qt:
>
> get_target_property(QT_CORE_LIBQt5::CoreLOCATION)
> get_filename_component(QT_RUNTIME_DIR"${QT_CORE_LIB}"DIRECTORY)
> list(APPENDLIBS_PATH"${QT_RUNTIME_DIR}")
>
> If you are using VTK, there is already a variable:
> list(APPENDLIBS_PATH"${VTK_RUNTIME_LIBRARY_DIRS}")
>
> You might as well run windeployqt (and similar tool for other 
> platforms) inside install(CODE) script if you have a Qt app, such that 
> the styles and the plugins and other stuff gets copied.
>
> execute_process(COMMANDwindeployqt.exe--release\"\${MAIN_APP}\")
>
> Workaround wrong tool detection using MinGW on Windows:
> if(WIN32ANDNOTMSVC)
> set(GP_TOOL"objdump")
> endif()
> install(CODE "\
> ...
> include(BundleUtilities)
> set(gp_tool\"${GP_TOOL}\")
> fixup_bundle(\"\${MAIN_APP}\"\"\"\"${LIBS_PATH}\")
> ...
> And there is the escaping... You have to escape quotes inside
> the script. Escape the '$' sign if you want to refer to the
> variable at install time. Remember that you don't have access
> to configure-time variables at install time. Unescaped '$' prefix
> will be replaced by its value at configure time, somewhat like
> a macro or a template.
>
> To see the generated script, look into ${CMAKE_BINARY_DIR} with
> the directory name corresponding to the CMakeLists.txt containing
> the install(CODE). Example:
> ${CMAKE_SOURCE_DIR}/cmake/bundle/CMakeLists.txt
> -> ${CMAKE_BINARY_DIR}/cmake/bundle/cmake_install.cmake
> You can check the generated script, its very
> handy when things go wrong.
> Also, it is easier to put all libraries and binaries in their
> own directory. I have this near the begining of my project's
> CMakeLists.
> set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY${CMAKE_BINARY_DIR}/lib)
> set(CMAKE_LIBRARY_OUTPUT_DIRECTORY${CMAKE_BINARY_DIR}/lib)
> set(CMAKE_RUNTIME_OUTPUT_DIRECTORY${CMAKE_BINARY_DIR}/bin)
> If you have some library that you don't want in your bundle,
> you might want to disable install for it, for instance,
> google test:
> add_subdirectory(3rdparty/googletest/EXCLUDE_FROM_ALL)
> I'm using "ntldd.exe -R" on Windows to check the dependencies manually
> (its very much like ldd on Linux). It is much more handy than
> dependency walker.
> Fixup_bundle is not magical either. The library dependencies must be
> known beforehand. It means that if you do some dlopen() tricks at
> runtime, fixup_bundle() cannot know that and you will have to install
> these libraries manually yourself. One notable example of this is
> Intel MKL using the Single Dynamic Library (mkl_rt). Using this
> library entry point simplifies the linking and will load the
> best library at runtime depending on the hardware. Fixup_bundle() will
> copy only mkl_rt and you have to copy the other mkl libraries to
> avoid runtime error.
> Fixup bundle is tricky to put in place, but having a fixed list
> of libraries to copy is even more cumbersome and flaky. When
> supplied with the proper directories, the bundle is right every time.
> Francis
> Le sam. 16 févr. 2019 à 04:04, Andreas Naumann 
> <Andreas-Naumann at gmx.net <mailto:Andreas-Naumann at gmx.net>> a écrit :
>
>     Dear CMakers,
>
>     recently I tried to bundle an application in Windows. From the
>     documentation [1] I see that I should provide the directories to the
>     non-system libraries.
>
>     But these information should be already in the properties of the
>     targets, arent they? Is there any extension in cmake, that provides
>     these paths?
>
>     How do other users handle dependencies to external dlls?
>
>
>     [1] https://cmake.org/cmake/help/v3.0/module/BundleUtilities.html
>
>     Regards,
>     Andreas
>
>     -- 
>
>     Powered by www.kitware.com <http://www.kitware.com>
>
>     Please keep messages on-topic and check the CMake FAQ at:
>     http://www.cmake.org/Wiki/CMake_FAQ
>
>     Kitware offers various services to support the CMake community.
>     For more information on each offering, please visit:
>
>     CMake Support: http://cmake.org/cmake/help/support.html
>     CMake Consulting: http://cmake.org/cmake/help/consulting.html
>     CMake Training Courses: http://cmake.org/cmake/help/training.html
>
>     Visit other Kitware open-source projects at
>     http://www.kitware.com/opensource/opensource.html
>
>     Follow this link to subscribe/unsubscribe:
>     https://cmake.org/mailman/listinfo/cmake
>
> -- 
> Francis Giraldeau
>



More information about the CMake mailing list