ld: символы не найдены для архитектуры x86_64, clang: команда компоновщика не удалась

Я пытаюсь использовать homebrew для загрузки и сборки таких пакетов, как boost, ceres-solver и тому подобное. Что происходит, так это то, что я пытаюсь скомпилировать код без каких-либо специальных флагов (g++ foo.cpp -o foo -I /usr/local/..., и я тоже пробовал clang++), и я постоянно получаю эту ошибку:

Undefined symbols for architecture x86_64:
  ...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Итак, я осмотрелся, и решение состоит в том, чтобы использовать флаг -stdlib=libstdc++. Я попробовал, и теперь он выдает мне ошибки, связанные с тем, что Apple поставляет старую версию libstdc++, не исправляется вызовом -std=c++11 или -std=c++14. Он вызывает возражения против синтаксиса C++11, такого как shared_ptr:

/usr/local/include/ceres/internal/port.h:62:12: error: no member named
      'shared_ptr' in namespace 'std'
using std::shared_ptr;
      ~~~~~^
...
/usr/local/include/ceres/solver.h:629:15: error: expected member name or ';'
      after declaration specifiers
    shared_ptr<ParameterBlockOrdering> inner_iteration_ordering;
    ~~~~~~~~~~^
5 errors generated.

Я бы предпочел не редактировать исходный код библиотеки, если в этом нет необходимости, я надеюсь, что разработчики проделали довольно хорошую работу?

Есть ли способ создать библиотеки (с доморощенным пивом или без него), которые дадут правильную ссылку? В настоящее время я просто brew install <package> я пропустил что-то очевидное? Или я что-то напортачил при компиляции самого кода?

У меня Mac OS X 10.10.5, и brew --config дает следующее:

HOMEBREW_VERSION: 0.9.5
ORIGIN: https://github.com/Homebrew/homebrew
HEAD: 03ad27453de01adc29cbf941bd29a2dfb54a9960
Last commit: 69 minutes ago
HOMEBREW_PREFIX: /usr/local
HOMEBREW_REPOSITORY: /usr/local
HOMEBREW_CELLAR: /usr/local/Cellar
HOMEBREW_BOTTLE_DOMAIN: https://homebrew.bintray.com
CPU: 8-core 64-bit ivybridge
OS X: 10.10.5-x86_64
Xcode: 6.4
CLT: 6.4.0.0.1.1435007323
Clang: 6.1 build 602
X11: N/A
System Ruby: 2.0.0-p481
Perl: /usr/bin/perl
Python: /usr/local/bin/python => /Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
Ruby: /usr/bin/ruby
Java: N/A

Запуск $arch дает: i386

и $clang++ -v дает:

Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

Я должен добавить, что я пытался очистить свой компьютер на случай, если там была старая версия или что-то испорченное. Все, что я видел, говорит о том, что эта ошибка вызвана неправильной компоновкой во время сборки, но похоже, что brew делает большую часть этого правильно, по крайней мере, насколько я могу судить? Все устанавливается и собирается нормально.

Я установил gcc с помощью brew и попытался скомпилировать библиотеку с помощью команд g++-5 и gcc-5, чтобы избежать лязга, и у меня возникает та же проблема, когда я пытаюсь передать флаг -std=c++11 во время компиляции — g++-5 foo.cpp -o foo -I /usr/local/bar -std=c++11. Ни один из них не работает.

Я также должен подчеркнуть, что это происходит, когда я пытаюсь скомпилировать и запустить примеры сценариев, которые поставляются, например, с boost, даже не мои собственные сценарии. Я просто надеюсь, что библиотеки, по крайней мере, в основном правильные.

Я также просмотрел здесь много подобных вопросов, многие из них остались без ответа, а те, у которых есть решения, ну, я пробовал многие решения, и они тоже не помогают. Пробовал -lstdc++.6, пробовал -stdlib=libstdc++. -l ничего не меняет, -stdlib вызывает проблемы, описанные выше.

Любая помощь, которую я могу получить, была бы отличной, я работаю над этим уже несколько недель, и это сводит меня с ума.

Быстрое редактирование для ясности:

Итак, когда я ввожу:

