2009-06-20 17 views
10

Tôi đang làm việc trên dự án C++ trên GNU/Linux và tôi đang tìm cách kiểm tra sự tồn tại và khả năng sử dụng của thư viện IBM Informix với các Autotools - cụ thể là, chỉnh sửa configure.in. Tôi không có kinh nghiệm với Autotools, vì vậy về cơ bản tôi đang chọn từ dự án của configure.inet al. tập lệnh và sao chép & thay đổi nơi tôi cảm thấy cần phải thay đổi. IOW, tôi đã thích nghi từ văn bản hiện tại trong configure.in.Làm thế nào để kiểm tra khả năng sử dụng thư viện C++ trong configure.in?

Cho đến nay tôi đã sử dụng thành công AC_CHECK_LIB trong configure.in để kiểm tra xem một thư viện nhất định có tồn tại và có thể sử dụng được hay không. Nhưng điều này dường như chỉ hoạt động với các thư viện có chức năng , không phải là các lớp học. Cụ thể, điều này không thành công khi thử nghiệm libifc++.so thư viện Informix của:

AC_CHECK_LIB(ifc++, ITString, 
     INFORMIX_LIB="-L$INFORMIX_LIB_LOCATION/c++ -lifc++ -L$INFORMIX_LIB_LOCATION -L$INFORMIX_LIB_LOCATION/dmi -L$INFORMIX_LIB_LOCATION/esql -lifdmi -lifsql -lifasf -lifgen -lifos -lifgls -lifglx $INFORMIX_LIB_LOCATION/esql/checkapi.o -lm -ldl -lcrypt -lnsl", 
     echo "* WARNING: libifc++.so not found!" 
     INFORMIX_INC="" 
     INFORMIX_LIB="" 
) 

Tôi cũng đã cố gắng sử dụng các kết hợp khác, như ITString::ITString vv

tôi đã không tìm thấy một chức năng "tinh khiết" trong API Informix (tức là , một trong đó không phải là ngữ cảnh trong một lớp C++). Vì vậy, tôi hy vọng rằng có một cách để sử dụng AC_CHECK_LIB trong ngữ cảnh này hoặc có một lệnh khác là "autoconf/configure.in" cho việc sử dụng cụ thể này.

Cảm ơn trước vì đã phản hồi của bạn.

Trả lời

5

Có thể có một cách rõ ràng hơn để đạt được điều này, nhưng tôi nghĩ rằng vấn đề của bạn là các phương pháp C++ bị 'xé' để cho phép thêm thông tin về phương pháp (đối số & kiểu trả về v.v.) được mã hóa. Ví dụ; phương pháp int A::foo(void) sẽ bị xáo trộn với một cái gì đó như __ZN1A3fooEv.

Vì vậy, bạn cần phải tìm tên bị xáo trộn của phương thức trong thư viện. Bạn có thể làm điều này bằng cách sử dụng các nm command trên Unix-like OS:

$ nm libifc++.so | grep ITString 

Nó đáng nói rằng các định dạng mangling chính xác thay đổi qua các trình biên dịch khác nhau; và do đó bằng cách nhúng một biểu tượng bị xáo trộn của trình biên dịch nào đó vào số configure.in của nó, nó có thể không hoạt động trên các nền tảng khác - YMMV.

Lưu ý: bạn có thể sử dụng tiện ích c++filt để gỡ rối tên trở lại thành dạng có thể đọc được của con người; ví dụ tôi đã đưa ra trước đây:

$ c++filt __ZN1A3fooEv 
A::foo() 

Xem Name Mangling in C++ trên Wikipedia để biết thêm thông tin.

+0

trình-For-Me. Tôi đã nghĩ về việc làm một cái gì đó như thế này, nhưng nó có vẻ giống như một hack. Ví dụ, tôi không chắc chắn những gì sẽ xảy ra nếu mã được biên dịch lại với một phiên bản thư viện Informix khác (tôi mong đợi tên bị xáo trộn thay đổi). Nhưng này, nó hoạt động! :-) – jbatista

+2

