♦ 🐆 2 min, 🐌 5 min
compiler
. But once our programs start to grow, we need to use slightly more powerful tools to manage all the mess.For the sake of this tutorial create first main.cpp
with the following content:#include
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
It should be clear what the above code is by now. If not consult the older posts.So instead of running lengthy terminal commands like:g++ -o my_project main.cpp -I/path/to/headers -std=c++11 -g
We can write a CMakeLists.txt
file and use that to specify how our C++
executable should be compiled. cmake
file should look?CMakeLists.txt
file with the following content (that's the minimal amount that should be in the file):cmake_minimum_required(VERSION 3.17)
project(my_project)
set(CMAKE_CXX_STANDARD 20)
add_executable(my_project main.cpp)
So what does each line do?With:cmake_minimum_required(VERSION 3.17)
we specify which minimum cmake
version we require on our system to build a particular project. If you can, use the latest available cmake
possible. Why? cmake
is regularly upgraded and became extremely powerful over the years. So use the cool new stuff 😉Next is project(my_project)
, which sets our project's name. It's required. Then:set(CMAKE_CXX_STANDARD 20)
Sets the C++
standard that we want to use. And the final line:add_executable(my_project main.cpp)
Specifies that we want to bundle main.cpp
into an executable called my_project
. And yes within one CMakeLists.txt
you can specify more different executables that all use different parts of your code. Just add another add_executable()
with another name of the output executable off course. cmake
?build
directory with mkdir
and move into it with cd
:> mkdir build
> cd build
We create this directory, so everything produced in the built process is in one place and not all over our codebase. Build files don't belong into the version control tree (those files shouldn't be on git
since they are computer specific).Then run cmake ..
The ..
part tells the cmake
to look for a CMakeLists.txt
file in one folder back, but spit the output files into the current directory.> cmake ..
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: ~/build
The output is nothing fancy. Now let's build the actual script using make
command:> make
Scanning dependencies of target my_project
[ 50%] Building CXX object CMakeFiles/my_project.dir/main.cpp.o
[100%] Linking CXX executable my_project
[100%] Built target my_project
Now you have an executable my_project
that you can run.If something goes wrong in the build process, you'll see errors here.You can speed-up make
process a bit with a flag -j [num_of_cores]
so for example if you have 8
cores:make -j 8
cmake
and make
? cmake
and make
besides the added c
:make
is a build system that uses Makefiles
cmake
is a build system generator. It can produce Makefiles
, Ninja build files, Xcode
build files, ...cmake
you can define how your script should be built independent of the platform and the build system and then generate the build files needed to compile your program for a specific platform.But make
is a bit slow and old, even with the parallel compiling. So there's, of course, a fester cousin on the market. Called ninja
.ninja
?make
. To install it on macOS:brew install ninja
Or on Debian/ubuntu:apt-get install ninja-build
For the rest of the platforms see here .The cool thing about ninja
is that it also ships with a python
module for generation of ninja
files. You can find the source of the python
interface here . I didn't find any other useful docs yet.make
with ninja
?ninja
build files, use the -GNinja
flag with cmake
:> cmake -GNinja ..
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: ~/build
While this printed output is the same, the created files are not.Now run ninja
:> ninja
[2/2] Linking CXX executable my_project
That's it. Parallelisation is used out of the box.All this hassle might sound like a bit too much, but once you have to start using libraries and your programs grow beyond hello world. You'll realise how powerful a build system and build system generator like cmake
can be.
Get notified & read regularly 👇