2015-11-07 99 views
0

我在編譯Ubuntu 12.04和Ubuntu 14.04上的代碼時遇到了問題。 代碼依賴於libcurl,libjsoncpp和mongo-cxx-client的傳統版本。它在Mac OS上效果很好。該代碼在Xcode上無缺陷。但是,它無法在Ubuntu上正確編譯。我已經開源了我的代碼在這裏: https://github.com/DengYiping/Shuoshuo_crawler/ 當我使用鐺編譯:GCC和Clang上的鏈接錯誤:什麼是'__tls_get_addr @@ GLIBC_2.3'

[email protected]:~/Apps/shuoshuo_crawler/shuoshuo_crawler/qqlogin$ make 
clang -c -Wall -std=c++11 -stdlib=libc++ main.cpp -pthread 
main.cpp:31:1: warning: unused label 'error_cleanup' [-Wunused-label] 
error_cleanup: 
^~~~~~~~~~~~~~ 
1 warning generated. 
clang -c -Wall -std=c++11 -stdlib=libc++ qqlogin.cpp -pthread 
clang -c -Wall -std=c++11 -stdlib=libc++ fetcher.cpp -pthread 
clang -v -Wl,--start-group -lmongoclient -lcurl -lpthread -ljsoncpp -lboost_system -lboost_thread -lboost_filesystem -lboost_program_options \-lssl -lcrypto main.o qqlogin.o fetcher.o -o qq_crawler 
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8 
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8.4 
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9 
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.3 
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1 
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8 
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.4 
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9 
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3 
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.2.1 
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9 
"/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o qq_crawler /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../.. -L/lib -L/usr/lib --start-group -lmongoclient -lcurl -lpthread -ljsoncpp -lboost_system -lboost_thread -lboost_filesystem -lboost_program_options -lssl -lcrypto main.o qqlogin.o fetcher.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o 
/usr/bin/ld: //usr/local/lib/libmongoclient.a(logstream_builder.o): undefined reference to symbol '[email protected]@GLIBC_2.3' 
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2: error adding symbols: DSO missing from command line 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make: *** [qq_crawler] Error 1 

這絕對是一個鏈接錯誤,但我沒有辦法解決它。

我的Makefile中使用鐺時:

CC=clang 
CFLAGS=-c -Wall -std=c++11 -stdlib=libc++ 
LDFLAGS= -v -Wl,--start-group -lmongoclient -lcurl -lpthread -ljsoncpp -lboost_system -lboost_thread -lboost_filesystem -lboost_program_options \-lssl -lcrypto 
EXECUTABLE=qq_crawler 

all: qq_crawler 

qq_crawler: main.o qqlogin.o fetcher.o 
     $(CC) $(LDFLAGS) main.o qqlogin.o fetcher.o -o qq_crawler 

main.o: main.cpp 
     $(CC) $(CFLAGS) main.cpp -pthread 

fetcher.o: fetcher.cpp 
     $(CC) $(CFLAGS) fetcher.cpp -pthread 

qqlogin.o: qqlogin.cpp 
     $(CC) $(CFLAGS) qqlogin.cpp -pthread 
clean: 
     rm *.o qq_crawler 

然後我嘗試使用G ++編譯,這是我的Makefile:

CC=g++-4.9 
CFLAGS=-c -Wall -std=c++11 
LDFLAGS= -v -Wl,--start-group -lmongoclient -lcurl -lpthread -ljsoncpp -lboost_system -lboost_thread -lboost_filesystem -lboost_program_options \-lssl -lcrypto 
EXECUTABLE=qq_crawler 

all: qq_crawler 

qq_crawler: main.o qqlogin.o fetcher.o 
     $(CC) $(LDFLAGS) main.o qqlogin.o fetcher.o -o qq_crawler 

main.o: main.cpp 
     $(CC) $(CFLAGS) main.cpp -pthread 

fetcher.o: fetcher.cpp 
     $(CC) $(CFLAGS) fetcher.cpp -pthread 

qqlogin.o: qqlogin.cpp 
     $(CC) $(CFLAGS) qqlogin.cpp -pthread 
clean: 
     rm *.o qq_crawler 

這就是結果。結果顯示condition_variables不可用。

g++-4.9 -c -Wall -std=c++11 main.cpp -pthread 
In file included from fetcher.hpp:22:0, 
       from main.cpp:11: 
threadtool.h:22:10: error: ‘condition_variable’ in namespace ‘std’ does not name a type 
    std::condition_variable queue_cond; 
     ^
threadtool.h: In member function ‘void threadtool::Threadsafe_queue<T>::push(T)’: 
threadtool.h:38:7: error: ‘queue_cond’ was not declared in this scope 
     queue_cond.notify_one(); 
    ^
threadtool.h: In member function ‘void threadtool::Threadsafe_queue<T>::wait_pop(T&)’: 
threadtool.h:60:7: error: ‘queue_cond’ was not declared in this scope 
     queue_cond.wait(locker,[this]{return !raw_queue.empty();}); 
    ^
