用 CPack 打包

CPack 是一个功能强大、易于使用、跨平台的软件打包工具,与 CMake 一起发布。它使用 CMake 的生成器概念对特定平台上的打包生成进行抽象。它可以与 CMake 结合使用或不结合使用,但是它可能需要系统安装某些软件。通过使用简单的配置文件或 CMake 模块,项目的作者可以将复杂项目打包成简单的安装程序。本章将介绍如何将 CPack 应用于 CMake 项目。

CPack 基本知识

你的软件的用户可能并不总是希望或能够构建该软件以进行安装。该软件可能是闭源的,或者编译可能需要很长时间,或者在终端用户应用程序的情况下,用户可能没有构建应用程序的技能或工具。对于这些情况,需要一种方法,即在一台机器上构建软件,然后将安装树转移到另一台机器上。执行此操作的最基本方法是使用 DESTDIR 环境变量将软件安装到临时位置,然后对该目录进行 tar 或 zip 压缩并将其移至另一台机器。但是,DESTDIR 方法在 Windows 系统中遇到了困难,因为路径名称通常以驱动器号 (C:/) 开头,而且你不能简单地用一个完整路径作为另一个完整路径的前缀,以获得有效的路径名称。另一种更强大的方法是使用 CMake 中包含的 CPack。

CPack 是 CMake 中包含的一个工具,它可用于为项目创建安装程序和程序包。CPack 可以创建两种基本类型的包,即源代码包和二进制包。CPack 的工作方式与 CMake 构建软件的工作方式大致相同。它并不旨在替换本机打包工具,而是为各种工具提供单个界面。目前,CPack 支持使用 NullSoft 安装程序 NSIS 或 WiX 创建 Windows 安装程序,Mac OS X PackageMaker 工具、OS X 拖放、OS X X11 拖放、Cygwin 安装程序包、Debian 包、RPM、.tar.gz、.sh(自解压的 .tar.gz 文件)和 .zip 压缩文件。CPack 的实现与 CMake 的实现方式类似。对于支持的每种打包工具类型,都有一个用 C++ 编写的 CPack 生成器,该生成器用于运行本机工具和创建程序包。对于基于 tar 的简单程序包,CPack 包含一个 tar 的库版本,并且不要求在系统上安装 tar。对于许多其他安装程序,必须存在本机工具才能使 CPack 正常运行。

对于源代码程序包,CPack 会复制源代码树并创建一个 zip 或 tar 文件。对于二进制程序包,CPack 的使用与为项目正确运行的安装命令相关联。设置安装命令时,第一步是确保文件以正确的权限进入正确的目录结构。下一步是确保该软件可重新定位,并且可以在已安装的树中运行。这可能需要更改软件本身,并且有许多针对不同环境的技术可以做到这一点,而这些技术超出了本书的范围。基本上,可执行文件应该能够使用相对路径找到数据或其他文件,该相对路径为其已安装位置。CPack 将软件安装到临时目录,并将安装树复制到本机打包工具的格式中。将安装命令添加到项目后,在最简单的情况下,可以通过将 CPack.cmake 文件包含到项目中来启用 CPack。

简单示例

最基本的 CPack 项目会类似这样

cmake_minimum_required(VERSION 3.20)
project(CoolStuff)
add_executable(coolstuff coolstuff.cxx)
install(TARGETS coolstuff RUNTIME DESTINATION bin)
include(CPack)

在 CoolStuff 项目中,一个可执行文件被创建并安装到 bin 目录中。然后,项目的 CPack 文件包含在内。此时,CoolStuff 项目将启用 CPack。要针对 CoolStuff 运行 CPack,首先要像任何其他 CMake 项目一样构建项目。CPack 会向生成的项目添加多个目标。在 Makefile 中,这些目标为 package 和 package_source,而在 Visual Studio 和 Xcode 中为 PACKAGE。例如,若要使用 Makefile 生成器为 CoolStuff 构建源代码包和二进制包,可以运行以下命令

mkdir build
cd build
cmake ../CoolStuff
make
make package
make package_source

这会创建名为 CoolStuff-0.1.1-Source.zip 的源代码 zip 文件,名为 CoolStuff-0.1.1-win32.exe 的 NSIS 安装程序和名为 CoolStuff-0.1.1-win32.zip 的二进制 zip 文件。同样的事情也可以使用 CPack 命令行来完成。

cd build
cpack --config CPackConfig.cmake
cpack --config CPackSourceConfig.cmake

包含 CPack.cmake 后会发生什么?

运行 include(CPack) 命令后,CPack.cmake 文件会被包含到项目中。默认情况下,这会使用 configure_file 命令在项目的二进制树中创建 CPackConfig.cmakeCPackSourceConfig.cmake。这些文件包含一系列 set 命令,用于在打包步骤中运行 CPack 时设置变量。用于配置 CPack.cmake 文件的文件名可以通过以下两个变量进行自定义;CPACK_OUTPUT_CONFIG_FILE,其默认值为 CPackConfig.cmakeCPACK_SOURCE_OUTPUT_CONFIG_FILE,其默认值为 CPackSourceConfig.cmake

这些文件的源代码可以在 Templates/CPackConfig.cmake.in 中找到。该文件包含一些注释和一个由 CPack.cmake 设置的变量。该文件包含以下 CMake 代码

@_CPACK_OTHER_VARIABLES_@

如果项目在源代码树的顶级目录中包含文件 CPackConfig.cmake.in,则将使用该文件,而不是模板目录中的文件。如果项目包含文件 CPackSourceConfig.cmake.in,则该文件将用于创建 CPackSourceConfig.cmake

CPack.cmake 创建的配置文件将包含当前项目中以“CPACK_"开头的所有变量。这是使用以下命令完成的

get_cmake_property(res VARIABLES)

上面的命令获取了当前 CMake 项目为其定义的所有变量。然后,一些 CMake 代码查找以“CPACK_"开头的所有变量,并将其找到的每个变量配置为两个配置文件中的 CMake 代码。例如,如果在 CMake 项目中将变量设置如下

set(CPACK_PACKAGE_NAME "CoolStuff")

CPackConfig.cmakeCPackSourceConfig.cmake 包含以下内容

set(CPACK_PACKAGE_NAME "CoolStuff")

需要注意,CMake 在项目上运行后会运行 CPack。CPack 使用与 CMake 相同的解析器,但不会有与 CMake 项目相同的变量值。它只会有以 CPACK_ 开头的变量,而且 CMake 会将这些变量配置到一个配置文件中。如果变量的值使用转义字符,这可能会导致一些错误和混乱。由于这些变量会被 CMake 语言解析,它们需要两级转义。例如,如果您的 CMake 项目中有以下内容

