使用makefile编译多个.c文件

时间:2017-01-29 14:22:49

标签: 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)

$(TAREGT) : $(OBJECTS)

         $(CC) $^ -o $@

$(OBJECTS) : $(SOURCES) 

         $(CC) $(CFLAGS) $(CPPFLAGS) -c $^

我不知道为什么这不起作用(“没有什么可以为所有人做”)。有人有想法吗?

4 个答案:

答案 0 :(得分:2)

这一行创建了一个循环依赖:

SOURCES = $(OBJECTS:.o =.c)

尝试将其替换为:

SOURCES = $(patsubst %.o,%.c,$(OBJECTS))

答案 1 :(得分:0)

您在“对象来源”规则中忘记了-o $@。因此它不会创造任何东西。

您还有拼写错误 - 您的$(TARGET)是'测试',但您的'所有'规则取决于$(TAREGT)为空。您还使用$(TAREGT)作为输入来编译'test'。

您无需指定$(SOURCES)或“对象来源”规则 - 隐式规则可以解决问题。

事实上,你的“对象来源”规则是不正确的 - 它说每个对象都依赖于所有来源。如果希望每个对象都依赖于一个源,则应使用后缀规则,模式规则或静态模式规则。或者只是隐含的规则。

答案 2 :(得分:0)

$(OBJECTS) : $(SOURCES) 

上面告诉Make,每个.o文件都依赖于所有源,即如果你更改了一个.c文件Make将重新编译所有.o文件。我想,这不是你真正想要的东西。我按照以下方式重新制定这条规则:

$(foreach s,$(SOURCES),$(eval $(filter %$(basename $(notdir $s)).o,$(OBJECTS)): $s))

这将迭代SOURCES中的每个来源,在OBJECTS中找到相应的.o文件并创建正确的规则:<obj>: <source>。如果源文件和目标文件之间的映射更复杂,那么工作就会很复杂。比如,在单独的目录中构建目标文件时。

这个神秘的代码甚至可以用于以下奇怪的源对象文件映射:

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

答案 3 :(得分:0)

谢谢大家的帮助,现在正在使用

我刚刚添加了一些规则:

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 $<