[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