如何在Makefile中获取脚本?

bro*_*sbp 71 shell makefile

有没有更好的方法从makefile中获取设置env变量的脚本?

FLAG ?= 0
ifeq ($(FLAG),0)
export FLAG=1
/bin/myshell -c '<source scripts here> ; $(MAKE) $@'
else
...targets...
endif
Run Code Online (Sandbox Code Playgroud)

Pur*_*reW 74

Makefile默认shell是/bin/sh不实现的source.

更改shell /bin/bash使其成为可能:

# Makefile

SHELL := /bin/bash

rule:
    source env.sh && YourCommand
Run Code Online (Sandbox Code Playgroud)

  • 这在 macOS 上不起作用 (8认同)
  • 这似乎对我不起作用? (5认同)
  • @VivekAditya当然,这是非常有用的东西。但是请注意,OP要求设置变量供`make`使用,而不仅仅是用于动作行。后者是这样做的方法,但是前者没有直接的方法。 (3认同)

dmc*_*kee 43

要回答问题:你做不到.

基本问题是子进程不能改变父进程的环境.外壳由能够规避这种不分叉一个新的进程时,source"荷兰国际集团,但只是运行在shell的当前版本的命令.这工作正常,但make不是/bin/sh(或者你的脚本所用的任何shell)并且不理解那种语言(除了它们共有的位).

Chris Dodd和Foo Bah解决了一个可能的解决方法,所以我建议另一个(假设您正在运行GNU make):将shell脚本后处理为make兼容文本并包含结果:

shell-variable-setter.make: shell-varaible-setter.sh
    postprocess.py @^

# ...
else
include shell-variable-setter.make
endif
Run Code Online (Sandbox Code Playgroud)

凌乱的细节留作练习.

  • 您“无法”为整个Makefile编写脚本,但是*可以*为单个配方执行脚本。 (2认同)
  • 您可以使用“include .env”(或任何键值文件)使变量可供整个 Makefile 访问,然后仅将所需的变量传递到相应的配方中。 (2认同)

Foo*_*Bah 22

如果您的目标只是为Make设置环境变量,为什么不将它保留在Makefile语法中并使用include命令?

include other_makefile
Run Code Online (Sandbox Code Playgroud)

如果必须调用shell脚本,请在shell命令中捕获结果:

JUST_DO_IT=$(shell source_script)
Run Code Online (Sandbox Code Playgroud)

shell命令应该在目标之前运行.但是,这不会设置环境变量.

如果要在构建中设置环境变量,请编写一个单独的shell脚本来源环境变量并调用make.然后,在makefile中,让目标调用新的shell脚本.

例如,如果您的原始makefile具有目标a,那么您希望执行以下操作:

# mysetenv.sh
#!/bin/bash
. <script to source>
export FLAG=1
make "$@" 

# Makefile
ifeq($(FLAG),0)
export FLAG=1
a: 
    ./mysetenv.sh a
else
a:
    .. do it
endif
Run Code Online (Sandbox Code Playgroud)

  • 我无法控制脚本.必须来源. (4认同)

Sam*_*uel 17

使用GNU Make 3.81我可以使用make来源shell脚本:

rule:
<tab>source source_script.sh && build_files.sh
Run Code Online (Sandbox Code Playgroud)

build_files.sh"获取"source_script.sh导出的环境变量.

请注意使用:

rule:
<tab>source source_script.sh
<tab>build_files.sh
Run Code Online (Sandbox Code Playgroud)

不管用.每一行都在自己的子shell中运行.

  • 只要每行以“\\”结尾,多行就可以工作 (2认同)

gdw*_*dw2 10

这适合我.替换env.sh为您要提供的文件的名称.它的工作原理是在bash中获取文件并在格式化后将输出修改后的环境输出到一个文件makeenv,然后由makefile提供.

IGNORE := $(shell bash -c "source env.sh; env | sed 's/=/:=/' | sed 's/^/export /' > makeenv")                         
include makeenv   
Run Code Online (Sandbox Code Playgroud)


art*_*ise 5

一些结构在shell和中都是相同的GNU Make.

var=1234
text="Some text"
Run Code Online (Sandbox Code Playgroud)

您可以更改shell脚本以获取定义.它们都必须是简单的name=value类型.

也就是说,

[script.sh]

. ./vars.sh
Run Code Online (Sandbox Code Playgroud)

[生成文件]

include vars.sh
Run Code Online (Sandbox Code Playgroud)

然后shell脚本和Makefile可以共享相同的"信息源".我找到了这个问题,因为我正在寻找可以在Gnu Make和shell脚本中使用的通用语法的清单(我不关心哪个shell).

编辑: 贝壳并理解$ {var}.这意味着你可以连接等,var ="One string"var = $ {var}"Second string"