0

I'm trying to build Crypto++ 5.6.2 in for Qt with Visual Studio 2013, but its producing errors. Here is what I've done so far.

The page says this about vs2010-dynamic.zip, but the ZIP includes only cryptest.sln for VS2005. Just a single file. But anyway, I used the file:

archive of a pre-converted solution file, project files and filters for Visual Studio 2010 and above."

I then:

  • Opened cryptest.sln in MSVC2013, and set "Multi-threaded DLL (/MD)" for each project (project --> properties --> C/C++ --> Code Generation --> Runtime Library --> /MD)

  • Build --> 'Batch Build' --> Check cryptdll, cryptest, cryptlib, dlltest (Release|win32) --> Build

It resulted in a DLL and LIB in DLL_Output directory. I then:

  • Moved the DLL to the directory where Qt executable resides.
  • In Qt, I added two lines to test.pro:
    • INCLUDEPATH += "../extern/msvc2013/cryptopp562/include"
    • LIBS += -L"..\extern\msvc2013\cryptopp562\include\cryptopp\Win32\DLL_Output\Release" -lcryptopp

But in Qt, I've got the following errors:

mainwindow.obj:-1: error: LNK2001: unresolved external symbol "public: virtual unsigned __int64 __thiscall CryptoPP::ThreadUserTimer::GetCurrentTimerValue(void)" (?GetCurrentTimerValue@ThreadUserTimer@CryptoPP@@UAE_KXZ)

mainwindow.obj:-1: error: LNK2001: unresolved external symbol "public: virtual unsigned __int64 __thiscall CryptoPP::ThreadUserTimer::TicksPerSecond(void)" (?TicksPerSecond@ThreadUserTimer@CryptoPP@@UAE_KXZ)

mainwindow.obj:-1: error: LNK2019: unresolved external symbol "class CryptoPP::NameValuePairs const & const CryptoPP::g_nullNameValuePairs" (?g_nullNameValuePairs@CryptoPP@@3ABVNameValuePairs@1@B) referenced in function "public: __thiscall CryptoPP::HMAC::HMAC(unsigned char const *,unsigned int)" (??0?$HMAC@VSHA256@CryptoPP@@@CryptoPP@@QAE@PBEI@Z)

release\user_account_registration.exe:-1: error: LNK1120: 3 unresolved externals

Do you have any ideas why I am getting the errors?

Any help/comment/insight would be really appreciated.

jww
  • 97,681
  • 90
  • 411
  • 885
