In fact, besides build management, CMake can also handle testing and creating installation packages. The packaging feature is supported by the CPack module, which can generate suitable installers for different platforms.
1. Qt Program CMake Configuration
Taking the previously written QML program as an example, the CMakeLists.txt configuration file is written as follows. The packaging.cmake file included at the end defines information related to packaging configuration.
cmake_minimum_required(VERSION 3.16)
set(PROJECT_NAME sample)
project(${PROJECT_NAME} VERSION 0.1 LANGUAGES CXX)
set(EXECUTABLE_NAME ${PROJECT_NAME}_app)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Quick)
if(Qt6_FOUND)
message(STATUS "Qt6 found: ${Qt6_DIR}")
else()
message(FATAL_ERROR "Qt6 not found!")
endif()
qt_standard_project_setup(REQUIRES 6.8)
qt_add_executable(${EXECUTABLE_NAME}
main.cpp
)
qt_add_qml_module(${EXECUTABLE_NAME}
URI ${PROJECT_NAME}
VERSION 1.0
QML_FILES
Main.qml
)
# set static linking for MSVC
if(MSVC AND (${VCPKG_TARGET_TRIPLET} MATCHES "static"))
message(STATUS "Configuring for MSVC static linking")
set_property(TARGET ${EXECUTABLE_NAME} PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.${EXECUTABLE_NAME}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
target_link_libraries(${EXECUTABLE_NAME}
PRIVATE Qt6::Quick
)
include(GNUInstallDirs)
install(TARGETS ${EXECUTABLE_NAME}
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(MSVC AND (${VCPKG_TARGET_TRIPLET} MATCHES "static"))
message(STATUS "Linking static MSVC runtime, skipping install of MSVC runtime DLLs")
else()
message(STATUS "Configuring install of runtime dependencies")
set(deploy_tool_options_arg "")
if(APPLE)
set(deploy_tool_options_arg --hardened-runtime)
elseif(WIN32)
set(deploy_tool_options_arg --no-compiler-runtime)
endif()
qt_generate_deploy_qml_app_script(
TARGET ${EXECUTABLE_NAME}
OUTPUT_SCRIPT deploy_script
MACOS_BUNDLE_POST_BUILD
NO_UNSUPPORTED_PLATFORM_ERROR
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
DEPLOY_TOOL_OPTIONS ${deploy_tool_options_arg}
)
install(SCRIPT ${deploy_script})
install(CODE [[
if("$ENV{VCPKG_TARGET_TRIPLET}" STREQUAL "")
find_program(QMAKE qmake6 HINTS $ENV{PATH})
if(NOT QMAKE)
message(FATAL_ERROR "qmake not found in PATH")
else()
message(STATUS "qmake found: ${QMAKE}")
cmake_path(GET QMAKE PARENT_PATH QT_BIN_DIR)
message(STATUS "qmake bin dir: ${QT_BIN_DIR}")
endif()
else()
set(QT_BIN_DIR "$ENV{VCPKG_ROOT}/installed/$ENV{VCPKG_TARGET_TRIPLET}/bin")
if(NOT EXISTS ${QT_BIN_DIR})
message(FATAL_ERROR "qmake bin dir not found: ${QT_BIN_DIR}")
endif()
endif()
file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR RESOLVED_DEPS
UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPS
# path to the executable files
EXECUTABLES $<TARGET_FILE:sample_app>
# directories to search for library files
DIRECTORIES ${QT_BIN_DIR}
PRE_EXCLUDE_REGEXES "system32"
PRE_EXCLUDE_REGEXES "api-ms-*"
POST_EXCLUDE_REGEXES "system32"
)
foreach(DEP_LIB ${RESOLVED_DEPS})
file(INSTALL ${DEP_LIB} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
endforeach()
]])
endif()
include(${CMAKE_CURRENT_SOURCE_DIR}/packaging.cmake)
After defining what to install in install, add packaging-related content at the end of the CMake configuration file.