[CMake] Creating an installer using cpack
Daniel Schepler
dschepler at scalable-networks.com
Thu Jan 8 16:05:44 EST 2015
For (a): If by "respecting its local location", you mean you want the scripts to be in the same location in the installation directory as it is in the source directory, we've been using the functions below (in cmake/installutils.cmake).
macro (split_install_args files_var install_args_var)
set(split_install_args_in_install_args 0)
set(${files_var})
set(${install_args_var})
foreach (arg ${ARGN})
if (arg STREQUAL "COMPONENT" OR
arg STREQUAL "PERMISSIONS" OR
arg STREQUAL "CONFIGURATIONS" OR
arg STREQUAL "RENAME" OR
arg STREQUAL "OPTIONAL" OR
arg STREQUAL "PATTERN" OR
arg STREQUAL "REGEX" OR
arg STREQUAL "USE_SOURCE_PERMISSIONS")
set(split_install_args_in_install_args 1)
endif ()
if (split_install_args_in_install_args)
list(APPEND ${install_args_var} "${arg}")
else ()
list(APPEND ${files_var} "${arg}")
endif ()
endforeach ()
endmacro ()
function (install_clone_aux basedir mode)
string(LENGTH ${basedir} basedir_len)
math(EXPR basedir_len_p1 "${basedir_len} + 1")
split_install_args(install_files install_args ${ARGN})
foreach (file ${install_files})
get_filename_component(abspath ${file} ABSOLUTE)
get_filename_component(abspath ${abspath} PATH)
string(SUBSTRING ${abspath} 0 ${basedir_len_p1} abspath_head)
if (abspath_head STREQUAL "${basedir}/")
string(SUBSTRING ${abspath} ${basedir_len_p1} -1 abspath_tail)
if (mode STREQUAL "DIRECTORY")
install(${mode} ${file} DESTINATION ${abspath_tail}
${install_args}
PATTERN ".svn" EXCLUDE)
else ()
install(${mode} ${file} DESTINATION ${abspath_tail}
${install_args})
endif ()
else ()
message(SEND_ERROR "install_clone: ${file} seems to be outside the
expected base directory ${basedir}")
endif ()
endforeach ()
endfunction ()
function (install_clone mode)
install_clone_aux(${CMAKE_SOURCE_DIR} ${mode} ${ARGN})
endfunction ()
function (install_clone_bin mode)
install_clone_aux(${CMAKE_BINARY_DIR} ${mode} ${ARGN})
endfunction ()
Example usage:
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
include(installutils)
install_clone(PROGRAMS script1.sh path/to/script2.sh)
configure_file(script3.sh.in script3.sh)
install_clone_bin(PROGRAMS script3.sh)
For (b), you probably want to look at either BundleUtilities, or GetPrerequisites for more fine-grained control over what gets installed. This example is probably a bit involved, but it might give you an idea of what we do here to install some libraries even if they happen to be on what CMake considers the "system library path", but exclude the libraries we consider "system" libraries.
# Install Qt plugins
macro (install_external_lib libfile dest)
install(FILES ${libfile} DESTINATION ${dest}
COMPONENT gui)
if (IS_SYMLINK ${libfile})
get_filename_component(libfile_link_target ${libfile} REALPATH)
install(FILES ${libfile_link_target} DESTINATION ${dest}
COMPONENT gui)
endif ()
endmacro ()
foreach (qt_plugin
accessible/qtaccessiblewidgets
codecs/qcncodecs
codecs/qjpcodecs
codecs/qkrcodecs
codecs/qtwcodecs
graphicssystems/qglgraphicssystem
graphicssystems/qtracegraphicssystem
iconengines/qsvgicon
imageformats/qgif
imageformats/qico
imageformats/qjpeg
imageformats/qmng
imageformats/qsvg
imageformats/qtga
imageformats/qtiff
sqldrivers/qsqlite)
if (WIN32)
set(qt_plugin_file "${qt_plugin}4.dll")
else ()
string(REGEX REPLACE "/([^/]*)$" "/lib\\1.so" qt_plugin_file "${qt_plugin}")
endif ()
set(qt_plugin_file "${QT_PLUGINS_DIR}/${qt_plugin_file}")
if (EXISTS "${qt_plugin_file}")
get_filename_component(plugin_dest_dir ${qt_plugin} PATH)
install_external_lib(${qt_plugin_file} gui/lib/${BUILD_PLATFORM_BASE}/plugins/${plugin_dest_dir})
endif ()
endforeach ()
# The following is used to install required libraries
if (WIN32)
set(search_path ${QT_BINARY_DIR})
else ()
set(search_path ${QT_LIBRARY_DIR})
endif ()
foreach (lib_for_search_path ${EXPAT_LIBRARY} ${GLUT_LIBRARIES})
if (lib_for_search_path STREQUAL "optimized" OR
lib_for_search_path STREQUAL "debug" OR
lib_for_search_path STREQUAL "general")
# ignore these markers
else ()
get_filename_component(search_dir ${lib_for_search_path} PATH)
list(APPEND search_path ${search_dir})
if (WIN32 AND search_dir MATCHES "/lib")
string(REPLACE "/lib" "/bin" search_dir ${search_dir})
if (EXISTS ${search_dir})
list(APPEND search_path ${search_dir})
endif ()
endif ()
endif ()
endforeach ()
list(SORT search_path)
list(REMOVE_DUPLICATES search_path)
if (WIN32)
install(CODE "
message(STATUS \"Calculating required libraries...\")
include(GetPrerequisites)
set(search_path \"${search_path}\")
get_prerequisites(\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/gui/lib/${BUILD_PLATFORM_BASE}/${BUILD_TARGET_GUI_NAME}.exe
prereqs 1 1 \"\" \"\${search_path}\")
file(GLOB_RECURSE qt_plugins \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/gui/lib/${BUILD_PLATFORM_BASE}/plugins/*.dll)
foreach (plugin_file \${qt_plugins})
get_prerequisites(\${plugin_file} prereqs 1 1 \"\" \"\${search_path}\")
endforeach ()
foreach (libfile \${prereqs})
gp_resolve_item(\"\" \${libfile} \"\" \"\${search_path}\" libfile_abs)
file(INSTALL \${libfile_abs} DESTINATION \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/gui/lib/${BUILD_PLATFORM_BASE})
endforeach ()
"
COMPONENT gui)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION gui/lib/${BUILD_PLATFORM_BASE})
include(InstallRequiredSystemLibraries)
else ()
# Linux
install(CODE "
message(STATUS \"Calculating required libraries...\")
include(GetPrerequisites)
set(search_path \"${search_path}\")
get_prerequisites(\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/gui/lib/${BUILD_PLATFORM_BASE}/${BUILD_TARGET_GUI_NAME}
prereqs 0 1 \"\" \"\${search_path}\")
file(GLOB_RECURSE qt_plugins \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/gui/lib/${BUILD_PLATFORM_BASE}/*.so)
foreach (plugin_file \${qt_plugins})
get_prerequisites(\${plugin_file} prereqs 0 1 \"\" \"\${search_path}\")
endforeach ()
foreach (libfile \${prereqs})
if (NOT (libfile MATCHES
\"/(lib(c|dl|drm|fontconfig|freetype|gcc_s|gfortran|GL|GLU|glapi|gomp|ICE|idn|m|png12|pthread|resolv|rt|SM|stdc\\\\+\\\\+|X11|X11-xcb|Xau|Xaw|Xaw7|xcb-dri2|xcb-glx|xcb|Xdamage|Xdmcp|Xext|Xfixes|Xmu|Xpm|Xrandr|Xrender|Xt|Xxf86vm|z)\\\\.so(\\\\.|\\\$))\"))
file(INSTALL \${libfile} DESTINATION \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/gui/lib/${BUILD_PLATFORM_BASE})
if (IS_SYMLINK \${libfile})
get_filename_component(libfile_target \${libfile} REALPATH)
file(INSTALL \${libfile_target} DESTINATION \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/gui/lib/${BUILD_PLATFORM_BASE})
endif ()
endif ()
endforeach ()
"
COMPONENT gui)
endif ()
--
Daniel Schepler
-----Original Message-----
From: CMake [mailto:cmake-bounces at cmake.org] On Behalf Of Gonzalo Garramuno
Sent: Thursday, January 08, 2015 12:47 PM
To: cmake at cmake.org
Subject: [CMake] Creating an installer using cpack
I have a cmake file to build my project (mrViewer). The project has additional script files that are not mentioned in my cmake file.
The project also has dependencies on c libraries installed elsewhere (/usr/local, etc).
The tgz,deb and rpm files currently contain just the main executable after a:
ADD_EXECUTABLE( mrViewer WIN32 ${SOURCES} ) TARGET_LINK_LIBRARIES( mrViewer ${LIBRARIES} )
INSTALL( TARGETS mrViewer
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)
What I would like to have is a cmake sample file that shows how to:
a) Install the script files respecting its local location.
b) Install the c libraries in a local lib directory.
for cpack packaging.
Thank you very much in advance,
Gonzalo
--
Powered by 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:
http://public.kitware.com/mailman/listinfo/cmake
More information about the CMake
mailing list