$g++ cerestest.cpp -o ceres -I /usr/local/include/eigen3

or

$clang++ cerestest.cpp -o ceres -I /usr/local/include/eigen3

Я получил:

Undefined symbols for architecture x86_64:
  "ceres::Solve(ceres::Solver::Options const&, ceres::Problem*, ceres::Solver::Summary*)", referenced from:
      _main in cerestest-ef733e.o
  "ceres::Solver::Summary::Summary()", referenced from:
      _main in cerestest-ef733e.o
  "ceres::Problem::AddResidualBlock(ceres::CostFunction*, ceres::LossFunction*, double*)", referenced from:
      _main in cerestest-ef733e.o
  "ceres::Problem::Problem()", referenced from:
      _main in cerestest-ef733e.o
  "ceres::Problem::~Problem()", referenced from:
      _main in cerestest-ef733e.o
  "google::LogMessage::stream()", referenced from:
      ceres::AutoDiffCostFunction<CostFunctor, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>::AutoDiffCostFunction(CostFunctor*) in cerestest-ef733e.o
      ceres::internal::AutoDiff<CostFunctor, double, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>::Differentiate(CostFunctor const&, double const* const*, int, double*, double**) in cerestest-ef733e.o
      void ceres::internal::Make1stOrderPerturbation<ceres::Jet<double, 1>, double, 1>(int, double const*, ceres::Jet<double, 1>*) in cerestest-ef733e.o
      void ceres::internal::Take0thOrderPart<ceres::Jet<double, 1>, double*>(int, ceres::Jet<double, 1> const*, double*) in cerestest-ef733e.o
      void ceres::internal::Take1stOrderPart<ceres::Jet<double, 1>, double, 0, 1>(int, ceres::Jet<double, 1> const*, double*) in cerestest-ef733e.o
  "google::LogMessageFatal::LogMessageFatal(char const*, int)", referenced from:
      void ceres::internal::Make1stOrderPerturbation<ceres::Jet<double, 1>, double, 1>(int, double const*, ceres::Jet<double, 1>*) in cerestest-ef733e.o
      void ceres::internal::Take0thOrderPart<ceres::Jet<double, 1>, double*>(int, ceres::Jet<double, 1> const*, double*) in cerestest-ef733e.o
      void ceres::internal::Take1stOrderPart<ceres::Jet<double, 1>, double, 0, 1>(int, ceres::Jet<double, 1> const*, double*) in cerestest-ef733e.o
  "google::LogMessageFatal::LogMessageFatal(char const*, int, google::CheckOpString const&)", referenced from:
      ceres::AutoDiffCostFunction<CostFunctor, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>::AutoDiffCostFunction(CostFunctor*) in cerestest-ef733e.o
      ceres::internal::AutoDiff<CostFunctor, double, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>::Differentiate(CostFunctor const&, double const* const*, int, double*, double**) in cerestest-ef733e.o
  "google::LogMessageFatal::~LogMessageFatal()", referenced from:
      ceres::AutoDiffCostFunction<CostFunctor, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>::AutoDiffCostFunction(CostFunctor*) in cerestest-ef733e.o
      ceres::internal::AutoDiff<CostFunctor, double, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>::Differentiate(CostFunctor const&, double const* const*, int, double*, double**) in cerestest-ef733e.o
      void ceres::internal::Make1stOrderPerturbation<ceres::Jet<double, 1>, double, 1>(int, double const*, ceres::Jet<double, 1>*) in cerestest-ef733e.o
      void ceres::internal::Take0thOrderPart<ceres::Jet<double, 1>, double*>(int, ceres::Jet<double, 1> const*, double*) in cerestest-ef733e.o
      void ceres::internal::Take1stOrderPart<ceres::Jet<double, 1>, double, 0, 1>(int, ceres::Jet<double, 1> const*, double*) in cerestest-ef733e.o
  "google::InitGoogleLogging(char const*)", referenced from:
      _main in cerestest-ef733e.o
  "google::base::CheckOpMessageBuilder::ForVar2()", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, int>(int const&, int const&, char const*) in cerestest-ef733e.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, ceres::DimensionType>(int const&, ceres::DimensionType const&, char const*) in cerestest-ef733e.o
  "google::base::CheckOpMessageBuilder::NewString()", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, int>(int const&, int const&, char const*) in cerestest-ef733e.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, ceres::DimensionType>(int const&, ceres::DimensionType const&, char const*) in cerestest-ef733e.o
  "google::base::CheckOpMessageBuilder::CheckOpMessageBuilder(char const*)", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, int>(int const&, int const&, char const*) in cerestest-ef733e.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, ceres::DimensionType>(int const&, ceres::DimensionType const&, char const*) in cerestest-ef733e.o
  "google::base::CheckOpMessageBuilder::~CheckOpMessageBuilder()", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, int>(int const&, int const&, char const*) in cerestest-ef733e.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::MakeCheckOpString<int, ceres::DimensionType>(int const&, ceres::DimensionType const&, char const*) in cerestest-ef733e.o
  "ceres::Solver::Summary::BriefReport() const", referenced from:
      _main in cerestest-ef733e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