set(CPACK_PACKAGE_VENDOR "Cool \"Company\"")

生成的 CPack 文件将是这种情况

set(CPACK_PACKAGE_VENDOR "Cool "Company"")

这并非您想要或期望的。实际上,它不起作用。为了解决这个问题,有两种解决方案。第一个是向原始 set 命令添加额外的转义,如下所示

set(CPACK_PACKAGE_VENDOR "Cool \\\"Company\\\"")

这将导致正确的 set 命令,如下所示

set(CPACK_PACKAGE_VENDOR "Cool \"Company\"")

转义问题的第二个解决方案是使用 CPack 项目配置文件,下一部分对此进行了说明。

添加自定义 CPack 选项

为了避免转义问题,可以指定一个项目特定的 CPack 配置文件。CPack 会在加载 CPackConfig.cmakeCPackSourceConfig.cmake 后加载此文件,并且 CPACK_GENERATOR 会被设置为正在运行的 CPack 生成器。在此文件中设置的变量只需一级 CMake 转义。此文件可以配置或不配置,并且包含常规 CMake 代码。在上面的示例中,您可以将 CPACK_PACKAGE_VENDOR 移到文件 MyCPackOptions.cmake.in 中,并将该文件配置到项目的构建树中。然后,按如下方式设置项目配置文件路径

configure_file ("${PROJECT_SOURCE_DIR}/MyCPackOptions.cmake.in"
                "${PROJECT_BINARY_DIR}/MyCPackOptions.cmake"
                @ONLY)
set (CPACK_PROJECT_CONFIG_FILE
     "${PROJECT_BINARY_DIR}/MyCPackOptions.cmake")

其中 MyCPackOptions.cmake.in 包含

set(CPACK_PACKAGE_VENDOR "Cool \"Company\"")

变量 CPACK_PROJECT_CONFIG_FILE 应包含指向项目 CPack 配置文件的完整路径,如上例所示。这有额外的优势,CMake 代码可以基于 CPACK_GENERATOR 值包含 if 语句,以便为项目设置打包程序特有的值。例如,CMake 项目在此文件中设置了安装程序的图标

set (CPACK_NSIS_MUI_ICON
     "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico")

请注意,路径使用正斜杠,但最后一部分使用转义的\作为路径分隔符。在本书撰写时,NSIS 需要路径的最后一部分有 Windows 样式的斜杠。如果您不这样做,可能会收到以下错误

File: ".../Release/CMakeLogo.ico" -> no files found.
Usage: File [/nonfatal] [/a] ([/r] [/x filespec [...]]
       filespec [...] | /oname=outfile one_file_only)

CPack 添加的选项

除了创建两个配置文件外,CPack.cmake还将向您的项目添加一些高级选项。添加的选项取决于 CMake 运行的环境和操作系统,并控制 CPack 创建的默认程序包。这些选项格式为 CPACK_<CPack Generator Name>,可以在以下表格中找到每个平台上可用的生成器名称

Windows

Cygwin

Linux/UNIX

Mac OS X

NSIS

CYGWIN_BINARY

DEB

PACKAGEMAKER

ZIP

SOURCE_CYGWIN

RPM

DRAGNDROP

SOURCE_ZIP

STGZ

BUNDLE

TBZ2

OSXX11

TGZ

TZ

SOURCE_TGZ

SOURCE_TZ

启用或禁用这些选项会影响在不使用任何选项的情况下运行 CPack 时创建的程序包。如果项目 CMakeCache.txt 文件中的选项处于禁用状态,您仍然可以通过向 CPack 命令行指定 -G 选项来构建该类型的程序包。

CPack 源程序包

CPack 中的源程序包只是将项目的整个源文件目录复制到程序包文件中,并且不使用安装规则,因为它们在二进制程序包中的情况一样。应使用非源构建,以避免额外二进制文件污染源程序包。如果您在源文件目录中拥有源程序包中不需要的文件或目录,可以使用变量 CPACK_SOURCE_IGNORE_FILES 从程序包中排除某些内容。此变量包含一个正则表达式列表。列在该列表中与正则表达式相匹配的任何文件或目录都将从源中排除。默认设置如下

"/CVS/;/\\\\\\\\.svn/;\\\\\\\\.swp$;\\\\\\\\.#;/#"

此变量由 CMake 解析一次、CPack 再次解析,因此默认值中使用了多级转义。重要的是要意识到源文件目录不会使用任何安装命令,它只是将整个源文件目录(减去它被告知要忽略的文件)复制到程序包中。为了避免使用多级转义,应使用 CPACK_PROJECT_CONFIG_FILE 引用的文件来设置此变量。表达式是一个正则表达式,而不是通配符语句,有关 CMake 正则表达式的更多信息,请参见第 4 章。

CPack 安装器命令

由于二进制程序包需要 CPack 与正在打包的项目的安装规则进行交互,因此本部分将介绍 CPack 提供的一些选项,以便与项目的安装规则进行交互。CPack 可以使用 CMake 的安装脚本或外部安装命令。

CPack 和 CMake 安装命令

在大多数 CMake 项目中,使用 CMake 安装规则就足够创建所需程序包。默认情况下,CPack 会运行当前项目的安装规则。但是,如果你有更复杂的项目,则可以使用变量 CPACK_INSTALL_CMAKE_PROJECTS 指定子项目和安装目录。此变量应包含安装目录、安装项目名称、安装组件以及安装子目录的四元组。例如,如果你有一个项目包含一个子项目 MySub,该子项目已编译到名为 SubProject 的目录,而且你希望安装其所有组件,则可以这样做

SET(CPACK_INSTALL_CMAKE_PROJECTS  "SubProject;MySub;ALL;/")

CPack 和 DESTDIR

