Makefile 将环境变量中的单词提取为两个字符串

Makefile 将环境变量中的单词提取为两个字符串,makefile,gnu-make,Makefile,Gnu Make,我有一个makefile,有两个这样的变量 OS = foo.o bar.o baz.o WS = -DWITH_FOO -DWITH_BAR -DWITH_BAZ 等等。当基于一个名为WITH的环境变量执行makefile时,我希望生成这两个变量,其中包含类似于foo-bar-baz的内容,而不是手动写入。如果此环境变量未设置或为空,则makefile应该使用一些硬编码的回退 我该怎么做?我不太擅长生成文件,我所能想到的只是某种形式的“foreach”调用,但具体细节我想不起来。好吧,我会写

我有一个makefile,有两个这样的变量

OS = foo.o bar.o baz.o
WS = -DWITH_FOO -DWITH_BAR -DWITH_BAZ
等等。当基于一个名为
WITH
的环境变量执行makefile时,我希望生成这两个变量,其中包含类似于
foo-bar-baz
的内容,而不是手动写入。如果此环境变量未设置或为空,则makefile应该使用一些硬编码的回退


我该怎么做?我不太擅长生成文件,我所能想到的只是某种形式的“foreach”调用,但具体细节我想不起来。

好吧,我会写这样的东西:

ifdef WITH
  OS := $(WITH:%=%.o)
  WS := $(WITH:%=-DWITH_%)
else
  # Fallback.
endif
这是我看到的最简单的解决方案,但是,它不是100%好,因为
WS
将是
-DWITH\u foo…
而不是
-DWITH\u foo…

如果这种行为不符合您的需要,您可以使用
tr
命令将
WS
转换为大写:

WS := $(shell echo '$(WS)' | tr 'a-z' 'A-Z')
或者,作为更便携的选项,从以下位置使用
tr
功能:


假设您在类UNIX操作系统上使用GNU Make,下面是一个可能的解决方案:

afineman@hotdog:/tmp$ cat Makefile
WITH = foo bar baz
WITH_UPPER = $(shell echo $(WITH) | tr a-z A-Z)

OS = $(WITH:%=%.o)
WS = $(WITH_UPPER:%=-DWITH_%)

.PHONY: env
env:
    @echo WITH=$(WITH)
    @echo WITH_UPPER=$(WITH_UPPER)
    @echo OS=$(OS)
    @echo WS=$(WS)
afineman@hotdog:/tmp$ make
WITH=foo bar baz
WITH_UPPER=FOO BAR BAZ
OS=foo.o bar.o baz.o
WS=-DWITH_FOO -DWITH_BAR -DWITH_BAZ
afineman@hotdog:/tmp$
如果愿意,您可以在您的环境中为
提供
,但一般来说,最好编写自包含的makefile。如果您确实有一个来自环境的需求,只需省略上面Makefile的第一行,
$(WITH)
将来自环境

您还可以通过使用
-e
开关运行Make来用覆盖
$,即

afineman@hotdog:/tmp$ WITH="bing bang buzz" make   # Not overridden
WITH=foo bar baz
WITH_UPPER=FOO BAR BAZ
OS=foo.o bar.o baz.o
WS=-DWITH_FOO -DWITH_BAR -DWITH_BAZ
afineman@hotdog:/tmp$ WITH="bing bang buzz" make -e   # Overridden
WITH=bing bang buzz
WITH_UPPER=BING BANG BUZZ
OS=bing.o bang.o buzz.o
WS=-DWITH_BING -DWITH_BANG -DWITH_BUZZ

谢谢我让它工作了。我可能会在某个时候研究GMSL,但现在这样还可以,谢谢。我希望标准过程是自包含的,仅当有人想要更改编译的部分时才使用
afineman@hotdog:/tmp$ WITH="bing bang buzz" make   # Not overridden
WITH=foo bar baz
WITH_UPPER=FOO BAR BAZ
OS=foo.o bar.o baz.o
WS=-DWITH_FOO -DWITH_BAR -DWITH_BAZ
afineman@hotdog:/tmp$ WITH="bing bang buzz" make -e   # Overridden
WITH=bing bang buzz
WITH_UPPER=BING BANG BUZZ
OS=bing.o bang.o buzz.o
WS=-DWITH_BING -DWITH_BANG -DWITH_BUZZ