Makefile compila archivos sin cambios

Makefile compila archivos sin cambios

Hizo un esfuerzo para obtener los archivos objeto en otro directorio, pero ese directorio reflejaría el árbol del directorio de origen. Conseguí que funcionara, pero falta una pieza en la $(OBJ):línea (¿verdad?), así que cambies la fuente o no, se vuelve a compilar. Echar un vistazo.

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

Esto funciona según lo previsto: no se vuelve a compilar. Además, es mucho más fácil de leer sin los complicados sufijos de un lado a otro. Vea las respuestas y comentarios a continuación.

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)

Respuesta1

Hay varios problemas:

Primero, su variable OBJ no hace referencia a una lista de archivos creados. Por ejemplo, cuando tiene los archivos fuente src/a.cpp y src/b.cpp, OBJ contendrá obj/a y obj/b. Entonces use OBJ_O en lugar de OBJ.

En segundo lugar, su objetivo para crear los archivos OBJ no proporciona dependencias entre los archivos .cpp y .o. Es un problema que escriba su regla para crear los archivos .o de esa manera, porque no puede proporcionar información de dependencia en esa línea. Reescribiría completamente esa regla para crear archivos .o:

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

Esto genera cada archivo .o por separado, y cada archivo .o depende del archivo .cpp correspondiente.

Esta es una regla para crear un ../obj/**.oarchivo a partir de cada archivo que coincida ../src/**.cpp.

Respuesta2

Para que quede más claro:

El principal problema es precisamente la línea$(OBJ):

El problema es que si hay un archivo fuente, ../src/a.cppla variable OBJcontiene ../obj/ay la regla $(OBJ):significa "use la siguiente receta para crear el archivo ../obj/a". ¡Pero eso no es lo que hace la receta! (En su lugar, crea un archivo ../obj/a.o).

Es por eso que make siempre ejecutará esa receta porque está desesperado por crear el archivo, ../obj/aya que ese nombre de archivo aparece como una dependencia en$(EXE): $(OBJ)

información relacionada