Book Image

Advanced C++

By : Gazihan Alankus, Olena Lizina, Rakesh Mane, Vivek Nagarajan, Brian Price
5 (1)
Book Image

Advanced C++

5 (1)
By: Gazihan Alankus, Olena Lizina, Rakesh Mane, Vivek Nagarajan, Brian Price

Overview of this book

C++ is one of the most widely used programming languages and is applied in a variety of domains, right from gaming to graphical user interface (GUI) programming and even operating systems. If you're looking to expand your career opportunities, mastering the advanced features of C++ is key. The book begins with advanced C++ concepts by helping you decipher the sophisticated C++ type system and understand how various stages of compilation convert source code to object code. You'll then learn how to recognize the tools that need to be used in order to control the flow of execution, capture data, and pass data around. By creating small models, you'll even discover how to use advanced lambdas and captures and express common API design patterns in C++. As you cover later chapters, you'll explore ways to optimize your code by learning about memory alignment, cache access, and the time a program takes to run. The concluding chapter will help you to maximize performance by understanding modern CPU branch prediction and how to make your code cache-friendly. By the end of this book, you'll have developed programming skills that will set you apart from other C++ programmers.
Table of Contents (11 chapters)
6. Streams and I/O

Managing C++ Projects

In the world of C++, we have several tools that help in managing project sources and their dependencies. For example, pkg-config, Autotools, make, and CMake are the most notable ones in the community. Compared to the tools of the other high-level languages, these are much more complicated to use. CMake has arisen among these as the de facto standard for managing C++ projects and their dependencies. It is more opinionated compared to make, and it is accepted as the direct project format for most IDEs (Integrated Development Environments).

While CMake helps with managing projects and their dependencies, the experience is still far from higher-level languages in which you list the libraries and their versions that you want to use and everything else is taken care of for you. With CMake, you still are responsible for installing libraries properly in your development environment, and you are expected to use compatible versions for each library. In popular Linux distributions with extensive package managers, you can easily install binary versions of most popular libraries. However, sometimes, you may have to compile and install the libraries yourself. This is a part of the whole C++ developer experience, which you will gather by learning more about the development platform of your choice. Here, we will focus more on how to properly set up our CMake projects, including understanding and resolving issues related to libraries.

The Code-Build-Test-Run Loop

In order to base our discussion on a solid foundation, we will immediately start with a practical example. We will start with a C++ code base template that you can use as a starting point for your own projects. We will see how we can build and compile it using CMake on the command line. We will also set up the Eclipse IDE for C/C++ developers and import our CMake project. The use of an IDE will provide us with facilities that ease the creation of source code and enable us to debug our programs line by line to view what exactly happens during the execution of our program and correct our mistakes in an informed fashion rather than trial and error and superstition.

Building a CMake Project

The de facto standard for C++ projects is to use CMake to organize and build the project. Here, we will use a basic template project as a starting point. The following is the folder structure of a sample template:

Figure 1.1: Folder structure of a sample template
Figure 1.1: Folder structure of a sample template

In the preceding figure, the .gitignore file lists the file patterns that should not be added to the git version control system. Such ignored files include the outputs of the build process, which are created locally and should not be shared among computers.

The files in the include and src folders are the actual C++ source files, and the CMakeLists.txt file is the CMake script file that glues the project together by handling the source compilation rules, library dependencies, and other project settings. CMake rules are high-level platform-independent rules. CMake uses them to create various types of make files for different platforms.

