我所拥有的是一个包含3个子目录的目录。 src / for .c和.h文件,bin /编译后的可执行文件应该去的地方和obj /我希望.obj文件去的地方。
现在我希望makefile从src编译每个.c文件(不需要在makefile中列出所有这些文件)并将.o文件放在obj中,将从foo.c构建的可执行文件保存为bin / foo。
有人可以帮帮我吗?每当我使用通配符时,都会抱怨规则不存在,当我使用隐式规则时,它不会将目标文件放在单独的文件夹中。
答案 0 :(得分:25)
从foo.o
本地构建foo.c
:
foo.o: foo.c
$(CC) -c $< -o $@
执行相同操作,但src/
中包含任何所需的头文件:
SRC := src
foo.o: foo.c
$(CC) -I$(SRC) -c $< -o $@
要做同样的事情,但使用src/
中的源文件:
SRC := src
foo.o: $(SRC)/foo.c
$(CC) -I$(SRC) -c $< -o $@
为此,请将目标文件放在obj/
:
SRC := src
OBJ := obj
$(OBJ)/foo.o: $(SRC)/foo.c
$(CC) -I$(SRC) -c $< -o $@
对任何此类目标文件(obj/foo.o
,obj/bar.o
,...)执行此操作的模式规则:
SRC := src
OBJ := obj
$(OBJ)/%.o: $(SRC)/%.c
$(CC) -I$(SRC) -c $< -o $@
创建所需对象的列表:
SOURCES := $(wildcard $(SRC)/*.c)
OBJECTS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SOURCES))
一条规则来涵盖所有人:
all: $(OBJECTS)
全部放在一起:
SRC := src
OBJ := obj
SOURCES := $(wildcard $(SRC)/*.c)
OBJECTS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SOURCES))
all: $(OBJECTS)
$(CC) $^ -o $@
$(OBJ)/%.o: $(SRC)/%.c
$(CC) -I$(SRC) -c $< -o $@
请注意,这有一个很大的缺点:不会跟踪头文件的依赖关系。这可以自动完成,但这是一个微妙的伎俩;它可以等到你掌握了这么多。