2010-11-14 5 views
6

Tôi không biết nhiều thứ makefile tôi đã có xu hướng tìm hiểu bit theo yêu cầu.gmake lấy danh sách các tập tin đối tượng từ nhiều thư mục

Sự thất bại lớn nhất của makefiles của tôi là tôi đã liệt kê tất cả các tệp theo cách thủ công, trong khi đây không phải là vấn đề mà dự án hiện tại của tôi đang trở nên khó sử dụng. Tôi có 4 thư mục mỗi tệp nguồn.

Làm cách nào để có được tất cả danh sách tệp đối tượng mà không phải liệt kê chúng theo cách thủ công.

Điều này không hiệu quả, nhưng nó cho thấy những gì tôi đang cố gắng làm.

VPATH = Lib GameCode Moot/Moot Moot/Impl 

OBJS = $(subst .cpp, .o, $(VPATH)) 

foobar: $(OBJS) 
    g++ -o [email protected] $^ 

%.o: %.cpp 
    g++ -c $< -o [email protected] -I Moot 

clean: 
    rm main.o lib.o foo.o foobar 

Trả lời

5

Cá nhân, tôi chưa bao giờ gặp vấn đề gì trong việc liệt kê tất cả các tệp theo cách thủ công. Việc liệt kê một tệp vào tệp makefile mất thời gian không đáng kể so với việc thêm nó vào với nội dung hữu ích.

Để nhận tất cả các tệp từ các thư mục khác nhau, người ta có thể đề xuất sử dụng wildcard function. Vì vậy, my_sources:=$(wildcard *.cpp dir1/*.cpp) sẽ làm cho biến chứa tệp nguồn khớp với biểu thức ký tự đại diện.

Tuy nhiên, tôi thấy nó kém thuận lợi hơn so với sử dụng thông thường lệnh Linux find qua shell:

# Find all sources 
my_sources:=$(shell find -iname '*.cpp') 
# Make targets out of them 
OBJS=$(my_sources:%.cpp=%.o) 

Find là mạnh mẽ hơn Hãy chắc của BUILTIN wildcard. Bạn cũng có thể muốn sử dụng các khả năng vỏ khác, chẳng hạn như đường ống, ví dụ, để lọc đầu ra của find (nếu chức năng của Make là filter-out là không đủ). Hoặc một cái gì đó như thế này, để tránh các biến quá mức:

OBJS:=$(shell find -iname '*.cpp' | sed 's/\.cpp$/.o/') 

Bạn đặt tên cho nó!

+0

Trên OS X, bạn phải thêm thư mục hiện tại sau lệnh tìm. Ví dụ: 'tìm. - tên '* .cpp''. – deepak

0

Sử dụng VPATH hoặc vpath sẽ không hoạt động cho vấn đề của bạn .. nó cung cấp đường dẫn tìm kiếm để tìm tệp nhưng bạn vẫn cần phải liệt kê các tệp. Nếu bạn chỉ cần biên dịch tất cả và bất kỳ .c/file cpp tìm thấy trong những thư mục sau đó điều này sẽ làm việc:

foobar: $(shell ls Lib/*.cpp) $(shell ls GameCode/*.cpp) $(shell ls Moot/Moot/*.cpp) $(shell ls Moot/Impl/*cpp) 
    g++ -o [email protected] $^ 

clean: 
    rm foobar $(shell ls Lib/*.o) $(shell ls GameCode/*.o) $(shell ls Moot/Moot/*.o) $(shell ls Moot/Impl/*o) 

Thông báo thông tin VPATH là không cần thiết, việc thay thế .o cho cpp có thể đi như thể ghi đè quy tắc ngầm. Ngoài ra, không sử dụng ls thay vì tìm kiếm để xem xét, và chỉ trong, các thư mục specfified.