¿Cómo llamar a Makefile desde otro Makefile?

125

Estoy obteniendo algunos resultados inesperados llamando a un archivo MAKE de otro. Tengo dos makefiles, uno llamado /path/to/project/makefiley otro llamado /path/to/project/gtest-1.4.0/make/Makefile. Estoy intentando que el primero llame al segundo. En / path / to / project / makefile, tengo

dev: $(OBJ_FILES)
  $(CPPC) $(LIBS) $(FLAGS_DEV) $(OBJ_FILES) -o $(BIN_DIR)/$(PROJECT)
  $(MAKE) -f ./gtest-1.4.0/make/Makefile

clean:
  rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o
  rm -f ../svn-commit.tmp~
  rm -f $(BIN_DIR)/$(PROJECT)
  make -f gtest-1.4.0/make/Makefile clean

Y en /path/to/project/gtest-1.4.0/make/Makefiletengo

all: $(TESTS)

clean:
  rm -f $(TESTS) gtest.a gtest_main.a *.o

Emitiendo lo siguiente:

cd /path/to/project
make

Salidas:

make -f ./gtest-1.4.0/make/Makefile
make[1]: Entering directory `/path/to/project'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/path/to/project'

Sin embargo, cuando publico estos comandos:

cd /path/to/project
make clean

Veo:

make -f gtest-1.4.0/make/Makefile clean
make[1]: Entering directory `/path/to/project'
rm -f  gtest.a gtest_main.a *.o
make[1]: Leaving directory `/path/to/project'

No entiendo: en ambos casos, /path/to/project/makefileme dice que está ingresando al directorio de trabajo actual. En el primer caso, no cree que tenga trabajo que hacer (cuando lo hace) y en el segundo caso, es capaz de encontrar la directiva adecuada (cuando la salida me dice que está buscando en el directorio incorrecto) pero intenta para ejecutar el rmcomando en /path/to/projectlugar de /path/to/makefile/gtest-1.4.0/make/.

¿Me estoy perdiendo algo fundamental para llamar a los makefiles el uno del otro? ¿He cometido un error conceptual atroz o he encontrado un error común? ¿Cómo cambio efectivamente los directorios y llamo a un segundo archivo MAKE desde el primero? Comprendí que simplemente llamar make -f <name>sería suficiente.

Esto es make / gmake 3.81 en bash.

Chris Tonkinson
fuente
3
Creo que, en vez de make -f gtest-1.4.0/make/Makefile cleanti, mejor dilo $(MAKE) -C gtest-1.4.0/make clean. ¿Por qué no has definido objetivos falsos?
dma_k

Respuestas:

112

Realmente no estoy muy claro lo que está preguntando, pero el uso de la -fopción de línea de comando solo especifica un archivo; no le dice a make que cambie los directorios. Si desea hacer el trabajo en otro directorio, debe hacerlo cden el directorio:

clean:
    cd gtest-1.4.0 && $(MAKE) clean

Tenga en cuenta que cada línea se Makefileejecuta en un shell separado, por lo que no es necesario volver a cambiar el directorio.

kenorb
fuente
67
En lugar de cdir manualmente al gtest-1.4.0directorio, debe usar la -Copción de make.
Tader
29
O al menos, definitivamente debes usar &&entre el cd y el comando make. De lo contrario, si el CD falla, se ejecutará make clean... ¡en el directorio incorrecto! Además, siempre debe usar SÓLO $(MAKE), nunca la palabra pura make, al recurrir. Así que algo como: cd gtest-1.4.0 && $(MAKE) clean
MadScientist
3
@Tader: -Cno está en la especificación
Janus Troelsen
1
Esta pregunta sobre gnu-make y -Cestá en la especificación: gnu.org/software/make/manual/make.html#Recursion
Cas
123

En lugar de la -fde makeusted, es posible que desee utilizar la -C <path>opción. Esto primero cambia a la ruta ' <path>', y luego las calles makeallí.

Ejemplo:

clean:
  rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o
  rm -f ../svn-commit.tmp~
  rm -f $(BIN_DIR)/$(PROJECT)
  $(MAKE) -C gtest-1.4.0/make clean
Tader
fuente
1
Este camino parece lo mejor. Vienen de las otras respuestas que cdhacen que la terminal entre en un bucle infinito.
gbmhunter
$ (MAKE) -C gtest-1.4.0 / make clean no me funciona. Creo que debería ser $ (MAKE) -C gtest-1.4.0 clean
Arigion
1

Parece claro que $(TESTS)está vacío, por lo que su archivo MAKE 1.4.0 es efectivo

all: 

clean:
  rm -f  gtest.a gtest_main.a *.o

De hecho, todo no tiene nada que hacer. y limpio hace exactamente lo que dicerm -f gtest.a ...

John Knoeller
fuente
$ (TESTS) se define con a wildcardy a patsubst, sin embargo, estos regresan vacíos desde el archivo MAKE principal, porque el directorio no se está cambiando efectivamente. Buen ojo.
Chris Tonkinson