Makefile 重写默认的隐式规则

4
为什么这条规则不能覆盖默认的隐式规则?
当使用make myapp命令时(假设已经存在myapp.c文件),make会运行默认的编译和链接程序的命令,而不是运行在这个隐式规则中定义的命令。
#... omitted code
LCUS=$(LIBS)/libcus.a

#... omitted code
% : %.o $(LCUS)
        echo  !!! Custom build !!!
        $(MY_CMD) $< -o $@ $(LCUS)

1
这个隐式规则中定义了:...你是不是想说“显式”? - Sourav Ghosh
尝试使用“make -r”禁用所有内置规则,这有帮助吗? - Maxim Egorushkin
2个回答

5
GNU online make manual中获取:

您可以通过定义一个新的模式规则来覆盖内置的隐式规则(或者您自己定义的规则),该规则具有相同的目标和先决条件,但具有不同的命令。

因此,我会认为这是因为前提条件与隐式规则不同。

还从make手册中获取:

Linking a single object file n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise command used is $(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS). This rule does the right thing for a simple program with only one source file. It will also do the right thing if there are multiple object files (presumably coming from various other source files), one of which has a name matching that of the executable file. Thus,

 x: y.o z.o

when x.c, y.c and z.c all exist will execute:

cc -c x.c -o x.o
cc -c y.c -o y.o
cc -c z.c -o z.o
cc x.o y.o z.o -o x
rm -f x.o
rm -f y.o
rm -f z.o
所以基本上,make可以理解从.o文件生成的程序文件的隐式规则,但是当你添加静态库时,它就无法理解了。一个简单的测试方法是将$(LCUS)从依赖项中移除(作为临时措施),看看它是否使用你的规则而不是内置的规则。如果是,那么你就知道这是你的问题所在。如果仅仅用myapp替换%会有问题,因为你想要构建多个目标,你可以尝试以下方法:
$(APPS): % : %.o $(LCUS)

其中$(APPS)是一个包含您希望构建的所有应用程序的变量。这将允许一个规则构建多个目标。您也可以跳过使用变量,直接放置一个以空格分隔的列表。这是一个静态模式规则的示例,更多信息可以在这里找到。静态模式和隐式规则之间的区别可以在这里找到。


请告诉我它是否有效,您也可以尝试我的后续编辑中的建议。 - missimer
1
取消默认规则,成功了!(%:%.c,%:%.o,%.o:%.c) - Luciano

3

你的规则与内置的隐式规则不同,因此它不会被取消。

此外,make 始终更喜欢不需要构建中间文件的规则,而不是需要构建中间文件的规则。如果您预先创建了 .a 文件,则 make 可能会使用您的规则(但也可能不会)。

如果您取消内置规则并保留自己的规则,则应该可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接