Ошибка при связывании библиотеки, созданной с ExternalProject_Add, для проекта, настроенного с помощью CMAKE_CXX_COMPILER - PullRequest
3 голосов
/ 18 июня 2019

Мой проект CMake использует библиотеку gtest , которую я добавляю с помощью модуля ExternalProject . Обычно это работает, но когда я настраиваю проект для использования цепочки инструментов Clang 3.8 , например ::100100

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 голосов
/ 18 июня 2019

У меня были похожие проблемы, даже когда библиотека gtest была построена с другой версией GCC.

Вместо использования предварительно скомпилированной библиотеки вы можете добавить код CMake в ваш проект для загрузки и компиляциибиблиотека на этапе настройки.

См. https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project

Вместо загрузки заголовка ветки master вы можете изменить CMakeLists.txt.in, чтобы получить версию с тегом.

0 голосов
/ 18 июня 2019

Вы можете передать значение 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 !)

...