2013-11-22 57 views
6

編輯:如果它的TLDR,只是跳到底部。其中我問:如何配置autotools項目使用靜態庫?在靜態庫配置中使用Clang消毒器配置autotools項目?

我正在和幾個開源庫一起工作,我試圖在Clang的衛生消毒劑下運行他們的測試套件。要在Clang消毒器下運行,我們需要(1)指定一些選項,並(2)根據需要鏈接來自Clang的Compiler-RT的靜態庫。 注意:沒有動態庫或共享對象。

設置選項很簡單:

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 

但是,這會產生一些存檔警告(當AR運行),並鏈接錯誤(當LD運行)與未定義的符號。該消息將類似於:

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' 

我知道需要鏈接的庫。對於我使用的消毒殺菌劑,它們是libclang_rt.asan_osx.alibclang_rt.ubsan_osx.a(或在Linux上爲libclang_rt.full-x86_64.alibclang_rt.ubsan-x86_64.a)。

爲了提供庫,我然後導出以下內容。 注意:它是LIBS,而不是LDLIBS正如大多數其他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" 

這導致的問題configure

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

看着config.log,它看起來像兩個問題發生。首先,路徑被從/usr/local/...更改爲/Users/jwalton/...。第二,文件名是由從靜態庫轉變到動態的lib屠殺:

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 

在另一種嘗試,我嘗試使用LDFLAGS

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

導致類似的錯誤:

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' 

而且從LIBS結果丟棄lib前綴和.a後綴:

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' 

而且在加入-lLIBS結果:

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 

最後,-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 

畢竟背景:我如何配置一個autotools項目來使用靜態庫?

加分:爲什麼有這麼容易的事情變得如此困難?

回答

1

發貨版本的GNU libtool不會向鏈接器傳遞-fsanitize = ...參數。您將需要從http://savannah.gnu.org/patch/?8775具體更新補丁的libtool:

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" 

至於讓libtool來接受靜態庫,你應該能夠只包括在命令行上的完整路徑,靜態庫,或您可以使用像-L/usr/local/lib/clang/3.3/lib/darwin/ -lclang_rt.ubsan_osx這樣的選項。然而,一旦libtool告訴它使用-fsanitize = ...進行鏈接,cfe應該爲您處理庫魔術。

+0

啊,完美。非常感謝你。我不會做出這些改變,但它清楚地顯示了它的一個Autotools問題和衛生消毒劑的解決方案。他們也許應該檢查「沒有衛生間」。例如,我對'CXXFLAGS'使用以下內容:'-fsanitize = undefined -fno-sanitize = vptr'。 – jww

+0

如果您使用MacPorts,則只需安裝libtool端口即可。它已經有了補丁。您需要在項目中適當地重新運行'autoreconf'或'glibtoolize'來獲取更新的版本,但這會有所幫助。 –

5

您還需要爲LDFLAGS添加-fsanitize標誌。

+1

有一點值得注意:對我來說,當我做到這一點時,即使我明確指出靜態鏈接它,動態鏈接「libubsan」。解決方案不是在LDFLAGS中使用'-fsanitize',而是在靜態庫'libubsan.a'中添加完整路徑。 –

+1

@ Hi-Angel對於GCC,規範的解決方案是使用'-static-libubsan'。 – yugr

0

至於未定義的符號問題,如果您要鏈接C++對象,那麼您必須使用clang++而不是clang。否則,你可以得到錯誤,如:

/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) 

在上述情況下,殘暴libtool使用鐺的鐺代替++因爲automake以爲你想要把一組C對象(不明白,鏈接一個libtool的用C++歸檔(libfreeswitch.la)意味着需要一個C++連接(注意--tag=CC)也https://lists.debian.org/debian-mentors/2003/06/msg00004.html見。

要解決此問題,請按照指示在https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html並添加(虛擬/真實)C++源到您的消息來源Makefile.am

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 \ 
    …