Aqui está o 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)
Exemplo de execução:
$ 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
Eu não pedi para que os arquivos de objeto fossem removidos, nem chamei "clean". Por que isso rm bin/main.o bin/graph.o bin/basic.o bin/colors.o bin/grid.o
ainda acontece?
Você tem certeza de que nos mostrou o makefile certo para essa saída? Isso parece muito errado para mim e quando eu recrio seu makefile e configuro localmente, não vejo o comportamento que você vê. Qual versão do GNU Make você tem?
O
rm
comando que recebo, o que eu esperava e parece correto, é este:Isso faz sentido porque esses dois arquivos são considerados arquivos intermediários (veja o link que urznow postou em um comentário acima).
Os outros arquivos de objeto não podem ser arquivos intermediários porque são listados explicitamente como pré-requisitos na
$(BIN)/%: $(BIN)/%.o $(COMMON_OBJS)
regra.De qualquer forma, para evitar que as coisas sejam consideradas intermediárias, você pode listá-las como pré-requisitos de alguma regra no makefile (note que essa regra não precisa ser executada, ela só precisa existir). Então, uma opção é adicionar uma regra "auxiliar" como esta:
(mas, como eu disse, na minha reprodução do seu makefile apenas
$(ALG_OBJS)
é necessário aqui). Isso lista todos os arquivos de objeto como pré-requisitos de um alvo explícito que os torna não intermediários.Outra opção é alterar a regra que constrói binários de uma regra implícita (regra de padrão aqui) para uma regra explícita, usando uma regra de padrão estática :
Qualquer uma delas funcionará.
A propósito, você provavelmente vai querer usar
:=
atribuição em seus makefiles, pelo menos para aswildcard
funções, só para ganhar um pouco de eficiência.