1

I have downloaded Crypto++ and I am trying to build it so that I can use it in a C++ Xcode project.

I compiled using just "make" command and included libcryptopp.a in my c++ project of my xcode. But it is giving errors:

Undefined symbols for architecture i386:   "CryptoPP::HashFilter::HashFilter(CryptoPP::HashTransformation&,
 CryptoPP::BufferedTransformation*, bool, int, std::__1::basic_string<char, std::__1::char_traits<char>,
 std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>,
 std::__1::allocator<char> > const&)", referenced from:
 ...
jww
  • 97,681
  • 90
  • 411
  • 885
  • Default make will build it with `-march=native` option, which leading to a x86_64 binary. – halfelf Aug 18 '16 at 09:09
  • what should I do then? @halfelf –  Aug 18 '16 at 09:10
  • Why not just use Common Crypto ,it is all "C" code and has optimizations for hardware support. – zaph Aug 19 '16 at 00:17
  • @zaph - Common Crypto only works on Apple systems. Apple also abandons its libraries and frameworks on down level OS versions. I have so many unpatched Apple hardware they outnumber the patched ones. Lack of QA is yet another problem with Apple software. I recommend avoiding Apple libraries at all costs. – jww Aug 19 '16 at 05:21
  • Depending on the implementation there can be substantial performance degradation on OSX as great as 200:1 and on iOS as great as 1000:1. For reference a 2.3 GHz Intel Core i7 AES-128-CBC on 100KB data encrypts at > 400 MB/s. – zaph Aug 19 '16 at 12:34

1 Answers1

2

I compiled using just "make" command and included libcryptopp.a in my c++ project of my xcode. But it is giving errors ...

As @halfelf said, you need to use LLVM's runtime (libc++) because that is what Xcode uses. Depending on the Crypto++ version you have, you may (or may not) be using GNU's runtime (libstdc++).

The easiest way to fix this is to checkout Master. Its OK to work from Master because its mostly stable and only suffers an occasional break (most development occurs on a separate branch).

$ git clone https://github.com/weidai11/cryptopp
Cloning into 'cryptopp'...
remote: Counting objects: 9116, done.
remote: Total 9116 (delta 0), reused 0 (delta 0), pack-reused 9116
Receiving objects: 100% (9116/9116), 8.05 MiB | 6.53 MiB/s, done.
Resolving deltas: 100% (6406/6406), done.
Checking connectivity... done.

Using Master is required because older versions of Crypto++ did not honor user's CXX and CXXFLAGS. You used to have to edit the makefile to fix it.

Then, perform the following:

export CXXFLAGS="-DNDEBUG -g2 -O2 -stdlib=libc++"
$ CXX=clang++ make -j 4
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -fPIC -march=native -pipe -c cryptlib.cpp
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -fPIC -march=native -pipe -c cpu.cpp
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -fPIC -march=native -pipe -c shacal2.cpp
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -fPIC -march=native -pipe -c md5.cpp
...

You have to set Debug/Release build, Symbol level and Optimization level. The makefile will add the rest of the flags.

There's some hand waiving above since it only adds -stdlib=libc++. You should use the CXXFLAGS that Xcode uses to ensure the most trouble-free link. Using different CXXFLAGS has caused a lot of trouble over the years.


Crypto++ is fat-binary safe (unlike cURL and OpenSSL), so you should be able to perform the following. In fact, our test script tests this class of configurations (Intel and PPC fat binaries, including C++03 through C++17), so it should work out of the box for you:

export CXXFLAGS="-DNDEBUG -g2 -O2 -stdlib=libc++ -arch i386 -arch x86_64"
$ CXX=clang++ make -j 4
$ make -j 4
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -arch i386 -arch x86_64 -fPIC -march=native -pipe -c cryptlib.cpp
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -arch i386 -arch x86_64 -fPIC -march=native -pipe -c cpu.cpp
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -arch i386 -arch x86_64 -fPIC -march=native -pipe -c shacal2.cpp
clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -arch i386 -arch x86_64 -fPIC -march=native -pipe -c md5.cpp
...

Using both architectures will avoid Undefined symbols for architecture i386 and Undefined symbols for architecture x86_64.


Here are some related Crypto++ wiki pages, but they are for iOS, and not OS X. They mostly apply, but not exactly.

Here's a wiki article on building the library from the command line. You're actually hitting the pain point discussed under "Compilers and C++ Runtimes", but its not readily apparent:

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • @user7234 - Open a new question, and provide the details. – jww Aug 19 '16 at 04:42
  • clang++ -DNDEBUG -g2 -O2 -stdlib=libc++ -arch i386 -arch x86_64 -fPIC -march=native -pipe -c camellia.cpp cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" :1:8: note: instantiated into assembly here pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx ^~~~~ cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" –  Aug 19 '16 at 04:47
  • :1:42: note: instantiated into assembly here pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx ^~~~ 2 errors generated. make: *** [cpu.o] Error 1 –  Aug 19 '16 at 04:47