这是以下有问题的Makefile:
#
# Compiler flags
#
CC = gcc
CFLAGS = -Wall -Werror -Wextra
#
# Project files
# example -
# SRCS = hash_table.c linked_list.c utils.c common.c business_logic.c user_interface.c
# SRCS = test/gc_test.c src/gc.c
SRCS := $(shell find . -name "*")
OBJS = $(SRCS:.c=.o)
EXE = output.out
FILENAMES := $(shell find . -type f -name "*.c" -printf "%fn")
FILENAMES_OUT = $(FILENAMES:.c=.o)
#
# Default build settings
#
BUILDDIR = build
BUILDCFLAGS = -g -O0
BUILDEXE = $(BUILDDIR)/$(EXE)
BUILDOBJS = $(addprefix $(BUILDDIR)/, $(FILENAMES_OUT))
# Rules for default build
all: clean build
build: $(BUILDEXE)
$(BUILDEXE): $(BUILDOBJS)
$(CC) $(CFLAGS) $(BUILDCFLAGS) -o $(BUILDEXE) $^ -lcunit
$(BUILDDIR)/%.o: %.c
$(CC) $(CFLAGS) $(BUILDCFLAGS) -c $< -o $@
memtest: $(BUILDEXE)
valgrind --leak-check=full ./$<
#
# Other rules
#
clean:
mkdir -p $(BUILDDIR)
问题->make: *** No rule to make target `build/gc_test.o', needed by `build/output.out'. Stop.
项目树
.
├── build
├── doc
│ └── design.md
├── Makefile
├── proj
│ ├── code_quality_report.md
│ ├── deviations.md
│ ├── individual_reflection.md
│ ├── team_reflection.md
│ └── test_report.md
├── README.md
├── src
│ ├── gc.c
│ └── headers
│ └── gc.h
└── tests
└── gc_test.c
问题本身发生在依赖关系为gc_test.c gc.c
的$(BUILDEXE): $(BUILDOBJS)
中。这些依赖关系应该被它下面的函数捕获,因为它的输入是build
目录中的所有.c文件。这些文件应该正确匹配,然后编译为.o文件,然后这些文件应该爬上树并生成可执行文件。我很困惑,因为$(BUILDOBJS)
应该和$(BUILDDIR)/%.o
一样。
我是制作Makefile的新手,但我想做得更好。请指出本可以更好地用于这篇文章的更好的命名约定或术语。谢谢
问题就在这里:
FILENAMES := $(shell find . -type f -name "*.c" -printf "%fn")
这是错误的,因为-printf "%fn"
只打印文件名,而没有任何路径。你正在丢失有关文件查找路径的所有信息,那么如何才能找到它们呢?
您应该将其更改为简单的-print
,这样它就可以工作了。