请考虑以下Makefile:
CC = g++
CFLAGS = -c -O -Wall
EFLAGS = -O -Wall -lm -o
UTILITIES = error.o stream_manip.o mat_ops.o GaussElim.o
UTILITIES += abstractmatrix.o dvector.o dmatrix.o ConjGrad.o
# All objects
%.o: %.cpp %.hpp
$(CC) $(CFLAGS) $<
# Executables (doesn't have extension)
% : %.cpp $(UTILITIES)
$(CC) $(EFLAGS) % $< $(UTILITIES)
# Specific executable
#TS_CG : TS_CG.cpp $(UTILITIES)
#$(CC) $(EFLAGS) $@ $@.cpp $(UTILITIES)
match-anything规则(对于可执行文件)应该允许我在终端中键入以下内容:
make TS_CG
并编译名为TS_CG的可执行文件。但是,make
不使用我的匹配所有目标。相反,它使用其默认编译规则。
另一方面,如果UTILITIES中列出的所有对象都存在,那么它确实使用了我的匹配所有目标。因此,似乎匹配取决于先决条件的存在。
显然:
当规则是终端时,除非其先决条件确实存在,否则它不适用。
(根据 make manual)。 但我的规则不是终点;它没有用双冒号标记!
那为什么这似乎仍然适用?
我可能还会问,是否有人有更好的解决方案来区分对象目标和可执行目标,正如我在我的文件中尝试过的那样。
答案 0 :(得分:1)
我很惊讶当UTILITIES尚不存在时,Make能够构建TS_CG,因为我不希望它知道TS_CG需要它们。
无论如何,当Make试图找到TS_CG的规则时,它发现的只是隐式规则(没有特定于TS_CG)。特别是,它提供了%: %.cpp $(UTILITIES)
和内置的%: %.cpp
。如果$(UTILITIES)都存在,那么它将使用第一个规则,否则它将向下移动,寻找其先决条件确实存在的规则,并找到第二个。只有当它找不到任何存在先决条件的规则时,才会寻求建立先决条件的规则。