CMake is cross-platform build and configuration system for C and C++ code, which also happens to be my favourite build system. In this post, I’ll present a quick tutorial on getting started with CMake.
But before we do, let’s start with an example of why other build systems such as Makefiles don’t necessarily cut it. Actually, Makefiles work fairly well, but writing Makefiles by hand is generally a pain in the neck. In a previous post, I described how to write Makefiles that take include file dependencies into account. If that post did not convince you that writing Makefiles is hard, let me show you another example of a terrible Makefile and hope that it scares you into never looking at a Makefile again. (This Makefile was actually part of a project that was handed over to me, I had to go over tonnes of other people’s code with comments written in non-ascii characters in a language that wasn’t English, so I clearly don’t have fond memories of this particular project.)
I’ve seen way too many projects that supply a makefile that requires the user to run make clean and make every single time they make a change to some file. This is annoying and error prone, and the good news is that it can be easily solved with this one simple trick. Use a good build-generation system like CMake instead.
I’ve seen a lot of people (I’m looking at you Daniel Lemire) praise newer languages like Go, which makes me sad as a C++ programmer. Well, that’s until I realise that most of the features touted could be easily incorporated in C++ with just a bit of elbow grease. In this post, I’ll show how to add an automated testing system using CTest.
Some days ago, I became aware of a bug in GCC that has apparently existed since 2015. As this is a bug that deals with memory leaks, it is fairly serious.
In this case, I really don’t want to re-post the entire content of the source, so I will only list my experiments with reproducing the bug once I became aware of it.
C++ assumes that if a constructor fails, then no memory is allocated for the object at all. This means that if a nested object was constructed, C++ will implicitly call the destructor for that object so that the programmer does not have to worry about partially constructed states. This bug in GCC exists because under certain circumstances, GCC fails this assumption.
With the <random> header in C++11 onwards, there really is no reason to use std::rand() to generate random numbers. In fact, using std::rand() could be really harmful.
I use Linux when I work from home, I’m forced to use a Mac at work (well, I boot up a virtual Linux OS), and I use Windows when I just want to goof around with my computer. So, while most of my work is done on Linux, it’s imperative that my code work on all platforms; just because I could use any of the three.
Traditionally, C required multiple versions of code, protected by #ifdefs. This often required multiple versions of code to be written, depending on the target system, target OS, and compiler being used. Clumsy and messy system.
People familiar with the GNU/Unix system would know that the standard way to install about any GNU software from code is to run the following commands
configure make sudo make install These commands are from the GNU autotools environment. Knowing the GNU environment, these tools are what I used to compile most of the (relatively small) pieces of code I wrote.
Until I discovered CMake.
CMake, or Cross-platform Make is a tool that serves the same functionality as the GNU autotools (hereafter referred to as autohell). As the name suggests, CMake can be used to compile software across multiple platforms.