Image source: Gartner (I’ve added the years to the original image)
The development of CMake began in 1999. The initial version was released by Kitware in the year 2000. Within the next five years, CMake was well recognized as a viable solution to build large open-source and proprietary projects alike. In 2006, KDE successfully migrated to CMake leaving behind their aging autotools build system. This came as a major triumph for CMake and – as it seems – to be the peak of Inflated expectations. It then took a painstaking wait of around ten years to release CMake 3.0 during which CMake – I would claim – went through the trough of disillusionment. Modern CMake (Versions after CMake 3.0) dropped many anti-patterns of classic CMake and has been riding on the Slope of Enlightenment. From Visual Studio 2017 to Qt 6.0 now deciding to support CMake, I believe, CMake currently has reached its plateau of productivity.
The CMake storm was twenty years in the making! Now that it has reached the plateau of productivity and the hype cycle has ended, let us see some of the success stories and why you should take modern CMake seriously.
Visual Studio and CMake
In long-running projects maintaining the sanity of visual studio projects and solutions is a pain, to put it mildly. It is not uncommon to see a branch being maintained that compiles only in Visual Studio 2010 to provide the customers with a migration path to later versions of the product. Maintaining multiple branches with different versions of the product compiled with different versions of Visual Studio is nothing short of a nightmare. Using CMake which generates the correct Visual Studio project/solution is Godsend. Starting with VS2017, Visual Studio comes bundled with Modern CMake (and Incredibuild is bundled inside Visual Studio). This makes it very easy to follow the CMake Visual Studio workflow to be adopted even for large projects. Now that CMake supports project generation and build for C# language, I expect CMake Visual Studio to become more popular in the Windows world. Here is a summary of why using Visual Studio CMake for your project makes sense:
- Maintaining multiple project and solutions in different branches are no longer needed. They are autogenerated from CMakefiles.txt file.
- A new version of Visual Studio does not necessitate the migration of solutions and projects. It is easy to be on the cutting edge of Visual Studio versions.
- Merging parallel work from different branches become a lot easier since there are no project/solution changes to be merged.
- Maintaining batch or Perl scripts is no longer necessary as CMake can automate builds.
- CI/CD pipelines built over CMake are a lot more maintainable than custom solutions based on homegrown scripts.
Visual Studio, CMake and WSL2
The amount of integration Visual Studio 2019 brings to Windows Subsystem for Linux version 2 is staggering. Without leaving the familiar Windows environment, developers can now start a CMake Visual Studio project, cross-compile it using Clang or GCC, and then debug the application running in WSL machine. When the project becomes stable, the cross-compilation hassle can be removed as the CMake Visual Studio based project is expected to configure and build correctly in the native environment.
CLion and CMake
CLion is an excellent cross platform integrated development from Jetbrains for C and C++ projects. CMake is the project model that is most deeply integrated into CLion. The smart CMake support in CLion is the best I have seen in any editor which makes working with CMake a pleasure.
Qt6.0 and CMake
December 2020 saw the release of “Next generation of Qt”, Qt6.0. Incredibuild has a great integration with Qt to speed up compilation time. You can read all about it here. One of the highlights of Qt6.0 was “CMake Support”. I quote them verbatim: “Use the industry-standard build system, with its wide feature set, large ecosystem to build Qt applications.” The emphasis is mine. Qt CMake integration was long in the pipeline.
Remember QMake? It is still supported but the recommended way is to use CMake for building your Qt6.0 based projects. What about the mammoth Qt source itself? Is that built using CMake too? I did a bit of research and stumbled on this blog post by Jörg Bornemann. Qt6.0 source is now built using CMake. No better proof that Qt CMake integration is really successful!
Vcpkg and CMake
(No part of this blog post is fiction; this part is a first-hand account of what transpired between me and an architect. Disclaimer: No architects were harmed during production)
On a busy Monday morning, I was pulled into a meeting with the architect of a high-flying project in our company. I was in charge of setting up the build pipeline for this project and things were rolling along fine. To satisfy a new requirement, the project was forced to include OpenSSL into their codebase and they wanted the nightly build to be up and running – yesterday.
Vcpkg to the rescue! Vcpkg install openssl even gave me the following lines:
The package openssl is compatible with built-in CMake targets:
target_link_libraries(main PRIVATE OpenSSL::SSL OpenSSL::Crypto)
The power of standardization! Vcpkg gave helpful hints how to integrate openssl into the build and the work was done, all in an hour!
VSCode and CMake
Microsoft’s Visual Studio Code is an open-source and cross-platform integrated development environment that has great support for CMake through its extension mechanism. It is easy to set up a C++ cross platform project that uses CMake to build in VS Code. It is even possible to use CMake: debug to debug the code within this excellent lightweight editor.
Node.js native addons are usually built using node-gyp, but CMake.js lets you build addons using CMake. This is definitely helpful for native developers since they don’t have to struggle with yet another build system.
Modern CMake is a great build generation system. Over the years many well-known open-source projects have adopted modern CMake because it is time tested and has great support on all major platforms (as opposed to Make). What is your success story with CMake?