使用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

我想使用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)

$(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他们应该是同等的,但事实并非如此。第一个会创建循环依赖项错误,第二个不会。试试看!我有,它们是等价的。这个表达式的真正问题是