Làm thế nào để gọi Makefile từ một Makefile khác?


125

Tôi nhận được một số kết quả không mong đợi khi gọi một makefile từ một makefile khác. Tôi có hai trang điểm, một được gọi /path/to/project/makefilevà một được gọi /path/to/project/gtest-1.4.0/make/Makefile. Tôi đang cố gọi trước là sau. Trong / path / to / project / makefile, tôi có

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

Và trong /path/to/project/gtest-1.4.0/make/Makefiletôi có

all: $(TESTS)

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

Phát hành như sau:

cd /path/to/project
make

Kết quả đầu ra:

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'

Tuy nhiên, khi tôi phát hành các lệnh này:

cd /path/to/project
make clean

Tôi hiểu rồi:

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'

Tôi không hiểu: Trong cả hai trường hợp, /path/to/project/makefilecho tôi biết rằng nó đang vào thư mục làm việc hiện tại. Trong trường hợp đầu tiên, nó không nghĩ rằng nó có việc phải làm (khi nó làm) và trong trường hợp thứ hai, nó có thể tìm thấy chỉ thị thích hợp (khi đầu ra cho tôi biết nó đang tìm kiếm trong thư mục sai) nhưng nó cố gắng để chạy rmlệnh trong /path/to/project, thay vì /path/to/makefile/gtest-1.4.0/make/.

Tôi có thiếu một cái gì đó cơ bản để gọi các tệp trang điểm từ nhau không? Tôi đã mắc phải một sai lầm nghiêm trọng về khái niệm hay mắc phải một lỗi chung? Làm cách nào để thay đổi hiệu quả các thư mục và gọi một makefile thứ hai từ bên trong tệp đầu tiên? Tôi hiểu rằng chỉ cần gọi điện make -f <name>là đủ.

Đây là make / gmake 3,81 trong bash.


3
Tôi nghĩ, thay vì make -f gtest-1.4.0/make/Makefile cleanbạn nói tốt hơn $(MAKE) -C gtest-1.4.0/make clean. Tại sao bạn chưa xác định mục tiêu giả?
dma_k

Câu trả lời:


113

Tôi không thực sự rõ bạn đang hỏi gì, nhưng việc sử dụng -ftùy chọn dòng lệnh chỉ xác định một tệp - nó không yêu cầu thực hiện thay đổi thư mục. Nếu bạn muốn thực hiện công việc trong một thư mục khác, bạn cần vào cdthư mục:

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

Lưu ý rằng mỗi dòng trong Makefilechạy trong một shell riêng biệt, vì vậy không cần phải thay đổi lại thư mục.


67
Thay vì nhập thủ công cdvào gtest-1.4.0dir, bạn nên sử dụng -Ctùy chọn make.
Tader

29
Hoặc ít nhất, bạn chắc chắn nên sử dụng &&giữa cd và lệnh make. Ngược lại nếu cd bị lỗi nó vẫn chạymake clean ... sai thư mục !! Ngoài ra, bạn nên luôn CHỈ sử dụng $(MAKE), không bao giờ sử dụng từ maketrần, khi đệ quy. Vì vậy, một cái gì đó như: cd gtest-1.4.0 && $(MAKE) clean
MadScientist

3
@Tader: -Ckhông có trong thông số kỹ thuật
Janus Troelsen

1
Câu hỏi này về gnu-make và -Cnằm trong spec: gnu.org/software/make/manual/make.html#Recursion
Cas

123

Thay vì -fcác makebạn có thể muốn sử dụng các -C <path>tùy chọn. Điều này đầu tiên thay đổi đường dẫn đến đường dẫn ' <path>', và sau đó gọi makeđến đó.

Thí dụ:

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
Cách này có vẻ là tốt nhất. Các câu trả lời khác được sử dụng cdkhiến thiết bị đầu cuối đi vào một vòng lặp vô hạn.
gbmhunter

$ (MAKE) -C gtest-1.4.0 / make clean không hoạt động với tôi. Tôi nghĩ nó phải là $ (MAKE) -C gtest-1.4.0 sạch
Arigion


1

Có vẻ như nó $(TESTS)trống nên makefile 1.4.0 của bạn hoạt động hiệu quả

all: 

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

Thật vậy, tất cả không có gì để làm. và clean làm đúng như những gì nó nóirm -f gtest.a ...


$ (TESTS) được định nghĩa bằng a wildcardvà a patsubst, tuy nhiên chúng trả về trống từ makefile chính, vì thư mục không được thay đổi một cách hiệu quả. Có mắt quan sát.
Chris Tonkinson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.