Makefile:如何正确使用 sed 编辑变量

Makefile:如何正确使用 sed 编辑变量

我正在尝试编写一个自定义 Makefile,在其中收集所有源文件以针对主文件进行编译。首先我收集他们的名字:

# other sources to compile against (without extensions, separated by spaces)
DEPENDENT_FILES = greet farewell

然后我想附加.o到每个单词。在外壳中,我可以通过多种方式做到这一点,例如

echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g' # but I know, it's UNIX dependant
# or ...
echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g'

greet.o farewell.o两者都会在终端上产生结果,但在此make过程中失败(导致空字符串)。我把它们写成

DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g')
# or ...
DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g')
# but they result in
$(info DEPENDENCIES is $(DEPENDENCIES)) # "DEPENDENCIES is "

我不知道我在这里做错了什么,我怀疑这可能与 Makefile 中的 echo 或管道有关,但我无法弄清楚。

请注意,我更喜欢与工作 sed 和 echo 解决方案相关的答案,而不是提出不同的方法:这不是我第一次在 Makefile 中遇到 echo 和管道问题,而且我仍然不知道我的方法出了什么问题。

答案1

然后我想在每个单词后面附加 .o 。

无需通过 shell 进行往返。 Make 足够强大,可以提供帮助文件名的常见操作 像这样。在您的情况下,您需要具有不言自明的名称的函数 addsuffix

DEPENDENCIES = $(addsuffix .o, $(DEPENDENT_FILES))

这将为您a.o b.o c.o提供输入列表a b c。一个更完整的例子:

units = a b c

inc = $(addsuffix .h,$(units))
obj = $(addsuffix .o,$(units))

myprog: $(obj)
    gcc -o $@ $(obj)

header-bundle.h: $(inc)
    cat $< >$@

如果您需要更复杂的替换,还有多种通用字符串操作 但在它们足够的情况下,文件操作会更方便,而且在我看来,谦虚的人更容易理解。

答案2

您需要认识到,尽管它们的语法有很多相似之处,makeshell它们却截然不同,必须非常谨慎地使用。更糟糕的是,make 的警告非常吝啬。

您的make代码中有两个地方出错了:

## bad code 
DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g')
  • 没有GNU make名为 的内置函数echo l,因为 make 就是这么理解它的意思的。
  • 当您需要运行外部实用程序时,您需要做的是调用 gnu make 内置$(shell ...)函数。
  • 现在,在编写 make 代码的方式中隐藏着一个潜在的问题,那就是变量$DEPENDENT_FILES。 make 会将其解析为 make 变量 $D ,后跟字符串文字 EPENDENT ! 这是因为当 make vars 没有用括号或大括号括起来时,它只有单个字母,其余的都被视为文字字符串。
  • 注意 shell vars vegin 带有 $$ 除非 eval 正在运行。

相关内容