使用makefile编译多个.c文件
我想使用makefile一次编译多个.c文件。 我已经说过:使用makefile编译多个.c文件,c,makefile,C,Makefile,我想使用makefile一次编译多个.c文件。 我已经说过: CC= gcc CPPFLAGS = -I. CFLAGS = -W -Wall -ansi -pedantic TARGET = test RM = rm OBJECTS = xxx.o yyy.o zzz.o SOURCES = $(OBJECTS:.o =.c) .PHONY: all clean all: $(TAREGT) clean: $(RM) $(TARGET) $(OBJECTS
CC= gcc
CPPFLAGS = -I.
CFLAGS = -W -Wall -ansi -pedantic
TARGET = test
RM = rm
OBJECTS = xxx.o yyy.o zzz.o
SOURCES = $(OBJECTS:.o =.c)
.PHONY: all clean
all: $(TAREGT)
clean:
$(RM) $(TARGET) $(OBJECTS)
$(TAREGT) : $(OBJECTS)
$(CC) $^ -o $@
$(OBJECTS) : $(SOURCES)
$(CC) $(CFLAGS) $(CPPFLAGS) -c $^
我不知道为什么这不起作用(“对“所有”都不做任何事情”)。有人有想法吗?这一行正在创建循环依赖关系:
SOURCES = $(OBJECTS:.o =.c)
尝试将其替换为以下内容:
SOURCES = $(patsubst %.o,%.c,$(OBJECTS))
此行正在创建循环依赖项:
SOURCES = $(OBJECTS:.o =.c)
尝试将其替换为以下内容:
SOURCES = $(patsubst %.o,%.c,$(OBJECTS))
您忘记了“从源到对象”规则中的
-o$@
。因此它不会创建任何内容
您还有拼写错误-您的$(目标)
是“test”,但您的“all”规则取决于$(TAREGT)
,该规则为空。您还使用$(TAREGT)
作为编译“test”的输入
您不需要指定$(源)
或“源到对象”规则-隐式规则将起作用
事实上,您的“源”指向对象“规则不正确——它说每个对象都依赖于所有源。如果希望每个对象依赖于一个源,则应使用后缀规则、模式规则或静态模式规则。或者只是隐式规则。您忘记了“源到对象”规则中的
-o$@
。因此,它不会创造任何东西
$(OBJECTS) : $(SOURCES)
您还有拼写错误-您的$(目标)
是“test”,但您的“all”规则取决于$(TAREGT)
,该规则为空。您还使用$(TAREGT)
作为编译“test”的输入
您不需要指定$(源)
或“源到对象”规则-隐式规则将起作用
事实上,您的“源到对象”规则是不正确的——它说每个对象都依赖于所有源。如果希望每个对象依赖于一个源,则应使用后缀规则、模式规则或静态模式规则。或者只是隐含的规则
$(OBJECTS) : $(SOURCES)
上面告诉Make,每个.o文件都依赖于所有源,也就是说,如果更改一个.c文件,Make将重新编译所有.o文件。我想这不是你真正想要的。我将按如下方式修改此规则:
$(foreach s,$(SOURCES),$(eval $(filter %$(basename $(notdir $s)).o,$(OBJECTS)): $s))
这将迭代源
中的每个源,在对象
中找到相应的.o文件,并创建正确的规则::
。如果源文件和目标文件之间的映射更复杂,那么工作起来就很复杂了。例如,在单独目录中构建对象文件时
即使在以下奇怪的源到对象文件映射中,此神秘代码也能正常工作:
SOURCES := a.cpp boo/b.c c.C
OBJECTS := foo/a.o bar/b.o c.o
$(foreach s,$(SOURCES),$(eval $(filter %$(basename $(notdir $s)).o,$(OBJECTS)): $s))
它将生成以下规则:
foo/a.o: a.cpp
bar/b.o: boo/b.c
c.o: c.C
上面告诉Make,每个.o文件都依赖于所有源,也就是说,如果更改一个.c文件,Make将重新编译所有.o文件。我想这不是你真正想要的。我将按如下方式修改此规则:
$(foreach s,$(SOURCES),$(eval $(filter %$(basename $(notdir $s)).o,$(OBJECTS)): $s))
这将迭代源
中的每个源,在对象
中找到相应的.o文件,并创建正确的规则::
。如果源文件和目标文件之间的映射更复杂,那么工作起来就很复杂了。例如,在单独目录中构建对象文件时
即使在以下奇怪的源到对象文件映射中,此神秘代码也能正常工作:
SOURCES := a.cpp boo/b.c c.C
OBJECTS := foo/a.o bar/b.o c.o
$(foreach s,$(SOURCES),$(eval $(filter %$(basename $(notdir $s)).o,$(OBJECTS)): $s))
它将生成以下规则:
foo/a.o: a.cpp
bar/b.o: boo/b.c
c.o: c.C
谢谢你们的帮助,现在开始工作了 我刚刚添加了一些规则:
CC= gcc
CPPFLAGS = -I.
CFLAGS = -W -Wall -ansi -pedantic
TARGET = test
RM = rm
SOURCES = xxx.c yyy.c zzz.c
OBJECTS = $(SOURCES:.c=.o)
.PHONY: all clean
all: $(TARGET)
clean:
$(RM) $(TARGET) $(OBJECTS)
$(TARGET) : $(OBJECTS)
$(CC) $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
CC=gcc
CPPFLAGS=-I。
CFLAGS=-W-墙壁-ansi-迂腐
目标=测试
RM=RM
SOURCES=xxx.cyy.czzz.c
对象=$(源:.c=.o)
.骗子:都是干净的
全部:$(目标)
清洁:
$(RM)$(目标)$(对象)
$(目标):$(对象)
$(CC)$^-o$@
%.o:%.c
$(CC)$(CFLAGS)$(CPPFLAGS)-c$<
谢谢你们的帮助,它正在工作
我刚刚添加了一些规则:
CC= gcc
CPPFLAGS = -I.
CFLAGS = -W -Wall -ansi -pedantic
TARGET = test
RM = rm
SOURCES = xxx.c yyy.c zzz.c
OBJECTS = $(SOURCES:.c=.o)
.PHONY: all clean
all: $(TARGET)
clean:
$(RM) $(TARGET) $(OBJECTS)
$(TARGET) : $(OBJECTS)
$(CC) $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
CC=gcc
CPPFLAGS=-I。
CFLAGS=-W-墙壁-ansi-迂腐
目标=测试
RM=RM
SOURCES=xxx.cyy.czzz.c
对象=$(源:.c=.o)
.骗子:都是干净的
全部:$(目标)
清洁:
$(RM)$(目标)$(对象)
$(目标):$(对象)
$(CC)$^-o$@
%.o:%.c
$(CC)$(CFLAGS)$(CPPFLAGS)-c$<
看起来您的目标拼错了:$(TAREGT)
Ohh谢谢。我现在修复了它,它说“gcc:致命错误:没有输入文件”,但不知何故它找不到输入文件;你至少犯了一个错误。并向我们展示Make试图执行的命令——它将出现在Make的输出中,就在错误上方。@Beta,不幸的是,我们可以猜到该命令将是gcc-W-Wall-ansi-pedantic-I.-c
看起来你有TARGET
拼写错误:$(TAREGT)
哦,谢谢。我现在修复了它,它说“gcc:致命错误:没有输入文件”,但不知何故它找不到输入文件;你至少犯了一个错误。并向我们显示Make试图执行的命令——它将出现在Make的输出中,就在错误上方。@Beta,不幸的是,我们可以猜测该命令将是gcc-W-Wall-ansi-pedantic-I.-c
,在上一条规则中,您仍然没有-o$@
。它仍然是不需要的,因为有一个隐式的规则可以做同样的事情。在最后一个规则中仍然没有-o$@
。这仍然是不需要的,因为有一个隐式规则,它也有同样的作用。这两条线是绝对等价的。第一种变体只是一种简写@Alexey Semenyuk他们应该是同等的,但事实并非如此。第一个会创建循环依赖项错误,第二个不会。试试看!我有,它们是等价的。这个表达式的真正问题是“o”和“=”字符之间的额外空格会阻止它工作。它应该是SOURCES=$(OBJECTS:.o=.c)
这两行绝对相等。第一种变体只是一种简写@Alexey Semenyuk他们应该是同等的,但事实并非如此。第一个会创建循环依赖项错误,第二个不会。试试看!我有,它们是等价的。这个表达式的真正问题是