Book Image

C++ System Programming Cookbook

By : Onorato Vaticone
Book Image

C++ System Programming Cookbook

By: Onorato Vaticone

Overview of this book

C++ is the preferred language for system programming due to its efficient low-level computation, data abstraction, and object-oriented features. System programming is about designing and writing computer programs that interact closely with the underlying operating system and allow computer hardware to interface with the programmer and the user. The C++ System Programming Cookbook will serve as a reference for developers who want to have ready-to-use solutions for the essential aspects of system programming using the latest C++ standards wherever possible. This C++ book starts out by giving you an overview of system programming and refreshing your C++ knowledge. Moving ahead, you will learn how to deal with threads and processes, before going on to discover recipes for how to manage memory. The concluding chapters will then help you understand how processes communicate and how to interact with the console (console I/O). Finally, you will learn how to deal with time interfaces, signals, and CPU scheduling. By the end of the book, you will become adept at developing robust systems applications using C++.
Table of Contents (13 chapters)

Using a makefile to compile and link a program

A makefile is a file that describes the relationship among the sources of a program used by the make utility to build (compile and link) the target goal (executable, shared object, and more). Makefiles are really important as they help to keep sources organized and easy to maintain. A program, to become executable, must be compiled and linked with other libraries. GCC is the most widely used collection of compilers. The two compilers used in the C and C++ world are GCC and g++ (for the C and C++ programs, respectively). This book will use g++.

How to do it...

This section will show how a makefile is written, to compile and run a simple C++ program. We'll develop a simple program, and create its makefile to learn its rules:

  1. Let's start by developing the program by opening the hello.cpp file: 
$vi hello.cpp
  1. Type in the following code (refer to the Learning the Linux fundamentals - shell recipe to review the vi commands):
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
  1. Save and exit: in vi, from the command mode, type :wq, which means write and quit. The :x command has the same effect.
  2. From the shell, create a new file called Makefile:
$ vi Makefile
  1. Type in the following code:
CC = g++
all: hello
hello: hello.o
${CC} -o hello hello.o
hello.o: hello.cpp
${CC} -c hello.cpp
clean:
rm hello.o hello

Although this is a typical Hello World! program, it is useful to show how a makefile is structured.

How it works...

Simply, a makefile consists of a set of rules. A rule consists of a target, a list of prerequisites, and a command.

In the first step, we opened the file (hello.cpp) and typed the program listed in step 2. Likewise, we opened another file, Makefile, in the same folder of the hello.cpp program, and typed the specific makefile commands. Let's now dive into the makefile internals. A typical makefile has the following content:

  1. The first rule consists of a target called all, and a prerequisite called hello. There is no command for this rule.
  2. The second rule consists of a target called hello. It has a prerequisite on hello.o and a command to link: g++.
  3. The third rule has a target called hello.o, a prerequisite on hello.cpp, and a command to compile: g++ -c hello.cpp.
  4. The last rule has a clean target with a command to remove all the hello and hello.o executables. This forces the recompilation of the files.
  5. For any rule, if any of the source files change, then the command defined is executed.

We're now able to compile the program using the makefile we created:

$ make

We're also able to execute the program, whose output is as follows:

The process of generating a binary executable from a source file includes the phase of compilation and linking, which here is compressed inside a single command; it'll be like this in most cases. In general, a large system code base relies on more sophisticated mechanisms but the steps are still the same: source file editing, compilation, and linking.

There's more...

This simple example just showed us the very basic concepts of a makefile and its make command. There is much more to it than that. Here are a few examples:

  1. Use of macros: A makefile allows the use of macros, which can be seen as variables. These can be used to organize the makefile to be more modular, for example:
    • A macro for all the dynamic libraries used in the program: LIBS = -lxyz -labc
    • A macro for the compiler itself (in case you want to change to another compiler): COMPILER = GCC
    • Reference these macros over all the makefile: $(CC). This gives us the freedom to make changes in just one place.
  2. By just typing make on a shell, the first rule defined in the makefile will run. In our case, the first rule is all. If we changed the makefile by putting clean as a first rule, running make without parameters would execute the clean rule. In general, you'll always pass some parameters—for example, make clean.