Makefile没有编译目录

时间:2017-08-24 19:42:38

标签: c gcc makefile mingw

我在Windows平台上使用gcc和MinGW。我有一个包含两个* .c文件的目录: main.c和funcs.c

我正在使用以下makefile:

CC=gcc
CFLAGS=-c
LDFLAGS= 
SOURCEDIR = src
BUILDDIR = build
SOURCES=$(wildcard $(SOURCEDIR)/*.c)
OBJECTS=$(patsubst $(SOURCEDIR)/%.c,$(BUILDDIR)/%.o,$(SOURCES))
LIBRARIES=-L/mingw64/lib
INC= -I./include
EXECUTABLE=testLink
VPATH = src include build

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) $(LIBRARIES)  -o ./dist/$@

$(OBJECTS): $(SOURCES)
    $(CC) $(INC) $(CFLAGS) $< -o $@

哪个应该使用* .c文件并生成具有相同名称的* .o文件。但是我在make上得到以下输出 -

$ make
gcc -I./include -c src/funcs.c -o build/funcs.o
gcc -I./include -c src/funcs.c -o build/main.o
gcc  build/funcs.o build/main.o -L/mingw64/lib  -o ./dist/testLink

当然是一堆多重定义错误。从前两行可以看出,它采用相同的* .c文件并将其编译为两个不同的* .o文件。

我是makefiles的新手,但我认为我的$(OBJECTS)规则有问题,我很确定它是$&lt;&lt;这是导致问题的原因。我试图创建一个通用的makefile,它总是适用于我的项目,这些项目具有相同的目录结构,并将.c文件转换为.o文件和链接。我是以完全错误的方式解决这个问题还是对我的makefile进行了简单的修复?

谢谢!

詹姆斯

2 个答案:

答案 0 :(得分:4)

这条规则:

$(OBJECTS): $(SOURCES)
    $(CC) $(INC) $(CFLAGS) $< -o $@

扩展为:

funcs.o main.c: funcs.c main.c
    $(CC) $(INC) $(CFLAGS) $< -o $@

相当于:

funcs.o: funcs.c main.c
    $(CC) $(INC) $(CFLAGS) $< -o $@

main.o: funcs.c main.c
    $(CC) $(INC) $(CFLAGS) $< -o $@

$<引用第一个依赖项(funcs.c),因此Makefile尝试从同一个源生成funcs.o和main.o。

您只需要使用%通配符匹配的通用规则:

%.o: %.c
    $(CC) $(INC) $(CFLAGS) $< -o $@

请参阅https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html

答案 1 :(得分:2)

杰克在他的回答中指出了错误(所有对象都依赖于所有来源:这不是c源的通用编译规则)。

但是,通用规则必须有源&amp;对象路径。总结一下,只需替换

$(OBJECTS): $(SOURCES)
    $(CC) $(INC) $(CFLAGS) $< -o $@

通过

$(BUILDDIR)/%.o : $(SOURCEDIR)/%.c
    $(CC) $(INC) $(CFLAGS) $< -o $@

(如How to generate a Makefile with source in sub-directories using just one makefile中所述)

请注意,此类依赖性测试并未将包含的.h文件考虑在内,因此它仅适用于首次构建。之后修改.h文件不会触发编译,因为头文件未列为依赖项。