如何修改传递给自定义 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)
这个问题的迟到答案,但也许会对某些人有所帮助。我们在 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.
,它确实有效
也许我遗漏了一些明显的东西,但我似乎无法弄清楚如何明确设置通过 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 variablesSET
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)
这个问题的迟到答案,但也许会对某些人有所帮助。我们在 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.
,它确实有效