3

我的 CMake 项目使用我使用ExternalProject模块添加的gtest库。这通常有效,但是当我将项目配置为使用Clang 3.8工具链时,例如:

cmake -DCMAKE_CXX_COMPILER=clang++-3.8 ..
cmake --build .

我在Ubuntu 16.04下收到以下链接器错误:

../lib/libgtest.a(gtest-all.cc.o): In function `testing::Message::Message()':
gtest-all.cc:(.text+0x2194): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../lib/libgtest.a(gtest-all.cc.o): In function `testing::internal::edit_distance::CreateUnifiedDiff(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, unsigned long)':
gtest-all.cc:(.text+0x3596): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../lib/libgtest.a(gtest-all.cc.o): In function `testing::internal::WideStringToUtf8[abi:cxx11](wchar_t const*, int)':
gtest-all.cc:(.text+0x53d7): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../lib/libgtest.a(gtest-all.cc.o): In function `testing::internal::String::FormatIntWidth2[abi:cxx11](int)':
gtest-all.cc:(.text+0x59f8): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../lib/libgtest.a(gtest-all.cc.o): In function `testing::internal::String::FormatHexInt[abi:cxx11](int)':
gtest-all.cc:(.text+0x5ac4): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../lib/libgtest.a(gtest-all.cc.o):gtest-all.cc:(.text+0x5b80): more undefined references to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()' follow
clang: error: linker command failed with exit code 1 (use -v to see invocation)

问题似乎是gtest是使用系统范围的编译器GCC 5构建的,并且 ignores CMAKE_CXX_COMPILER。确保所有依赖项都使用相同的工具链构建的正确方法是什么?

4

2 回答 2

0

即使gtest库是用不同的 GCC 版本构建的,我也遇到了类似的问题。

您可以将一些 CMake 代码添加到项目中,以在配置阶段下载和编译库,而不是使用预编译的库。

请参阅https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project

master您可以修改CMakeLists.txt.in以获取标记版本,而不是下载分支的 HEAD 。

于 2019-06-18T16:36:06.570 回答
0

您可以将CMAKE_CXX_COMPILER值传递给ExternalProject_Add参数CONFIGURE_COMMAND,但这不可扩展。您还可以设置_GLIBCXX_USE_CXX11_ABI标志来避免这种特定的标准库不匹配——但同样——这是一个脆弱的解决方案。

最终,您希望在整个项目中为任何给定的配置使用相同的编译器。最好的方法是使用环境变量 指定编译器CXX,而不是通过 CMake 变量指定编译器CMAKE_CXX_COMPILER

export CXX=clang++-3.8
cmake ..
cmake --build .

请注意,CXX配置命令和构建命令都需要设置,因此如果您不想通过更改来污染环境,请在CXX两个命令前面加上前缀:

CXX=clang++-3.8 cmake ..
CXX=clang++-3.8 cmake --build .

(更好的是,使用ConanVcpkg等包管理器!)

于 2019-06-18T16:00:22.370 回答