I have a CMake project that installs things to a system according to the install
command as follows:
install (
TARGETS myTarget
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)
make install
works perfectly. And then I want to have a binary archive:
set(CPACK_GENERATOR "TGZ")
make package
produces an tar.gz file with the same folder structure as the install
command specified. However, I want to have a flat structure, that is, put everything (both executables and libraries) in "prefix", without the "bin" and "lib" directory.
Is that possible? May be with some clever use of the component system, the build type system, or CPACK_PROJECT_CONFIG_FILE
?
At the end I added a custom install script, which detects whether it is run by CPack by looking at CMAKE_INSTALL_PREFIX
, and restructure the install tree if necessary.
Here is my solution:
In CMakeLists.txt, after all the install()
commands, add
install(SCRIPT "${CMAKE_SOURCE_DIR}/cmake/flatten.cmake")
Add a file, "cmake/flatten.cmake", with content as follows
# Detect if the install is run by CPack.
if (${CMAKE_INSTALL_PREFIX} MATCHES "/_CPack_Packages/.*/(TGZ|ZIP)/")
# Flatten the directory structure such that everything except the header files is placed in root.
file(GLOB bin_files LIST_DIRECTORIES FALSE ${CMAKE_INSTALL_PREFIX}/bin/*)
file(GLOB lib_files LIST_DIRECTORIES FALSE ${CMAKE_INSTALL_PREFIX}/lib/*)
foreach(file ${bin_files} ${lib_files})
get_filename_component(file_name ${file} NAME)
execute_process(
COMMAND ${CMAKE_COMMAND} -E rename
${file}
${CMAKE_INSTALL_PREFIX}/${file_name}
)
endforeach()
execute_process( COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_INSTALL_PREFIX}/bin)
execute_process( COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_INSTALL_PREFIX}/lib)
endif()