Coming from other build systems to CMake one will quickly learn that CMake can build only one configuration at a time. In practice you need to set up multiple build directories and configure/build with CMake for each and every one.
Autotools can do static and shared builds of libraries. For CMake
most of the project would do a static build, then a shared build
by setting the CMake variable
QMake can do debug and release builds at the same time, and as we can read at Qt for Android better than ever before, it can configure multiple Android architecture configurations at the same time.
What can we do to get the same level of convenience with CMake?
Shared and static
CMake needs to have unique target names, so if we would have to build a shared and static build we would need to have different target names.
Since we need to build the same library twice, but with only
cmake --build invocation, it would mean that CMake needs
to call itself.
That’s it what I’m going to do. Build the same source directory in two different build directories. The add_subdirectory CMake command allows a second parameter for a build directory.
Here is what’s needed to have a library build itself shared and static:
Debug and release
If we apply the same idea to a debug and release build, we have:
This will work with command line generators like Ninja or Makefiles, but it won’t work with multi-config generators like Visual Studio.
Debug and release for Visual Studio
In order to get Visual Studio to produce a debug and release mode,
we need to be able to invoke CMake with separate
values for Debug and Release.
Even if we fiddle with CMAKE_CONFIGURATION_TYPES the above method is not enough. msbuild will fail to build.
We need to get independent CMake runs on the same source code. Luckily CMake provides us with ExternalProject module.
ExternalProject is meant for software downloaded from the internet, but
it also works fine with existing source code
The code looks like this:
I needed to restrict the
CMAKE_CONFIGURATION_TYPES only for the needed configuration,
and to have a custom
INSTALL_COMMAND, and to install the library.
At the end in the build directory I’ve got a
lib directory containing the two libraries.
Android multi architecture
In order to test the same setup for Android, I am assuming you have the Android NDK somewhere in your system.
I configured and build the project from a Windows command prompt window like this:
The CMake code which builds for
x86_64 is below:
I only needed to pass the
With the technique presented here CMake can easily do multiple configuration builds in one go!