Building CppCMS using Visual Studio
Introduction
In general build on Windows using Microsoft Visual Studio is quite complex due to several factors:
- Lack of easily accessible already build libraries in both debug and release variants for your MSVC version
- Need of strict debug/release separation
So in order to make your life while building CppCMS simpler I suggest following rules:
Keep strict separation of debug and release installations and 32/64 bit architectures, for example
c:\cppcms_deps\x64\Debug c:\cppcms_deps\x64\Release c:\cppcms_deps\x86\Debug c:\cppcms_deps\x86\Release
Note: pcre, icu and zlib support debug/release mangling of the libraries/dlls for debug/release flavor, but OpenSSL does not. So I strongly recommend to use separate trees to ensure safety.
When building with CMake always use "NMake Makefiles" generator to prevent collisions of debug/release methods
- Start from basic dependencies zlib and pcre that can be built using CMake than go with more complex ones like OpenSSL and ICU if needed.
Before We Begin
Building Dependencies
- Install Visual Studio or Visual Studio build tools
- Install CMake, make sure it is in global path
- Install Python 2.x version, make sure it is in global path
- Optionally install git if you want to build upstream branches.
Checks: open cmd and try to run cmake, python and optionally git - see if it works.
And finally make sure the directories you are building in are not scanned by anti-virus - otherwise you may get some build failures - due to files being locked by AV.
Note: in all builds we will use Visual Studio console - open one for correct architecture.
For example:
- MSVC 2017 64 bit builds open:
x64 Native Tools Command Prompt for VS 2017
- MSVC 2017 32 bit builds open:
x86 Native Tools Command Prompt for VS 2017
I assume during this tutorial that you work in one of such a consoles.
Mandatory Dependencies
PCRE
PCRE comes with CMake build system, however building it correctly may be somewhat tricky.
Download the latest version of PCRE 8.x. Do not use PCRE2, it isn't supported.
Important options to note:
- Use "NMake Makefiles" generator, default generator is multi flavor one and much harder to use properly.
- Make sure you explicitly specify Release/Debug flavor
-DCMAKE_BUILD_TYPE=Release
- Build Shared version of PCRE (i.e. dll)
-DBUILD_SHARED_LIBS=ON
- Make sure you put
-DPCRE_SUPPORT_UNICODE_PROPERTIES=ON
option on to enable utf-8 support - otherwise regex tests will fail
Step by step in the console:
Release:
cd \path\to\pcre\soures mkdir msvc-release-x64 cd msvc-release-x64 cmake -DBUILD_SHARED_LIBS=ON ^ -DPCRE_SUPPORT_UNICODE_PROPERTIES=ON ^ -G"NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Release ^ -DCMAKE_INSTALL_PREFIX=c:\cppcms_deps\x64\Release ^ .. nmake nmake install cd ..
Debug:
cd \path\to\pcre\soures mkdir msvc-debug-x64 cd msvc-debug-x64 cmake -DBUILD_SHARED_LIBS=ON ^ -DPCRE_SUPPORT_UNICODE_PROPERTIES=ON ^ -G"NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Debug ^ -DCMAKE_INSTALL_PREFIX=c:\cppcms_deps\x64\Debug ^ .. nmake nmake install cd ..
zlib
Fortunately latest zlib versions come with CMake support making it much easier to build with Visual Studio.
- Use "NMake Makefiles" generator, default generator is multi version and much trickier to use.
- Make sure you explicitly specify Release/Debug flavor
-DCMAKE_BUILD_TYPE=Release
- Build Shared version of zlib (i.e. dll)
-DBUILD_SHARED_LIBS=ON
Step by step:
Open Visual studio command prompt, for example x64 Native Tools Command Prompt for VS 2017
or x86 Native Tools Command Prompt for VS 2017
and change directory to location of zlib sources. Create build directory and run the commands:
For example for x64 build
Release
mkdir msvc-release-x64 cd msvc-release-x64 cmake -DBUILD_SHARED_LIBS=ON ^ -G"NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Release ^ -DCMAKE_INSTALL_PREFIX=c:\cppcms_deps\x64\Release ^ .. nmake nmake install cd ..
Debug
mkdir msvc-debug-x64 cd msvc-debug-x64 cmake -DBUILD_SHARED_LIBS=ON ^ -G"NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Debug ^ -DCMAKE_INSTALL_PREFIX=c:\cppcms_deps\x64\Debug ^ .. nmake nmake install cd ..
Checking the build results.
After installation of PCRE and zlib you need to get structure like this:
c:\cppcms_deps\x64\Release c:\cppcms_deps\x64\Release\include c:\cppcms_deps\x64\Release\include\zlib.h c:\cppcms_deps\x64\Release\include\pcre.h ... c:\cppcms_deps\x64\Release\lib c:\cppcms_deps\x64\Release\lib\zlib.lib c:\cppcms_deps\x64\Release\lib\pcre.lib ... c:\cppcms_deps\x64\Release\bin c:\cppcms_deps\x64\Release\bin\zlib1.dll c:\cppcms_deps\x64\Release\bin\pcre.dll ... c:\cppcms_deps\x64\Debug c:\cppcms_deps\x64\Debug\include c:\cppcms_deps\x64\Debug\include\zlib.h c:\cppcms_deps\x64\Debug\include\pcre.h ... c:\cppcms_deps\x64\Debug\lib c:\cppcms_deps\x64\Debug\lib\zlibd.lib c:\cppcms_deps\x64\Debug\lib\pcred.lib ... c:\cppcms_deps\x64\Debug\bin c:\cppcms_deps\x64\Debug\bin\zlibd1.dll c:\cppcms_deps\x64\Debug\bin\pcred.dll
Note - the DLLs and libs with "d" suffix are placed in debug location.
Optional Dependencies
OpenSSL
Warning: OpenSSL does not mangle its Debug and Release flavors - so make sure you have a separate install prefix for two OpenSSL flavors and never mix them!
First of all you need to install perl as it is basic building and configuration tool. ActivePerl is recommended. Make sure it is in system path. Note: msys2 perl or cygwin perl does not work.
Note: Make sure you open correct MSVC console for x64 and x86 builds.
For 64 bit release build run the command:
perl Configure VC-WIN64A no-asm ^ --prefix=c:\cppcms_deps\x64\Release ^ --openssldir=c:\cppcms_deps\x64\Release
For 64 bit debug build run the command
perl Configure debug-VC-WIN64A no-asm ^ --prefix=c:\cppcms_deps\x64\Release ^ --openssldir=c:\cppcms_deps\x64\Release
For 32 bit release build run the command:
perl Configure VC-WIN32 no-asm ^ --prefix=c:\cppcms_deps\x86\Release ^ --openssldir=c:\cppcms_deps\x86\Release
For 32 bit debug build run the command
perl Configure debug-VC-WIN32 no-asm ^ --prefix=c:\cppcms_deps\x86\Debug ^ --openssldir=c:\cppcms_deps\x86\Debug
Afterwards run:
nmake nmake install
And between flavors make sure you run
nmake distclean
Notes:
VC-WIN64A
anddebug-VC-WIN64A
are 64 bit build flavors for release and debugVC-WIN32
anddebug-VC-WIN32
are32 bit build flavors for release and debug- no-asm - disable NASM dependency - not really needed
--prefix
and--openssldir
are location of build results
ICU
Several notes before building ICU on Windows.
- Don't use official builds from ICU website - it does not contain debug version and are build for only 1 specific MSVC versions.
- You can try get ready libraries there: https://www.npcglib.org/~stathis/blog/precompiled-icu/ however the site by not be updated or have variants for your version of MSVC.
- If you build ICU use cygwin/MSVC combination, do not use provided MSVC solution.
Using Downloadable binaries
You can get them there: https://www.npcglib.org/~stathis/blog/precompiled-icu
You need to put the include/bin/lib files to your tree according to correct paths debug/release and 32/64 bit. For example copy following:
Headers:
icu-59.1-vs2017/include/unicode -> c:\cppcms_deps\x64\Release\include\unicode c:\cppcms_deps\x64\Debug\include\unicode c:\cppcms_deps\x86\Release\include\unicode c:\cppcms_deps\x86\Debug\include\unicode
Import Libraries:
icu-59.1-vs2017/include/lib/*d.lib -> c:\cppcms_deps\x86\Debug\lib icu-59.1-vs2017/include/lib/*.lib -> # without d c:\cppcms_deps\x86\Release\lib icu-59.1-vs2017/include/lib64/*d.lib -> c:\cppcms_deps\x64\Debug\lib icu-59.1-vs2017/include/lib64/*.lib -> # without d c:\cppcms_deps\x64\Release\lib
DLLs:
icu-59.1-vs2017/include/bin/*d59.dll -> c:\cppcms_deps\x86\Debug\bin icu-59.1-vs2017/include/bin/*59.dll -> # without d c:\cppcms_deps\x86\Release\bin icu-59.1-vs2017/include/bin64/*d59.dll -> c:\cppcms_deps\x64\Debug\bin icu-59.1-vs2017/include/bin64/*59.dll -> # without d c:\cppcms_deps\x64\Release\bin
This may save you the hassle of building ICU.
Building ICU
Note instructions are based on instructions from there: https://wiki.qt.io/Compiling-ICU-with-MSVC
Steps to build:
- Download icu-xx-src.zip. Note zip, not tgz. The tgz does not contain all files for Windows build
- Install cygwin - only basic packages are needed:
make
,dos2unix
andbinutils
. Open Visual Studio console and configure path to location of cygwin\bin directory, so bash and other tools will be accessible:
set PATH=%PATH%;c:\cygwin\bin
This way you can run cygwin commands from MSVC command line
Go to source directory of the icu package and fix line encodings, otherwise bash will not work:
dos2unix * dos2unix -f configure
For release build run:
bash runConfigureICU ^ Cygwin/MSVC ^ --prefix=/cygdrive/c/cppcms_deps/x64/Release make make install make distclean
Distclean will allow to run debug configuration smoothly. Note cygwin style path to installation location:
/cygdrive/c/cppcms_deps/x64/Release
For debug build run
bash runConfigureICU ^ --enable-debug --disable-release ^ Cygwin/MSVC ^ --prefix=/cygdrive/c/cppcms_deps/x64/Debug make make install make distclean
Note
--enable-debug --disable-release
must go beforeCygwin/MSVC
- otherwise you'll get release binaries- Note, the installation script installs dlls to the same location as lib, so you need to move them from
c:\cppcms_deps\x64\(Release|Debug)\lib
toc:\cppcms_deps\x64\(Release|Debug)\bin
Now you have working ICU.
Building CppCMS
Several notes when building using MSVC:
- Only "NMake Makefiles" generator is supported
- You need to specify
-DCMAKE_BUILD_TYPE=Debug
or-DCMAKE_BUILD_TYPE=RelWithDebInfo
explicitly since default is Debug for MSVC. - You also recommend to add
-DDISABLE_STATIC=ON
since on Windows only dll version allows to build dynamically loadable views and use plugins.
So open the VS console, go to cppcms source directory and run configuration and build:
Release
Release build
mkdir msvc-x64-rel cd msvc-x64-rel cmake -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=RelWithDebInfo ^ -DDISABLE_STATIC=ON ^ -DCMAKE_INCLUDE_PATH=c:\cppcms_deps\x64\Release\include ^ -DCMAKE_LIBRARY_PATH=c:\cppcms_deps\x64\Release\lib ^ -DCMAKE_INSTALL_PREFIX=c:\cppcms_deps\x64\Release ^ .. nmake
Testing:
set PATH=%PATH%;c:\cppcms_deps\x64\Release\bin;.\booster\ nmake test
Installation:
nmake install
Debug
Debug build
mkdir msvc-x64-deb cd msvc-x64-deb cmake -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Debug^ -DDISABLE_STATIC=ON ^ -DCMAKE_INCLUDE_PATH=c:\cppcms_deps\x64\Debug\include ^ -DCMAKE_LIBRARY_PATH=c:\cppcms_deps\x64\Debug\lib ^ -DCMAKE_INSTALL_PREFIX=c:\cppcms_deps\x64\Debug ^ .. nmake
Testing:
set PATH=%PATH%;c:\cppcms_deps\x64\Debug\bin;.\booster\ nmake test
Installation:
nmake install
And now start development using CppCMS