Pregunta sobre c++, makefile – makefile detección automática de archivos src y generación de dependencias

2

Tengo la siguiente configuración para mi proyecto c ++:

en la carpeta src, hay archivos * .cpp y * .h correspondientes y en las carpetas obj quiero tener mis archivos .o.

Hasta ahora, compilar y enlazar no es el problema. Pero ahora tengo demasiados archivos .cpp y .h para ponerlos en el Makefile manualmente. Así que decidí escribir esta pequeña instrucción en el makefile:

<code>collect_sources:
@echo "collecting source files";
@echo "SRCS = \\" > sources;
@for file in ./src/*.cpp; \
do \
    echo "$$file \\" >> sources; \
done
</code>

yo también hago

<code>-include sources
</code>

al comienzo del makefile

El archivo resultantesources se ve bien, aunque hay una barra invertida en la última línea que no me gusta. Pero afaik también debería ser perjudicial.

Ahora también necesito construir dependencias automáticamente. En mi última versión en la que definí los archivos * .cpp comoSRCS directamente en el Makefile, el siguiente código era bueno:

<code>$(SRCDIR)/%.cpp:
  @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);
clear_dependencies:
    echo "" > $(DEP);

depend: clear_dependencies $(SRCS)
</code>

Pero con incluir elsources-archivo, nunca llega al bloque de código superior.

Aquí están las constantes definidas en la parte superior de Makefile:

<code>CXX = g++
CXXFLAGS = -Wall \
       -Wextra \
       -Wuninitialized \
       -Wmissing-declarations \
       -pedantic \
       -O3 \
       -p -g -pg
LDFLAGS =  -p -g -pg
DEPFLAGS = -MM

SRCDIR  = ./src
OBJDIR  = ./obj

TARGET = ./bin/my_funky_function_which_is_not_the_real_name

-include sources

OBJSTMP =   $(SRCS:.cpp=.o)
OBJS        =   $(OBJSTMP:$(SRCDIR)=$(OBJDIR))
DEP = depend.main
EXT_SRC =   .cpp
EXT_OBJ =   .o
</code>

¿Qué me estoy perdiendo? ¿Es mi enfoque válido / factible?

en una nota al margen: por favor, no sugiera ninguna herramienta que lo haga ya. Realmente quiero entender esto y tener control total sobre lo que está sucediendo. stefan
paso a paso hasta el óptimo absoluto ;-) stefan
Hay un error simple y muchas mejoras posibles. Que tan lejos quieres ir? Beta

Tu respuesta

1   la respuesta
7

1: Tucollect_sources:... include sources Es gloriosa la piratería de Rube Goldberg. Solo haz esto:

<code>SRCS = $(wildcard ./src/*.cpp)
</code>

Y si quieres confirmarlo a ojo, puedes hacer esto:

<code>$(info $(SRCS))
</code>

2:

<code>clear_dependencies:
    echo "" > $(DEP);
</code>

Solo por el bien de la estética, vamos a arreglar esto.

<code>clear_dependencies:
    $(RM) $(DEP);
</code>

3:

<code>$(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);
</code>

Esto llevará un poco de trabajo. Primero, el problema inmediato: el destino es un archivo real que existe y la regla no tiene requisitos previos. Por lo tanto, la regla no se ejecutará (no tengo idea de por qué funcionó para usted en una versión anterior, tal vez algo más fue diferente). Como una solución temporal, sugiero que cambiemos a una regla de patrón estático y objetivos de PHONY:

<code>.PHONY:$(SRCS)
$(SRCS) : $(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
   ...
</code>

A ver si todo eso funciona, entonces podemos abordar las cosas grandes.

No, es un efecto secundario de hacer que las fuentes sean objetivos de PHONY. Beta
En primer lugar, gracias por tu respuesta. No entiendo lo que quiere decir con "el objetivo es un archivo real que existe". tienes razón en que no era ese código originalmente En lugar del archivo $ era algo con una @. stefan
Estás absolutamente en lo correcto. y con su sugerencia de "PHONY" y "$ @" funciona bien :) stefan
Guay. En unas horas tendré tiempo para añadir más. Beta

Preguntas relacionadas