在阅读关于非递归makefile的Emile van Bergen文章后,我试图从递归到非递归,但似乎我没有做对。
更新:我终于做对了
文件是:
$ ls -R
.:
folder1 Makefile test.c topRules.mk
./folder1:
file.c Rules.mk
extern void sub_print();
void main()
{
printf("Top Hello\r\n");
sub_print();
}
TARGET = test.exe
.PHONY: all
all: $(TARGET)
include topRules.mk
dir = folder1
include folder1/Rules.mk
$(TARGET): test.o $(OBJS_folder1)
$(LINK)
COMPILE = $(CC) $(CFLAGS) -o $@ -c $<
LINK = $(CC) -o $@ $^
%.o: %.c
$(COMPILE)
sp := $(sp).x
dirstack_$(sp) := $(d)
d := $(dir)
OBJS_$(d) := $(d)/file.o
$(d): $(OBJS_$(d))
void sub_print()
{
printf("Hello Sub World\r\n");
}
答案 0 :(得分:1)
来自对象列表的源的替换生成列表是错误的。它没有剥离.o
扩展名:
SRC_$(d) := $(OBJS_$(d):%.o=%.c))
^^
完全删除变量,在下一个点上你不会需要它。
$(OBJS_$(d)): $((SRC_$(d))
规则既多余又错误:
%.o: %.c
模式规则适用并做正确的事。这是错误的,因为它创建了一个规则来执行所有编译,但是您需要单独编译每个源。即如果您有两个文件,它将扩展为:
foo.o bar.o : foo.c bar.c
但你想要两个单独的规则。
完全删除该规则,不要添加任何其他规则。那里有正确的规则。
实际上,错误是由于两个规则相互影响很严重。文档说&#34;如果规则从隐式规则获得它的命令,$<
将是隐式规则添加的第一个先决条件&#34;。由于隐式规则%.o: %.c
首先出现,它提供了命令,但由于显式规则提供了先决条件,因此隐式规则不添加任何内容,$<
扩展为空。明确的规则不应该存在。比隐式的提供先决条件和命令都应该有效。
由于make without argument会执行文件中的第一个目标,您应该在include之前移动$(TARGET): ...
规则,或者应该定义规则all: $(TAREGT)
(不需要任何操作,但规则应该在开头附近标记.phony
。
请注意,您根本不需要进行替换,因为您不需要使用该规则。
有时会发生一个目录需要特殊标志。在这种情况下,您仍然不会为该目录中的文件创建特殊的隐式规则,但您可以创建特殊规则,以便为特定目标在本地设置变量。语法如下:
$(OBJS_$(d)): %.o: %.c
specific-command
或
$(OBJS_$(d)): %.o: CFLAGS=specific-cflags
后者仍然从一般隐式规则中获取配方,但定义了给定变量的特定于目标的值。我想这是使用无效$(OBJS_$(d)): $(SRC_$(d))
规则尝试的内容。
这在GNU make documentation中称为static pattern rules。
答案 1 :(得分:0)
在$(sp)
被包含之前,如何设置$(d)
和folder1/Rules.mk
?
你没有设置它们,所以它们是空的。
替换$(OBJS_$(d):%=%.c))
可能没有做你想做的事。
尝试添加一些$(info Current value of d is $(d))
行以显示您已将变量设置为的内容。
此外,main()
应该返回int
而不是void
。