我正在尝试创建一个通用的Makefile以用于我的大多数项目。它应按以下方式工作:仅重建和链接其。c或。h依赖项已更改的。o文件。 。o和。d文件存储在称为“ build”的单独目录中。
[借助官方GNU Make手册和一些谷歌搜索,我成功实现了所需的行为,除了一件事:运行make re
时出现错误:Assembler messages: Fatal error: can't create build/ft_build_buffer.o: No such file or directory
–原因是仅在生成。d文件时才创建“ build”目录,但由于某些原因,re
规则只是跳过了这一步,然后继续编译 .o文件马上!注意:如果我运行make clean && make fclean && make all
(应该是完全相同的东西),则一切正常。
其他一些事情:我尝试使用-MMD
选项动态生成依赖项,但是在我的机器上导致。d文件仅包含。c依赖项。当然,我可以使所有。c文件都依赖于所有。h文件,但这似乎是一个很草率的解决方案。
随时分享任何其他建议/改进,以使此文件更清晰易读,谢谢! :)
# Define the C compiler to use.
CC := gcc
# Define any compile-time flags.
CFLAGS := -I./include -Wall -Wextra -Werror -g
#CFLAGS := -I./include -march=native -O2 -pipe
# Define the executable file.
BIN := ft_hexdump
# Define build directory.
BUILD_DIR := build
# Define source files directory.
SRC_DIR := src
# Define the C source files.
SRCS := $(wildcard $(SRC_DIR)/*.c)
# Define the C object files.
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
# Define the prerequisite files.
DEPS := $(OBJS:%.o=%.d)
.PHONY: all clean fclean re
.DELETE_ON_ERROR:
all: $(BIN)
-include $(DEPS)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.d
$(CC) $(CFLAGS) -c $(SRC_DIR)/$*.c -o $@
$(BUILD_DIR)/%.d: $(SRC_DIR)/%.c
@mkdir -p $(@D)
@set -e; rm -f $@; \
$(CC) $(CFLAGS) $(INCLUDE) -MM $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
clean:
-rm -rf $(BUILD_DIR)
fclean: clean
-rm -f $(BIN)
re: fclean all
这里是@ M.M建议的修改后的工作版本
# Define the C compiler to use.
CC := gcc
# Define any compile-time flags.
CFLAGS := -I./include -Wall -Wextra -Werror -g
#CFLAGS := -I./include -march=native -O2 -pipe
# Define the executable file.
BIN := ft_hexdump
# Define build directory.
BUILD_DIR := build
# Define source files directory.
SRC_DIR := src
# Define the C source files.
SRCS := $(wildcard $(SRC_DIR)/*.c)
# Define the C object files.
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
# Define the prerequisite files.
DEPS := $(OBJS:%.o=%.d)
.PHONY: all clean fclean re
.DELETE_ON_ERROR:
all: $(BIN)
-include $(DEPS)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -MMD -c $(SRC_DIR)/$*.c -o $@
clean:
-rm -rf $(BUILD_DIR)
fclean: clean
-rm -f $(BIN)
re:
$(MAKE) fclean
$(MAKE) all