2008-11-26 40 views
21

Tôi đang sử dụng (GNU) Tạo trong dự án của mình. Tôi hiện đang đặt một makefile cho mỗi thư mục và chỉ định các thư mục con bằng cách sử dụng SUBDIRS. Nó được đề nghị với tôi rằng đây không phải là cách lý tưởng để sử dụng make, mà sử dụng một cái để làm cho một tập tin (hoặc một số, chia nhỏ bằng cách sử dụng bao gồm). Tôi đã cố gắng di chuyển/sử dụng bố cục này trong quá khứ, nhưng nó xuất hiện với tôi rằng nó không cần thiết phức tạp.Đệ quy Làm bạn - hay kẻ thù?

Lợi ích/hạn chế của việc sử dụng các tệp dữ liệu đệ quy là gì?

Trả lời

22

Điều đầu tiên bạn nên ghi nhớ (chỉ để loại bỏ bất kỳ sự hiểu lầm nào) là chúng ta không nói về một đơn so với nhiều makefiles. Việc tách tập tin makefile của bạn thành một trong mỗi thư mục con có lẽ là một ý tưởng hay trong mọi trường hợp.

Tệp đệ quy đệ quy là chủ yếu do bạn phân đoạn cây phụ thuộc của bạn thành nhiều cây. Điều này ngăn cản sự phụ thuộc giữa các trường hợp làm cho việc thể hiện chính xác. Điều này cũng gây ra (các phần của) cây phụ thuộc được tính toán lại nhiều lần, đó là vấn đề hiệu suất cuối cùng (mặc dù thường không phải là vấn đề lớn.)

Có một vài thủ thuật bạn cần sử dụng để sử dụng đúng cách tiếp cận đơn, đặc biệt khi bạn có một cơ sở mã lớn:

Đầu tiên, hãy sử dụng GNU (bạn đã làm, tôi thấy). GNU tạo ra một số tính năng đơn giản hóa mọi thứ, và bạn sẽ không phải lo lắng về sự tương thích.

Thứ hai, sử dụng giá trị biến mục tiêu cụ thể.Điều này sẽ cho phép bạn có, ví dụ, các giá trị khác nhau của CFLAGS cho các mục tiêu khác nhau, thay vì buộc bạn phải có một CFLAGS duy nhất trong toàn bộ làm cho bạn:

main: CFLAGS=-O2 
lib: CFLAGS=-O2 -g 

Thứ ba, chắc chắn rằng bạn sử dụng VPATH/vpath đến mức độ đầy đủ được hỗ trợ bởi GNU.

Bạn cũng muốn đảm bảo rằng bạn không có nhiều tệp nguồn có cùng tên. Một hạn chế của VPATH là nó không cho phép bạn có các định nghĩa VPATH mục tiêu cụ thể, do đó tên của các tệp nguồn của bạn sẽ phải cùng tồn tại trong một "không gian tên VPATH" duy nhất.

+0

Câu trả lời hay, cảm ơn! Tôi đang thực sự sử dụng VPATH ngay cả đối với một dự án sử dụng đệ quy làm cho các tập tin, nó làm cho dễ dàng hơn rất nhiều, đặc biệt là cho srcdir! = Builddir xây dựng. –

0

Lợi ích mà tôi đã nhận được từ điều này trong quá khứ là việc tạo tệp trong một thư mục con dễ dàng hơn. Bạn có thể làm điều này với các phụ thuộc, nhưng đó là một chút công việc để giữ cho tất cả các mục tiêu thẳng. Về cơ bản, điều này làm cho nó dễ dàng hơn để thực hiện thay đổi và kiểm tra một thư viện mà không cần phải đối phó với sự phức tạp đầy đủ của dự án lớn hơn.

+0

Bạn nói đúng. Việc tái sử dụng các mục tiêu chung dễ dàng hơn là một lợi thế khác –

-1

Vấn đề với việc tạo đệ quy là thời gian trên đầu của việc đánh giá tất cả các tệp tạo khác nhau so với việc đánh giá một tệp lớn tạo. Một phần của điều này chỉ là các quá trình sinh sản mà còn (IIRC) bạn có xu hướng bị buộc phải giả định rằng các tệp khác làm cho một cái gì đó và xây dựng lại khi bạn không thực sự cần.

Việc thực hiện của tôi là tạo một tệp đơn cho mỗi "Đơn vị", số tiền nhiều hơn hoặc ít hơn để tạo tệp cho mỗi đoạn mã mà bạn mong đợi có thể được sử dụng trên riêng nó (ví dụ như thư viện độc lập))