Điều này sẽ tiếp tục hoạt động với phiên bản thư viện mới (giả sử tên lớp và tên phương thức không thay đổi), nhưng có thể bị hỏng nếu phiên bản trình biên dịch của bạn thay đổi và hầu như chắc chắn sẽ bị hỏng nếu ai đó cố biên dịch mã của bạn trên một mã khác phiên bản trình biên dịch hoặc trình biên dịch. –

+0

@Tyler - điểm hợp lệ; Tôi đã nhấn mạnh điều này trong câu trả lời. – DaveR

13

Bạn đã phát hiện ra một thiếu sót của các autotools, nhưng không thể thực sự được giúp đỡ. Autotools kiểm tra các tên ký hiệu trong thư viện nhị phân, và không giống như C, nơi tên biểu tượng của hàm giống hệt với tên hàm, tên biểu tượng của hàm "C++" mangles "để thực hiện những việc như quá tải hàm. Điều tệ hơn là C++ thậm chí không thực sự có quy ước mangling "chuẩn", vì vậy các trình biên dịch C++ khác nhau có thể tạo ra các tên biểu tượng khác nhau cho cùng một hàm. Do đó, autotools không thể kiểm tra tên biểu tượng C++ một cách đáng tin cậy.

Thư viện bạn đang cố sử dụng có bất kỳ chức năng nào được khai báo với extern "C" không? Điều này làm cho trình biên dịch C++ tạo ra các tên biểu tượng kiểu C tiêu chuẩn hóa và các autotools sẽ có thể tìm thấy chúng.

Tôi chạy vào vấn đề này đang cố gắng để phát hiện gtestgmock (kiểm tra đơn vị của Google và đối tượng khung chế giễu) với Autotools, và đây là những gì tôi đã đưa ra:

# gtest has a main function in the gtest_main library with C linkage, we can test for that. 
AC_CHECK_LIB([gtest_main], [main], [HAVE_GTEST=1] [TEST_LIBS="$TEST_LIBS -lgtest_main"], 
     AC_MSG_WARN([libgtest (Google C++ Unit Testing Framework) is not installed. Will not be able to make check.])) 

# gmock has no functions with C linkage, so this is a roundabout way of testing for it. We create a small test 
# program that tries to instantiate one of gmock's objects, and try to link it with -lgmock and see if it works. 
if test "$HAVE_GTEST"                 
then                     
    saved_ldflags="${LDFLAGS}"               
    LDFLAGS="${LDFLAGS} -lgtest -lgmock"             
    AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <gmock/gmock.h>], [testing::Cardinality dummy])], 
    [TEST_LIBS="$TEST_LIBS -lgmock"] [HAVE_GMOCK=1],           
    [AC_MSG_WARN([libgmock (Google C++ Object Mocking Framework) is not installed. Will not be able to make check.])]) 
    LDFLAGS="${saved_ldflags}"                       
fi   
2

Nếu thư viện bạn đang kiểm tra cho hỗ trợ pkg-config, điều này trở nên rất dễ dàng. Dưới đây là tất cả tôi thêm vào configure.in của tôi để kiểm tra và cho phép gtestgmock:

dnl ************************************ 
dnl Check for googletest and googlemock 
dnl ************************************ 

PKG_CHECK_MODULES(gtestmock, libgtest >= 0.4.0, libgmock >= 0.4.0) 
AC_SUBST(gtestmock_LIBS) 
AC_SUBST(gtestmock_CFLAGS) 

Và sau đó trong Makefile.am của tôi ở đâu đó:

sometarget_CXXFLAGS = $(gtestmock_CFLAGS) $(AM_CXXFLAGS) 
sometarget_LDADD = $(gtestmock_LIBS) 

Khá tầm thường, eh?

+0

[Có vấn đề] (http://stackoverflow.com/questions/10220946/pkg-check-modules-considered-harmful/10229811#10229811) bằng cách sử dụng pkg-config, mặc dù. Và, về cơ bản hơn, pkg-config và autotools hoạt động theo một cách khác. Autoconf kiểm tra các tính năng, trong khi kiểm tra pkg-config cho các phiên bản gói. Nếu bạn đang cố gắng làm mọi thứ theo cách tự động, điều này sẽ cho bạn khả năng tương thích tối đa trên các hệ thống, tôi sẽ không đề nghị sử dụng pkg-config. – edam