threadtool.h: In member function ‘std::shared_ptr<_Tp1> threadtool::Threadsafe_queue<T>::wait_pop()’: 
threadtool.h:68:7: error: ‘queue_cond’ was not declared in this scope 
     queue_cond.wait(locker,[this]{return !raw_queue.empty();}); 
    ^
threadtool.h: At global scope: 
threadtool.h:101:10: error: ‘condition_variable’ in namespace ‘std’ does not name a type 
    std::condition_variable stack_cond; 
     ^
threadtool.h: In member function ‘void threadtool::Threadsafe_stack<T>::push(T)’: 
threadtool.h:116:7: error: ‘stack_cond’ was not declared in this scope 
     stack_cond.notify_one(); 
    ^
threadtool.h: In member function ‘void threadtool::Threadsafe_stack<T>::wait_pop(T&)’: 
threadtool.h:126:7: error: ‘stack_cond’ was not declared in this scope 
     stack_cond.wait(locker,[this]{return !raw_stack.empty();}); 
    ^
threadtool.h: In member function ‘std::shared_ptr<_Tp1> threadtool::Threadsafe_stack<T>::wait_pop()’: 
threadtool.h:134:7: error: ‘stack_cond’ was not declared in this scope 
     stack_cond.wait(locker,[this]{return !raw_stack.empty();}); 
    ^
main.cpp: In function ‘int main(int, const char**)’: 
main.cpp:31:1: warning: label ‘error_cleanup’ defined but not used [-Wunused-label] 
error_cleanup: 
^ 
make: *** [main.o] Error 1 

然後我嘗試使用clang編譯和gcc鏈接編譯的.o文件。

g++-4.9 -v -Wl,--start-group -lmongoclient -lcurl -lpthread -ljsoncpp -lboost_system -lboost_thread -lboost_filesystem -lboost_program_options \-lssl -lcrypto main.o qqlogin.o fetcher.o -o qq_crawler 
Using built-in specs. 
COLLECT_GCC=g++-4.9 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.3-5ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 4.9.3 (Ubuntu 4.9.3-5ubuntu1~14.04) 
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/ 
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../:/lib/:/usr/lib/ 
COLLECT_GCC_OPTIONS='-v' '-o' 'qq_crawler' '-shared-libgcc' '-mtune=generic' '-march=x86-64' 
/usr/lib/gcc/x86_64-linux-gnu/4.9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper -plugin-opt=-fresolution=/tmp/cc01qoam.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o qq_crawler /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. --start-group -lmongoclient -lcurl -lpthread -ljsoncpp -lboost_system -lboost_thread -lboost_filesystem -lboost_program_options -lssl -lcrypto main.o qqlogin.o fetcher.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o 
/usr/bin/ld: //usr/local/lib/libmongoclient.a(replica_set_monitor.o): undefined reference to symbol '[email protected]@GLIBC_2.2.5' 
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/libm.so: error adding symbols: DSO missing from command line 
collect2: error: ld returned 1 exit status 
make: *** [qq_crawler] Error 1 

我已經開放源代碼,我在這裏: https://github.com/DengYiping/Shuoshuo_crawler/

非常感謝您對我們的支持。

回答

2

有各種各樣的事情錯了你的makefile,都與CC = clangCC = g++-4.9

CC = clang的首要錯誤是,你正在試圖建立一個C++項目
用C編譯器。 clang是LLVM C編譯器。 clang++是LLVM C++ 編譯器。當您使用clang編譯 時,這是未定義符號引用的原因。

雖然這裏的任何錯誤,而不是原因,會議決定了生成文件 表示C編譯器爲CC和C++編譯器爲CXX,所以你 CC應該成爲CXX

同樣的C編譯器標誌由CFLAGS和C++編譯器標誌 爲CXXFLAGS表示,所以你CFLAGS應該成爲CXXFLAGS

請求POSIX線程的鏈接器選項是-pthread,而不是-lpthread。進行聯動需要

圖書館應通過可變LIBS表示,並且 其他通過LDFLAGS鏈接器選項。您不需要做出此區分,並且 在LDFLAGS中包含所有-l<libname>選項。然後,你要 你的可執行文件,配方鏈接:

$(CC) $(LDFLAGS) main.o qqlogin.o fetcher.o -o qq_crawler 

在出現的命令行,這將使所有的庫 出現之前,你的任何目標文件,從而使圖書館將 忽略和聯動將會失敗並顯示未解決的符號。在命令行 要鏈接的事物序列中,需要的東西符號定義 必須出現在提供的定義之前的東西。這就是 爲什麼你需要:

$(CC) $(LDFLAGS) main.o qqlogin.o fetcher.o -o qq_crawler $(LIBS) 

你在https://github.com/DengYiping/Shuoshuo_crawler/ 公佈的代碼,顯然不是最新的,因爲makefile中有來自你已經張貼在這裏 那些無論是不同的,尤其是指 到一個沒有源文件的目標文件downloader.o:它應該是qqlogin.o。但是,如果您發佈 代碼至少需要相同的庫的代碼,你是在談論這裏,那麼 有用於連接需要兩個庫,都 不是在你的Makefile中提到:libboost_regexlibboost_system

