在学校里我们写程序根本不关心打包发布的问题,但作为一个完整的程序开发流程,打包发布是不可忽略且十分重要的一步。本质上打包和安装主要是压缩和解压的过程,在Linux平台上可以清楚地感受到这一点(很多时候直接打成zip包)。在Windows平台上,常见的安装包有.msi和.exe格式,除了将文件解压到指定位置,还可以设置使用许可(License),环境变量。利用CMake和WiX工具可以在Windows上构建.msi安装包(.exe安装包可以基于NSIS工具构建),下面将介绍细节。
CMake:https://cmake.org/download
WiX Toolset:https://wixtoolset.org/releases
示例代码:https://github.com/LeiChenIntel/wheels/tree/main/cmake_guide/sample4
示例基于sample3构建,这里只讨论打包部分:
# set install path
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/install")
endif()
message("Install prefix: " ${CMAKE_INSTALL_PREFIX})
# copy and relocate files
install(TARGETS sample4 calculations
RUNTIME DESTINATION bin # executable file
LIBRARY DESTINATION bin # dynamic library
ARCHIVE DESTINATION lib)# static library
install(FILES calculations.h DESTINATION include)
install(FILES config.json DESTINATION config)
# set installer configurations
set(CPACK_GENERATOR "WIX") # set installer
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt") # set license in installer
set(CPACK_WIX_PATCH_FILE "${PROJECT_SOURCE_DIR}/wix-patch.xml") # set environment variables
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}") # set package name
# package files into installer
include(CPack)
首先是install过程,单纯的install过程不会打包,只会将文件拷贝到指定的目录下。CMake关于INSTALL也会有很多写好的宏,比如,检查CMAKE_INSTALL_PREFIX是否被设置,如果没有,则设置目录为./install文件夹。如果不设置,默认安装目录一般为C:/Program Files (x86)/{ProjectName},比如这里为C:/Program Files (x86)/CMakeWheels。
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/install")
endif()
install可以直接基于TARGETS构建,即CMake会自动拷贝TARGETS中的可执行文件,动态库,静态库到给出的目标文件夹bin,lib,include,config。
install(TARGETS sample4 calculations
RUNTIME DESTINATION bin # executable file
LIBRARY DESTINATION bin # dynamic library
ARCHIVE DESTINATION lib)# static library
同时install也支持单个文件的拷贝,用于拷贝配置文件等。
install(FILES calculations.h DESTINATION include)
install(FILES config.json DESTINATION config)
通过以下命令可以在sample4文件夹下构建./install文件夹。
cd wheels\cmake_guide\sample4
mkdir build
cd build
cmake ..
cd wheels\cmake_guide\sample4
cmake --build build --config Release
cmake --install build
# set installer configurations
set(CPACK_GENERATOR "WIX") # set installer
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt") # set license in installer
set(CPACK_WIX_PATCH_FILE "${PROJECT_SOURCE_DIR}/wix-patch.xml") # set environment variables
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}") # set package name
最后,添加include(CPack)告诉CMake需要调用相关内容。
通过以下命令可以在sample4文件夹下构建.msi安装包。
cd wheels\cmake_guide\sample4
mkdir build
cd build
cmake ..
cd wheels\cmake_guide\sample4
cmake --build build --config Release
cd wheels\cmake_guide\sample4\build
cpack --config CPackConfig.cmake
目前通过增加patch的方法在installer中添加环境变量设置(参考1,参考2),解析wix-patch.xml:
<CPackWiXPatch>
<CPackWiXFragment Id="CM_CP_bin.sample4.exe">
<Environment Id="SAMPLE4_DIR" Action="set"
Name="SAMPLE4_DIR" Value="[INSTALL_ROOT]"/>
<Environment Id="CALCULATIONS_LIB_DIR" Action="set"
Name="CALCULATIONS_LIB_DIR" Value="[INSTALL_ROOT]lib"/>
<Environment Id="CALCULATIONS_BIN_DIR" Action="set" Part="first"
Name="PATH" Value="[INSTALL_ROOT]bin"
System="yes"/>
</CPackWiXFragment>
</CPackWiXPatch>
CM_CP_bin.sample4.exe这个Id不是随便设置的,它必须在build_CPack_Packages\win64\WIX\files.wxs中找到对应,否则会报CPack Error: Some XML patch fragments did not have matching IDs: 'CM_CP_bin.samplexx.exe’错误。
<Environment Id="SAMPLE4_DIR" Action="set" Name="SAMPLE4_DIR" Value="[INSTALL_ROOT]"/>
<Environment Id="CALCULATIONS_LIB_DIR" Action="set" Name="CALCULATIONS_LIB_DIR" Value="[INSTALL_ROOT]lib"/>
是在用户环境变量中设置,
<Environment Id="CALCULATIONS_BIN_DIR" Action="set" Part="first" Name="PATH" Value="[INSTALL_ROOT]bin" System="yes"/>
是在系统环境变量中设置。
.msi安装包将在build文件夹下面生成,运行.msi安装包,可以看到“License”已经被导入,环境变量也已经设置。
此时,能在任何目录下运行sample4了。
CSDN参考
https://blog.csdn.net/qq_38410730/article/details/102837401
CMake,CPack文档
https://cmake.org/cmake/help/latest/module/CPack.html#variable:CPACK_GENERATOR
其他
http://cmake.3232098.n2.nabble.com/CPack-WIX-examples-td7588561.html