Custom compiling of Cryptopp for my project

I want to develop a very simple licensing system. I decided to use Crypto++ v5.6.2 for generating public and private keys, cypher and decipher files. This library is build under Windows with Visual Studio and its solution files, but my project is using CMake for generating these solution files. Therefore, either I can write some CMake files for compiling Crypto++ or I can compile it and move the resulting files to my environment, using CMake to collect and include them in my solution. The latter is the approach that I have chosen with some libraries, since it is usually really difficult to write CMake files for building a library that you have not develop.

These are the steps I followed:

  1. Read Readme.txt at the root folder inside the zip file, and pay attention to the MSVC section. The cryplib project is the full static library project.
  2. I am using Ogre and other projects that force me to use shared C++ run-time libraries. Criptop++ use static C++ run-time libraries by default. As I explained in other posts, make sure that this setting is consistent across all your dependencies. Therefore, go to the cryplib Project Properties -> C/C++ -> Code Generation and switch from Multi-threaded to Multi-threaded DLL, in debug /MTd to /MDd and in release /MT to /MD.
  3. Ogre also uses multi-byte character set, so switch for all configurations General -> Character Set to Use Multi-Byte Character Set.
  4. Make sure Code Generation -> Enable Enhanced Instruction Set is set to /arch:SSE2 in release and debug.
  5. Following the same philosophy than Ogre and other libraries, I will build release and debug libraries with different names, in order to make it easier to add them by hand in my CMake project files. Switch to the debug configuration and find Target Name property at General, change its value to $(ProjectName)_d. It is advisable to rename the *.pdb files with the same name than the target name, so go to C/C++ -> Output files and and change its value to $(OutDir)$(TargetName).pdb.
  6. I will create another configuration for compiling in release mode with debugging information. Click on the Configuration Manager button. Unfold the Active Solution Configuration list, and select <New>. Then, choose in Copy settings from the release configuration, and use the CMake name for this kind of build RelWithDebInfo. Once the new configuration has been created, I recommend to save, close the IDE, and open it again. Now, make sure the release configuration does not include debugging information. C/C++ -> Debug Information Format should be empty, and this property in RelWithDebInfo configuration should be set to Program Database /Zi. Lastly, disable any optimization by setting C/C++ -> Optimization -> Optimization to Disabled (/Od).
  7. I do not want the whole program optimization, because other libraries do not use it, and some warnings or errors may happen when the final linking of my application is done. Hence, go to General -> Whole Program Optimization and set No Whole Program Optimization in release and RelWithDebInfo configurations. Besides, in Librarian -> Link Time Code Generation set it to No. Deactivation of /LTGC optimization flag must be done in both places, when compiling and when linking.

Finally, you are ready to compile and include the final results in your project. I created a new folder called Cryptopp with two folders: lib for the binaries and include for the header files. In my CMake files, ExternalDependencies.cmake contains the path to the include and binary folders, and the name of the libraries for the debug and release configurations, such as:

SET(EXTERNAL_DEPENDENCIES_DIR “${CMAKE_CURRENT_SOURCE_DIR}/Source/External”)

SET(EXTERNAL_DEPENDENCIES_INCLUDE_DIRS
“${EXTERNAL_DEPENDENCIES_DIR}/Boost”
“${EXTERNAL_DEPENDENCIES_DIR}/Ogre/include/OGRE”
“${EXTERNAL_DEPENDENCIES_DIR}/Ogre/include/OIS”
“${EXTERNAL_DEPENDENCIES_DIR}/Bullet/src”
“${EXTERNAL_DEPENDENCIES_DIR}/CEGUI/include”
“${EXTERNAL_DEPENDENCIES_DIR}/OpenNI/include”
“${EXTERNAL_DEPENDENCIES_DIR}/PrimeSense_NITE/include”
“${EXTERNAL_DEPENDENCIES_DIR}/Wiiuse/include”
“${EXTERNAL_DEPENDENCIES_DIR}/NatNetClient/include”
“${EXTERNAL_DEPENDENCIES_DIR}/TrackingTools/include”
“${EXTERNAL_DEPENDENCIES_DIR}/irrKlang/include”
“${EXTERNAL_DEPENDENCIES_DIR}/OpenCV/include”
“${EXTERNAL_DEPENDENCIES_DIR}/Cryptopp/include”
)

SET(EXTERNAL_DEPENDENCIES_LIBRARY_DIRS
“${EXTERNAL_DEPENDENCIES_DIR}/Boost/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/Ogre/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/Bullet/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/CEGUI/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/OpenNI/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/PrimeSense_NITE/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/Wiiuse/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/NatNetClient/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/TrackingTools/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/irrKlang/lib/Win32-visualStudio”
“${EXTERNAL_DEPENDENCIES_DIR}/OpenCV/lib”
“${EXTERNAL_DEPENDENCIES_DIR}/Cryptopp/lib”
)

SET(EXTERNAL_DEPENDENCIES_LIBRARIES_DEBUG
ogremain_d
ois_d
LinearMath_Debug
BulletCollision_Debug
BulletDynamics_Debug
irrKlang
CEGUIBase_d
CEGUIOgreRenderer_d
ws2_32
NatNetLibStatic
NPTrackingTools
wiiuse
opencv_core243d
opencv_highgui243d
opencv_imgproc243d
OpenNI
XnVNITE
cryptlib_d
)

SET(EXTERNAL_DEPENDENCIES_LIBRARIES_RELEASE
ogremain
ois
LinearMath
BulletCollision
BulletDynamics
irrKlang
CEGUIBase
CEGUIOgreRenderer
ws2_32
NatNetLibStatic
NPTrackingTools
wiiuse
opencv_core243
opencv_highgui243
opencv_imgproc243
OpenNI
XnVNITE
cryptlib
)

Advertisements

CMake and the executable stack size in Visual Studio

Today I have been struggling with my first mystical error at my new job. The C++ project was able to compile and execute. At least, the screen was showing the 3D initial menu. However, when I tried to open any of the sub-applications where big 3D models where used, strange exceptions were thrown, such as out of memory when loading a texture, vertex buffer can not be allocated, and similar ones depending on the sub-application executed.

I have been porting the project from a manually maintained .sln file to CMake. So, the first step was to make sure that the original executable was working, and it was. Then, I compared the compilation and linking flags in the both project files, and I removed the new flags, which were not present in the original solution, one by one. Finally, I discovered (after 5 hours) that CMake (version 2.8.10) adds to the linker flags /STACK:10000000, which means that the heap size is initialized to 10MB, instead of the default 1MB. Adding the following lines to the main CMake file:
STRING(REGEX REPLACE “/STACK:[0-9]+[ ]” “” CMAKE_EXE_LINKER_FLAGS “${CMAKE_EXE_LINKER_FLAGS}”)
SET(CMAKE_EXE_LINKER_FLAGS “${CMAKE_EXE_LINKER_FLAGS}”
CACHE STRING “Flags used by the linker.”
FORCE
)

solved the problem. Note that a similar problem may occur if there are multiple threads in the application, since the total amount of memory used will be num_threads by stack_size.

Note that this flag must be also removed from all your project dependencies that use CMake for generating project files. Then, the modified dependencies must be rebuild and finally your project, too.