Makefile compila arquivos inalterados

3

Fez 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. Tem que funcionar, mas há uma peça faltando na linha $(OBJ): (direita?), Então se você alterar a fonte ou não, recompila. Dê 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 como esperado: não recompila. Além disso, é muito mais fácil de ler sem os complicados sufixos para frente e para trás. Veja as 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)
    
por Emanuel Berg 11.07.2012 / 02:35

2 respostas

5

Existem vários problemas:

Primeiro, sua variável OBJ não se refere a uma lista de arquivos criados. Por exemplo, quando você tiver arquivos de origem src / a.cpp e src / b.cpp, o OBJ conterá obj / a e obj / b. Então use OBJ_O ao invés de OBJ.

Em segundo lugar, seu destino para criar os arquivos OBJ não fornece dependências entre os arquivos .cpp e .o. É um problema que você escreve sua regra para criar os arquivos .o dessa forma, porque você não pode fornecer informações de dependência nessa linha. Eu reescreveria completamente essa regra para criar 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 arquivo ../obj/**.o de cada arquivo que corresponda a ../src/**.cpp .

    
por 11.07.2012 / 10:15
2

Para tornar mais claro:

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

O problema é que, se houver um arquivo de origem ../src/a.cpp , a variável OBJ contém ../obj/a e a regra $(OBJ): significa "use a seguinte biblioteca para criar o arquivo ../obj/a ". Mas não é isso que a receita faz! (Em vez disso, cria um arquivo ../obj/a.o .)

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

    
por 11.07.2012 / 11:34

Tags