using cpack with install of auxiliary includes/libraries like those of ExternalProject_Add

I have a project that depends on a git submodule and several static libraries that are built with add_subdirectory and they all have install commands to install the libraries and header files in CMAKE_INSTALL_PREFIX/lib, /include. I invoke the main cmake command CMakeLists.txt, with:

$ cd build
$ cmake … -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install -DCMAKE_PREFIX_PATH=$PWD/install (+ flags for the submodule )l
$ cmake --build . -j 4 -config Release

This works perfectly and it creates a executable binary, .h files, .so and .a libraries in the right places (build/bin/, build/include and build/lib/ respectively).
My problem now is trying to pack the binary into a tar.gz or similar package. My problem is two fold:

  1. It packs alll the .h files, .a files and all that is in the bin directory, in the binary distribution when I only need to pack the main executable, a shell start up script and the .so files. I need a way to set a regex in some variable to exclude the unwanted files and directories.

  2. It installs it into a path that mimics my CMAKE_INSTALL_PREFIX (the full $PWD/install inside the tar.gz file, which is /home/$USER/code/ directory and leaves the CPACK_INSTALL_PREFIX path empty),. This is me probably using CPACK_INSTALL_PREFIX wrong, my guess.

If you run just the install, does the install tree look like what you want? If not, you’ll probably have to fix install() commands (or the variables that feed into them) in the tree. As for excluding files, COMPONENTS can be used to tell CPack to only install certain parts of the project.

I’m also not sure that CMAKE_PREFIX_PATH is something you need to set; that is usually for dependencies as it mostly help find_* commands search more places.

Thanks for your help, Ben. I managed to solve the issue indeed with COMPONENT for Linux and Windows. However it seems it does not work for macOS Bundle CPack generator.

I have, for example:

add_library(mrvCore STATIC ${SOURCES} ${HEADERS})

install(TARGETS mrvCore
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include/mrv/mrvCore
COMPONENT libraries )

…etc…

add_executable(mrViewer WIN32 ${SOURCES} ${HEADERS})

install(TARGETS mrViewer
RUNTIME DESTINATION bin COMPONENT applications
LIBRARY DESTINATION lib COMPONENT libraries
ARCHIVE DESTINATION lib COMPONENT libraries )

…etc…
set(CPACK_COMPONENTS_ALL applications )
set(CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME “mrViewer2 Application”)

include(CPack)

I’m not that familiar with any interop between components and the bundle generator (I’ve used DragNDrop); macOS packaging is certainly an outlier though, so there’s probably some detail that is useful (though I don’t know what it is off hand).

I looked at the source code. The Bundle generator does not support COMPONENT installation, while DragNDrop does.
Do you have a sample of DragNDrop? Idealy, I am looking for a way to deal with dylibs. Currently, I have a bash script used to start the application that sets the environment’s DYLD_FALLBACK_LIBRARY_PATH to look for my dylib libraries in the local install location, but I read there’s a fixup_bundle() script.

I’d avoid CMake’s fixup_bundle() as it has…limitations (especially on macOS) both in performance and handling complex rpath setups. Rather than DYLD_FALLBACK_LIBRARY_PATH, I recommend using @executable_path and/or @loader_path as makes sense (either in library IDs or as rpath entries), but this requires editing all of the library metadata consistently. The *.apple.* code in this directory has much better performance and behavior if you want to adapt it. Note that the script prefers to write direct library IDs rather than using @rpath at all because of how complicated the latter can get.