如何为模块化 c 项目制作模块化 Makefile?

How to make a modular Makefile for a modular c project?

我有一个包含以下代码的 C 程序:

#if defined(MATRIX)
    #include "Matrix.h"
#elif defined(QTREE)
    #include "QTree.h"
#endif

并且我想创建一个给定目标的 Makefile 将 de -D 标志传递给具有相应 MACRO 的 GCC,以便编译正确的头文件和源文件。

目前我有这个 Makefile:

# Makefile for compiling the battleship game

C=gcc
STANDARD=c99
HEADER_DIR=includes
ODIR=obj
CFLAGS=$(C) -c -std=$(STANDARD) -I$(HEADER_DIR)
SDIR=src

_OBJS = Battleship.o Game.o Cell.o Ship.o Bitmap.o IO.o Aux.o Matrix.o QTree.o Board.o
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))

# Program name
PROG=battleship

$(ODIR)/%.o: $(SDIR)/%.c
    $(CFLAGS) -o $@ $<

$(PROG1): $(OBJS)
    $(C) -o $(PROG) -D MATRIX $(OBJS)

$(PROG2): $(OBJS)
    $(C) -o $(PROG) -D QTREE $(OBJS)

.PHONY: game_with_matrix

game_with_matrix: $(PROG1)

.PHONY: game_with_qtree

game_with_qtree: $(PROG2)

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o $(PROG)

但它总是输出:make: Nothing to be done for [target].

我真的不知道怎么了:(

编辑:

当我调用 make 时,我使用的是 make game_with_matrixmake game_with_qtree

提前致谢!

这是您实际使用的 makefile 吗?因为您没有定义变量 PROG1 或变量 PROG2,所以如果您的 makefile 看起来像那样,那显然是问题所在。

但是,即使你修复了这个也是危险的。您不应将两种类型的对象放在同一个子目录中。你必须记住在它们之间切换时总是做一个 make clean 因为 make 没有办法知道以前的构建是否使用 MATRIXQTREE 设置并且你会尝试到 link 个使用不同设置编译的目标文件。

您应该创建两个不同的 OBJ 目录,每个目录一个,并在构建该程序时使用它们。

首先,这个:

C=gcc
CFLAGS=$(C) -c -std=$(STANDARD) -I$(HEADER_DIR)

$(ODIR)/%.o: $(SDIR)/%.c
    $(CFLAGS) -o $@ $<

"CFLAGS" 是一个不好的名字。我强烈建议:

C=gcc
CFLAGS= -c -std=$(STANDARD) -I$(HEADER_DIR)

$(ODIR)/%.o: $(SDIR)/%.c
    $(C) $(CFLAGS) -o $@ $<

现在您可以添加 target-specific variable value:

$(PROG1): CFLAGS += -DMATRIX

$(PROG1): $(OBJS)
    $(C) -o $(PROG) $(OBJS)

$(PROG2): CFLAGS += -DQTREE

$(PROG2): $(OBJS)
    $(C) -o $(PROG) $(OBJS)

但是您还没有定义 PRG1PROG2,我认为没有必要。摆脱它们并执行此操作:

$(PROG): $(OBJS)
    $(C) -o $@ $^

game_with_matrix: CFLAGS += -DMATRIX
game_with_matrix: $(PROG)

game_with_qtree: CFLAGS += -DQTREE
game_with_qtree: $(PROG)