以下是 makefile:
.PHONY: all clean
CC = gcc
CFLAGS = -g -m32 -std=c17
BIN = bin
ALG_SRCS = $(wildcard alg/*.c)
COMMON_SRCS = $(wildcard *.c)
ALG_OBJS = $(patsubst alg/%.c, $(BIN)/%.o, $(ALG_SRCS))
COMMON_OBJS = $(patsubst %.c, $(BIN)/%.o, $(COMMON_SRCS))
ALG_EXES = $(patsubst alg/%.c, $(BIN)/%, $(ALG_SRCS))
all: $(ALG_EXES)
$(BIN)/%: $(BIN)/%.o $(COMMON_OBJS) | $(BIN)
$(CC) $(CFLAGS) -o $@ $^ -lncursesw
$(BIN)/%.o: %.c | $(BIN)
$(CC) $(CFLAGS) -c $< -o $@
$(BIN)/%.o: alg/%.c | $(BIN)
$(CC) $(CFLAGS) -c $< -o $@
$(BIN):
mkdir -p $(BIN)
clean:
rm -rf $(BIN)
执行示例:
$ make
mkdir -p bin
gcc -g -m32 -std=c17 -c alg/basic.c -o bin/basic.o
gcc -g -m32 -std=c17 -c graph.c -o bin/graph.o
gcc -g -m32 -std=c17 -c grid.c -o bin/grid.o
gcc -g -m32 -std=c17 -c main.c -o bin/main.o
gcc -g -m32 -std=c17 -o bin/basic bin/basic.o bin/graph.o bin/grid.o bin/main.o -lncursesw
gcc -g -m32 -std=c17 -c alg/colors.c -o bin/colors.o
gcc -g -m32 -std=c17 -o bin/colors bin/colors.o bin/graph.o bin/grid.o bin/main.o -lncursesw
rm bin/main.o bin/graph.o bin/basic.o bin/colors.o bin/grid.o
我没有要求删除目标文件,也没有调用“清理”。为什么rm bin/main.o bin/graph.o bin/basic.o bin/colors.o bin/grid.o
还是会发生这种情况?
您确定您向我们展示了该输出的正确 makefile 吗?在我看来,这非常错误,当我重新创建您的 makefile 并在本地进行设置时,我没有看到您所看到的行为。您使用的是哪个版本的 GNU Make?
我收到的命令
rm
以及我完全预料到的并且看起来正确的命令是这样的:这是有道理的,因为这两个文件被视为中间文件(请参阅 urznow 在上面的评论中发布的链接)。
其他目标文件不能是中间文件,因为它们在规则中被明确列为先决条件
$(BIN)/%: $(BIN)/%.o $(COMMON_OBJS)
。无论如何,为了避免事情被视为中间状态,您可以将它们列为 makefile 中某些规则的先决条件(请注意,此规则实际上不必运行,它必须存在)。因此,一个选项是添加一个“辅助”规则,如下所示:
(但是,正如我所说,在我重现的 makefile 中,
$(ALG_OBJS)
这里只需要)。这会将所有目标文件列为显式目标的先决条件,从而使它们成为非中间文件。另一种选择是使用静态模式规则将构建二进制文件的规则从隐式规则(此处为模式规则)更改为显式规则:
任何一个都可以。
顺便说一句,您可能希望
:=
在 makefile 中使用赋值,至少对于wildcard
函数而言,只是为了获得一点效率。