澄清makefile语法

时间:2016-04-27 18:02:42

标签: linux makefile

有人可以澄清这段代码是如何运作的吗?

PRE_PROC_EXE        := $(shell which pre_proc.pl)
PRE_PROC2_EXE       := $(shell which pre_proc2.pl)

$(filter $(TMP_DIR)/%.c,$(FILES)):$(TMP_DIR)/%.c: $(SRC_DIR)/%.c
    $(PRE_PROC_EXE) < $< > $@

我试图在第一步生成的文件上添加一个预处理步骤(使用PRE_PROC2_EXE)。我该怎么做?

2 个答案:

答案 0 :(得分:1)

这是如何工作的?它通过魔法工作! - 在我看来,这是一个非常糟糕的Makefile(最后的实际评论)。

make是一个简单的系统,语法简单,做得好。然而,多年来,它已经获得了(并且是的,我正在看着你,GNU Make)一个精心设计的功能,压缩语法和庞大的手册,它们共同使一些Makefile看起来像线噪声。比如这里。

有时你必须做一些或多或少的聪明的事情来构建一些软件,但是(在我看来和经验中)这些通过为规则添加复杂性来更加自然和理解地处理,而不是Makefile语法本身。这样,您可以让Makefile的结构合理地理解,如果您需要了解和调整软件的构建方式,这一点非常重要。

我编写了非常复杂的Makefile,但只偶尔使用像patsubst这样复杂的过滤器(但我通常使用GNU Make - BSD / POSIX Make是一种禁欲主义太过分了。)

此外,您可以使用辅助工具来完成重物的某些部分。例如,您可以使用autoconf进行工具搜索,编写

PRE_PROC_EXE=@PRE_PROC_EXE@
PRE_PROC_EXE2=@PRE_PROC_EXE2@

Makefile.in中,并写一个包含

configure.ac
dnl  Process this file with autoconf
AC_INIT(fooprog, 0.1-SNAPSHOT, author@example.org)

AC_PATH_PROG(PRE_PROC_EXE, pre_proc.pl, NOT_FOUND)
AC_PATH_PROG(PRE_PROC_EXE2, pre_proc2.pl, NOT_FOUND)

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

然后autoconf; ./configure会找到pre_proc{,2}.pl并将其替换为新的Makefile。第一次autoconf需要一点点习惯,但是一旦你习惯它就很自然了。

回到你的特定例子,我不知道该目标是做什么的(两个冒号?我不想知道......),但你可以将规则调整为

$(PRE_PROC_EXE) < $< | $(PRE_PROC_EXE2) > $@

通过两个预处理器传递输入*.c文件。

答案 1 :(得分:1)

$(shell)是一个make函数,它运行shell命令并返回其输出。

因此PRE_PROC_EXE包含运行which pre_proc.pl的输出,而PRE_PROC2_EXE包含运行which pre_proc2.pl的输出。 (我会指出which不可移植,不保证存在且没有对其行为的规范,所以你不能依赖它的输出所以这样使用它不是一个好主意。)

其余为Static Pattern Rule,对$(FILES)中符合$(TMP_DIR)/%.c模式(来自$(filter $(TMP_DIR)/%.c,$(FILES)))的条目进行操作,并使用匹配{将配方应用于它们{1}}文件作为先决条件($(SRC_DIR)/%.c),匹配的$<文件作为目标($(TMP_DIR)/%.c)。

关于如何将$@应用于此不容易回答的问题,因为您尚未解释该脚本的工作原理或您需要如何应用它。