2013-11-22 25 views
6

EDIT: Nếu TLDR của nó, chỉ cần bỏ qua xuống dưới cùng. Nơi tôi yêu cầu: Làm cách nào để định cấu hình dự án tự động phát để sử dụng thư viện tĩnh?Định cấu hình dự án autotools với Clang khử trùng trong cấu hình lib tĩnh?

Tôi đang làm việc với một vài thư viện nguồn mở và tôi đang cố gắng chạy bộ thử nghiệm của mình dưới các chất vệ sinh của Clang. Để chạy dưới Clit khử trùng, chúng ta cần phải (1) xác định một số tùy chọn, và (2) liên kết các thư viện tĩnh từ Clang's Compiler-RT theo yêu cầu. Lưu ý: không có thư viện động hoặc đối tượng được chia sẻ.

Thiết lập tùy chọn là dễ dàng:

export DYLD_FALLBACK_LIBRARY_PATH=/usr/local/lib/clang/3.3/lib/darwin/ 
export CC=/usr/local/bin/clang 
export CXX=/usr/local/bin/clang++ 
export CFLAGS="-g3 -fsanitize=address -fsanitize=undefined" 
export CXXFLAGS="-g3 -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr" 

./configure 

Tuy nhiên, điều này sẽ tạo ra một số cảnh báo lưu trữ (khi AR đang chạy) và các lỗi liên kết (khi LD đang chạy) với các biểu tượng không xác định. Tin nhắn sẽ tương tự như:

libjpeg.a(jmemmgr.o): In function `do_sarray_io': 
/home/jwalton/jpeg-6b/jmemmgr.c:695: undefined reference to 
`__ubsan_handle_type_mismatch' 
/home/jwalton/jpeg-6b/jmemmgr.c:695: undefined reference to 
`__ubsan_handle_type_mismatch' 
/home/jwalton/jpeg-6b/jmemmgr.c:696: undefined reference to 
`__ubsan_handle_type_mismatch' 

Tôi biết các thư viện cần được liên kết. Đối với các chất vệ sinh mà tôi sử dụng, chúng là libclang_rt.asan_osx.alibclang_rt.ubsan_osx.a (hoặc libclang_rt.full-x86_64.alibclang_rt.ubsan-x86_64.a trên Linux).

Để cung cấp thư viện, tôi sau đó xuất các mục sau. Lưu ý: là LIBS và không phải là LDLIBS như mong đợi bởi hầu hết các công cụ có liên quan khác make.

export LIBS="/usr/local/lib/clang/3.3/lib/darwin/libclang_rt.asan_osx.a \ 
      /usr/local/lib/clang/3.3/lib/darwin/libclang_rt.ubsan_osx.a" 

Điều này dẫn đến một vấn đề configure của:

configure: error: cannot run C compiled programs. 
If you meant to cross compile, use `--host'. 
... 

Nhìn vào config.log, nó trông giống như hai vấn đề đang xảy ra. Đầu tiên, đường dẫn đang bị tàn sát bằng cách thay đổi từ /usr/local/... thành /Users/jwalton/....Và thứ hai, tên tập tin đang được chặt ra từng khúc bằng cách thay đổi từ một lib tĩnh để một lib động:

configure:3346: ./conftest 
dyld: Library not loaded: /Users/jwalton/clang-llvm/llvm-3.3.src/Release+Asserts/lib/clang/3.3/lib/darwin/libclang_rt.asan_osx_dynamic.dylib 
    Referenced from: /Users/jwalton/libpng-1.6.7/./conftest 
Reason: image not found 

Trong nỗ lực khác, tôi đã cố gắng sử dụng LDFLAGS:

export LDFLAGS="-L/usr/local/lib/clang/3.3/lib/darwin/" 
export LIBS="libclang_rt.asan_osx.a libclang_rt.ubsan_osx.a" 

Điều đó dẫn tới một lỗi tương tự:

configure: error: in `/Users/jwalton/libpng-1.6.7': 
configure: error: C compiler cannot create executables 

config.log:

configure:3209: /usr/local/bin/clang -g3 -fsanitize=address -fsanitize=undefined -L/usr/local/lib/clang/3.3/lib/darwin/ conftest.c libclang_rt.asan_osx.a libclang_rt.ubsan_osx.a >&5 
clang: error: no such file or directory: 'libclang_rt.asan_osx.a' 
clang: error: no such file or directory: 'libclang_rt.ubsan_osx.a' 

Và thả lib tiền tố và .a hậu tố từ LIBS kết quả trong:

configure:3209: /usr/local/bin/clang -g3 -fsanitize=address -fsanitize=undefined -L/usr/local/lib/clang/3.3/lib/darwin/ conftest.c clang_rt.asan_osx clang_rt.ubsan_osx >&5 
clang: error: no such file or directory: 'clang_rt.asan_osx' 
clang: error: no such file or directory: 'clang_rt.ubsan_osx' 

Và thêm -l để LIBS kết quả trong:

configure:3335: /usr/local/bin/clang -o conftest -g3 -fsanitize=address -fsanitize=undefined 
    -L/usr/local/lib/clang/3.3/lib/darwin/ conftest.c -lclang_rt.asan_osx -lclang_rt.ubsan_osx >&5 
configure:3339: $? = 0 
configure:3346: ./conftest 
dyld: could not load inserted library: /Users/jwalton/libpng-1.6.7/./conftest 

./configure: line 3348: 38224 Trace/BPT trap: 5  ./conftest$ac_cv_exeext 