默认情况下,CPack 在安装阶段不会使用 DESTDIR 选项。相反,它将 CMAKE_INSTALL_PREFIX 设置为 CPack 用于暂存安装程序包的临时目录的完整路径。这可以通过将 CPACK_SET_DESTDIR 设置为 on 来更改。如果 CPACK_SET_DESTDIR 选项为 on,则 CPack 将使用项目的缓存值 CPACK_INSTALL_PREFIX,并将 DESTDIR 设置为临时暂存区。这允许在临时目录下安装绝对路径。相对路径安装到 DESTDIR/${project's CMAKE_INSTALL_PREFIX},其中 DESTDIR 设置为临时暂存区。

如前所述,如果安装规则使用以驱动器号开头的 Windows 完整路径 (C:/) 来引用文件,则 DESTDIR 方法不起作用。

在对非 DESTDIR 安装进行打包(默认方式)时,任何绝对路径都将安装到绝对目录中,而不是包中。因此,不使用 DESTDIR 选项的项目,不得在安装规则中使用任何绝对路径。相反,使用绝对路径的项目,必须使用 DESTDIR 选项。

还可以使用另一个变量来控制项目安装到的根路径,即 CPACK_PACKAGING_INSTALL_PREFIX。默认情况下,许多生成器都安装到 /usr 目录中。该变量可以用来将它更改为任何目录,包括 /。

CPack 和其他已安装目录

如果项目不是基于 CMake,则可以运行其他安装规则。这可以通过使用变量 CPACK_INSTALL_COMMANDSCPACK_INSTALLED_DIRECTORIES 来完成。CPACK_INSTALL_COMMANDS 是将在打包的安装阶段运行的命令。CPACK_INSTALLED_DIRECTORIES 应包含目录和子目录对。子目录可以是“.”,以安装在安装的最顶级目录中。每个目录中的文件将被复制到 CPack 暂存目录的相应子目录中,并打包到其他文件一起。

适用于 Windows Installer NSIS 的 CPack

要创建基于 Windows 样式向导的安装程序,CPack 使用了 NSIS(NullSoft 可脚本安装系统)。有关 NSIS 的更多信息,请访问 NSIS 主页:http://nsis.sourceforge.net/ NSIS 是一款功能强大的工具,带有用于创建专业 Windows 安装程序的脚本语言。要使用 CPack 创建 Windows 安装程序,您需要在计算机上安装 NSIS。

CPack 使用已配置的模板文件来控制 NSIS。在创建 NSIS 安装程序期间,CPack 会配置两个文件。这两个文件都位于 CMake 模块目录中。Modules/NSIS.template.in 是 NSIS 脚本的模板,Modules/NSIS.InstallOptions.ini.in 是由 NSIS 使用的现代用户界面或 MUI 的模板。安装选项文件包含有关安装向导中所用页面的信息。本部分将介绍如何配置 CPack 以创建 NSIS 安装向导。

用于 NSIS 的 CPack 变量

本部分包含 CMake NSIS 安装向导的屏幕截图。对于从 CPack 更改或控制的安装程序的每部分,都会给出所用变量和值。

用户在 Windows 中看到的安装程序的第一件事是安装程序可执行文件的图标。默认情况下,安装程序将具有 Null Soft Installer 图标,如 20071023 CMake 安装程序的图 1 中所示。可以通过设置变量 CPACK_NSIS_MUI_ICON 来更改此图标。同一图中的 20071025 安装程序显示了为安装程序使用的 CMake 图标。

../_images/IconforinstallerinWindowsExplorer.png

图 1:Windows 资源管理器中的安装程序图标

用户在 Windows 中看到的安装程序的最后一件事是卸载可执行文件的图标,如图 2 所示。此选项可通过 CPACK_NSIS_MUI_UNIICON 变量进行设置。安装和卸载图标必须具有相同的大小和格式,可供 Windows 资源管理器使用有效 windows .ico 文件。图标的设置方式如下

# set the install/uninstall icon used for the installer itself
set (CPACK_NSIS_MUI_ICON
     "${CMake_SOURCE_DIR}/Utilities/Release\\CMakeLogo.ico")
set (CPACK_NSIS_MUI_UNIICON
     "${CMake_SOURCE_DIR}/Utilities/Release\\CMakeLogo.ico")
../_images/UninstallIconforNSISinstaller.png

图 2:NSIS 安装程序的卸载图标

在 Windows 上,还可以使用控制面板中的“添加或删除程序”工具删除程序,如图 3 所示。此图标应嵌入到已安装的可执行文件中之一。设置方法如下

# set the add/remove programs icon using an installed executable
SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\cmake-gui.exe")
../_images/AddorRemoveProgramsEntry.png

图 3:添加或删除程序项

../_images/FirstScreenofInstallWizard.png

图 4:安装向导的第一屏

运行安装程序时,向导的第一屏将显示如图 4 所示。在此屏幕中,可以控制在屏幕上两个位置显示的项目名称。用于项目的名称由变量 CPACK_PACKAGE_INSTALL_DIRECTORYCPACK_NSIS_PACKAGE_NAME 控制。在此示例中,将其设置为“CMake 2.5”,如下所示

set (CPACK_PACKAGE_INSTALL_DIRECTORY "CMake
     ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")

或者这样

set (CPACK_NSIS_PACKAGE_NAME "CMake
     ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")
../_images/SecondScreenofInstallWizard.png

图 5:安装向导的第二屏

安装向导的第二页可在 图 5 中看到。此屏幕包含许可协议,并且此页面上可以配置许多内容。位于“许可协议”标签左边的横幅位图由变量 CPACK_PACKAGE_ICON 这样控制

set (CPACK_PACKAGE_ICON
     "${CMake_SOURCE_DIR}/Utilities/Release\\CMakeInstall.bmp")

CPACK_PACKAGE_INSTALL_DIRECTORY 再次在此页面上的任何地方都使用,你看到“CMake 2.5”文本。许可协议文本设置为 CPACK_RESOURCE_FILE_LICENSE 变量中指定的文件内容。CMake 执行以下操作

set (CPACK_RESOURCE_FILE_LICENSE
     "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
../_images/Thirdpageofinstallerwizard.png

图 6:安装向导的第三页

安装程序的第三页可在 图 6 中看到。当 CPACK_NSIS_MODIFY_PATH 设置为开时,此页面才会显示。如果你勾选创建“名称”桌面图标按钮,并且在变量 CPACK_CREATE_DESKTOP_LINKS 中放入可执行名称,那么会为这些可执行文件创建一个桌面图标。例如,要为 CMake 的 cmake-gui 程序创建一个桌面图标,将执行以下操作

set (CPACK_CREATE_DESKTOP_LINKS cmake-gui)

如果应用程序包含多个可执行文件,则可以创建多个桌面链接。链接将创建到开始菜单项,因此 CPACK_PACKAGE_EXECUTABLES(本节后面将介绍)也必须包含该应用程序,才能创建桌面链接。

../_images/Fourthpageofinstallerwizard.png

图 7:安装向导的第四页

图 7 中显示的安装向导的第四页使用 CPACK_PACKAGE_INSTALL_DIRECTORY 变量指定 Program Files 中的默认目标文件夹。以下 CMake 代码用于设置该默认值

set (CPACK_PACKAGE_INSTALL_DIRECTORY "CMake
     ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")

安装向导的其余页面不使用任何其他 CPack 变量,因此不包含在此部分。NSIS CPack 生成器可以设置的另一个重要选项是所使用的注册表项。有几个 CPack 变量控制使用的默认项。项在 NSIS.template.in 文件中定义如下

!define MUI_STARTMENUPAGE_REGISTRY_KEY
    "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"

其中 CPACK_PACKAGE_VENDOR 值默认为 Kitware,而 CPACK_PACKAGE_INSTALL_REGISTRY_KEY 默认为 ${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}

对于 CMake 2.5.20071025 注册表键 trông giống như thế này

HKEY_LOCAL_MACHINE\SOFTWARE\Kitware\CMake 2.5.20071025

Tạo Phím Tắt Windows trong Menu Bắt Đầu

Có hai biến điều khiển các phím tắt được tạo trong Menu Bắt Đầu của Windows bởi NSIS. Các biến này chứa danh sách các cặp và phải có một số phần tử chẵn để hoạt động chính xác. Biến đầu tiên là CPACK_PACKAGE_EXECUTABLES, chứa tên tập tin thực thi tiếp theo là tên văn bản phím tắt. Ví dụ trong trường hợp CMake, tên thực thi được gọi là cmake-gui còn tên phím tắt là “CMake”. CMake thực hiện như sau để tạo phím tắt đó

set (CPACK_PACKAGE_EXECUTABLES "cmake-gui" "CMake" )

Biến thứ hai là CPACK_NSIS_MENU_LINKS. Biến này chứa các liên kết tùy ý tới cây cài đặt hoặc các trang web bên ngoài. Phần đầu tiên của cặp luôn là tệp nguồn hiện có hoặc vị trí, còn phần thứ hai là tên sẽ hiện lên trong Menu Bắt Đầu. Để thêm liên kết tới tập tin trợ giúp cho cmake-gui và liên kết tới trang web CMake, hãy thêm như sau

set (CPACK_NSIS_MENU_LINKS
     "doc/cmake-${VERSION_MAJOR}.${VERSION_MINOR}/cmake-gui.html"
     "cmake-gui Help" "http://www.cmake.org" "CMake Web Site")

Tùy chọn CPack NSIS Nâng cao

Ngoài các biến đã thảo luận, CPack còn cung cấp một số biến bổ sung được cấu hình trực tiếp vào tập tin tập lệnh NSIS. Những biến này có thể được sử dụng để thêm các phần lệnh NSIS vào lệnh NSIS cuối cùng dùng để tạo cài đặt. Như sau

CPACK_NSIS_EXTRA_INSTALL_COMMANDS

Các lệnh bổ sung được sử dụng trong khi cài đặt.

CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS

Các lệnh bổ sung được sử dụng trong khi gỡ cài đặt.

CPACK_NSIS_CREATE_ICONS_EXTRA

Các lệnh NSIS bổ sung trong phần biểu tượng của lệnh.

CPACK_NSIS_DELETE_ICONS_EXTRA

Các lệnh NSIS bổ sung trong phần xóa biểu tượng của lệnh.

Khi sử dụng các biến này, bạn nên tham khảo tài liệu NSIS và xem tập tin NSIS.template.in để biết vị trí chính xác của các biến.

Thiết lập Chế độ Liên kết Phần mở rộng Tập tin với NSIS

Một ví dụ về việc hữu ích có thể thực hiện với các lệnh cài đặt bổ sung là tạo chế độ liên kết các phần mở rộng tập tin với ứng dụng đã cài đặt. Ví dụ: nếu bạn có một ứng dụng CoolStuff có thể mở các tập tin có phần mở rộng .cool, bạn nên thiết lập các lệnh cài đặt và gỡ cài đặt như sau

set (CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
     WriteRegStr HKCR '.cool' '' 'CoolFile'
     WriteRegStr HKCR 'CoolFile' '' 'Cool Stuff File'
     WriteRegStr HKCR 'CoolFile\\shell' '' 'open'
     WriteRegStr HKCR 'CoolFile\\DefaultIcon' \\
                      '' '$INSTDIR\\bin\\coolstuff.exe,0'
     WriteRegStr HKCR 'CoolFile\\shell\\open\\command' \\
                      '' '$INSTDIR\\bin\\coolstuff.exe \"%1\"'
     WriteRegStr HKCR \"CoolFile\\shell\\edit' \\
                      '' 'Edit Cool File'
     WriteRegStr HKCR 'CoolFile\\shell\\edit\\command' \\
                      '' '$INSTDIR\\bin\\coolstuff.exe \"%1\"'
     System::Call \\
       'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
     ")

set (CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "
     DeleteRegKey HKCR '.cool'
     DeleteRegKey HKCR 'CoolFile'
     ")

Điều này tạo một chế độ liên kết tập tin Windows với tất cả các tập tin có phần mở rộng .cool, do đó khi người dùng nhấp đúp vào tập tin .cool, coolstuff.exe sẽ chạy với đường dẫn đầy đủ tới tập tin dưới dạng đối số. Điều này cũng thiết lập chế độ liên kết để chỉnh sửa tập tin từ menu chuột phải của Windows tới cùng một chương trình coolstuff.exe. Biểu tượng Windows Explorer sẽ được thiết lập biểu tượng tìm thấy trong tệp thực thi coolstuff.exe. Khi gỡ cài đặt, các khóa đăng ký sẽ bị xóa. Do phải thoát dấu ngoặc kép và dấu phân cách đường dẫn Windows, tốt nhất là đặt mã này vào CPACK_PROJECT_CONFIG_FILE cho dự án.

configure_file(
  ${CoolStuff_SOURCE_DIR}/CoolStuffCPackOptions.cmake.in
  ${CoolStuff_BINARY_DIR}/CoolStuffCPackOptions.cmake @ONLY)

set (CPACK_PROJECT_CONFIG_FILE
  ${CoolStuff_BINARY_DIR}/CoolStuffCPackOptions.cmake)
include (CPack)

Cài đặt Thư viện Run Time của Microsoft

Mặc dù không hoàn toàn là lệnh CPack NSIS, nếu bạn đang tạo ứng dụng trên Windows bằng trình biên dịch Microsoft, rất có thể bạn sẽ muốn phân phối các thư viện run time từ Microsoft cùng với dự án của mình. Trong CMake, bạn chỉ cần thực hiện như sau

include (InstallRequiredSystemLibraries)

这会将编译器运行时库添加为安装文件,该文件会放入应用程序的 bin 目录。如果您不希望库放入 bin 目录,请执行此操作

set (CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
include (InstallRequiredSystemLibraries)
install (PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
        DESTINATION mydir)

需要注意的是,运行时库必须紧邻包的可执行文件,以便 Windows 找到它们。使用 Visual Studio 2005 和 2008 时,还需要在分发运行时库时随应用程序安装 side by side 清单文件。如果您想打包软件的调试版本,则需要在 include 之前将 CMAKE_INSTALL_DEBUG_LIBRARIES 设置为 ON。但是,请注意,许可条款可能会禁止您重新分发调试库。在决定将 CMAKE_INSTALL_DEBUG_LIBRARIES 设置为 ON 之前,请仔细检查您使用的 Visual Studio 版本的许可条款。

CPack 组件安装支持

默认情况下,CPack 的安装程序会将项目安装的所有文件视为一个独立的整体:安装整个文件集或不安装任何文件。但是,对于许多项目而言,将安装细分为不同的可供用户选择的组件是有意义的。一些用户可能只希望安装项目的命令行工具,而另一些用户可能需要 GUI 或头文件。

本节说明如何配置 CPack 以生成基于组件的安装程序,该安装程序允许用户选择希望安装的项目组件集。举个例子,将为具有三个组件的库创建一个简单的安装程序:库二进制文件、示例应用程序和 C++ 头文件。完成后,Windows 和 Mac OS X 的最终安装程序如下图所示 8

../_images/MacandWindowsComponentInstallers.png

图 8:Mac 和 Windows 组件安装程序

我们接下来要处理的简单示例如下;它有一个库和一个可执行文件。使用已介绍过的 CPack 命令。

cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
project(MyLib)

add_library(mylib mylib.cpp)

add_executable(mylibapp mylibapp.cpp)
target_link_libraries(mylibapp mylib)

install(TARGETS mylib ARCHIVE DESTINATION lib)
install(TARGETS mylibapp RUNTIME DESTINATION bin)
install(FILES mylib.h DESTINATION include)
# add CPack to project
set(CPACK_PACKAGE_NAME "MyLib")
set(CPACK_PACKAGE_VENDOR "CMake.org")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
    "MyLib - CPack Component Installation Example")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "0")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")

# This must always be after all CPACK\_\* variables are defined
include(CPack)

指定组件

构建基于组件的安装的第一步是确定可安装组件的集合。在此示例中,将创建三个组件:库二进制文件、应用程序和头文件。此决定是任意的并且针对项目,但务必确定与对用户重要的功能单元对应的组件,而不是根据您程序的内部结构确定组件。

对于这些组件中的每一个,我们需要确定安装的每个文件所属的组件。对于每个 install 命令在 CMakeLists.txt 中,添加适当的 COMPONENT 参数,指出已安装文件将关联到的组件

install(TARGETS mylib
  ARCHIVE
  DESTINATION lib
  COMPONENT libraries)
install(TARGETS mylibapp
  RUNTIME
  DESTINATION bin
  COMPONENT applications)
install(FILES mylib.h
  DESTINATION include
  COMPONENT headers)

请注意,install 命令的 COMPONENT 参数并不新鲜;它一直是 CMake 的install 的一部分。如果您使用任何较旧的安装命令 (install_targetsinstall_files 等),您需要将其转换为install 的命令,才能使用组件。

下一步是通过为软件包的每个组件调用 cpack_add_component 函数,将您的项目中所有组件的名称通知 CPack。

cpack_add_component(applications)
cpack_add_component(libraries)
cpack_add_component(headers)

此时,您可以使用 CPack 构建一个基于组件的安装程序,它将允许独立安装 MyLib 的应用程序、库和头文件。Windows 和 Mac OS X 安装程序将如下图 9 所示。

../_images/WindowsandMacOSXComponentInstallerFirstPage.png

图 9:Windows 和 Mac OS X 组件安装程序首页

组件命名

这时,您可能已注意到,安装程序中实际组件的名称并不是非常具有描述性:它们只显示“应用程序”、“库”或“头文件”,如组件名称中所指定的那样。可以使用 cpack_add_component function 中的 DISPLAY_NAME 选项来通过提升名称级别。

cpack_add_component(applications DISPLAY_NAME
"MyLib Application")
cpack_add_component(libraries DISPLAY_NAME "Libraries")
cpack_add_component(headers DISPLAY_NAME "C++ Headers")

任何以 CPACK_COMPONENT_${COMPNAME} 为前缀的宏,其中 ${COMPNAME} 是某个组件的大写名称,用于在安装程序中设置该组件的某个特定属性。此处,我们设置我们每个组件的 DISPLAY_NAME 属性,以便我们获得人类可读的名称。这些名称将列在选择框中,而不是内部组件名称“应用程序”、“库”、“头文件”,

../_images/WindowsandMacOSXInstallerswithnamedcomponents.png

图 10:具有命名组件的 Windows 和 Mac OS X 安装程序

添加组件描述

与组件关联的还有多个其他属性,包括提供额外描述性信息的组件默认隐藏、必需或禁用功能。需要特别注意的是,DESCRIPTION 属性为组件提供某些描述性文本。此描述性文本将显示在安装程序的单独“描述”框中,并将更新内容——要么是在用户将鼠标悬停在相应组件名称上时(Windows),要么是在用户点击组件时(Mac OS X)。我们将在下面添加我们每个组件的描述

 cpack_add_component(applications DISPLAY_NAME "MyLib Application"
  DESCRIPTION
  "An extremely useful application that makes use of MyLib"
  )
cpack_add_component(libraries DISPLAY_NAME "Libraries"
  DESCRIPTION
  "Static libraries used to build programs with MyLib"
  )
cpack_add_component(headers DISPLAY_NAME "C++ Headers"
  DESCRIPTION "C/C++ header files for use with MyLib"
  )

通常,说明应该提供足够的信息,使用户能够决定是否安装组件,但本身不要超过几行长(安装程序中的“说明”框往往较小)。图 11 显示了 Windows 和 Mac OS X 安装程序的说明显示。

../_images/ComponentInstallerswithdescriptions.png

图 11:带有说明的组件安装程序

组件相互依赖性

对于大多数项目,各个组件都不是完全独立的。例如,应用程序组件可能依赖于另一个组件中的共享库才能正常执行,因此在没有相应共享库的情况下安装应用程序组件将导致无法使用的安装。CPack 允许您表达组件之间的依赖关系,以便只有在已安装其所依赖的所有其他组件时才会安装组件。

为了说明组件依赖关系,我们将对基于组件的安装程序实施一个简单的限制。由于我们在安装程序中不提供源代码,因此我们分发的 C++ 头文件只有在用户还安装了库二进制文件用于链接其程序时才能实际使用。因此,“headers” 组件依赖于“libraries”组件的可用性。我们可以通过设置 DEPENDSHEADERS 组件的属性来表达此概念

cpack_add_component(headers DISPLAY_NAME "C++ Headers"
  DESCRIPTION
  "C/C++ header files for use with MyLib"
  DEPENDS libraries
  )

组件的 DEPENDS 属性实际上是一个列表,因此一个组件可以依赖于其他多个组件。通过以这种方式表达所有组件依赖关系,您可以确保用户在安装时无法选择不完整的组件集。

组件分组

当您项目中的组件数量逐渐增多时,可能需要为组件列表提供额外的组织。为了帮助组织,CPack 包括组件组的概念。组件组只是一种为一组相关组件提供名称的方法。在用户界面中,组件组有自己的名称,并且在该组下显示该组中所有组件的名称。用户可以选择通过单击来(取消)选择组中所有组件的安装,或者展开组以选择各个组件。

我们将通过将三个组件“applications”、“libraries”和“headers”分类为“Runtime”和“Development”组来扩展我们的示例。我们可以通过将 GROUP 选项用于 cpack_add_component 函数来将组件放入组,如下所示

 cpack_add_component(applications
  DISPLAY_NAME "MyLib Application"
  DESCRIPTION
   "An extremely useful application that makes use of MyLib"
  GROUP Runtime)
cpack_add_component(libraries
  DISPLAY_NAME "Libraries"
  DESCRIPTION
  "Static libraries used to build programs with MyLib"
  GROUP Development)
cpack_add_component(headers
  DISPLAY_NAME "C++ Headers"
  DESCRIPTION "C/C++ header files for use with MyLib"
  GROUP Development
  DEPENDS libraries
  )

与组件类似,组件组具有可以自定义的各种属性,包括 DISPLAY_NAMEDESCRIPTION。例如,以下代码添加了对“Development”组的扩展说明

cpack_add_component_group(Development
 EXPANDED
 DESCRIPTION
"All of the tools you'll ever need to develop software")

一旦你按照自己的喜好自定义了组件组,就重新构建二进制安装程序以查看新组织:MyLib 应用程序将显示在新“Runtime”组下,而 MyLib 库和 C++ 头将显示在新“Development”组下。可以在 GUI 安装程序中轻松的打开/关闭组内的所有组件。这可以在图 12 中看到。

../_images/ComponentGrouping.png

图 12:组件分组

安装类型(仅限 NSIS)

当项目包含大量组件时,Windows 安装程序通常会提供基于特定用户需求的预选组件集。例如,希望开发针对库的软件的用户将需要一组组件,而最终用户可能需要完全不同的组件集。CPack 通过安装类型支持这种预选组件集概念。安装类型只是一组组件。当用户选择一种安装类型时,将选择完全相同的那组组件。然后允许用户进一步自定义其安装。目前仅支持 NSIS 生成器。

对于我们的简单示例,我们将创建两种安装类型:“完整”安装类型(包含所有组件)和“开发人员”安装类型(仅包含库和头)。为此,我们使用 cpack_add_install_type 函数来添加类型。

cpack_add_install_type(Full DISPLAY_NAME "Everything")
cpack_add_install_type(Developer)

接下来,我们将 INSTALL_TYPES 属性设置为每个组件的状态,说明哪些安装类型将包含该组件。这是通过 cpack_add_component 函数的 INSTALL_TYPES 选项完成的。

 cpack_add_component(libraries DISPLAY_NAME "Libraries"
  DESCRIPTION
   "Static libraries used to build programs with MyLib"
  GROUP Development
  INSTALL_TYPES Developer Full)
cpack_add_component(applications
  DISPLAY_NAME "MyLib Application"
  DESCRIPTION
   "An extremely useful application that makes use of MyLib"
  GROUP Runtime
  INSTALL_TYPES Full)
cpack_add_component(headers
  DISPLAY_NAME "C++ Headers"
  DESCRIPTION "C/C++ header files for use with MyLib"
  GROUP Development
  DEPENDS libraries
  INSTALL_TYPES Developer Full)

组件可以列在任何数量的安装类型下。如果你重新构建 Windows 安装程序,组件页面将包含一个允许你选择安装类型的组合框,因此它对应的组件集如图 13 所示。

../_images/NSISInstallationTypes.png

图 13:NSIS 安装类型

控制 CPack 组件的变量

函数 cpack_add_install_typecpack_add_component_groupcpack_add_component 只设置 CPACK_ 变量。这些变量在以下列表中进行描述

CPACK_COMPONENTS_ALL

这是一个包含 CPack 应该安装的所有组件名称的列表。此宏的存在表示 CPack 应构建一个基于组件的安装程序。与此处未列出的任何组件关联的文件或与任何组件关联的任何安装命令都将不会安装。

CPACK_COMPONENT_${COMPNAME}_DISPLAY_NAME

组件 ${COMPNAME} 的显示名称,用于图形安装程序中显示组件名称。此值可以是任何字符串。

CPACK_COMPONENT_${COMPNAME}_DESCRIPTION

组件 ${COMPNAME} 的扩展说明,用于在图形化安装程序中向用户提供组件的其他信息。说明可以使用“\n”作为换行符跨越多行。

CPACK_COMPONENT_${COMPNAME}_HIDDEN

指示该组件将隐藏在图形化安装程序中的标志,因此无法选择或安装。仅在 NSIS 中可用。

CPACK_COMPONENT_${COMPNAME}_REQUIRED

指示该组件为必需组件的标志,因此始终将安装该组件。它将在图形化安装程序中可见,但无法取消选择。

CPACK_COMPONENT_${COMPNAME}_DISABLED

指示该组件应默认禁用(取消选择)的标志。用户可以自由选择此组件进行安装。

CPACK_COMPONENT_${COMPNAME}_DEPENDS

列出此组件依赖的组件。如果选择此组件,则还必须选择其中列出的每个组件。

CPACK_COMPONENT_${COMPNAME}_GROUP

指定此组件所属的组件组的名称。如果未提供,该组件将成为一个独立组件,不属于任何组件组。

CPACK_COMPONENT_${COMPNAME}_INSTALL_TYPES

列出该组件所属的安装类型。当选择其中一种安装类型时,将自动选择此组件。仅在 NSIS 中可用。

CPACK_COMPONENT_GROUP_${GROUPNAME}_DISPLAY_NAME

组件组 ${GROUPNAME} 的显示名称,用于在图形化安装程序中显示组件组名称。该值可以是任何字符串。

CPACK_COMPONENT_GROUP_${GROUPNAME}_DESCRIPTION

组件组 ${GROUPNAME} 的扩展说明,用于在图形化安装程序中向用户提供该组中包含的组件的其他信息。说明可以使用“\n”作为换行符跨越多行。

CPACK_COMPONENT_GROUP_${GROUPNAME}_BOLD_TITLE

指示组标题是否应加粗的标志。仅在 NSIS 中可用。

CPACK_COMPONENT_GROUP_${GROUPNAME}_EXPANDED

指示该组是否应从“展开”状态开始,显示其组件。否则,仅显示组名称本身,直到用户单击该组。仅在 NSIS 中可用。

CPACK_INSTALL_TYPE_${INSTNAME}_DISPLAY_NAME

安装类型的显示名称。该值可以是任何字符串。

用于 Cygwin 安装程序的 CPack

Cygwin (http://www.cygwin.com/) 是一个类 Linux 运行时 DLL 和一系列工具组成的 Windows 环境。若要将工具添加到官方 cygwin 中,将使用 cygwin 安装程序。该安装工具具有非常具体的要纳入的源和二进制树布局。CPack 可以创建源和二进制 tar 文件并正确地对其进行 bzip 压缩,以便将其上传到 cygwin 镜像站点。当然,在完成此操作之前,你必须让你的程序包获得 cygwin 社区的认可。由于程序包的布局比其他包装工具更具限制性,你可能需要更改项目的一些安装选项。

cygwin 安装程序要求将所有文件安装到 /usr/bin/usr/share/package-version/usr/share/man/usr/share/doc/package-version 中。cygwin CPack 生成器将自动将 /usr 添加到项目的安装目录中。该项目必须安装到 sharebin 中,而 CPack 将自动添加 /usr 前缀。

Cygwin 还要求您提供一个可用于根据源信息创建包的 shell 脚本。还必须在一个 diff 文件中提供该包所需的全部 cygwin 特定修补程序。CMake 的 configure_file 命令可用于为某个项目创建这两个文件。由于 CMake 是一个 cygwin 包,因此用于为 cygwin CPack 生成器配置 CMake 的 CMake 代码如下所示

set (CPACK_PACKAGE_NAME CMake)

# setup the name of the package for cygwin
set (CPACK_PACKAGE_FILE_NAME
    "${CPACK_PACKAGE_NAME}-${CMake_VERSION}")

# the source has the same name as the binary
set (CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})

# Create a cygwin version number in case there are changes
# for cygwin that are not reflected upstream in CMake
set (CPACK_CYGWIN_PATCH_NUMBER 1)

# if we are on cygwin and have cpack, then force the
# doc, data and man dirs to conform to cygwin style directories
set (CMAKE_DOC_DIR "/share/doc/${CPACK_PACKAGE_FILE_NAME}")
set (CMAKE_DATA_DIR "/share/${CPACK_PACKAGE_FILE_NAME}")
set (CMAKE_MAN_DIR "/share/man")

# These files are required by the cmCPackCygwinSourceGenerator and
# the files put into the release tar files.
set (CPACK_CYGWIN_BUILD_SCRIPT
    "${CMake_BINARY_DIR}/@CPACK_PACKAGE_FILE_NAME@-
       @[email protected]")
set (CPACK_CYGWIN_PATCH_FILE
     "${CMake_BINARY_DIR}/@CPACK_PACKAGE_FILE_NAME@-
        @[email protected]")

# include the sub directory for cygwin releases
include (Utilities/Release/Cygwin/CMakeLists.txt)

# when packaging source make sure to exclude the .build directory
set (CPACK_SOURCE_IGNORE_FILES
 "/CVS/" "/\\\\.build/" "/\\\\.svn/" "\\\\.swp$" "\\\\.#" "/#" "~$")

Utilities/Release/Cygwin/CMakeLists.txt:

# create the setup.hint file for cygwin
configure_file (
 "${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/cygwin-setup.hint.in"
 "${CMake_BINARY_DIR}/setup.hint")

configure_file (
 "${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/README.cygwin.in"
 "${CMake_BINARY_DIR}/Docs/@CPACK_PACKAGE_FILE_NAME@-
    @[email protected]")

install_files (/share/doc/Cygwin FILES
   ${CMake_BINARY_DIR}/Docs/@CPACK_PACKAGE_FILE_NAME@-
       @[email protected])

# create the shell script that can build the project
configure_file (
"${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/cygwin-package.sh.in"
  ${CPACK_CYGWIN_BUILD_SCRIPT})

# Create the patch required for cygwin for the project
configure_file (
"${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/cygwin-patch.diff.in"
  ${CPACK_CYGWIN_PATCH_FILE})

文件 Utilities/Release/Cygwin/cygwin-package.sh.in 在 CMake 原信息树中。这是一个 shell 脚本,可用于根据源信息重新创建 cygwin 包。对于其他项目,Templates/cygwin-package.sh.in 中有一个模板安装脚本。该脚本应该能够配置和打包任何基于 cygwin 的 CPack 项目,并且是所有官方 cygwin 包的必需项。

对于 cygwin 二进制文件,另一个重要文件是 share/doc/Cygwin/package-version.README。该文件应包含 cygwin 所需的有关项目的信息。对于 CMake,文件被配置为可包含正确的版本信息。例如,CMake 中该文件的部分内容如下所示

Build instructions:
  unpack CMake-2.5.20071029-1-src.tar.bz2
    if you use setup to install this src package, it will be
         unpacked under /usr/src automatically
  cd /usr/src
  ./CMake-2.5.20071029-1.sh all
This will create:
  /usr/src/CMake-2.5.20071029.tar.bz2
  /usr/src/CMake-2.5.20071029-1-src.tar.bz2

Mac OS X PackageMaker 的 CPack

在 Apple Mac OS X 操作系统上,CPack 提供了使用系统 PackageMaker 工具的能力。本节将展示安装 OS X 上的 CMake 包时用户将看到的 CMake 应用程序安装屏幕。设置更改了安装程序中文本的 CPack 变量,将针对安装程序的每个屏幕给出。

../_images/MacPackageinsidedmg.png

图 14:dmg 中的 Mac 包

在图 14 中,可以看到 Mac OS X 的 CPack 包制作器创建的 .dmg 磁盘映像中找到的 .pkg 文件。该文件的名称由 CPACK_PACKAGE_FILE_NAME 变量控制。如果未设置此变量,CPack 将使用基于包名称和版本设置的默认名称。

../_images/IntroductionScreenMacPackageMaker.png

图 15:Mac PackageMaker 的介绍屏幕

.pkg 文件运行时,包向导以图 15 中所示的屏幕启动。该窗口中的文本由 CPACK_RESOURCE_FILE_WELCOME 变量指向的文件控制。

../_images/ReadmesectionofMacpackagewizard.png

图 16:Mac 包向导的自述文件部分

上图显示了包向导的自述文件部分。该窗口的文本使用 CPACK_RESOURCE_FILE_README 变量进行自定义。它应包含指向应在此屏幕上显示的文本文件的路径。

../_images/LicensescreenMacpackager.png

图 17:Mac 包装器的许可证屏幕

此图包含包的许可证文本。用户必须接受许可证,安装过程才能继续。许可证的文本来自 CPACK_RESOURCE_FILE_LICENSE 变量指向的文件。

安装过程中的其他屏幕不可通过 CPack 进行自定义。如需更改此安装程序的更多高级功能,则可以修改两个 CPack 模板,Modules/CPack.Info.plist.inModules/CPack.Description.plist.in。可使用 CMAKE_MODULE_PATH 变量将这些文件替换为一个指向包含经过修改的某个或两个文件的副本的目录的项目。

适用于 Mac OS X 的 CPack 拖放

CPack 还支持创建 Mac 拖放安装程序。在本例中,将创建一个 .dmg 磁盘镜像。该镜像包含到 /Applications 目录的符号链接以及项目安装树的副本。本例中,最好将包含可重定位安装程序的 Mac 应用程序软件包或单个文件夹用作项目唯一的安装目标。变量 CPACK_PACKAGE_EXECUTABLES 用于指向项目的应用程序软件包。

../_images/DragandDropLicensedialog.png

图 18:拖放许可证对话框

../_images/ResultingDragandDropfolders.png

图 19:生成的拖放文件夹

适用于 Mac OS X X11 应用程序的 CPack

CPack 还附带一个 OS X X11 包制作工具生成器。可以将其用于打包基于 X11 的应用程序,并且可以将利用包裹它们,允许用户像运行任何本机 OS X 应用程序那样运行它们的脚本将它们包装成更类似于本机 OS X 应用程序的形式。与 OS X PackageMaker 生成器类似,OS X X11 生成器创建磁盘镜像 .dmg 文件。在此示例中,名为 KWPolygonalObjectViewerExample 的 X11 应用程序与 OS X X11 CPack 生成器一起打包。

../_images/MacOSXX11packagediskimage.png

**图 20:Mac OS X X11 包磁盘镜像**

此图片显示创建的磁盘镜像。本例中,CPACK_PACKAGE_NAME 已设置为 KWPolygonalObjectViewerExample,并且版本信息保留了 CPack 的默认版本 0.1.1。变量 CPACK_PACKAGE_EXECUTABLES 已设置为 KWPolygonalObjectViewerExample 和 KWPolygonalObjectViewerExample 这对,已安装的 X11 应用程序名为 KWPolygonalObjectViewerExample。

../_images/OpeningOSXX11diskimage.png

**图 21:打开 OS X X11 磁盘镜像**

上图显示了用户单击 CPack 创建的 .dmg 文件后所看到的内容。Mac OS X 将此磁盘镜像装载为一个磁盘

../_images/Mounteddmgdiskimage.png

**图 22:已装载的 .dmg 磁盘镜像**

此图显示挂载的磁盘映像。它包含系统 /Applications 目录的符号链接,它还包含 CPACK_PACKAGE_EXECUTABLES 中找到的每个可执行文件的一个应用程序包。用户可以像下图所示将应用程序拖放至 Applications 文件夹中。

../_images/DraganddropapplicationtoApplications.png

图 23:将应用程序拖放至 Applications

CPack 实际上提供了一个基于 C++ 的可执行文件,可通过 Apple 脚本语言运行 X11 应用程序。用户双击 KWPolygonalObjectViewerExample 时,已安装的应用程序包将运行该转发应用程序。此脚本将确保 X11 服务器已启动。可在 CMake/Modules/CPack.RuntimeScript.in 中找到运行的脚本。可在 Source/CPack/OSXScriptLauncher.cxx 中找到脚本启动器 C++ 程序的源代码。

面向 Debian 软件包的 CPack

Debian 软件包 .deb 只是一个“ar”存档。CPack 包含 Debian 软件包所需的 BSD 样式 ar 的代码。Debian 软件包生成器使用 CPack 变量的标准集来初始化一组特定于 Debian 的变量。这些变量可在 CPACK_PROJECT_CONFIG_FILE 中替代;生成器的名称为“DEB”。DEB 生成器使用的变量如下

CPACK_DEBIAN_PACKAGE_NAME

默认为 CPACK_PACKAGE_NAME 的小写形式。

CPACK_DEBIAN_PACKAGE_ARCHITECTURE

默认为 i386

CPACK_DEBIAN_PACKAGE_DEPENDS

此变量必须设置为此软件包依赖的其他软件包,如果为空,则会发出警告。

CPACK_DEBIAN_PACKAGE_MAINTAINER

默认为 CPACK_PACKAGE_CONTACT 的值

CPACK_DEBIAN_PACKAGE_DESCRIPTION

默认为 CPACK_PACKAGE_DESCRIPTION_SUMMARY 的值

CPACK_DEBIAN_PACKAGE_SECTION

默认为 devl

CPACK_DEBIAN_PACKAGE_PRIORITY

默认为 optional

面向 RPM 的 CPack

CPack 支持创建 Linux RPM 文件。在 CPACK_GENERATOR 中设置的生成器的名称为“RPM”。RPM 软件包功能要求在计算机上安装并配置 rpmbuild,并且它位于 PATH 中。RPM 软件包生成器使用 CPack 变量的标准集来初始化特定于 RPM 的变量。特定于 RPM 的变量如下

CPACK_RPM_PACKAGE_SUMMARY

默认为 CPACK_PACKAGE_DESCRIPTION_SUMMARY 的值

CPACK_RPM_PACKAGE_NAME

默认为 CPACK_PACKAGE_NAME 的小写形式。

CPACK_RPM_PACKAGE_VERSION

默认为 CPACK_PACKAGE_VERSION 的值。

CPACK_RPM_PACKAGE_ARCHITECTURE

默认为 i386

CPACK_RPM_PACKAGE_RELEASE

默认为 1。这是 RPM 文件的版本,而不是被软件包软件的版本。

CPACK_RPM_PACKAGE_GROUP

默认为 none

CPACK_RPM_PACKAGE_VENDOR

默认为 CPACK_PACKAGE_VENDOR 的值

CPack 文件

CPack 使用一些文件,这些文件有助于进一步了解 CPack 的工作方式和可以设置哪些选项。这些文件还可以用作针对 CPack 的其他生成器的起点。这些文件大部分在 CMake 的 Modules 和 Templates 目录中,并且通常以 CPack 前缀开头。在 2.8.8 版本中,还可以查阅 cpack --help-variable-listcpack --help-variable 以获取全部已记录CPACK_* 变量。