为简单起见,请说我有以下文件夹:
./src/
包含许多.c文件./obj/
包含许多.obj文件./output/
包含我要构建的二进制文件我的makefile如下:
all: init mybin
# init commands
init:
mkdir obj
mkdir output
mybin: project1 project2 project3
$(CC) src/misc.c ... etc
$(LK) obj/first.obj obj/second.obj obj/third.obj obj/four.obj obj/five.obj obj/six.obj obj/seven.obj obj/eight.obj obj/nine.obj -o output/myapp.bin
project1: obj/first.obj obj/second.obj obj/third.obj
obj/first.obj: src/first.c
$(CC) first.c ... etc
obj/second.obj: src/second.c
$(CC) obj/second.c ... etc
obj/third.obj: src/third.c
$(CC) obj/third.c ... etc
project2: obj/four.obj obj/five.obj obj/six.obj
obj/four.obj: src/four.c
$(CC) four.c ... etc
obj/five.obj: src/five.c
$(CC) obj/five.c ... etc
obj/six.obj: src/six.c
$(CC) obj/six.c ... etc
project3: obj/seven.obj obj/eight.obj obj/nine.obj
obj/seven.obj: src/seven.c
$(CC) seven.c ... etc
obj/eight.obj: src/eight.c
$(CC) obj/eight.c ... etc
obj/nine.obj: src/nine.c
$(CC) obj/nine.c ... etc
我第一次运行make all
时,编译的所有内容都找到了。然后我做了:
$ touch src/four.c
$ make all
$
但是make
退出而没有编译任何内容。我猜它没有检测到其中一个.c文件发生了变化,但是我没有看到我的依赖项出了什么问题。
我的期望:
touch
src/four.c
obj/four.obj
标记为project2
已过时,mybin
也是如此,因此标记src/four.c
也已过时。该链应该触发obj/four.obj
到{{1}}的新汇编,然后是整个项目的新链接。
答案 0 :(得分:1)
您是否指定了编译的输出文件(可能是-o
选项)?默认情况下(对于大多数工具链),编译.c
文件会生成.o
文件,而不是.obj
文件。
要在某些先决条件发生变化时获取更新目标,您必须在文件之间提供完全依赖关系,直到使用时间戳来确定文件是否已更改。
也就是说,all
和init
可以保留为所谓的.PHONY
targets,但将其余目标设为文件是一种很好的做法。
OUT_DIR := ./output
SRC_DIR := ./src
OBJ_DIR := ./obj
MYBIN := $(OUT_DIR)/myapp.bin
OBJS := $(addprefix $(OBJ_DIR)/, \
first.obj \
second.obj \
third.obj \
four.obj \
five.obj \
six.obj \
seven.obj \
eight.obj \
nine.obj)
.PHONY : all mkdir-output mkdir-obj
all : $(MYBIN)
mkdir-output :
@mkdir -p $(OUT_DIR)
mkdir-obj :
@mkdir -p $(OBJ_DIR)
$(MYBIN) : $(OBJS) | mkdir-output
$(LK) $^ -o $@
$(OBJS) : | mkdir-out
$(OBJS) : $(OBJ_DIR)/%.obj : $(SRC_DIR)/%.c
$(CC) $< -object=$@ $(CC_OPT)
最后一条规则是GNU Make的static pattern rule。管道符号mkdir-xxx
后的|
先决条件为order-only个。