我无法在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/
非常感谢您的支持。
答案 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_regex
和libboost_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上的编译将需要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