Makefile:分离的源和对象
Makefile: Separated sources and objects
一段时间以来,我一直在尝试将项目的源文件与生成的目标文件分开。
确实,我希望我的项目结构如下:
obj/
main.o
src1.o
[...]
src/
main.c
src1.c
[...]
Makefile
我目前的Makefile如下:
NAME = a.out
OBJ_DIR = "obj"
SRC_DIR = "src"
MAIN_SRC = main.c
PROJ_SRC = src1.c \
src2.c \
src3.c
MAIN_OBJ = $(MAIN_SRC:%.c=%.o)
PROJ_OBJ = $(PROJ_SRC:%.c=%.o)
CC = gcc
RM = rm -rf
$(NAME): $(MAIN_OBJ) $(PROJ_OBJ)
$(CC) $(MAIN_OBJ) $(PROJ_OBJ) -o $(NAME)
all: $(NAME)
clean:
$(RM) $(MAIN_OBJ) $(PROJ_OBJ)
fclean: clean
$(RM) $(NAME)
我尝试使用 pattern rules,但没有成功。
MAIN_OBJ = $(MAIN_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
PROJ_OBJ = $(PROJ_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
[...]
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
有人能解决我的问题吗?
MAIN_SRC
和 PROJ_OBJ
没有目录前缀,因此表达式
$(MAIN_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
$(PROJ_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
不要替换任何东西。
修复:
MAIN_OBJ := $(MAIN_SRC:%.c=$(OBJ_DIR)/%.o)
PROJ_OBJ := $(PROJ_SRC:%.c=$(OBJ_DIR)/%.o)
然后你的模式规则应该起作用了。
您可能希望 make
为您创建 $(OBJ_DIR)
:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
$(CC) $(CFLAGS) -c -o $@ $<
$(OBJ_DIR) :
mkdir -p $@
A more advanced example for you with automatic header dependency generation.
兄弟!
如果您的项目“main
”的架构是这样的:
main
|
|__Makefile
|__obj
|__src
|__main.c
|__src1.c
|__src2.c
[...]
只需将此添加到您的“Makefile
”即可将您的对象存储在源文件目录之外:
# Object files
# String substituion for every C/C++ file
# e.g: ./src/src1.cpp turns into ./obj/src1.o
OBJS := $(patsubst %.c, ${OBJ_DIR}/%.o, $(notdir $(SRC_DIR)))
只需将此添加到您的“Makefile
”即可编译:
# Compile: Generate object files from source files
# $@ := {NAME}
# $< := THE first file
# $^ all the dependency
# C Sources
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(C_FLAGS) -c $< -o $@
结束!
一段时间以来,我一直在尝试将项目的源文件与生成的目标文件分开。
确实,我希望我的项目结构如下:
obj/
main.o
src1.o
[...]
src/
main.c
src1.c
[...]
Makefile
我目前的Makefile如下:
NAME = a.out
OBJ_DIR = "obj"
SRC_DIR = "src"
MAIN_SRC = main.c
PROJ_SRC = src1.c \
src2.c \
src3.c
MAIN_OBJ = $(MAIN_SRC:%.c=%.o)
PROJ_OBJ = $(PROJ_SRC:%.c=%.o)
CC = gcc
RM = rm -rf
$(NAME): $(MAIN_OBJ) $(PROJ_OBJ)
$(CC) $(MAIN_OBJ) $(PROJ_OBJ) -o $(NAME)
all: $(NAME)
clean:
$(RM) $(MAIN_OBJ) $(PROJ_OBJ)
fclean: clean
$(RM) $(NAME)
我尝试使用 pattern rules,但没有成功。
MAIN_OBJ = $(MAIN_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
PROJ_OBJ = $(PROJ_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
[...]
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
有人能解决我的问题吗?
MAIN_SRC
和 PROJ_OBJ
没有目录前缀,因此表达式
$(MAIN_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
$(PROJ_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
不要替换任何东西。
修复:
MAIN_OBJ := $(MAIN_SRC:%.c=$(OBJ_DIR)/%.o)
PROJ_OBJ := $(PROJ_SRC:%.c=$(OBJ_DIR)/%.o)
然后你的模式规则应该起作用了。
您可能希望 make
为您创建 $(OBJ_DIR)
:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
$(CC) $(CFLAGS) -c -o $@ $<
$(OBJ_DIR) :
mkdir -p $@
A more advanced example for you with automatic header dependency generation.
兄弟!
如果您的项目“main
”的架构是这样的:
main
|
|__Makefile
|__obj
|__src
|__main.c
|__src1.c
|__src2.c
[...]
只需将此添加到您的“Makefile
”即可将您的对象存储在源文件目录之外:
# Object files
# String substituion for every C/C++ file
# e.g: ./src/src1.cpp turns into ./obj/src1.o
OBJS := $(patsubst %.c, ${OBJ_DIR}/%.o, $(notdir $(SRC_DIR)))
只需将此添加到您的“Makefile
”即可编译:
# Compile: Generate object files from source files
# $@ := {NAME}
# $< := THE first file
# $^ all the dependency
# C Sources
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(C_FLAGS) -c $< -o $@
结束!