Cmake O2

FCL - The Flexible Collision Library. Linux / OS X Windows Coverage. FCL is a library for performing three types of proximity queries on a pair of geometric models composed of triangles. I'm following the instructions in the CMake FAQ entry 'How can I build my MSVC application with a static runtime?' To centralize selection of the MSVC runtime for a bunch of nested CMake projects (. Chip's answer was helpful, however since the SET line overwrote CMAKECXXFLAGSDEBUG this removed the -g default which caused my executable to be built without debug info. I needed to make a small additional modification to CMakeLists.txt in the project source directory to get an executable built with debugging info and-O0 optimizations (on cmake version 2.8.12.2).

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. 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.

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. If you have an improvement, then make the change and submit a pull request. It is a separate project to ensure folks don't accidentally use it. (Our unofficial Android.mk and Autotools are separate projects, too).

If you built the Crypto++ library using the makefile or MSBuild then you can incorporate it into a CMake project by following CMake link to external library.

A related topic is Requirements. Crypto++ attempts to minimize external dependencies like Autotools and CMake, so CMake will likely never be part of the official sources.

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.

Bug Reports

Cmake O2

CMake questions should be asked on the mailing list. CMake bug reports should be reported at cryptopp-cmake. Please do not ask questions or report bugs at the Crypto++ GitHub.

Using CMake

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.

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.

Select Options

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.

The table below provides CMake options to control library configurations.

Library Configuration Options
DefineValuesDefaultComments
BUILD_TESTINGON/OFFONEnables building the test drive program (cryptest.exe).
BUILD_DOCUMENTATIONON/OFFOFFEnables building documentation using Doxygen.
DISABLE_ASMON/OFFOFFDisables 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_SSSE3ON/OFFOFFDisables SSSE3 instructions. This option is needed for some older Binutils due to downlevel assemblers. Also see the wiki page config.h assembly defines.
DISABLE_SSE4ON/OFFOFFDisables 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_AESNION/OFFOFFDisables 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_SHAON/OFFOFFDisables SHA instructions. This option is needed for some Binutils due to downlevel assemblers. Also see the wiki page config.h assembly defines.
CRYPTOPP_NATIVE_ARCHON/OFFOFFEnables 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 --prefix in Autotools). The default value is platform dependent.
CMAKE_BUILD_TYPESee belowDebugSets 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.

Library Configuration Options
ValueComments
DebugThis option is similar to similar to -O0 -g.
ReleaseThis option is similar to similar to -O2 -DNDEBUG.
MinSizeRelThis option is similar to similar to -O2 -DNDEBUG.
RelWithDebInfoThis 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 -dbg packages in Debian.

Generate Makefiles

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.

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-static or 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

Cmake Optimization Level

Install the library

To install the library after building invoke

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.

Importing Crypto++

Cmake O2

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:

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.

IDE Generators

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:

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 Removal

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.

CMake was a good learning experience. Based on the experience we knew not to add Android and Autotools to the official sources because the projects would likely suffer the same problems as CMake. In fact, Android, Autotools and CMake are all hosted on GitHub in separate projects and all carry the same 'unofficial warnings'.

Current Status

The table below lists the state of the CMake project files before they were removed.

PlatformStatusComments
Windows x86Not using library options
Windows x64Not using library options
Windows PhoneNot using library options
Windows StoreUnknown
MinGWDon't careAbandoned by its authors
MinGW-64Unknown
CygwinUnknown
Cygwin-64Unknown
Linux i686Mostly using library options
Linux x86_64Mostly using library options
OS X i386Unknown
OS X x86_64Unknown
OS X PPCUnknown
iOS ARMUnknown
iOS ARM64Unknown
iOS TVUnknown
iOS WatchUnknown
Linux A-32Mostly using library options
Linux Aarch32Mostly using library options
Linux Aarch64Mostly using library options
Linux MIPSNot using library options
Linux MIPS64Not using library options
Linux PPCMostly using library options
Linux PPC64Mostly using library options
AIX PPCUnknown
AIX PPC64Unknown
Solaris i386Mostly using library options for GCCLinker flags missing -xarch options
Solaris x86_64Mostly using library options for GCCLinker flags missing -xarch options
Solaris SparcMostly using library options for GCCLinker flags missing -xarch options
Solaris Sparc64Mostly using library options for GCCLinker flags missing -xarch options
Android armeabiNot using library optionsNot using Android options
Android armv7aNot using library optionsNot using Android options
Android armv7a+NEONNot using library optionsNot using Android options
Android armv8aNot using library optionsNot using Android options
Android i686Not using library optionsNot using Android options
Android x86_64Not using library optionsNot using Android options

Downloads

cryptopp-cmake - GitHub with the latest CMake sources. Releases are tagged so you can download a version of the CMake project files to fit a version of the library.

