返回

全局配置 CMake 安装路径: 项目名称自动管理

windows

全局配置CMake安装路径并使用项目名称

当使用 CMake 构建项目时,我们常常需要定制安装路径,特别是在跨平台或构建多个不同项目时。CMake 默认的安装路径规则可能并不总是符合预期。 本文讨论如何在全局层面设置安装路径,使其包含项目名称。这能够方便用户在没有修改各个项目的 CMakeLists.txt 文件的情况下实现灵活的路径管理。

问题背景

CMake 默认的 CMAKE_INSTALL_PREFIX 变量在 Windows 上的默认值是 C:/Program Files/${PROJECT_NAME}。 如果我们需要使用其他位置,例如 D:/ownbuilds/${PROJECT_NAME} ,我们期望它能像默认情况一样,根据具体的项目名称自动调整。 然而,直接设置 CMAKE_INSTALL_PREFIX 环境变量为字面量 D:/ownbuilds/${PROJECT_NAME},并不能实现预期的项目名称展开,install 命令的行为如同该前缀设置为 D:/ownbuilds, 遗漏了项目名称。 如何让CMake在全局设置的环境变量中正确解析和使用项目变量成为了需要解决的关键。

分析

问题的核心在于 CMake 处理环境变量和变量展开的方式。尽管 CMake 允许从环境变量中导入 CMAKE_INSTALL_PREFIX, 但它仅仅是将环境变量的内容直接复制 ,并不会对该内容执行 CMake 变量展开。这意味着像${PROJECT_NAME} 这样的 CMake 变量并不会在环境变量被导入后动态地替换为实际的项目名称,它只会被视为普通字符串,保持字面量不变。为了在全局层面上使用项目名作为安装路径的一部分,我们需要采取一些特殊措施,而非仅仅依赖环境变量。

解决方案一:CMake用户初始化文件

CMake 提供了一个机制来运行用户指定的初始化代码,它在任何项目之前执行。这个文件通常名为 CMakeUserPresets.jsonCMakeUser.txt (旧格式)。利用这一机制,我们可以覆盖默认的安装路径。通过 CMakeUserPresets.json 方案更受欢迎,因为这种结构化格式更易于阅读和维护。

操作步骤如下:

  1. 创建一个名为 CMakeUserPresets.json 的文件,将其放在合适的目录。 (例如,你的 home 目录下的 .cmake 目录中:~/.cmake/CMakeUserPresets.json 或者项目代码所在的目录)。

  2. 在文件中定义一个 configurePresets 字段。并在该字段中,配置一个新的 CMAKE_INSTALL_PREFIX 变量,使用一个可展开的路径, 例如D:/ownbuilds/${sourceDirName}。 此处的 ${sourceDirName} 也是 CMake 的一个变量,包含源目录的基本名称,它通常与项目名称匹配,但情况并非总是如此。对于 sourceDirName 不能与项目名称完全对齐的情况,还可以使用其它CMake预定义变量来帮助进行路径解析(例如 CMAKE_PROJECT_NAME)。这里我们选用 CMAKE_PROJECT_NAME 更好。所以最终的配置可以是D:/ownbuilds/${CMAKE_PROJECT_NAME}

以下是一个简单的 CMakeUserPresets.json 示例:

{
  "version": 3,
  "configurePresets": [
    {
      "name": "custom_install_path",
      "hidden": true,
       "cacheVariables": {
         "CMAKE_INSTALL_PREFIX": "D:/ownbuilds/${CMAKE_PROJECT_NAME}"
       }
    }
  ],
    "buildPresets": [ {
       "name": "default_build",
      "configurePreset": "custom_install_path"
    }] ,
   "packagePresets":[ {
          "name": "default_package",
      "configurePreset": "custom_install_path",
           "buildPreset": "default_build"

        }]

}

此配置定义了一个名为custom_install_path 的预设值,将 CMAKE_INSTALL_PREFIX 设置为目标值。然后,我们通过 buildPresetspackagePresetscustom_install_path 配置项激活。

  1. 运行 CMake 时,它会加载此文件,并应用这些预设,最终的安装目录就会按照定义的模式执行了。 验证方式依旧是,在项目构建之前,在项目的CMakeLists.txt 文件中加入类似 message(">> CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}") 的指令。

此方法为全局配置提供了一个高效且可维护的解决方案,无需修改每个项目的 CMakeLists.txt 文件。这种方法优于环境变量设定,在于CMake会在项目配置时动态扩展变量。

解决方案二:使用cmake命令行的参数 --prefix

也可以在 cmake 命令中使用参数 --prefix 指定安装路径。它会覆盖 CMake 文件内的默认值或者全局默认设置。尽管这种方法需要在命令行中显式指定,而不是像前面的方式自动处理。它仍然可以作为临时的或者特定的安装场景提供额外的控制。比如:

cmake --prefix="D:/ownbuilds/AnotherProject"  ../source_directory

此命令行指令可以将 CMAKE_INSTALL_PREFIX 强制设置为 D:/ownbuilds/AnotherProject。使用此方法需要您在构建时额外指定 --prefix参数,相对前一种解决方案而言,更不便利。它更适合于临时覆盖或者自动化脚本的情况。

安全提示

需要注意的是,更改安装路径会影响应用程序的运行环境,尤其是在多平台开发时,注意测试以保证软件在新的安装位置能正常运行。为了确保安全和一致性,推荐在统一的位置管理你的安装路径,减少配置上的混乱。避免直接向Program Files写入文件,建议在数据分区(非系统分区)设立安装位置。在不同的开发环境下,要检查权限和配置问题,避免安装时的意外失败。

以上,提供了两个有效的方法来解决 CMake 安装路径的全局定制问题。其中利用 CMakeUserPresets.json 可以为大多数场景提供一劳永逸的解决方案,更推荐优先使用。 而通过命令行参数控制 cmake 更适合在特殊的情况下进行临时调整。用户应该根据自身实际需要灵活地选用对应的方案。