如何修改传递给自定义 CMake 目标的环境变量?

How to modify environment variables passed to custom CMake target?

也许我遗漏了一些明显的东西,但我似乎无法弄清楚如何明确设置通过 add_custom_target().

启动的进程可以看到的环境变量

我尝试了以下方法:

set(ENV{PATH} "C:/Some/Path;$ENV{PATH}")
add_custom_target(newtarget somecommand)

不幸的是,%PATH% 环境变量似乎未更改为 somecommand。 (我已经设置了一个重现问题的 Gist here。)

我做错了什么?

您在 configuration 步骤设置了环境变量,但在 build 步骤执行了为 add_custom_target 指定的命令。另请参阅 CMake 常见问题解答:How can I get or set environment variables?

[...]
environment variables SET in the CMakeLists.txt only take effect for cmake itself (configure-time), so you cannot use this method to set an environment variable that a custom command might need (build-time). Barring environment variable support by various CMake commands (e.g. add_custom_command(), currently not supported yet), an acceptable workaround may be to invoke shell scripts instead which wrap the commands to be executed.

目前add_custom_target(以及其他定义构建步骤操作的命令,例如add_custom_command)不支持简单设置环境变量。根据 this bugreport 中的建议,对于 Linux 上不带空格的设置变量值 ,您可以在命令前添加 "VAR=VAL" 子句。对于一般情况,您可以准备 wrapper 脚本,它设置环境和 运行 实际命令:

在 Windows:

wrapper.bat:

@ECHO OFF
set PATH=C:\Some\Path;%PATH%
%*

CMakeLists.txt:

add_custom_target(...
    COMMAND cmd /c ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.bat <real_command> args...
)

在 Linux:

wrapper.sh:

export "PATH=/Some/Path:$PATH"
eval "$*"

CMakeLists.txt:

add_custom_target(...
    COMMAND /bin/sh ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.sh <real_command> args...
)

如果变量的值取决于配置,您可以使用 configure_file.

配置包装脚本

更新:

如@sakra 所述,cmake 可执行文件的 env 工具模式可用作包装脚本:

add_custom_target(...
    COMMAND ${CMAKE_COMMAND} -E env "PATH=C:/Some/Path;$ENV{PATH}" <real_command> args...
)

从 CMake 3.2 开始可以使用这种方式。

为自定义目标设置环境变量的可移植方法是使用 CMake 的 command-line 工具模式命令 env:

env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...

Run command in a modified environment.

例如:

add_custom_target(newtarget ${CMAKE_COMMAND} -E env NAME=VALUE somecommand)

另见 Command Line Tool Mode

这个问题的迟到答案,但也许会对某些人有所帮助。我们在 Windows.

上的 cmake 文件中使用 && 运算符来执行此操作
set(MY_COMMAND set "PATH=C:\some\path\;%PATH%"&&
        somecommand)

add_custom_target(TARGET newtarget COMMAND ${MY_COMMAND})

请注意,在 && 之前不能有 space(由于我不完全理解的原因)。此外,spaces 在这里处理起来真的很痛苦,所以我不知道如果 c:\some\path 有 spaces 我是否正确。如果您的原始路径有 spaces.

,它确实有效