Retrieved from 'https://www.cryptopp.com/w/index.php?title=CMake&oldid=28417'

CMake has for single configuration configurators the following build types (configuration):

  • Empty (Qt Creator wrongly refers to this as “Default”)
  • Debug
  • Release
  • RelWithDebInfo – Release with debug information, needed for profiling / post mortem debugging
  • MinSizeRel – Release optimized for size, and not for speed.

If we have a look at CMake’s Modules/Compiler/GNU.cmake we can see:

The empty build type usually contains the common build flags for all build types. It is generated from the CMAKE_C_FLAGS_INIT / CMAKE_CXX_FLAGS_INIT variables, and the CFLAGS / CXXFLAGS system environment variables.

But in the case of an IDE like Qt Creator makes no sense to have, you will end up for GCC with a -O0 (Debug) build. I’ve opened QTCREATORBUG-22013 in this regard.

CMake uses the CMAKE_<LANG>_FLAGS_<CONFIG>_INITvariables which will be used to populate the CMAKE_CMAKE_<LANG>_FLAGS_<CONFIG> variables.

There are cases when you might want to change the default build types:

  • Want to have -g1 for RelWithDebInfo, because your binaries are becoming too big
  • Want to improve build times in Debug mode with -gsplit-dwarf
  • Want to link to a different version of the CRT
  • Want to enable all possible warnings from the compiler

Lastly, we want to do all this without putting if clauses in the code, and manually changing the CMAKE_<LANG>_FLAGS variables. The rule of thumb is: if you have to change compiler flags, you should do it in a toolchain file!

Cmake O2 Meter

Writing a CMake toolchain file

If we read the CMake documentation about writing a toolchain,we can see how easy is to write such a toolchain file. You pass the path to the compiler, while CMake will do autodetection for you.This works fine for GNU GCC / Clang / Visual C++ compilers.

Cmake

Here is what you have to set for using clang as a cross compiler for Arm platform:

There is nothing about CMAKE_<LANG>_FLAGS_<CONFIG>, because it is assumed we are using the defaults. If one needs to add somethingspecial to CMAKE_<LANG>_FLAGS_<CONFIG> variable, you are supposed to use the CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variables.

Android NDK Toolchain

The Android NDK CMake toolchain wants to have for Release build type debugging information enabled, and the -O2 compilation flag, while the default CMake Release build type is using -O3. Basically having the default CMake RelWithDebInfo build type.

In the NDK19 we can see in the android.toolchain.cmake the following:

Which is then followed by (edited a bit for brevity):

The comment in the above code shows some problems one might have while editing CMAKE_<LANG>_FLAGS_<CONFIG> variables.

Static linking to CRT with Visual C++

On Windows CMake has selected dynamic linking to the CRT for its build types, namely the /MD compiler flag.

But what if we want to link statically to the CRT with the /MT compiler flag, thus avoiding the need of deploying the CRT runtime on older Windows versions?

Here is what Google Test is doing in its googletest/cmake/internal_utils.cmake:

This means that you need to call this macro in your CMake code, and that it will affect the compilation of all subsequent targets.

We can avoid this by having a toolchain file:

This unfortunately only works starting with CMake version 3.11, released in March 2018!

CMake 3.11 has gathered the generation of all config variable generation in one function. This is an internal function, and it’s functionality has not been documented in the 3.11 release notes. We have the variable CMAKE_NOT_USING_CONFIG_FLAGS documented, variable which is used in the cmake_initialize_per_config_variable function.

cmake_initialize_per_config_variable will be called at the point of generating the CMAKE_<LANG>_FLAGS_<CONFIG>, which is done after the toolchain code has been processed.

CMake versions lower than 3.11

The CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variables are defined in different places, for Clang / GCC you have them in Modules/Compiler/GNU.cxx, for Visual C++ they are in Modules/Platform/Windows-MSVC.cmake. They are also defined with string(APPEND, which means that they will overpower your toolchain versions.

I am mentioning this because you might get something like this working for GNU like compilers for CMake versions lower than 3.11:

But this will partially work for Visual C++. Compiler feature detection won’t be working, etc.

With cmake_initialize_per_config_variable you can replace / modify the CMAKE_<LANG>_FLAGS_<CONFIG>_INIT values at will.

Android NDK toolchain patch

Armed with this information, I decided to hack the Android NDK toolchain. Below you have the patch:

The new code involves a bit more time to figure out what it does, but you have the benefit of havingin the CMakeCache.txt the CMAKE_<LANG>_FLAGS_<CONFIG> values, as opposed to having empty values as you get with the default toolchain.

Roundup

As a conclusion to this article is that you should never touch CMAKE_<LANG>_FLAGS_<CONFIG> variables directly. All the compiler build flags should be set in a toolchain, even if you don’t do cross compiling.

This way you can have a consistent build, with the same compiler flags used for all targets / subprojects!