Bagaimana cara memanggil Makefile dari Makefile lain?

125

Saya mendapatkan hasil yang tidak terduga dengan memanggil satu makefile dari yang lain. Saya punya dua makefile, satu dipanggil /path/to/project/makefiledan satu lagi dipanggil /path/to/project/gtest-1.4.0/make/Makefile. Saya mencoba agar yang pertama menelepon yang terakhir. Di / path / to / project / makefile, saya punya

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

Dan /path/to/project/gtest-1.4.0/make/Makefilesaya punya

all: $(TESTS)

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

Menerbitkan hal berikut:

cd /path/to/project
make

Keluaran:

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'

Namun, ketika saya mengeluarkan perintah ini:

cd /path/to/project
make clean

Saya melihat:

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'

Saya tidak mengerti: Dalam kedua kasus, /path/to/project/makefilememberi tahu saya bahwa itu memasuki direktori kerja saat ini. Dalam kasus pertama, ia tidak berpikir itu harus dilakukan (ketika itu terjadi) dan dalam kasus kedua, ia dapat menemukan direktif yang sesuai (ketika keluaran memberi tahu saya bahwa ia mencari di direktori yang salah) namun ia mencoba untuk menjalankan rmperintah /path/to/project, alih-alih /path/to/makefile/gtest-1.4.0/make/.

Apakah saya kehilangan sesuatu yang mendasar untuk memanggil makefiles dari satu sama lain? Apakah saya telah membuat kesalahan konseptual yang parah, atau mengalami kesulitan yang umum? Bagaimana cara mengubah direktori secara efektif dan memanggil makefile kedua dari dalam yang pertama? Pemahaman saya adalah bahwa menelepon make -f <name>saja sudah cukup.

Ini adalah make / gmake 3.81 di bash.

Chris Tonkinson
sumber
3
Saya pikir, daripada make -f gtest-1.4.0/make/Makefile cleanAnda lebih baik katakan $(MAKE) -C gtest-1.4.0/make clean. Mengapa Anda belum menetapkan target palsu?
dma_k

Jawaban:

113

Saya tidak terlalu jelas apa yang Anda tanyakan, tetapi menggunakan -fopsi baris perintah hanya menentukan file - tidak memberi tahu make to change direktori. Jika Anda ingin melakukan pekerjaan di direktori lain, Anda perlu ke cddirektori:

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

Perhatikan bahwa setiap baris dalam Makefileberjalan di shell terpisah, jadi tidak perlu mengubah direktori kembali.

kenorb
sumber
67
Alih-alih cdmembuka gtest-1.4.0direktori secara manual , Anda harus menggunakan -Copsi make.
Tader
29
Atau paling tidak, Anda harus menggunakan &&perintah antara cd dan make. Jika tidak, jika cd gagal, CD akan tetap berjalan make clean... di direktori yang salah !! Juga Anda harus selalu HANYA menggunakan $(MAKE), tidak pernah bareword make, saat berulang. Jadi kira-kira seperti: cd gtest-1.4.0 && $(MAKE) clean
MadScientist
3
@Tader: -Ctidak ada dalam spesifikasi
Janus Troelsen
1
Pertanyaan ini tentang gnu-make dan -Cada di dalam spek: gnu.org/software/make/manual/make.html#Recursion
Cas
123

Alih-alih -fdari makeAnda mungkin ingin menggunakan -C <path>opsi. Ini pertama-tama mengubah ke jalur ' <path>', dan kemudian memanggil ke makesana.

Contoh:

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
sumber
1
Cara ini sepertinya yang terbaik. Datang dari balasan lain yang digunakan cdmenyebabkan terminal masuk ke loop tak terbatas.
gbmhunter
$ (MAKE) -C gtest-1.4.0 / make clean tidak bekerja untuk saya. Saya pikir itu harus $ (MAKE) -C gtest-1.4.0 clean
Arigion
1

Tampaknya jelas $(TESTS)kosong sehingga file 1.4.0 Anda efektif

all: 

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

Memang, semua tidak ada hubungannya. dan bersih melakukan persis seperti yang dikatakannyarm -f gtest.a ...

John Knoeller
sumber
$ (TESTS) didefinisikan dengan a wildcarddan a patsubst, namun ini kembali kosong dari makefile utama, karena direktori tidak diubah secara efektif. Mata yang bagus.
Chris Tonkinson