Starting a C++ project with CMake in 2024
published at 15.03.2024 18:59 by Jens Weller
Save to Instapaper Pocket
Last year I've written last year about my plans to return to C++, taking on some project ideas with C++20 and CMake.
The first project is now in its beginning, so I thought to share the steps so far. Some of this blog post is covered by my recent talk Starting a modern C++ project with CMake in 2024. In this post I'm going stay within the parts of the build tooling, following up with the code in other posts.
After working through the official CMake tutorial, I wanted to start an actual project. But not in writing the CMake from scratch, I was curious if a CMake generator could do a good job here and save me time. Also this will kinda give all my future projects a similar layout, as I'm likely to use the generator again. I've compared various ways of generating projects for CMake, and decided for now to use cmake-init.
Regarding other tooling, I use QtCreator as my IDE.
Starting with a library at first
I've decided to split up my project into 3 subprojects: the UI Application, and two libraries for this UI Application: a general C++ library and a library that hosts the classes needed for the UI. As for the UI I use Qt in LGPL, the splitting in two libraries allows me to choose a different license for the general C++ Library. And at the moment, thats where I am, this library is now implemented.
My first try to bring this to life with cmake-init:
cmake-init . -s --std 20 --examples
This was executed in the folder for the project and created a CMake library and example and test executable. When I've started to play around with this in QtCreator, I've noticed that the clang-tidy settings it seemed to pick up on was for me a bit too noisy. So I've decided to give this a try without support for clang-tidy (and cppcheck, as I don't have this currently installed)
cmake-init . -s --std 20 --examples --no-clang-tidy --no-cppcheck
And with that I was setup to start my project. What I like is that this gives me a library + the test executable in one project. When starting library projects with other generators this was never setup. But I think its crutial for the workflow that you start your library with the tests being your first client. Moving forward I will have to do some refactoring to account for some of the changes coming from the way Qt handles things, and verifying directly with the tests that this works as intended is a great benefit.
Though there are some minor issues. First, at least QtCreator only picks up a Debug build when configuring the project with the first opening. Seems I've got to read into the CMakePresets.json format to add a release build in the future. Also QtCreator does not pick up on the headers, I've had to add them to the CMakeLists.txt file in order to have them showup. But usually I just navigate with F4 or ctrl + click on #include. I'm not sure if cmake-init or QtCreator placed the project locally into git. Its a nice to have and my plan is to push this to Github once things are more stable.
For the moment I'm not using a package manager, but may add conan in the future.
Other options I've tried
First I'd like to mention Jason Turners CMake Starter Template. Its great, but doesn't quite fit what I was looking for. First, its already an application, and at the moment I'm more looking for a library template. When playing around with it last year it became also clear that it is quite advanced and adds some other technologies to my learning curve. With just having learned CMake, some of this was a bit too much. I remember getting emails from failing github actions, just because I played around a bit and broke things. If you've got a bit more experience with the general tooling that Jason includes, its a great starter point for applications I'd say. It comes with CPM preconfigured to include any libraries you might need in your project.
Prior to using cmake-init in 2024 it came to my attention that I've not tried out what using QtCreator to start the project would give me. Like most IDEs in the past, it created a working library project, which did not include an executable for tests. Though it did include Qt, which in this project wasn't needed. But this gives me a great way to see how to include Qt into CMake from QtCreators point of view.
Most recently I've started to play around with Conan 2.0, after watching CMake and Conan: past, present and future at the watchparty event from Meeting C++ online. Diego pointed out that also conan can create projects with conan new. This line will create a library project with catch2 dependency:
conan new cmake_lib -d name=conan_libtest -d version=0.1 -d requires=catch2/3.5.2
Unfortunately this does not include a test executable. But I think that the conanfile.py created here is helpful. The 3.5.2 version is what cmake-init includes as a dependency when you use its package manager option. When I'll start using conan, I likely will merge these files together. As both cmake-init and conan generate conanfile.py files with good features. From conan comes a lot of the meta data and configuration, while cmake-init generates a more basic version.
And thats it for the moment. More ways to start a project exist, but in the end you got to start your project. At the moment the library is in its basic beta version finished, with the next project being to create a project that consumes the library, which will be the library for the Qt related code. I'll write more on the general plans for this project and the code of this first library in an upcoming post.
Talks to watch and more
There are two talks in particular that also deal with starting a c++ project:
- How to start a modern C++ project - Mikhail Svetkin - Meeting C++ 2023
- Dušan Jovanović — Start your C++ project today
- on learning CMake there is a great playlist by LearnQtGuide
And recently I've found this CMake tutorial from last year, which is worth a look.
Join the Meeting C++ patreon community!
This and other posts on Meeting C++ are enabled by my supporters on patreon!