使用CPack打包生成安装程序
事实上,CMake除了构建管理之外,还可以进行测试和打包安装程序。其中打包功能由CPack模块1支持,可以针对不同平台打包生成适用的安装程序。
1. Qt程序CMake配置
以之前编写的QML程序为例,编写CMakeLists.txt配置文件如下。末尾引入的packaging.cmake文件定义了打包配置相关信息。
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)
在install定义了要安装什么内容之后,在cmake配置文件末尾增加打包相关内容2。