2013-11-27 25 views
8

Tôi đang làm việc trên dự án C++ sử dụng autoconf & automake và tôi đang cố gắng thiết lập chính xác đường dẫn bao gồm trong *CPPFLAGS. Tôi đã đọc tài liệu trị giá khoảng 3 giờ và tôi chưa thể tìm ra được. Tôi không tìm kiếm một hack, nhưng đối với cách chính xác để làm điều này. Đây là câu hỏi hóc búa của tôi.cách đặt bao gồm đường dẫn bằng tự động

Như tôi đã nhìn thấy nó, có 3 nguồn hoàn toàn khác nhau cho bao gồm đường dẫn:

  1. thư viện bên ngoài mà phải được cài đặt cùng với gói của tôi, mà được cấu hình bởi configure --with-XXX=<PATH>.
  2. Trong gói của tôi, một số tệp nguồn sử dụng #include <file.h> ngay cả khi file.h là một phần của gói, do đó, để biên dịch chúng, tôi phải đặt đường dẫn bao gồm chính xác. (Lưu ý, đó không phải là tùy chọn để chỉnh sửa tất cả các tệp này.)
  3. Các tiêu chuẩn hay thay đổi (hay không) chỉ định người dùng phải được phép chỉ định đường dẫn riêng của họ. Đó là, tôi không nên thiết lập CPPFLAGS ở tất cả.

Trong thiết lập hiện tại của tôi:

  • Loại 1 đường dẫn được thiết lập bên trong configure.ac bởi AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>").
  • Đường dẫn loại 2 được đặt bên trong Makefile.am theo test_CPPFLAGS = -I<path>.
  • Không thể đặt loại 3. Chính xác hơn, nếu người dùng đặt CPPFLAGS trước khi chạy make, điều này sẽ ghi đè cài đặt Loại 1, làm cho quá trình biên dịch thất bại. Tất nhiên, người dùng có thể thử sử dụng CXXFLAGS thay vào đó, nhưng người dùng đó có cách sử dụng khác (hãy nhớ, tôi yêu cầu cách chính xác để thực hiện việc này, không phải là hack).

Tôi đã cố khắc phục điều này bằng cách đặt đường dẫn Loại 1 sử dụng AM_CPPFLAGS bên trong configure.ac. (Để tham khảo: nếu bạn đặt AM_CPPFLAGS thay vì CPPFLAGS, nhưng bạn vẫn cần chạy một số kiểm tra chẳng hạn như AC_CHECK_HEADERS, bạn cần tạm thời đặt CPPFLAGS và sau đó hoàn nguyên để kiểm tra hoạt động; điều này được giải thích here.) Điều này giải phóng CPPFLAGS đối với đường dẫn Loại 3, nhưng tiếc là quá trình biên dịch không thành công do Makefile -s được sản xuất bởi configure sẽ chỉ sử dụng AM_CPPFLAGS nếu không có <target>_CPPFLAGS chuyên biệt nào tồn tại. Vì vậy, nếu test_CPPFLAGS tồn tại với đường dẫn Loại 2, biên dịch test sẽ không thành công vì nó không có đường dẫn Loại 1.

Sửa chữa sẽ chỉ định bên trong Makefile.am để luôn sử dụng AM_CPPFLAGS. Nhưng đây có phải là "bởi cuốn sách" không? Tôi có thể làm điều này một cách toàn cầu hay tôi phải chỉnh sửa từng đơn target_CPPFLAGS? Có một giải pháp "chính xác" nào khác không?

+0

Bằng cách "hay thay đổi", bạn có bao gồm tài liệu tự động chính thức nêu rõ rằng CPPFLAGS là biến người dùng không nên được sửa đổi bởi người duy trì không? (Xem phần 4.8.1 tại http://www.gnu.org/software/autoconf/manual/autoconf.html) –

+0

Mặc dù một ví dụ ít mơ hồ hơn từ tài liệu tự động chính thức có thể rõ ràng hơn, trong đó nêu rõ "Bạn không bao giờ nên xác định lại biến người dùng như CPPFLAGS trong Makefile.am. " trong phần 27.6 tại http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html#Flag-Variables-Ordering –

Trả lời

18

Tôi biết rất khó để có được câu trả lời thẳng từ sách hướng dẫn tự động. Có một số hướng dẫn bắt đầu hoàn thành tốt herehere.

Không có biến chuẩn cho gói cụ thể *CPPFLAGS trong tự động định cấu hình. configure có thể được gọi với CPPFLAGS=... và tự động thêm số này CPPFLAGS vào các quy tắc makefile có liên quan - tìm kiếm CPPFLAGS trong một tệp Makefile.in để biết ví dụ.Vì lý do đó, tôi đề nghị bạn không phải sử dụng biến này cho bất kỳ thứ gì khác.

Thêm cờ trong Makefile.am vào biến số AM_CPPFLAGS (mặc định cho tất cả cuộc gọi preprocessor) hoặc ghi đè cờ tiền xử lý riêng lẻ với target_CPPFLAGS. Trong ví dụ của một thư viện của bên thứ 3, cách tốt nhất là sử dụng một cái tên như: FOO_CPPFLAGS giữ tùy chọn tiền xử lý, ví dụ như,

FOO_CPPFLAGS="-I${FOO_DIR}/include -DFOO_BAR=1" 
... 
AC_SUBST(FOO_CPPFLAGS) 

và trong Makefile.am:

AM_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS) 
# or: 
target_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS) 

Biến top_srcdir được xác định bởi configure - Tôi sử dụng nó để minh họa cho trường hợp thứ 2. Giả sử bạn có file.h trong một thư mục khác other, trong thư mục cấp cao nhất. -I$(top_srcdir) cho phép bạn bao gồm nó là <other/file.h>. Ngoài ra, -I$(top_srcdir)/other sẽ cho phép bạn bao gồm nó là <file.h>.

Một số hữu ích preset variable khác là srcdir - thư mục hiện tại. -I$(srcdir) được thêm vào AM_CPPFLAGStheo mặc định. Vì vậy, nếu file.h nằm trong thư mục hiện tại, bạn có thể bao gồm nó với <file.h> hoặc thậm chí "file.h". Nếu other là thư mục 'anh chị em', -I$(srcdir)/.. sẽ cho phép bạn bao gồm <other/file.h>-I$(srcdir)/../other sẽ cho phép <file.h>.


Tôi cũng sẽ thêm một số gói cài đặt tệp pkg-config .pc. Với việc cài đặt pkg-config được thiết lập để tìm kiếm đúng thư mục, bạn có thể thấy macro PKG_CHECK_MODULES rất hữu ích.

+2

Loại khác là '$ (builddir)' hoặc '$ (top_builddir) 'có vẻ như được sử dụng cho bất kỳ tệp nào được tạo trong quá trình xây dựng. – CMCDragonkai

Các vấn đề liên quan