[CMake] best practice for bundling 3rdparty dependencies in, windows

Lee Butler iraytrace at gmail.com
Mon Feb 20 11:26:33 EST 2017


Since I have wrestled with this on a recurring basis let me offer the following.  We package Qt. OpenSceneGraph and other libraries as 3rdParty content to the application we build/deploy.  Because the 3rd party libraries have their own plugins and dependencies, we end up doing a number of things:

1) install(TARGETS ...) to get the things we build installed
2) install(CODE ...) to get a lot of dependencies installed.

The thing to keep in mind is that CPACK essentially does an install to a directory other than the CMAKE_INSTALL_PREFIX to create the file system structure that it will package.  It seems to do this by setting CMAKE_INSTALL_PREFIX to something it wants.  This is slick but if you are doing things by hand you have to realize that it isn't the location you set when you run CMAKE.

Some of the key code looks like this:set(EXEC_NAME "vsl-bin")

 1. set(EXEC_NAME "vsl-bin")
 2. add_executable(${EXEC_NAME} ${product_SRCS} ${UIS} ${RCS} )
 3. target_link_libraries(${EXEC_NAME} ${product_LIBS})
 4. install(TARGETS ${EXEC_NAME}
 5.       BUNDLE DESTINATION . COMPONENT Runtime
 6.       RUNTIME DESTINATION bin COMPONENT Runtime )
 7. INSTALL(CODE "file(GLOB_RECURSE VSLPLUGINS
    \"\${CMAKE_INSTALL_PREFIX}/bin/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
 8.       FILE(COPY \"${OSG_INCLUDE_DIR}/../bin/osgPlugins-3.4.0\"
    DESTINATION \"\${CMAKE_INSTALL_PREFIX}/bin\")
 9.       FILE(GLOB OSGLIBS
    \"${OSG_INCLUDE_DIR}/../bin/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
10.       FILE(COPY \${OSGLIBS} DESTINATION
    \"\${CMAKE_INSTALL_PREFIX}/bin\")
11.       FILE(GLOB QTPLUGINS \"${Qt5_DIR}/../../../plugins/*\")
12.       FILE(COPY \${QTPLUGINS} DESTINATION
    \"\${CMAKE_INSTALL_PREFIX}/bin\")
13.       include(BundleUtilities)
14. fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/bin/${EXEC_NAME}${CMAKE_EXECUTABLE_SUFFIX}\"
    \"\${VSLPLUGINS}\" \"${DIRS}\")
15.       " COMPONENT Runtime)

This works in conjunction with CPACK to create our installer (using WIX) and zip file installers.
7 Copy the application plugins we just build as part of the project
8 get the OSG plugins from where they live into our bin directory
9 get the list of OSG libraries (precompiled elsewhere)
10 copy the OSG Libraries into our bin directory
11 get all the Qt plugins
12 get Qt plugins into our bin directory
13..14 get libraries that we build and depend on into bin (this introspects on the binary to discover)

Alas, CMake/CPack cannot "recursively" look at libraries to find what dependencies exist in the libraries you depend on.  And of course, finding plugins those libraries depend on isn't really possible.  I would really like to see fixup_bundle improved to help handle this sort of thing.  I'd even be willing to pay Kitware to work on it.

So this is the best we have been able to come up with short of diving into the source code for cmake and cpack themselves.  Hope this helps.

Lee

    I have a question about best practice for app bundling especially 3rdparty libs. In Linux it is not some common to bundle 3rdparty libs with my application but in windows this is highly recommended. What?s a good way to bundle 3rdparty libs (mostly .dll, sometimes also .exe) in windows (maybe macos x has the same ?problem?).

    At the moment i use install(FILES ?) to install the 3rdparty libs (i?ve tried to install imported target, but thats not possible  ). I use a cmake variable to activate (default is off) to copy 3rdparty libs to the install directory. The only other way i could go is to add a cpack_install_script file, but this is only availabe in cpack time.

    So is there a better way to bundle 3rdparty libs or is this the recommended approach?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20170220/790e5948/attachment-0001.html>


More information about the CMake mailing list