Makefile'ı başka bir Makefile'dan nasıl çağırabilirim?


125

Bir makefile'ı diğerinden çağırarak bazı beklenmedik sonuçlar alıyorum. İki makefile var, biri aradı /path/to/project/makefile, diğeri aradı /path/to/project/gtest-1.4.0/make/Makefile. Birincisinin ikincisini aramasını sağlamaya çalışıyorum. Proje / makefile / yol / yolunda, var

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

Ve /path/to/project/gtest-1.4.0/make/Makefilebende var

all: $(TESTS)

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

Aşağıdakileri yayınlamak:

cd /path/to/project
make

Çıktılar:

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'

Ancak, şu komutları verdiğimde:

cd /path/to/project
make clean

Anlıyorum:

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'

Anlamıyorum: Her iki durumda da, /path/to/project/makefilebana geçerli çalışma dizinine girdiğini söylüyor. İlk durumda, yapması gereken bir işi olduğunu düşünmez (yaptığında) ve ikinci durumda, uygun yönergeyi bulabilir (çıktı bana yanlış dizine baktığını söylediğinde) ama dener rmkomutu /path/to/projectyerine çalıştırmak için /path/to/makefile/gtest-1.4.0/make/.

Birbirinden makefiles çağırmak için temel bir şeyi mi kaçırıyorum? Korkunç bir kavramsal hata mı yaptım veya genel bir tuzağa düştüm mü? Nasıl etkili bir şekilde dizinleri değiştiririm ve ilkinden ikinci bir makefile çağırırım? Anladığım kadarıyla sadece aramanın make -f <name>yeterli olacağıydı.

Bu bash'ta make / gmake 3.81'dir.


3
Sanırım make -f gtest-1.4.0/make/Makefile cleansenin yerine söylesen iyi olur $(MAKE) -C gtest-1.4.0/make clean. Neden sahte hedefler tanımlamadınız?
dma_k

Yanıtlar:


113

Ne istediğinizi tam olarak anlamadım, ancak -fkomut satırı seçeneğini kullanmak sadece bir dosyayı belirtir - dizinleri değiştirmeyi söylemez. İşi başka bir dizinde yapmak istiyorsanız, dizine gitmeniz gerekir cd:

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

Her satırın Makefileayrı bir kabukta çalıştığına dikkat edin, bu nedenle dizini geri değiştirmeye gerek yoktur.


67
El ile cddizine girmek yerine gtest-1.4.0, -Cseçeneğini kullanmalısınız make.
Tader

29
Ya da en azından kesinlikle &&cd ve make komutu arasında kullanmalısınız . Aksi takdirde cd başarısız olursa, yine de çalışacaktır make clean... yanlış dizinde !! Ayrıca $(MAKE)yinelemede her zaman SADECE SADECE kullanmalısınız , asla yalancı makesözcük kullanmalısınız. Yani şöyle bir şey: cd gtest-1.4.0 && $(MAKE) clean
MadScientist

3
@Tader: teknik özellikte -Cdeğil
Janus Troelsen

1
Gnu-make ile ilgili bu soru -Cspesifikasyondadır: gnu.org/software/make/manual/make.html#Recursion
Cas

123

Yerine -farasında makesize kullanmak isteyebilirsiniz -C <path>seçeneği. Bu önce yolu değiştirir ' <path>' ve sonra makeorayı çağırır .

Misal:

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
Bu yol en iyisi gibi görünüyor. cdTerminalin sonsuz bir döngüye girmesine neden olan diğer yanıtlardan gelin .
gbmhunter

$ (MAKE) -C gtest-1.4.0 / make clean benim için çalışmıyor. Bence $ (MAKE) -C gtest-1.4.0 clean
Arigion


1

Görünüşe göre $(TESTS)boş olduğu için 1.4.0 makefile etkin

all: 

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

Aslında, hiçbir şey yapmaz. ve temiz söylediği şeyi yaparrm -f gtest.a ...


$ (TESTS), a wildcardve a ile tanımlanır patsubst, ancak bunlar ana makefile'dan boş dönüyor, çünkü dizin etkin bir şekilde değiştirilmiyor. Güzel göz.
Chris Tonkinson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.