10

I am trying to install an executable using cmake. My real problem here is: how to install the executable and its dependencies.

Here an example: I want to install one executable that depend on two libraries of my cmake and one 3rdparty (pre-compiled).

set(EXECUTABLE_NAME MyExecutable)
file(GLOB_RECURSE ${EXECUTABLE_NAME}_SOURCES *.cpp)    
add_executable(${EXECUTABLE_NAME} ${${EXECUTABLE_NAME}_SOURCES})
target_link_libraries(${EXECUTABLE_NAME} MyLibrary1
  MyLibrary2
  ${Boost_PROGRAM_OPTIONS_LIBRARY})
install(TARGETS ${EXECUTABLE_NAME}
 ARCHIVE DESTINATION lib
 LIBRARY DESTINATION lib
 RUNTIME DESTINATION bin
 COMPONENT ${EXECUTABLE_NAME})

At the end I would like to find with this kind of CMakeLists.txt my two libraries, my executable and Boost_PROGRAM_OPTIONS_LIBRARY in the install folder and in my package.

What I have found, but I did not succeed to use:

  1. BundleUtilities.cmake, here an example: https://cmake.org/Wiki/BundleUtilitiesExample. As you can see it seems to do the perfect jobs, but it's complaining about "external prerequisites". I personally found that normal and I don't understand how to fix that. (Note: it succeeds in finding and copying the dependencies into a same folder before failing, Doc: https://cmake.org/cmake/help/v3.5/module/BundleUtilities.html)

  2. GetPrerequisites.cmake. get_prerequisites is a lower level function that allow you to get the dependencies. The thing is, I don't any good way/best practice to use it.

Thanks,

Hevy
  • 101
  • 1
  • 7

1 Answers1

0

I personally would make a library out of all of your dependencies with add_library(MyLibrary1 STATIC/SHARED/INTERFACE) and for boost most probably add_library(boost INTERFACE) followed by adding any include directories and linking the .as or .sos to them.

I would then link all my dependencies to MyExecutable as you have above. And at any point you can call the install function on all of these targets one at a time.

If you don't like repeating

install(TARGETS target
 ARCHIVE DESTINATION lib
 LIBRARY DESTINATION lib
 RUNTIME DESTINATION bin
 COMPONENT target
)

then you could break it out in to a function, something like this

function(INSTALL_CUSTOM target
  install(TARGETS target
   ARCHIVE DESTINATION lib
   LIBRARY DESTINATION lib
   RUNTIME DESTINATION bin
   COMPONENT target
  )
endfunction()

and then you could just call INSTALL_CUSTOM(MyLibrary1) or INSTALL_CUSTOM(boost).

Cascades
  • 627
  • 7
  • 18
  • 1
    Note that as of CMake 3.14, you no longer need that destination boilerplate as long as it matches the 3.14 defaults. – starball Jul 19 '22 at 03:25