CMake is a build process manager designed to be used with the native build system of the platform. CMake supports various platforms, including Windows desktops and servers, Windows Phone, Windows Store, Linux, OS X, Android, iOS, Solaris, Unix and others. Its appealing to use CMake because it supports so many platforms.
Crypto++ 5.6.3 through 5.6.5 provided limited Cmake support. The CMake support files of interest are CMakeFile.txt and cryptopp-config.cmake. The three library versions can be built using CMake with some cautions. The cautions are CMake does not use the library's recommended flags and options, and it could lead to compile, link or runtime problems later, like CVE-2016-7420.
Note: CMake was removed from the library prior to the release of Crypto++ 6.0. The mailing list discussion is at Remove CMake from GitHub; add it to Patch Page on wiki?, and the check-in of interest is Commit 913a9e60d375e458.
Note: The CMake project files are now maintained by the community, and not the library. If you want to use CMake then download it from GitHub | cryptopp-cmake. It is a separate project to ensure folks don't accidentally use it. If you have an improvement, then make the change and submit a pull request.
Many thanks to the folks who contributed to the CMake task. Special thanks to GamePad64, who made early contributions and wrote the initial wiki page. Additional thanks go to Anonimal, who also provided patches.
This section provides instructions on using CMake to build the library. If the library is built and your are trying to CMake find it, then see CMake link to external library on Stack Overflow.
Create a build directory
First, create a directory outside the source directory, for example /home/user/cryptopp-build, then
cd into it.
$ mkdir /home/user/cryptopp-build $ cd /home/user/cryptopp-build
This step is optional, but recommended. CMake creates out-of-source builds, so all the build artifacts are created in a separate directory, leaving the original source directory untouched. You can read more at CMake FAQ.
The Crypto++ library can be configured to suit your particular needs. For example, it can be configured for a dbug build or a release build. To select a library configuration, use CMake options to control the library configuration. Multiple options can be selected.
To set an option, simply pass it to CMake using -D. For example, to enable a debeg configuration, perform the following.
cmake ... -DCMAKE_BUILD_TYPE=Release -DDISABLE_ASM=OFF
The table below provides CMake options to control library configurations.
|BUILD_TESTING||ON/OFF||ON||Enables building the test drive program (cryptest.exe).|
|BUILD_DOCUMENTATION||ON/OFF||OFF||Enables building documentation using Doxygen.|
|DISABLE_ASM||ON/OFF||OFF||Disables assembler and intrinsic code. This is a fail safe option and it should not be needed. Also see the wiki page config.h | assembly defines.|
|DISABLE_SSSE3||ON/OFF||OFF||Disables SSSE3 instructions. This option is needed for some older Binutils due to downlevel assemblers. Also see the wiki page config.h | assembly defines.|
|DISABLE_SSE4||ON/OFF||OFF||Disables SSE4.1 and SSE4.2 instructions. This option is needed for some older Binutils due to downlevel assemblers. Also see the wiki page config.h | assembly defines.|
|DISABLE_AESNI||ON/OFF||OFF||Disables AES-NI instructions. This option is needed for some older Binutils due to downlevel assemblers. Also see the wiki page config.h | assembly defines.|
|DISABLE_SHA||ON/OFF||OFF||Disables SHA instructions. This option is needed for some Binutils due to downlevel assemblers. Also see the wiki page config.h | assembly defines.|
|CRYPTOPP_NATIVE_ARCH||ON/OFF||OFF||Enables the addition of -march=native (IA32), -march=armv7-a -mfpu=neon (AMRv7a) or -march=armv8-a (AMRv8a) to CXXFLAGS.|
|CRYPTOPP_DATA_DIR||-||""||Sets the Crypto++ test data directory. The default value is an empty string. For more information see Issue #82: Add Debian-style Data Directory patch.|
|CMAKE_INSTALL_PREFIX||-||-|| Sets the install prefix (similar to |
|CMAKE_BUILD_TYPE||See below||Debug||Sets the build type. The value can be one of Debug/Release/MinSizeRel/RelWithDebInfo. You should explicitly set this value.|
Note: the library's CRYPTOPP_DISABLE_ASM is a fail-safe. It should not be needed under any configurations, from X86 or X64 through ARM or MIPS. If its needed, then please report it on the mailing list or bug tracker so the issue can be fixed.
DISABLE_SSSE3, DISABLE_SSE4, DISABLE_AESNI, and DISABLE_SHA are automatically engaged if the assembler is too old to assemble an object file with the respective instruction. DISABLE_SHA is new, and it may miss the mark. If its needed, then please report it on the mailing list or bug tracker so the issue can be fixed.
If given a choice you should enable CRYPTOPP_NATIVE_ARCH by configuring CMake with -DCRYPTOPP_NATIVE_ARCH=1. On modern processors it will engage CPU features like AVX, AVX2, BMI and BMI2. AVX-based memcpy is often translated into 32-byte vmovdqa/vmovdqu and it is lightening fast. The library will usually perform much better with CRYPTOPP_NATIVE_ARCH.
The table below discusses values for CMAKE_BUILD_TYPE.
|Debug||This option is similar to similar to -O0 -g.|
|Release||This option is similar to similar to -O2 -DNDEBUG.|
|MinSizeRel||This option is similar to similar to -O2 -DNDEBUG.|
|RelWithDebInfo|| This option is similar to similar to -O2 -DNDEBUG -g. This is mostly used to strip symbols into a separate file after building. For example, for building |
Next, generate the makefiles. Be sure to use the source directory as argument; and not the build directory. It may be either absolute or relative path.
$ cmake /home/user/cryptopp
Build the Library
Once the Makefiles are generated, you only have to run make to compile and link the library and test program.
This step builds static and shared versions of the library + tests binary (cryptest). If you want to build only shared or static version, then make
cryptopp-shared targets. Like so:
$ make cryptopp-static.
A more cross-platform way to build is to invoke
$ cmake --build . (notice the dot) instead of
make. It can be used, if we use non-Makefile generator (Ninja or Visual Studio, for example).
CMake hides the output of the compilation process by default. You can use VERBOSE=1 to display it. Please use VERBOSE=1 if you are asking for help on the mailing list or filing a bug report.
Test the Library
Once the library is built, it should be tested to ensure operational correctness.
TODO: talk about how to run cryptest.exe v and cryptest.exe tv all
Install the library
To install the library after building invoke
# make install
If you want to change installation prefix, you can do it using
-DCMAKE_INSTALL_PREFIX=YOUR_INSTALL_PREFIX as described in CMake Options.
Note, that you may need root privileges if you install it in a system location.
If you have a project that uses Crypto++ and CMake, and you want to add Crypto++ as a dependency. Include directories will be added automatically.
On Linux add these lines to CMakeLists.txt in your project directory:
find_package(CryptoPP REQUIRED) target_link_libraries(YOUR_TARGET_NAME cryptopp-shared)
If you want to link with static version of the library, then use
cryptopp-static instead of
cryptopp-shared. On Windows you must use
cryptopp-static because the dynamic link library is the FIPS DLL (which is something you should avoid).
Also see Issue 249, How to find Crypto++ package using CMake? and CMake link to external library on Stack Overflow. In Issue 249 we were trying to figure out what needed to be done. Unfortunately the CMake manual did not cover the topic and their mailing list was closed to subscriptions so we could not ask questions.
CMake includes built-in support for a number of command line and IDE environments, including Nmake, Unix, VC++, Visual Studio 2002-2013 and Xcode. You can enlist a Generator with the -G option:
# Visual Studio 2013 cmake -G "Visual Studio 12" #Xcode cmake -G "Xcode"
Sometimes the output artifacts don't work as expected. For example, CMake does not generate a functioning set of Xcode project files; see Issue 355: CMake-based Xcode build fails to build any library, Issue 374: CMake XCode build on macOS fails and Cmake generated Xcode project does not produce library artifacts? on Stack Overflow.
CMake was added to the library at Crypto++ 5.6.3. The CMake project files never achieved a good state and no one was available with the necessary skills to move them into a good state (or maybe, no one was available to perform the work). CMake was a failed experiment and removed from the library prior to the release of Crypto++ 6.0. The mailing list discussion is at Remove CMake from GitHub; add it to Patch Page on wiki?, and the check-in of interest is Commit 913a9e60d375e458.
The experiment failed for several reasons. First, CMake is a redundant build system because the Makefile is used on Unix & Linux; and Visual Studio & MSBuild are used on Windows. CMake users could integrate the library by using ExternalProject_Add. There was no reason for us to provide CMake to create Makefiles and MSBuild files we were already providing. We were doing over twice the amount of work than we needed to be doing. Also see CMake link to external library on Stack Overflow.
Second, CMake was consuming disproportionate amounts of our time. It accounted for over 18% of bug reports in the issue tracker. When an issue was encountered, it was often non-trivial to find a solution. Even simple workflows, like "add a flag to CXXFLAGS" or "add a flag to LDFLAGS" were complicated. Based on Current Status below there was no end in sight.
Third, CMake uses an insecure configuration for release builds. All CMake projects are vulnerable to CVE-2016-7420 -like findings if the project uses the default options provided by CMake. Secrets that Crypto++ may protect could be egressed because of the CMake's insecure configuration (which have nothing to do with the Crypto++ configuration). Additionally, CMake does not use required platform flags, like -mfloat-abi=softfp for armeabi builds on Android.
Fourth, CMake did not provide a cross platform way to get a shell for testing. We had to prepare arguments for a call to exec or CreateProcess. It also meant we could not do thing like assign sh -c to a variable and call through it. Also see Avoid egrep when possible, remove egrep from DumpMachine in the Crypto++ issue tracker.
Fifth, CMake makes it difficult to impossible to change flags it wants to use, like -O2. Vectorization gained widespread support in the mid-2000's. The library has a lot of code and patterns to take advantage of it. To engage vectorizations we need -O3 for compilers like Clang, GCC and Intel ICC. Unfortunately, CMake has forced us to use their poor selection.
Sixth, CMake lacked good native support for AIX, Android, iOS, PowerPC, Solaris, Windows Phone, Windows Store, SSE, ARMv7, ARMv8 and Power8. We had to do nearly everything manually, and it placed too much of a burden on the library maintainers.
Seventh, we could not query CMake and user options in a particular configuration to further tune our use of flags and options. Also see Difference between add_compile_options and SET(CMAKE_CXX_FLAGS…) on Stack Overflow.
Eighth, CMake had too many bugs that went unfixed and required too many work-arounds. For example, we were never able to set project(cryptopp, CXX) because CMake could not perform its tests with a C++ compiler. Two years later the bug was still not fixed. Also see Tell CMake to use C++ compiler for C files coming from CMake? on Stack Overflow. Another example is How to have CHECK_CXX_COMPILER_FLAG fail on illegal value? on Stack Overflow, where the compiler would report an illegal option but CMake would report success. Yet another example is How to strip trailing whitespace in CMake variable?, where STRIP does not strip whitespace.
Ninth, CMake uses anti-patterns, like not driving link through the compiler. Best practice dictates using the compiler driver for link. The compiler driver will pass necessary options and libraries to the linker. CMake failed to honor the practice or supply the equivalent functionality. Also see Instruct CMake to use CXX and CXXFLAGS when driving link? on Stack Overflow.
Tenth, CMake hides output that is necessary for users to confirm their configuration and report bugs to the library. Nearly every bug report received had 1%, 2%, 3%, etc. Nearly every report lacked information we request, like a typical compile command and the link command. Its yet another example of making the "common case" difficult.
Eleventh, its impossible to comply with best practices and policies. For example, we started catching policy violations for quoting CMake variables. We removed the quotes to comply with policy, which subsequently broke Windows because of spaces in pathnames. Also see How to use variables and avoid CMP0054 policy violations? on Stack Overflow.
Twelfth, the documentation sucks. We did not know how to approach many workflows or treat most problems. Simple workflows, like "change release optimizations from -O2 to -O3" , were not documented and lacked exemplary code. When we experienced a problem it was hard to find a solution. We spent hours in their manuals without learning how to do much of anything.
Thirteenth, the CMake mailing list sign-up was disabled. We could not join the list and ask questions.
Fourteenth, no one stepped up to maintain it. Part of the agreement in adding CMake support was the community would maintain it. Once the initial files were added the Cmake supporters mostly disappeared. The library maintainers then had to field the bugs.
Also see Remove CMake from GitHub; add it to Patch Page on wiki? (mailing list), Commit 1c740b0a097aecaa (warning message) and Commit 913a9e60d375e458 (library removal).
Crypto++ was not the only project to suffer chronic CMake problems. See, for example, Monero Issue 771, Windows not bundling OpenSSL statically.
The table below lists the state of the CMake project files before they were removed. As can be seen there are many gaps in the project files. Nearly all platforms have problems with their linker flags due to Instruct CMake to use CXX and CXXFLAGS when driving link? which means all the sanitzers are broken. JW takes full responsibility for the problems with the project files.
Including the project files in their current state would be like adding a cipher that produces incorrect results. It would harm users who believe they are using well maintained source files from the Crypto++ project.
|Windows x86||Not using library options|
|Windows x64||Not using library options|
|Windows Phone||Not using library options|
|MinGW||Don't care||Abandoned by its authors|
|Linux i686||Mostly using library settings|
|Linux x86_64||Mostly using library settings|
|OS X i386||Unknown|
|OS X x86_64||Unknown|
|OS X PPC||Unknown|
|Linux ARM A-32||Mostly using library settings|
|Linux Aarch32||Mostly using library settings|
|Linux Aarch64||Mostly using library settings|
|Linux MIPS||Not using library options|
|Linux MIPS64||Not using library options|
|Linux PPC||Not using library options|
|Linux PPC64||Not using library options|
|AIX PPC||Not using library options|
|AIX PPC64||Not using library options|
|Solaris i386||Mostly using library options||Linker flags missing -xarch options|
|Solaris x86_64||Mostly using library options||Linker flags missing -xarch options|
|Solaris Sparc||Using some library options||Linker flags missing -xarch options|
|Solaris Sparc64||Using some library options||Linker flags missing -xarch options|
|Android armeabi||Not using library options||Not using Android options|
|Android armv7a||Not using library options||Not using Android options|
|Android armv7a+NEON||Not using library options||Not using Android options|
|Android armv8a||Not using library options||Not using Android options|
|Android i686||Not using library options||Not using Android options|
|Android x86_64||Not using library options||Not using Android options|
GitHub | cryptopp-cmake - GitHub with the latest CMake sources.