Использование Crypto++ с clang

Я пытаюсь получить следующий пример Crypto++ (библиотека классов криптографических схем C++) для работы на iMac с помощью clang++.

Пример

SHA256 hash;

byte digest[ SHA256::DIGESTSIZE ];

hash.CalculateDigest( digest, (byte*) &value[ 0 ], value.size( ) );

HexEncoder encoder;

string result = String::empty;

encoder.Attach( new StringSink( result ) );

encoder.Put( digest, sizeof( digest ) );

encoder.MessageEnd( );

Команда сборки

Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix
 "/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.7.4 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name checksum_impl.cpp -pic-level 2 -mdisable-fp-elim -relaxed-aliasing -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 123.2.1 -v -resource-dir /usr/bin/../lib/clang/2.1 -D framework_EXPORTS -I /Users/Ben/Dropbox/appon/build/../source -nostdinc++ -cxx-isystem /usr/include/c++/v1 -Wall -Wextra -Weffc++ -pedantic -std=c++0x -fdeprecated-macro -ferror-limit 19 -fmessage-length 175 -stack-protector 1 -fblocks -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o CMakeFiles/framework.dir/Users/Ben/Dropbox/source/example.cpp.o -x c++ /Users/Ben/Dropbox/source/example.cpp
clang -cc1 version 2.1 based upon llvm 3.0svn hosted on x86_64-apple-darwin11.4.0
#include "..." search starts here:
#include <...> search starts here:
 /Users/Ben/Dropbox/build/../source
 /usr/include/c++/v1
 /usr/local/include
 /usr/bin/../lib/clang/2.1/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.

Выход компоновщика

clang: warning: argument unused during compilation: '-std=c++0x'
Undefined symbols for architecture x86_64:
  "CryptoPP::Filter::TransferTo2(CryptoPP::BufferedTransformation&, unsigned long long&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
      vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
  "CryptoPP::Filter::CopyRangeTo2(CryptoPP::BufferedTransformation&, unsigned long long&, unsigned long long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) const", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
      vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
  "CryptoPP::BufferedTransformation::ChannelCreatePutSpace(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long&)", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
      vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
  "CryptoPP::BufferedTransformation::ChannelPut2(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned char const*, unsigned long, int, bool)", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
      vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
  "CryptoPP::BufferedTransformation::ChannelPutModifiable2(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned char*, unsigned long, int, bool)", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
      vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
  "CryptoPP::BufferedTransformation::ChannelFlush(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, int, bool)", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
  "CryptoPP::BufferedTransformation::ChannelMessageSeriesEnd(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, bool)", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
      vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
  "CryptoPP::BufferedTransformation::SetRetrievalChannel(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
      vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
      vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [all] Error 2

Я использую последнюю разрабатываемую версию Crypto++ 5.6.2, так как предыдущая версия 5.6.1 не строится с помощью clang++. Однако я сталкиваюсь с проблемами сборки, в которых говорится, что у меня отсутствуют символы для архитектуры x86_64.

Любые подсказки будут очень признательны.


person Ben Crowhurst    schedule 03.06.2012    source источник


Ответы (4)


Crypto++ 5.6.2 успешно собран на LLVM версии 6.1.0 (clang-602.0.53) с параметрами make:

CXXFLAGS="-std=c++11 -stdlib=libstdc++ -DCRYPTOPP_DISABLE_ASM -Wno-c++11-narrowing"

соответственно этот скрипт: https://github.com/mapnik/mapnik-packaging/blob/master/osx/scripts/build_cryptopp.sh

-stdlib=libstdc++ требуется для MacOSX, начиная с Mavericks, см.: Когда необходимо использовать флаг use -stdlib=libstdc++?

person lexa-b    schedule 04.09.2015

вам нужно связать с библиотекой, которая предоставляет эти символы, которые должны быть libcryptopp.so, используя-lcryptopp в команде компилятора

Глядя на вашу «команду сборки» (это не команда, которую вы запускаете, это вывод команды, которую вы запускаете, было бы намного легче читать, если бы вы показали фактическую команду ) кажется, что вы компилируете файл .cpp в файл .o, но получаете ошибку компоновщика, что странно, поскольку создание файла .o обычно происходит на этапе перед компоновкой. Какой шаг вы пытаетесь сделать? Возможно, вам также нужно добавить -c, чтобы он только компилировался и не пытался линковаться. Вам все равно понадобится -lcryptopp при связывании.

person Jonathan Wakely    schedule 28.06.2012
comment
О: простите, Джонатан Уэйкли, я забыл, что разместил этот вопрос здесь. Причина в плохой поддержке llvm-clang++. Спасибо за ваше время. - person Ben Crowhurst; 14.07.2012

В дополнение к ответу Джонатона, потому что это довольно распространенная проблема, когда указано -lcryptopp...

Неопределенные символы для архитектуры x86_64. CryptoPP::Filter::TransferTo2(CryptoPP::BufferedTransformation&, unsigned long long&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)"...

__1 указывает, что вы используете среду выполнения LLVM C++ (libc++). Где-то вы, вероятно, смешиваете и сопоставляете со средой выполнения GNU C++ (libstdc++). Среда выполнения GNU C++ (libstdc++) не имеет украшения __1 на своих символах.

Вы должны просмотреть проект и все готовые библиотеки и убедиться, что они используют одну или другую. Для каждого вы должны использовать CXXFLAGS либо (1) -stdlib=libc++ (LLVM), либо (2) -stdlib=libstdc++ (GNU).

Имейте в виду, что такие IDE, как Xcode, могут использовать настройку -stdlib=..., отличную от Crypto++. В этом случае сделайте так, чтобы Xcode соответствовал Crypto++, или перестройте библиотеку Crypto++, чтобы она соответствовала Xcode.

Если Xcode использует LLVM libc++ и вам нужно пересобрать Crypto++, откройте GNUmakefile и переработайте этот раздел (около строки 90):

ifeq ($(UNAME),Darwin)
  AR = libtool
  ARFLAGS = -static -o
  CXX = c++
  IS_GCC2 = $(shell $(CXX) -v 2>&1 | $(EGREP) -c gcc-932)
ifeq ($(IS_GCC2),1)
    CXXFLAGS += -fno-coalesce-templates -fno-coalesce-static-vtables
    LDLIBS += -lstdc++
    LDFLAGS += -flat_namespace -undefined suppress -m
endif
endif

Если вы хотите использовать LLVM libc++, удалите:

# GNU C++ Runtime
LDLIBS += -lstdc++

И добавить:

# LLVM C++ Runtime
CXXFLAGS += -stdlib=libc++

Для полноты, если вы хотите использовать среду выполнения GNU, удалите LDLIBS += -lstdc++ и добавьте CXXFLAGS += -stdlib=libstdc++.

Вы также можете изменить CXX = c++ на CXX ?= c++, чтобы make-файл использовал c++, если это не указано в среде или командной строке.


Если интересно, __1 — это встроенное пространство имен, используемое для управления версиями. См. Для чего нужны встроенные пространства имен? и Где символ __1 появился при использовании LLVM libc++?.

person jww    schedule 27.03.2015

Эта проблема была связана с тем, что Crypto++ не был перенесен на llvm-clang++. См. здесь список поддерживаемых компиляторов.

Я решил использовать GCrypt.

К сожалению, я не могу предоставить более подробную информацию о причине сбоя.

person Ben Crowhurst    schedule 14.07.2012
comment
Этот ответ не поможет никому, кто сталкивается с той же проблемой. Не могли бы вы уточнить, в чем была причина проблемы и какое решение? - person Richard Smith; 15.09.2012