在GCC和Clang上链接错误:什么是'__tls_get_addr @@ GLIBC_2.3'

时间:2015-11-07 00:03:23

标签: c++ mongodb compiler-errors linker

我无法在Ubuntu 12.04和Ubuntu 14.04上编译代码。 代码依赖于libcurl,libjsoncpp和mongo-cxx-client的旧版本。它在Mac OS上运行良好。该代码在Xcode上没有bug。但是,它无法在Ubuntu上正确编译。我在这里开源代码: https://github.com/DengYiping/Shuoshuo_crawler/ 当我使用clang编译时:

scott@Harold:~/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 '__tls_get_addr@@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

这绝对是一个链接器错误,但我无法对其进行故障排除。

使用clang时的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 'ceilf@@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/

非常感谢您的支持。

1 个答案:

答案 0 :(得分:2)

您的makefile存在各种问题,包括CC = clang和。{ CC = g++-4.9

CC = clang最重要的错误是你正在尝试构建一个C ++项目 用C编译器。 clang是LLVM C编译器。 clang++是LLVM C ++ 编译器。这是你的未定义符号引用的原因 用clang编译。

虽然这里不是任何错误的原因,但惯例规定了makefile 将C编译器表示为CC,将C ++编译器表示为CXX,所以你的 CC应该成为CXX

同样,C编译器标志由CFLAGS和C ++编译器标志表示 为CXXFLAGS,因此CFLAGS应成为CXXFLAGS

请求POSIX线程的链接器选项是-pthread,而不是-lpthread

链接所需的库应该由变量LIBS表示,并且 LDFLAGS其他链接器选项。你没有做出这种区分 在-l<libname>中添加所有LDFLAGS个选项。然后你想链接 您的可执行文件与食谱:

$(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 cleanqq_crawler因任何原因而不存在make clean 会失败。

当你链接libjsoncpp时,你需要安装libjsoncpp-dev, 或者自己构建和安装库。如果你已安装 libjsoncpp-dev然后你在Ubuntu上的编译将需要include-search 选项:

-I/usr/include/jsoncpp

或者,您可以在代码中将#include <json/json.h>替换为#include <jsoncpp/json/json.h>

makefile中没有更多重大缺陷。

与Ubuntu&lt; = 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 '__tls_get_addr@@GLIBC_2.3'

我的结论是你已经发现了这个并安装了当前版本 版本或/usr/local/下您需要的版本,因此您不需要 -I的{​​{1}}或-L选项。

您无需使用Clang而不是GCC进行编译。海湾合作委员会不是 任何问题的原因。

将所有这些组合在一起,您可以构建在https://github.com/DengYiping/Shuoshuo_crawler/发布的项目 这个makefile:

libmongoclient

这不是一个值得称赞的makefile,但它会做。

然而,在您可以这样做之前,您需要修复各种编译错误 在使用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 构建时遇到threadtool.h。这些都是造成的 事实上,在g++-4.9中你没有包含标准标题 其中声明了std::condition_variable; 所以编辑threadtool.h并添加

threadtool.h

#include <condition_variable> 之后。

现在,项目将使用上面的makefile构建,假设所需的库 适当安装。

最后,随着构建的进行,您将观察到多次出现 警告:

#include <stack>

正如它所说,std::auto_ptr is deprecated in C++11。 那是因为warning: ‘template<class> class std::auto_ptr’ is deprecated [-Wdeprecated-declarations] 智能指针是一个根本上有缺陷的尝试。弃用意味着 在未来的标准库中,它将消失。你应该把它从你的 代码并用std::shared_pointer替换它 或std::unique_ptr, 或两者的结合。阅读 文档并确定哪个替换适合您的std::auto_ptr

<强>后来

  

libmongoclient实际上是使用clang与libc ++和c ++ 11编译的。它应该正常工作。我还是面临一些问题。

它无法正常工作。您需要从源代码下载和构建mongo-client(默认使用GCC), 并安装到std::auto_ptr

/usr/local