И это касается не только цереры, подобные ошибки бывают и на бусте.


person bzcheeseman    schedule 06.09.2015    source источник
comment
Используйте libc++, а не libstdc++. Если вы покажете фактические сообщения об отсутствующих символах, будет легче увидеть, что происходит :) IIRC libstdc++ - это более старая версия библиотеки GNU. libc++ теперь должен работать для большинства вещей. И, может быть, показать точные шаги, чтобы произвести проблему?   -  person JCx    schedule 06.09.2015
comment
Добавлено выше, спасибо :) Единственная причина, по которой я использовал libstdc++, заключается в том, что он на самом деле выдал мне другую ошибку, я подумал, что это может быть полезно для выяснения того, что не так.   -  person bzcheeseman    schedule 06.09.2015
comment
попробуйте ввести which g++ и which clang++. похоже, что ваши пути перепутались, и вы на самом деле не запускаете программы, которые вы думаете. если вы хотите точно указать, какой двоичный файл запускать, вы можете использовать синтаксис ./ в bash и указать полный путь к двоичному файлу   -  person Chris Beck    schedule 06.09.2015
comment
Обычно с библиотекой вы должны сначала сообщить компилятору, где находятся файлы заголовков, как вы сделали с -I ..., а затем сообщить компоновщику, где библиотеки также с -l, например. -lpng -ljpeg или что-то вроде pkgconfig. Это dash lower-case ell, а не dash upper case i.   -  person Mark Setchell    schedule 06.09.2015
comment
Поэтому я фактически удалил gcc после того, как это не помогло, поэтому which g++ и which clang++ дают мне /usr/bin/g++ и /usr/bin/clang++ соответственно. Также попытался добавить -L /usr/local/lib, та же ошибка. Если я использую -lceres -lglog, это работает, но мне придется использовать это с каждой библиотекой или есть путь, который я могу отредактировать?   -  person bzcheeseman    schedule 06.09.2015
comment
Очень интересно, что это наконец-то работает, @MarkSetchell   -  person bzcheeseman    schedule 06.09.2015
comment
Обычно вы помещаете все это в Makefile и просто набираете make, и он применяет все флаги, библиотеки и опции.   -  person Mark Setchell    schedule 06.09.2015
comment
Блестящий. Я немного продолжу тестирование, удостоверюсь, что это работает для всех библиотек, а затем опубликую ответ, когда буду уверен, что это работает универсально. Пока никаких проблем.   -  person bzcheeseman    schedule 06.09.2015


Ответы (1)


Спасибо Марку Сетчеллу:

При использовании homebrew важно следить за /usr/local/lib, необходимо указать библиотеки для связывания.

Окончательный код, который работал, был таким:

g++ cerestest.cpp -o ceres -lglog -lceres -I /usr/local/include

Тот же ответ, кажется, работает для библиотек повышения, а также для всех других, которые я пробовал (до сих пор включая Qt).

person bzcheeseman    schedule 07.09.2015
comment
Большое спасибо! я решил ту же проблему только с одним изменением gcc-›g++. РЖУ НЕ МОГУ. ???? - person kyb; 31.05.2018