Building a project with CMake is a two-step process. First, we get CMake to generate platform-dependent configuration files for a native build system that will compile and build the project. Then, we will use the generated files to build the project. The platform-dependent build systems that CMake can generate configuration files for include UNIX Makefiles, Ninja build files, NMake Makefiles, and MinGW Makefiles. The choice here depends on the platform in use, the availability of these tools, and personal preference. UNIX Makefiles are a de facto standard for Unix and Linux, whereas NMake is its Windows and Visual Studio counterpart. MinGW, on the other hand, is a Unix-like environment in Windows in which Makefiles are also in use. Ninja is a modern build system that provides exceptional speed compared to other build systems coupled with multi-platform support, which we choose to use here. Furthermore, in addition to these command-line build systems, we can also generate IDE projects for Visual Studio, XCode, Eclipse CDT, and many others, and build our projects inside the IDE. Therefore, CMake is a meta tool that will create the configuration files for another system that will actually build the project. In the next section, we will solve an exercise, wherein we will generate Ninja build files using CMake.

Exercise 1: Using CMake to Generate Ninja Build Files

In this exercise, we will use CMake to generate Ninja build files, which are used to build C++ projects. We will first download our source code from a git repository and will use CMake and Ninja to build it. The aim of this exercise is to use CMake to generate Ninja build files, build the project, and then run them.


The link to the GitHub repository can be found here:

Perform the following steps to complete the exercise:

  1. In a terminal window, type the following command to download the CxxTemplate repository from GitHub onto your local system:

    git clone

    The output of the previous command is similar to the following:

    Figure 1.2: Checking out the sample project from GitHub
    Figure 1.2: Checking out the sample project from GitHub

    Now you have the source code in the CxxTemplate folder.

  2. Navigate into the CxxTemplate folder by typing the following command in the terminal:

    cd CxxTemplate

  3. Now you can list all the files in the project by typing the following command:

    find .

  4. Generate our Ninja build file using the cmake command in the CxxTemplate folder. To do that, write the following command:

    cmake -Bbuild -H. -GNinja

    The output of the preceding command is as follows:

    Figure 1.3: Generating the Ninja build file
    Figure 1.3: Generating the Ninja build file

    Let's explain parts of the preceding command. With -Bbuild, we are telling CMake to use the build folder to generate build artifacts. Since this folder does not exist, CMake will create it. With –H., we are telling CMake to use the current folder as the source. By using a separate build folder, we will keep our source files clean and all the build artifacts will live in the build folder, which is ignored by Git thanks to our .gitignore file. With –GNinja, we are telling CMake to use the Ninja build system.

  5. Run the following commands to list the project files and to check the files that were created inside the build folder:


    ls build

    The preceding command will show the following output in the terminal:

    Figure 1.4: Files in the build folder
    Figure 1.4: Files in the build folder

    It's clear that the preceding files will be present inside the build folder. and in the preceding output are the Ninja build files that can actually build our project in this platform.


    By using CMake, we did not have to write the Ninja build files and avoided committing to the Unix platform. Instead, we have a meta-build system that can generate low-level build files for other platforms such as UNIX/Linux, MinGW, and Nmake.

  6. Now, go into the build folder and build our project by typing the following commands in the terminal:

    cd build


    You should see a final output like the following:

    Figure 1.5: Building with ninja
    Figure 1.5: Building with ninja
  7. Type ls in the build folder and check whether we have generated the CxxTemplate executable or not:


    The previous command yields the following output in the terminal:

    Figure 1.6: Files in the build folder after running ninja
    Figure 1.6: Files in the build folder after running ninja

    In the preceding figure, you can see that the CxxTemplate executable is generated.

  8. In the terminal, type the following command to run the CxxTemplate executable:


    The previous command in the terminal will provide the following output:

Figure 1.7: Running the executable

The following line from the src/CxxTemplate.cpp file is responsible for writing the previous output:

std::cout << "Hello CMake." << std::endl;

Now you have successfully built a CMake project in Linux. Ninja and CMake work quite well together. You have to run CMake only once and Ninja will detect whether CMake should be called again and will call it for you. For example, even if you add new source files to your CMakeLists.txt file, you only need to type the ninja command in the terminal, and it will run CMake automatically for you to update the Ninja build files. Now that you have learned about building a CMake project in Linux, in the next section, we will look at how to import a CMake project into Eclipse CDT.