Como chamar Makefile de outro Makefile?


125

Estou obtendo resultados inesperados chamando um makefile de outro. Eu tenho dois makefiles, um chamado /path/to/project/makefilee outro chamado /path/to/project/gtest-1.4.0/make/Makefile. Estou tentando fazer com que o primeiro ligue para o último. Em / path / to / project / makefile, tenho

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

E /path/to/project/gtest-1.4.0/make/Makefileeu tenho

all: $(TESTS)

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

Emitindo o seguinte:

cd /path/to/project
make

Saídas:

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'

No entanto, quando eu emito estes comandos:

cd /path/to/project
make clean

Entendo:

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'

Não entendo: nos dois casos, /path/to/project/makefileestá me dizendo que está entrando no diretório de trabalho atual. No primeiro caso, ele não acha que tem trabalho a fazer (quando existe) e no segundo caso, é capaz de encontrar a diretiva apropriada (quando a saída está me dizendo que está procurando no diretório errado), mas tenta para executar o rmcomando /path/to/project, em vez de /path/to/makefile/gtest-1.4.0/make/.

Estou perdendo algo fundamental para chamar makefiles um do outro? Cometi um erro conceitual flagrante ou atingi uma armadilha comum? Como altero efetivamente os diretórios e chamo um segundo makefile de dentro do primeiro? Meu entendimento era que simplesmente chamar make -f <name>seria suficiente.

Isso é make / gmake 3.81 no bash.


3
Eu acho que, em vez de make -f gtest-1.4.0/make/Makefile cleanvocê dizer melhor $(MAKE) -C gtest-1.4.0/make clean. Por que você não definiu alvos falsos?
dma_k

Respostas:


112

Não estou muito claro o que você está perguntando, mas o uso da -fopção de linha de comando apenas especifica um arquivo - ele não informa o make para alterar os diretórios. Se você quiser fazer o trabalho em outro diretório, precisará cddo diretório:

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

Observe que cada linha Makefileé executada em um shell separado, portanto, não há necessidade de alterar o diretório novamente.


67
Em vez de manualmente cdpara o gtest-1.4.0dir, você deve usar a -Copção de make.
Tader

29
Ou, no mínimo, você deve definitivamente usar &&entre o cd e o comando make. Caso contrário, se o CD falhar, ele ainda será executado make clean... no diretório errado !! Além disso, você deve sempre usar SOMENTE $(MAKE), nunca a palavra de baralho make, ao recorrer. Então algo como: cd gtest-1.4.0 && $(MAKE) clean
MadScientist

3
@Tader: -Cnão está na especificação
Janus Troelsen

1
Esta pergunta sobre gnu-marca e -Cestá no spec: gnu.org/software/make/manual/make.html#Recursion
Cas

123

Em vez de o -fde makeque você pode querer usar a -C <path>opção. Isso primeiro muda para o caminho ' <path>' e depois chama makelá.

Exemplo:

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

1
Desta forma, parece o melhor. As outras respostas usadas cdfazem com que o terminal entre em um loop infinito.
Gbmhunter

$ (MAKE) -C gtest-1.4.0 / make clean não funciona para mim. Eu acho que deveria ser $ (MAKE) -C gtest-1.4.0 clean
Arigion 31/07


1

Parece claro que $(TESTS)está vazio, então seu makefile 1.4.0 é efetivamente

all: 

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

De fato, tudo não tem nada a ver. e limpo faz exatamente o que dizrm -f gtest.a ...


$ (TESTES) é definido com ae wildcarda patsubst, no entanto, eles retornam vazios do makefile principal, porque o diretório não está sendo efetivamente alterado. Bom olho.
22610 Chris Cornkinson
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.