将使用ExternalProject_Add构建的库链接到使用CMAKE_CXX_COMPILER配置的项目时出错

时间:2019-06-18 16:00:22

标签: c++ linux cmake clang++ external-project

我的CMake项目使用 gtest 库,该库是通过 ExternalProject 模块添加的。这通常可行,但是当我将项目配置为使用 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 构建的,并且忽略了CMAKE_CXX_COMPILER。确保所有依赖项都使用同一工具链构建的正确方法是什么?

2 个答案:

答案 0 :(得分: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 .

(最好还是使用软件包包管理器,例如 Conan Vcpkg !)

答案 1 :(得分:0)

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

除了使用预编译的库外,您还可以在项目中添加一些CMake代码,以在配置阶段下载并编译该库。

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

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