Sam Kim
  • 35
  • 6
  • *"... but vs2010-dynamic.zip includes only cryptest.sln for VS2005..."* - Arg... something sounds broken. Give me a few hours and I'll get it fixed. By the way, you should only need either `vs2010.zip` or `vs2010-dynamic.zip`. You should not need both. – jww May 27 '16 at 21:57
  • A couple of other items... Don't use the DLL unless you have a hard requirement to do so. Also see [FIPS DLL](http://www.cryptopp.com/wiki/FIPS_DLL) on the Crypto++ wiki. Here's how to integrate Crypto++ with QT when things are working as expected: [Integrate Crypto++ code to Qt Application In Linux](http://stackoverflow.com/q/31660366) and [Adding Crypto++ .lib file to Qt project](http://stackoverflow.com/q/23223528). – jww May 27 '16 at 22:01
  • @jww First of all, thank a lot for your comments and the links. "You should not need both" ==> I guessed so. :) Let me try again with vs2010-dynamic.zip after it gets fixed. Thanks. – Sam Kim May 27 '16 at 22:19
  • A new `vs2010-dynamic.zip` was uploaded. The project files might reference some source files that you don't have because its built from the latest stable sources. If the source file is missing, then simply delete it from the project file. You should also consider using Crypto++ 5.6.3 instead of 5.6.2. Or better, use the ZIP from [Wei Dai's GitHub](http://github.com/weidai11/cryptopp/). Master is stable and not experimental; and has ChaCha, BLAKE2, etc that are not yet available in a release ZIP. There's also better support for Windows Phone, Windows Store and Universal Windows Platform (UWP). – jww May 28 '16 at 00:36
  • By the way, the ZIP also includes the script I use to build `vs2010-dynamic.zip` from `vs2010.zip`. If you find any problems, then point them out or [file a bug report](http://github.com/weidai11/cryptopp/issues). Ironically, its a Bash script that runs on Linux and OS X because the command line tools are a little better. – jww May 28 '16 at 00:49
  • @jww Thanks for your comments. Actually, I will be working on it soon. – Sam Kim May 31 '16 at 19:07
  • @jww I copied the files of vs2010-dynamic.zip into cryptopp562 folder, and tried to build with msvc2013, but I've got the following errors. 1> Assembling: C:\Users\skim\Desktop\Hyrule\user_account_registration\extern\msvc2013\cryptopp562\include\cryptopp562\rdrand.asm 1>MASM : fatal error A1000: cannot open file : C:\Users\skim\Desktop\Hyrule\user_account_registration\extern\msvc2013\cryptopp562\include\cryptopp562\rdrand.asm 2>c1xx : fatal error C1083: Cannot open source file: 'bench1.cpp': No such file or directory BTW, the static lib worked well with Qt. Thanks. – Sam Kim May 31 '16 at 21:45
  • ***`cannot open file... rdrand.asm...`*** - Right. HKDF, RDRAND, RDSEED, ChaCha, et al, came after 5.6.2. In the case of RDRAND in particular, it was provided at 5.6.3. Delete them from the project files. Or, use the [ZIP from Wei Dai's GitHub](http://github.com/weidai11/cryptopp). ***`bench1.cpp`*** was renamed recently. It used to be called ***`bench.cpp`***. Also see [Rename bench.cpp to bench1.cpp](http://groups.google.com/d/msg/cryptopp-users/Inz3uhNxd4g/Y6VJPUg4EQAJ) on the mailing list. – jww May 31 '16 at 22:26
  • @jww OK. Building is working now. :) Like you mentioned "If you look at the source code for hrtimer.h, ThreadUserTimer is missing CRYPTOPP_DLL. That means the DLL does not export ThreadUserTimer (and many other classes).", for now, I might need to use the static lib, but I think finally I have a working version based on dll. Thank you so much for your help. :) – Sam Kim Jun 01 '16 at 00:44
  • Very good. Did you decide to use DLL+LIB? If so, I can provide better instructions for it at Visual Studio and FIPS DLL wiki pages (I've been trying to dissuade people from using it). Also, you should click the ✓ at the answer below if it solved your problems. It will help other Stack Overflow visitors. *If* it did not help, then don't check it. – jww Jun 01 '16 at 00:51
  • @jww I discussed with my boss, and he said we're good with the static lib for now, but I am so happy that we have a working version of dll and lib. Thanks a lot. :) – Sam Kim Jun 01 '16 at 05:06

1 Answers1

1
mainwindow.obj:-1: error: LNK2001: unresolved external symbol "public: virtual unsigned __int64 __thiscall CryptoPP::ThreadUserTimer::GetCurrentTimerValue(void)" (?GetCurrentTimerValue@ThreadUserTimer@CryptoPP@@UAE_KXZ)

mainwindow.obj:-1: error: LNK2001: unresolved external symbol "public: virtual unsigned __int64 __thiscall CryptoPP::ThreadUserTimer::TicksPerSecond(void)" (?TicksPerSecond@ThreadUserTimer@CryptoPP@@UAE_KXZ)

mainwindow.obj:-1: error: LNK2019: unresolved external symbol "class CryptoPP::NameValuePairs const & const CryptoPP::g_nullNameValuePairs" (?g_nullNameValuePairs@CryptoPP@@3ABVNameValuePairs@1@B) referenced in function "public: __thiscall CryptoPP::HMAC::HMAC(unsigned char const *,unsigned int)" (??0?$HMAC@VSHA256@CryptoPP@@@CryptoPP@@QAE@PBEI@Z)

If you look at the source code for hrtimer.h, ThreadUserTimer is missing CRYPTOPP_DLL. That means the DLL does not export ThreadUserTimer (and many other classes).

In general, you should avoid the FIPS DLL unless you have a hard requirement to do so. Its special purpose, and its not easy to work with. It also has Operational Environment requirements from FIPS 140-2. I doubt you want to limit yourself to Visual Studio 2005 and Windows Server 2003.

If you insist on using the FIPS DLL, then you need to link against the DLL as expected. "As expected" means you use the cryptopp.lib import library at compile/link time; and cryptopp.dll at runtime. You also have to link again cryptlib.lib to get the missing classes, like ThreadUserTimer, while setting CRYPTOPP_IMPORTS to avoid duplicate symbols when using both libraries.


Instead of using the DLL, download the updated (and fixed) vs2010-dynamic.zip. Use it to build the Crypto++ library and then use the static library. "Use the static library" means to link against cryptlib.lib only.

The project files from vs2010-dynamic.zip might reference some source files that you don't have because its built from the latest stable sources. If the source file is missing, then simply delete it from the project file. Off the top of my head, Crypto++ 5.6.2 should be missing HKDF, RDRAND, RDSEED, ChaCha, BLAKE2, Base64URLEncoder, Base64URLDecoder, etc. It also lacks the rename of bench.cpp to bench1.cpp.

The Visual Studio wiki page has more information on Windows project files and artifacts like cryptlib.lib.


INCLUDEPATH += ".../cryptopp562/include"
LIBS += -L"...\cryptopp562\include\cryptopp\Win32\DLL_Output\Release" -lcryptopp

I think you should use only -lcryptlib because its the static library, and it has everything you need. The path to the library is $(Platform)\Output\$(Configuration), but I don't know how to translate it into something QT composer can use.

Otherwise, I think you need to specify both -lcryptopp -lcryptlib, and add CRYPTOPP_IMPORTS to preprocessor definitions.


vs2010.zip, vs2010-dynamic.zip and vs2005-dynamic.zip are built from the latest GitHub sources. As of this writing (JUN 1 2016), that's effectively pre-Crypto++ 5.6.4. If you are using the ZIP files with a down level Crypto++, like 5.6.2 or 5.6.3, then you will run into minor problems.

There are two minor problems I am aware. First is a rename of bench.cpp to bench1.cpp. Its error is either:

  • C1083: Cannot open source file: 'bench1.cpp': No such file or directory
  • LNK2001: unresolved external symbol "void __cdecl OutputResultOperations(char const *,char const *,bool,unsigned long,double)" (?OutputResultOperations@@YAXPBD0_NKN@Z)

The fix is to either (1) open cryptest.vcxproj in notepad, find bench1.cpp, and then rename it to bench.cpp. Or (2) rename bench.cpp to bench1.cpp on the filesystem.

The second problem is a little trickier because its a moving target. Down level releases, like 5.6.2 or 5.6.3, are missing the latest classes available in GitHub. They include HKDF (5.6.3), RDRAND (5.6.3), RDSEED (5.6.3), ChaCha (5.6.4), BLAKE2 (5.6.4), Poly1305 (5.6.4), etc.

The fix is to remove the missing source files from the Visual Studio project files since they don't exist for the down level releases.

Another option is to add the missing class files from the latest sources, but there could be complications. For example, many of the sources subtly depend upon the latest config.h, cpu.h and cpu.cpp. The "subtlety" is you won't realize you are getting an under-performing class.

An example of under-performing class is BLAKE2. config.h adds compile time ARM-32 and ARM-64 detection. cpu.h and cpu.cpp adds runtime ARM instruction detection. If you add BLAKE2 without the other files, then none of the detection occurs and you get a straight C/C++ implementation. The NEON implementation runs around 9 to 12 cycles per byte, while the C/C++ implementation runs around 40 cycles per byte.

jww
  • 97,681
  • 90
  • 411
  • 885