强制make在同一环境中执行命令

时间:2018-03-11 06:55:21

标签: makefile gnu-make

我有一个makefile来编译跨平台的应用程序。对于Windows,我决定使用MSVC。要设置编译器工具链(环境变量以便轻松访问特定目标体系结构的编译器),MSVC会提供名为vcvarsall的批处理文件。如果我手动调用它,它工作正常,makefile也可以执行。我试图通过从makefile调用它来自动化它,但是make似乎在不同的环境中运行它,所以它无法找到编译器。

有没有办法强制make不要在不同的环境中执行某些命令?

1 个答案:

答案 0 :(得分:2)

与所有进程一样,Make在启动它的环境中运行。 它执行的配方的每个行都在 distinct 子流程中运行,具体来说, 一个独特的shell调用。子进程无法做任何改变环境的事情 它的父进程或兄弟子进程:它只能传递一个修改过的环境 到它自己的子过程。

targetA: prequisitesA...
    command1        # New shell; inherits environment of `make`
    command2        # Another new shell; inherits environment of `make`
    ...

targetB: prequisitesB...
    command1 && command2    # New shell; inherits environment of `make`
    command3        # Another new shell; inherits environment of `make`
    ...

targetC: prequisitesC...
    command1 && \
    command2    # New shell; inherits environment of `make`
    command3; \
    command4    # Another new shell; inherits environment of `make`
    ...

在任何环境设置的make-recipe中的命令中使用 通过运行vcvarsall来应用,然后必须运行make vcvarsall在同一环境中,或者是保留这些环境的继承者 设置,或者每个依赖的配方命令必须相同 在这些设置上。

您可以指示Make在一个 shell中运行每个配方的所有命令, 每个食谱,通过编写伪目标.ONESHELL: 在makefile中。但这似乎不太适合你。

您的案例可能适合自动化是编写包装器 在vcvarsall之前调用make的脚本。

取决于你的makefile的结构,以及你对递归make的容忍度,你可能会想到一个递归的解决方案:

ARCH ?= amd64

.PHONY: all

all:
    vcvarsall $(ARCH) && $(MAKE) prog

其中: -

  • ARCH(架构)如果未在amd64上定义,则默认为make 命令行或在调用环境中

  • all是您的默认目标虚假目标

  • prog是您真正的目标。