OTOH dự án hiện tại của tôi sẽ phá vỡ tất cả những nơi này khi tôi tạo tệp trong khi tạo. : b

+1

Không, thời gian không phải là vấn đề lớn nhất. Vấn đề lớn nhất là phân vùng cây phụ thuộc thành một số cây phụ thuộc, ngăn cản bạn thể hiện sự phụ thuộc đúng cách giữa các công cụ phụ. – JesperE

+3

IMNSHO lý do duy nhất bạn thậm chí quan tâm đến các phụ thuộc ở tất cả * là * thời gian. Nếu bạn không quan tâm về thời gian, chỉ cần làm một từ đầu, trống đá phiến xây dựng lại mỗi lần. Bạn có thể nhận được phụ thuộc "chính xác" được thể hiện bằng cách mã hóa vì vậy nếu bất cứ điều gì thay đổi, nó giả định rằng tất cả mọi thứ thay đổi, nhưng phải mất nhiều thời gian hơn. – BCS

17

Bài viết có tựa đề "Đệ quy được coi là có hại" có thể tìm thấy tại đây: http://miller.emu.id.au/pmiller/books/rmch/?ref=DDiyet.Com. (Hoặc tại dự án Aegis tại SourceForge.)

Khám phá các vấn đề với makefiles đệ quy và đề xuất phương pháp tiếp cận một lần.

+0

Đó là một tài liệu tham khảo tốt, cảm ơn bạn đã chỉ ra nó. –

+0

Thật không may, liên kết đến giấy thực tế đang đưa ra 500. –

+0

Liên kết tới giấy dường như ổn. –

0

Để ném tùy chọn thứ ba, bạn có thể sử dụng GNU Autotools. Chủ yếu được sử dụng vì các lý do khác, nhưng cũng có thể hữu ích trong việc tổ chức xây dựng nhiều thư mục.

http://www.lrde.epita.fr/~adl/autotools.html

Nó phải được lưu ý, mặc dù, rằng kết quả là một phiên bản đệ quy.

+0

Tôi thực sự đang sử dụng các autotools, nhưng bạn có thể sử dụng cả chế độ đệ quy và không đệ quy. –

4

Chạy, đừng đi bộ, đến cmake.org và nhận Cmake, một trong những công cụ xây dựng tốt nhất hiện có.

Bạn vẫn sẽ sử dụng GNU, nhưng trong trường hợp này, CMake sẽ tạo các tệp makefiles cho bạn.

Tôi không thể đảm bảo 100%, nhưng tôi chưa bắt gặp trường hợp nó không xử lý chính xác các phụ thuộc giữa các thư mục con một cách chính xác (tức là vấn đề gây ra việc đệ quy). Ít nhất thì việc duy trì Cmakefiles dễ dàng hơn rất nhiều so với makefiles. Rat khuyen khich.

Không sử dụng GNU autotools - theo cách điên rồ đó!

+1

Tôi đã biết GNU autotools quá tốt và tôi đang ngày càng già để tìm hiểu một hệ thống mới. Có thể trong 5 năm nữa :-) –

+3

CMake xứng đáng với nỗ lực cần thiết để học. Nó dễ dàng hơn nhiều so với Autotools, và nó hỗ trợ đa nền tảng tốt hơn nhiều. –

+8

Tôi đã tìm thấy việc tạo ra một đường cong học tập nông hơn nhiều so với CMake. Cú pháp của CMake liên tục, tài liệu là khủng khiếp, và cuối cùng nó vẫn không thể tự động tìm các vị trí của các thư viện phổ biến bị tấn công trên các hệ thống, vì vậy bạn liên tục tìm kiếm các kịch bản lệnh "FindLibraryXYZ.CMake". dự án. Không có gì thanh lịch về nó, vì vậy chỉ sử dụng nó nếu bạn thực sự cần nó. Xin lỗi cho rant. –

1

Makepp là bạn của bạn.

http://makepp.sourceforge.net/

  • Tương thích ngược với make
  • tự động quét phụ thuộc tiêu đề
  • xử lý Graceful cây thư mục
5

tôi sử dụng đệ quy rộng rãi. mỗi nút lá sẽ có một tệp makefile riêng của mình, hãy xem xét:

$LIBS = libfoo libbar 
$(LIBS): 
    cd [email protected] && $(MAKE) 

Trên các hệ thống lớn, sẽ là một thách thức nếu không có cấu trúc này. Những gì folks nói về "đệ quy làm cho có hại" là một đánh giá chính xác. Tôi nghĩ rằng mỗi tình huống có một chút khác biệt và chúng tôi thực hiện một số thỏa hiệp.