如何为模块化 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_matrix
或 make game_with_qtree
。
提前致谢!
这是您实际使用的 makefile 吗?因为您没有定义变量 PROG1
或变量 PROG2
,所以如果您的 makefile 看起来像那样,那显然是问题所在。
但是,即使你修复了这个也是危险的。您不应将两种类型的对象放在同一个子目录中。你必须记住在它们之间切换时总是做一个 make clean
因为 make 没有办法知道以前的构建是否使用 MATRIX
或 QTREE
设置并且你会尝试到 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)
但是您还没有定义 PRG1
和 PROG2
,我认为没有必要。摆脱它们并执行此操作:
$(PROG): $(OBJS)
$(C) -o $@ $^
game_with_matrix: CFLAGS += -DMATRIX
game_with_matrix: $(PROG)
game_with_qtree: CFLAGS += -DQTREE
game_with_qtree: $(PROG)
我有一个包含以下代码的 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_matrix
或 make game_with_qtree
。
提前致谢!
这是您实际使用的 makefile 吗?因为您没有定义变量 PROG1
或变量 PROG2
,所以如果您的 makefile 看起来像那样,那显然是问题所在。
但是,即使你修复了这个也是危险的。您不应将两种类型的对象放在同一个子目录中。你必须记住在它们之间切换时总是做一个 make clean
因为 make 没有办法知道以前的构建是否使用 MATRIX
或 QTREE
设置并且你会尝试到 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)
但是您还没有定义 PRG1
和 PROG2
,我认为没有必要。摆脱它们并执行此操作:
$(PROG): $(OBJS)
$(C) -o $@ $^
game_with_matrix: CFLAGS += -DMATRIX
game_with_matrix: $(PROG)
game_with_qtree: CFLAGS += -DQTREE
game_with_qtree: $(PROG)