【问题标题】:How to modify environment variables passed to custom CMake target?如何修改传递给自定义 CMake 目标的环境变量?
【发布时间】:2016-05-03 22:15:21
【问题描述】:

也许我遗漏了一些明显的东西,但我似乎无法弄清楚如何显式设置通过add_custom_target() 启动的进程可以看到的环境变量。

我尝试了以下方法:

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

不幸的是,%PATH% 环境变量似乎与somecommand 保持不变。 (我已经设置了一个 Gist 来重现问题here。)

我做错了什么?

【问题讨论】:

  • 我建议,由于您正在创建一个新进程(从您的 cmets),那么新进程将提供自己的环境,而不是继承主进程的环境。如果您创建主进程的子进程,那么应该继承环境 - 但我对cmake 一无所知,所以我可能会离开这里。但是,您应该使用backslash 作为目录分隔符,而不是/,因为/ 是一个开关前缀。有时/ 工作愉快,但并不可靠。

标签: cmake environment-variables


【解决方案1】:

为自定义目标设置环境变量的一种可移植方式是使用 CMake 的命令行工具模式命令env

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

在修改后的环境中运行命令。

例如:

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

另见Command Line Tool Mode

【讨论】:

    【解决方案2】:

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

    [...]
    CMakeLists.txt 中的环境变量SET 仅限 对 cmake 本身生效(configure-time), 所以你不能使用这个方法来设置环境变量 自定义命令可能需要(构建时间)。 禁止各种 CMake 命令支持环境变量 (例如add_custom_command(),目前尚不支持), 一个可接受的解决方法可能是调用 shell 脚本 其中包装了要执行的命令。

    目前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 开始可用。

    【讨论】:

    • 写什么代替 3 点?什么是“real_command”?什么是“参数”?不好的答案
    • add_custom_target() 的第一个参数是目标名称。 &lt;real_command&gt; 是原始 COMMAND 参数的替代品,args... 是原始命令的参数。
    • 没有完整的例子我完全不明白这个命令是如何工作的,对不起
    • 如果您不明白 add_custom_target 的作用,您可以查看 documentation 或在 Stack Overflow 上提出新问题。当前问题帖子包含调用add_custom_target(newtarget somecommand),因此两个答案(sakra 的一个和我的)都意味着读者知道此调用的含义。
    • 没有示例的Cmake文档 - 花了很多时间我还是不明白!所以,这个答案对我没有帮助。
    【解决方案3】:

    对此的回答较晚,但也许会对某人有所帮助。我们在 Windows 上的 cmake 文件中使用 && 运算符来执行此操作。

    set(MY_COMMAND set "PATH=C:\\some\\path\;%PATH%"&&
            somecommand)
    
    add_custom_target(TARGET newtarget COMMAND ${MY_COMMAND})
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-17
      • 2013-06-05
      • 1970-01-01
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多