2016-08-17 81 views
1

我有一个makefile其中我试图设置一些已存在于我写的bash脚本中的变量:set-vars.sh(它只包含变量名称和值)。从bash脚本读取makefile变量

我在其他bash脚本中使用这些变量。我需要也可以在我的makefile中使用它们。

经过大量研究并试图找出makefilebash脚本中设置变量的最佳方法后,我找到了一种可行的方法;这是如下:

set-vars.sh

# set vars 
foo=FOO1 
bar=BAR1 
baz=BAZ1 

# if a command line arg is given (e.g. foo) 
# echo value command line arg (e.g. echo $foo) 

if ! [ -z ${1+x} ]; then echo ${!1}; fi 

这里神奇的是最后一行,其echo ES在命令行参数提供了其名称的变量的值,如果有一个命令行参数。我在makefile中调用此脚本并提供变量名称,并使用echo ed值设置makefile变量。

Makefile

.PHONY: target1 target2 target3 

export foo = $(shell sh set-vars.sh foo) 

target1: 
    @echo $(foo) 

# ... other targets which reference $(foo) ... 

这工作,但它可能是做这件事的哈克方式。我想知道是否有更简单,更优雅的方式来做我想做的事情。

我在StackOverflow上遇到过几个类似的问题和答案,但没有找到任何适用于我的示例的东西。如果我已经错过了一个答案,请告诉我。

非常感谢!

+0

你不能在调用'make'的shell中设置变量,或者将它们放在'make'命令行上? – Barmar

+0

其他脚本需要'如果! [-z ...'line? – Beta

+0

@Barmar,我不能把它们放在make命令行上,因为这个makefile会被其他可能熟悉或者不熟悉这个makefile内部工作的人使用。我想保持makefile的调用尽可能简单......但是,通过在调用'make'的shell中设置变量,你的意思是什么?对不起,我不太精通shell脚本。 – tamjd1

回答

3

您可以定义,可以从你的shell脚本来源和Makefile中包含的文件的变量:

$ cat vardef.txt 
foo=FOO1 
bar=BAR1 
baz=BAZ1 
$ cat set-vars.sh 
source ./vardef.txt 
echo "$foo $bar $baz" 
$ sh ./set-vars.sh 
FOO1 BAR1 BAZ1 
$ cat Makefile 
include vardef.txt 
all: 
    @echo "$(foo) $(bar) $(baz)" 
$ make 
FOO1 BAR1 BAZ1 

是不是真是太好了,当两种语言部分使用相同的语法?

+0

这看起来很有希望......我会试试看。谢谢! – tamjd1

+0

试一试。与'Makefile'很好地配合,不太适合shell脚本。得到这个:'subtest.sh:line 3:source:vars.txt:file not found'。 – tamjd1

+0

你试过'source。/ vars.txt'还是'source vars.txt'? –

1

不知道它是不是很冒险,但你可以“创建”一个可以包含到Makefile中的文件。在运行时。像这样:

$(shell grep '=' vars.sh > /tmp/vars.tmp) 
include /tmp/vars.tmp 
$(shell rm /tmp/vars.tmp) 

用更理智的东西替换第一行。

1

构建系统依赖于环境变量通常被认为是糟糕的做法,因为如果他们这样做,当输出不仅依赖于命令行而且还依赖于环境变量的状态时,您突然产生可重复性问题。

已经警告过你,所有的环境变量都可以在make,:

user := ${USER} # ${USER} comes from the environment. 
all : 
    @echo ${user} 

换句话说,有一个脚本,设置环境变量和调用make

#!/bin/bash 
export foo=FOO1 
export bar=BAR1 
export baz=BAZ1 
exec make "[email protected]" 

或者,你可以只用export foo=FOO1语句的shell脚本。事实证明这是有效的makefile语法,因此您可以在Makefile中执行include set-vars.sh

+0

这会工作,但我需要能够从命令行运行'make',而不是从脚本运行。我需要make来获得所有正确的变量和值。从而创建一个抽象级别,用户不需要执行任何操作,只需运行'make install'或任何他们想运行的目标,而不需要知道'Makefile'里面的内容。 – tamjd1

+0

@ tamjd1为您添加了替代解决方案。 –

+0

只是注意到@RenaudPacalet最初给出了这个建议。 –