有在clean目標的錯誤:

clean: 
    rm *.o qq_crawler 

它應該是:

clean: 
    rm -f *.o qq_crawler 

隨着在-f之外,如果make clean在目標文件 或qq_crawler因任何原因不存在時被調用,則make clean 將失敗。

當您連接libjsoncpp您需要安裝libjsoncpp-dev, 或者自己構建並安裝庫。如果您已經安裝 libjsoncpp-dev那麼你在Ubuntu上編譯將需要包括搜索 選項:

-I/usr/include/jsoncpp 

或者,你可以在你的代碼替換#include <jsoncpp/json/json.h>#include <json/json.h>

你的makefile中沒有更多的主要缺陷。

與Ubuntu < = 15.10一起發佈的libmongo-client對於您的構建而言太舊,無法使用 。因此,您需要自己構建它,並將其安裝在/usr/local之下 或者提供編譯器選項-I/path/to/mongo/headers 和鏈接器選項-L/path/to/mongo/libs。從發佈的鏈接器 錯誤消息中,例如

/usr/bin/ld: //usr/local/lib/libmongoclient.a(logstream_builder.o): undefined reference to symbol '[email protected]@GLIBC_2.3' 

我斷定你已經發現了這一點,並安裝最新的版本 或者您需要/usr/local/下一個,這樣你就不需要爲libmongoclient-I-L選項。

您不需要使用Clang而不是GCC進行編譯。 GCC不是 任何問題的原因。

把所有這些組合起來,你可以建立在https://github.com/DengYiping/Shuoshuo_crawler/與 此生成的文件發佈的項目:

CXX=g++ 
CXXFLAGS=-c -Wall -std=c++11 -I/usr/include/jsoncpp 
LDFLAGS=-pthread 
LIBS= -lcurl -lstdc++ -lpthread -ljsoncpp -lmongoclient -lboost_thread -lboost_filesystem -lboost_program_options -lboost_regex -lboost_system 

all: qq_crawler 

qq_crawler: main.o qqlogin.o fetcher.o 
    $(CXX) $(LDFLAGS) main.o qqlogin.o fetcher.o -o qq_crawler $(LIBS) 

main.o: main.cpp 
    $(CXX) $(CXXFLAGS) main.cpp 

fetcher.o: fetcher.cpp 
    $(CXX) $(CXXFLAGS) fetcher.cpp 

qqlogin.o: qqlogin.cpp 
    $(CXX) $(CXXFLAGS) qqlogin.cpp 
clean: 
    rm -f *.o qq_crawler 

這不是一個值得稱道的makefile,但它會做。

但是,在您可以這樣做之前,您需要修復g++-4.9構建時您在threadtool.h中遇到的各種編譯錯誤 。由於threadtool.h中沒有包含標準標頭 (其中std::condition_variable已被聲明),因此導致了 ; 所以編輯threadtool.h#include <stack>後添加

#include <condition_variable> 

現在,項目將使用上面的makefile進行構建,假設所需的庫文件 已正確安裝。

最後,作爲構建進行,你會觀察到 警告的衆多事件:

warning: ‘template<class> class std::auto_ptr’ is deprecated [-Wdeprecated-declarations] 

,因爲它說,std::auto_ptr is deprecated in C++11。 這是因爲std::auto_ptr 是一個智能指針的基本上有缺陷的嘗試。棄用意味着 在未來的標準庫中會消失。您應將其從 代碼中刪除,並將其替換爲std::shared_pointerstd::unique_ptr, 或這兩者的組合。閱讀 文檔,並決定哪個替換適用於您的每個std::auto_ptr

後來

libmongoclient使用鐺用的libC++和C++ 11的實際編譯。它應該正常工作。我仍然遇到一些問題。

它將無法正常工作。您需要下載和從源代碼編譯蒙戈的客戶端(與海灣合作委員會,默認值), 並安裝到/usr/local

$ sudo apt-get install scons 
$ git clone https://github.com/mongodb/mongo-cxx-driver.git 
$ cd mongo-cxx-driver 
$ scons CXXFLAGS=-Wno-error=unused-variable 
$ sudo scons install --prefix=/usr/local 
+0

非常感謝你,代碼是在GCC下鐺正確的,但錯誤的,因爲'condition_variable'是在使用libC++而不是libstdC++進行編譯時在線程或互斥體頭文件中。這是libC++和libstdC++之間的一個小差異。使用clang ++時仍然爲glibc問題而奮鬥。我想知道你是否成功構建了這個源代碼?我會盡快發佈一個最新的Makefile。期待與您交談。非常感謝。 –

+0

libmongoclient實際上是使用clang和libC++和C++ 11編譯的。它應該正常工作。我仍然遇到一些問題。 –

+0

@ScottDeng我已經成功地構建了項目,昨天下載了我的makefile。查看更新的答案。 –