จะเรียก Makefile จาก Makefile อื่นได้อย่างไร?


125

ฉันได้รับผลลัพธ์ที่ไม่คาดคิดโดยเรียกใช้ makefile จากอีก ฉันมีสอง makefiles หนึ่งเรียกว่าและเป็นหนึ่งเรียกว่า/path/to/project/makefile /path/to/project/gtest-1.4.0/make/Makefileฉันพยายามที่จะเรียกอดีตคนหลัง ใน / path / to / project / makefile ฉันมี

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

และในตัว/path/to/project/gtest-1.4.0/make/Makefileฉันมี

all: $(TESTS)

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

ออกรายการต่อไปนี้:

cd /path/to/project
make

ขาออก:

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'

อย่างไรก็ตามเมื่อฉันออกคำสั่งเหล่านี้:

cd /path/to/project
make clean

ฉันเห็น:

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'

ฉันไม่เข้าใจ: ในทั้งสองกรณี/path/to/project/makefileกำลังบอกฉันว่ากำลังเข้าสู่ไดเร็กทอรีการทำงานปัจจุบัน ในกรณีแรกไม่คิดว่าจะมีงานทำ (เมื่อมี) และในกรณีที่สองสามารถค้นหาคำสั่งที่เหมาะสมได้ (เมื่อผลลัพธ์บอกฉันว่ามันกำลังมองหาในไดเรกทอรีที่ไม่ถูกต้อง) แต่มันก็พยายาม เพื่อเรียกใช้rmคำสั่ง/path/to/projectแทน/path/to/makefile/gtest-1.4.0/make/.

ฉันขาดอะไรพื้นฐานในการโทรหา makefiles จากกันและกันหรือไม่? ฉันได้ทำผิดพลาดทางความคิดอย่างร้ายแรงหรือเกิดข้อผิดพลาดทั่วไปหรือไม่? ฉันจะเปลี่ยนไดเร็กทอรีอย่างมีประสิทธิภาพและเรียก makefile ที่สองจากภายในไดเร็กทอรีแรกได้อย่างไร ความเข้าใจของฉันคือแค่การโทรmake -f <name>ก็เพียงพอแล้ว

นี่คือ make / gmake 3.81 ใน bash


3
ผมคิดว่าแทนการที่คุณพูดดีกว่าmake -f gtest-1.4.0/make/Makefile clean $(MAKE) -C gtest-1.4.0/make cleanทำไมคุณไม่ได้กำหนดเป้าหมายของปลอม?
dma_k

คำตอบ:


113

ฉันไม่ค่อยชัดเจนว่าคุณกำลังถามอะไร แต่การใช้-fตัวเลือกบรรทัดคำสั่งเพียงแค่ระบุไฟล์ - มันไม่ได้บอกให้เปลี่ยนไดเรกทอรี หากคุณต้องการทำงานในไดเร็กทอรีอื่นคุณต้องcdไปที่ไดเร็กทอรี:

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

โปรดทราบว่าแต่ละบรรทัดในMakefileทำงานในเชลล์แยกกันดังนั้นจึงไม่จำเป็นต้องเปลี่ยนไดเร็กทอรีกลับ


67
แทนที่จะcdใช้gtest-1.4.0dir ด้วยตนเองคุณควรใช้-Cตัวเลือกของmake.
Tader

29
หรืออย่างน้อยที่สุดคุณควรใช้&&ระหว่างคำสั่ง cd และ make ไม่งั้นถ้า cd ล้มเหลวมันจะยังรันmake clean... ผิดไดเร็กทอรี !! นอกจากนี้คุณควรใช้เท่านั้น$(MAKE)อย่าใช้คำmakeเปล่าเมื่อเรียกซ้ำ สิ่งที่ชอบ: cd gtest-1.4.0 && $(MAKE) clean
MadScientist

3
@Tader: -Cไม่อยู่ในข้อมูลจำเพาะ
Janus Troelsen

1
คำถามเกี่ยวกับ gnu-make และ-Cอยู่ในข้อมูลจำเพาะ: gnu.org/software/make/manual/make.html#Recursion
Cas

123

แทนที่จะเป็น-fของmakeคุณอาจต้องการที่จะใช้-C <path>ตัวเลือก ขั้นแรกนี้จะเปลี่ยนไปยังเส้นทาง ' <path>' จากนั้นเรียกที่makeนั่น

ตัวอย่าง:

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
วิธีนี้น่าจะดีที่สุด การตอบกลับอื่น ๆ ที่ใช้cdทำให้เทอร์มินัลเข้าสู่ลูปที่ไม่มีที่สิ้นสุด
gbmhunter

$ (MAKE) -C gtest-1.4.0 / make clean ไม่ได้ผลสำหรับฉัน ฉันคิดว่ามันควรจะเป็น $ (MAKE) -C gtest-1.4.0 clean
Arigion


1

ดูเหมือนชัดเจนว่า$(TESTS)ว่างเปล่าดังนั้น makefile 1.4.0 ของคุณจึงมีประสิทธิภาพ

all: 

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

แท้จริงแล้วทั้งหมดไม่มีอะไรทำ และการทำความสะอาดก็ทำตามที่กล่าวไว้rm -f gtest.a ...


$ (TESTS) ถูกกำหนดด้วย a wildcardและ a patsubstอย่างไรก็ตามสิ่งเหล่านี้จะคืนค่าว่างเปล่าจาก makefile หลักเนื่องจากไดเร็กทอรีไม่มีการเปลี่ยนแปลงอย่างมีประสิทธิภาพ ตาดี.
Chris Tonkinson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.