Cuối cùng, lập luận -L là hợp lệ:

$ ls /usr/local/lib/clang/3.3/lib/darwin/ 
libclang_rt.10.4.a   libclang_rt.ios.a 
libclang_rt.asan_osx.a   libclang_rt.osx.a 
libclang_rt.asan_osx_dynamic.dylib libclang_rt.profile_ios.a 
libclang_rt.cc_kext.a   libclang_rt.profile_osx.a 
libclang_rt.cc_kext_ios5.a  libclang_rt.ubsan_osx.a 
libclang_rt.eprintf.a 

Sau tất cả nền: làm cách nào để định cấu hình dự án autotools để sử dụng thư viện tĩnh?

Điểm thưởng: tại sao có điều gì đó trở nên dễ dàng như vậy?

Trả lời

1

Phiên bản vận chuyển của GNU libtool không chuyển -fsanitize = ... đối số cho trình liên kết. Bạn sẽ cần phải cập nhật libtool với các bản vá từ http://savannah.gnu.org/patch/?8775 Cụ thể:

diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in 
index 0c40da0..b99b0cd 100644 
--- a/build-aux/ltmain.in 
+++ b/build-aux/ltmain.in 
@@ -5362,10 +5362,11 @@ func_mode_link() 
     # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization 
     # -specs=*    GCC specs files 
     # -stdlib=*   select c++ std lib with clang 
+  # -fsanitize=*   Clang memory and address sanitizer 
     -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ 
     -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ 
     -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ 
-  -specs=*) 
+  -specs=*|-fsanitize=*) 
     func_quote_for_eval "$arg" 
    arg=$func_quote_for_eval_result 
     func_append compile_command " $arg" 

Đối với nhận libtool để chấp nhận một thư viện tĩnh, bạn sẽ có thể chỉ bao gồm đường dẫn đầy đủ đến thư viện tĩnh trên dòng lệnh, hoặc bạn có thể sử dụng các tùy chọn như -L/usr/local/lib/clang/3.3/lib/darwin/ -lclang_rt.ubsan_osx. Tuy nhiên, cfe nên chăm sóc thư viện ma thuật cho bạn một khi libtool bảo nó sử dụng -fsanitize = ... để liên kết.

+0

Ah, hoàn hảo. Cảm ơn nhiều. Tôi sẽ không thực hiện những thay đổi đó, nhưng nó cho thấy rõ ràng một vấn đề của Autotools và giải pháp cho các chất khử trùng. Có lẽ họ cũng nên kiểm tra "no sanitzer". Ví dụ: tôi sử dụng thông tin sau cho 'CXXFLAGS':' -fsanitize = undefined -fno-sanitize = vptr'. – jww

+0

Nếu bạn sử dụng MacPorts, bạn chỉ có thể cài đặt cổng libtool. Nó đã có bản vá. Bạn sẽ cần chạy lại 'autoreconf' hoặc' glibtoolize' khi thích hợp trong dự án của bạn để nó nhận phiên bản mới hơn, nhưng điều đó sẽ giúp ích. –

5

Bạn cũng cần thêm -xác định cờ vào LDFLAGS.

+1

Một lưu ý nhỏ: đối với tôi khi tôi làm điều đó, «libubsan» được liên kết động mặc dù tôi đã chỉ rõ ràng liên kết nó tĩnh.Giải pháp không được sử dụng '-fsanitize' trong LDFLAGS, mà thay vào đó thêm một đường dẫn đầy đủ vào thư viện tĩnh' libubsan.a'. –

+1

@ Hi-Angel Đối với GCC, giải pháp kinh điển là sử dụng '-static-libubsan'. – yugr

0

Đối với vấn đề biểu tượng không xác định, nếu bạn đang liên kết đối tượng C++, thì bạn phải sử dụng clang++ thay vì clang. Nếu không, bạn có thể nhận được lỗi như:

/bin/bash libtool --tag=CC --mode=link clang-3.6 ... -fsanitize=undefined -o freeswitch ... 
libtool: link: clang-3.6 ... -fsanitize=undefined -o .libs/freeswitch ./.libs/libfreeswitch.so ... 
./.libs/libfreeswitch.so: undefined reference to `__ubsan_vptr_type_cache' 
./.libs/libfreeswitch.so: undefined reference to `__ubsan_handle_dynamic_type_cache_miss' 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Trong trường hợp trên, tàn bạo libtool sử dụng kêu vang thay vì kêu vang ++ vì automake nghĩ rằng bạn muốn liên kết một tập các đối tượng C (nó không hiểu rằng việc liên kết một libtool lưu trữ (libfreeswitch.la) sử dụng C++ có nghĩa là một C++ mối liên kết là cần thiết (chú ý --tag=CC). Xem thêm https://lists.debian.org/debian-mentors/2003/06/msg00004.html.

để làm việc xung quanh vấn đề này, hãy làm theo các hướng dẫn tại https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html và thêm một (dummy/thực) C++ nguồn để bạn nguồn trong số Makefile.am:

của bạn
SUBDIRS = sub1 sub2 … 
lib_LTLIBRARIES = libtop.la 
libtop_la_SOURCES = 
# Dummy C++ source to cause C++ linking. 
nodist_EXTRA_libtop_la_SOURCES = dummy.cxx 
libtop_la_LIBADD = \ 
    sub1/libsub1.la \ 
    sub2/libsub2.la \ 
    … 
Các vấn đề liên quan