Makefile compila arquivos inalterados

Makefile compila arquivos inalterados

Fiz um esforço para obter os arquivos de objeto em outro diretório, mas esse diretório refletiria a árvore de diretórios de origem. Fiz isso funcionar, mas falta uma peça na $(OBJ):linha (certo?), então, quer você altere a fonte ou não, ele recompila. Dar uma olhada.

SRC_PATH=../src/
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lSDL -lSDL_gfx
INCL=-I $(SRC_PATH)include/
EXE=run

SRC=$(wildcard $(SRC_PATH)*.cpp $(SRC_PATH)game/*.cpp $(SRC_PATH)player/*.cpp)
OBJ=$(subst ../src, ../obj, $(SRC:.cpp=))
OBJ_O=$(addsuffix .o, $(OBJ))

all: $(SRC) $(EXE)

$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $(OBJ_O) -o $@

$(OBJ):
    $(CC) $(CFLAGS) $(INCL) -o $(addsuffix .o, $@) $(subst ../obj, ../src, $@).cpp

clean:
    rm -rf run $(OBJ_O)

Editar

Isso funciona conforme o esperado: não recompila. Além disso, é muito mais fácil de ler sem sufixos complicados. Veja respostas e comentários abaixo.

SRC_PATH=../src/
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lSDL -lSDL_gfx
INCL=-I $(SRC_PATH)include/
EXE=run

SRC=$(wildcard $(SRC_PATH)*.cpp $(SRC_PATH)game/*.cpp $(SRC_PATH)player/*.cpp)
OBJ=$(subst ../src, ../obj, $(SRC:.cpp=.o))

all: $(SRC) $(EXE)

$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $(OBJ) -o $@

../obj/%.o: ../src/%.cpp
    $(CC) $(CFLAGS) $(INCL) -o $@ $<

clean:
    rm -rf run $(OBJ)

Responder1

Existem vários problemas:

Primeiro, sua variável OBJ não se refere a uma lista de arquivos criados. Por exemplo, quando você tem arquivos fonte src/a.cpp e src/b.cpp, OBJ conterá obj/a e obj/b. Então use OBJ_O em vez de OBJ.

Segundo, seu objetivo para construir os arquivos OBJ não fornece dependências entre os arquivos .cpp e .o. É um problema você escrever sua regra para criar os arquivos .o dessa maneira, porque você não pode fornecer informações de dependência nessa linha. Eu reescreveria completamente essa regra para a criação de arquivos .o:

../obj/%.o: ../src/%.cpp
    $(CC) $(CFLAGS) $(INCL) -o "$@" "$<"

Isso cria cada arquivo .o separadamente e cada arquivo .o depende do arquivo .cpp correspondente.

Esta é uma regra para criar um ../obj/**.oarquivo a partir de cada arquivo que corresponda a ../src/**.cpp.

Responder2

Para deixar mais claro:

O principal problema é justamente a linha$(OBJ):

O problema é que se houver um arquivo fonte ../src/a.cppa variável OBJcontém ../obj/ae a regra $(OBJ):significa "use a seguinte receita para construir o arquivo ../obj/a". Mas não é isso que a receita faz! (Em vez disso, ele cria um arquivo ../obj/a.o.)

É por isso que o make sempre executará essa receita porque está desesperado para criar o arquivo, ../obj/apois o nome do arquivo está listado como uma dependência em$(EXE): $(OBJ)

informação relacionada