【问题标题】:Is it possible to set Environment variables in Makefile - to be used after是否可以在 Makefile 中设置环境变量 - 之后使用
【发布时间】:2019-02-06 10:38:51
【问题描述】:

我正在尝试在 Makefile 中设置环境变量,以便它可以用于在 sam shell 中以 make 运行的另一个程序中,但在 make 运行之后。

更新:根据接受的 cmets 答案,这是不可能的。

步骤:

  1. 运行make test设置环境:export TEST_ENV_ONE=OneString
  2. 运行另一个程序,它可以读取TEST_ENV_ONE

试过这个:

不工作:

test:
    export TEST_ENV_ONE=OneString
    $(shell export TEST_ENV_TWO=TwoString)

然后这是空的:

echo $TEST_ENV_ONE
echo $TEST_ENV_TWO

【问题讨论】:

    标签: bash makefile gnu-make


    【解决方案1】:

    您上面的export TEST_ENV_ONE=OneString 正在专用外壳中运行。后续命令在其他 shell 实例中运行。因此,它们不会继承环境变量TEST_ENV_ONE


    您可以在 makefile 中使用顶级(即不在目标配方中)export directive

    export env_var := MyEnvVariable
    
    .PHONY: all
    all:
        echo env_var: $$env_var
    

    这样,变量env_var 被导出到将执行配方的shell。

    如果您使用上面的 makefile 运行 make

    $ make
    echo env_var: $env_var
    env_var: MyEnvVariable
    

    从输出中可以看出,运行 echo env_var: $env_var 的 shell 在其环境中具有变量 env_var

    【讨论】:

    • 谢谢你是对的,当你写“......有变量..”我的问题是我需要 env_var 在另一个程序中可用 - 仍然在同一个 shell/终端/bash 中制作。
    • 你的意思是它必须在执行make的shell中可用?
    • 是的,如果可能的话
    • make在该shell的子进程中运行,因此在该子进程中创建环境变量不会影响父进程的环境。
    • 我建议您创建一个全新的问题,在更高级别上解释您的问题。在我看来,这像是一个 XY 问题。
    【解决方案2】:

    如果您希望将环境变量导出到您调用的 shell,这会有些困难,因为正如 ネロク 解释的那样,您不能直接将环境变量从子进程 (make) 导出到其父进程进程(调用 make 的 shell)。但是,如果您接受这样调用 make:

    eval "$(make)"
    

    那么确实有可能:只需在您的食谱中回显export VARIABLE1=VALUE1; export VARIABLE2=VALUE2; ...。警告:您还必须保证 make 在标准输入上不会回显任何其他内容。但是您可以改用标准错误。示例:

    $ cat Makefile
    export TEST_ENV_ONE := OneString
    
    all:
        @printf 'make variable TEST_ENV_ONE = %s\n' "$(TEST_ENV_ONE)" 1>&2
        @printf 'in-recipe shell variable TEST_ENV_ONE = %s\n' "$$TEST_ENV_ONE" 1>&2
        @printf 'export TEST_ENV_ONE="%s"\n' '$(TEST_ENV_ONE)'
    
    $ unset TEST_ENV_ONE
    $ printenv TEST_ENV_ONE
    $ eval "$(make)"
    make variable TEST_ENV_ONE = OneString
    in-recipe shell variable TEST_ENV_ONE = OneString
    $ printenv TEST_ENV_ONE
    OneString
    

    请注意,make 或多或少将环境变量视为 make 变量。来自 GNU make 手册:

    make 中的变量可以来自 make 运行的环境。 make 启动时看到的每个环境变量都是 转换为具有相同名称和值的 make 变量。 但是,makefile 中的显式分配,或使用命令 参数,覆盖环境。 (如果指定了“-e”标志, 然后来自环境的值会覆盖 makefile 中的分配。 请参阅选项摘要。但这不是推荐的做法。)

    因此,除非您的变量的值是 make 本身复杂计算的结果,否则获得相同结果的更自然的方法是在父 shell 中定义环境变量并在生成文件:

    $ cat Makefile
    all:
        @printf 'make variable TEST_ENV_ONE = %s\n' "$(TEST_ENV_ONE)"
        @printf 'in-recipe shell variable TEST_ENV_ONE = %s\n' "$$TEST_ENV_ONE"
    
    $ export TEST_ENV_ONE=OneString
    $ make
    make variable TEST_ENV_ONE = OneString
    in-recipe shell variable TEST_ENV_ONE = OneString
    $ printenv TEST_ENV_ONE
    OneString
    

    【讨论】:

    • eval "$(make)" 加上引号,出错的事情会更少。 eval 不是特殊语法——它的参数像其他任何东西一样受到分词和通配符的影响。
    猜你喜欢
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 2018-09-15
    相关资源
    最近更新 更多