Makefile 不编译目录中的所有 C 文件

Makefile not compiling all C files in directory

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

我正在使用以下生成文件:

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 文件。

我是 makefile 的新手,但我认为我的 $(OBJECTS) 规则有问题,我很确定是 $< 导致了问题。我正在尝试创建一个通用的 makefile,它将始终在我的具有相同目录结构的项目上运行,并将 .c 文件转换为 .o 文件和 link。我是不是以完全错误的方式解决了这个问题,还是对我的 makefile 进行了简单的修复?

谢谢!

詹姆斯

这条规则:

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

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

但是,通用规则必须具有源路径和对象路径。总结起来就是替换

$(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 文件不会触发编译,因为头文件未列为依赖项。