有人可以澄清这段代码是如何运作的吗?
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
)。我该怎么做?
答案 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
)。
关于如何将$@
应用于此不容易回答的问题,因为您尚未解释该脚本的工作原理或您需要如何应用它。