Build C++ Application with GNU GCC by Command Line, GNU make and Cmake

Quoc Le
LecleVietnam
Published in
4 min readMay 4, 2020

There are many toolsets used to build C++ applications such as GCC, Visual C++, Borland… Today, I want to share about GNU GCC and how to build a complex C++ application with GCC since it’s a popular toolset for C++ developers, and it supports both Windows and Unix.

Overview

1. Installing GCC

2. Building C++ App by Command Line

3. Building C++ App by Makefile

4. Using Cmake to generate Makefile

Install GCC C/C++ Compiler

gcc -v

To understand the build process, I’ve made a project which has four modules: a simple executable helloworld, a static library, a dynamic library, and an executable. You can pull it from here

.├── helloworld
│ └── helloworld.cpp
├── phone
│ └── phone.cpp
├── dynamiclib
│ ├── include
│ │ └── software
│ │ ├── gmail.hpp
│ │ ├── googlemap.hpp
│ │ └── software.hpp
│ └── src
│ ├── gmail.cpp
│ ├── googlemap.cpp
│ └── software.cpp
└── staticlib
├── include
│ └── hardware
│ ├── camera.hpp
│ ├── hardware.hpp
│ └── screen.hpp
└── src
├── camera.cpp
├── hardware.cpp
└── screen.cpp

Building C++ App by Command Line

Helloworld:
Let’s start with helloworld example:

$ cd helloworld# -o : output file
$ g++ -o hello helloworld.cpp
$ ls
hello helloworld.cpp
$ ./hello
Hello, World!

Simple! right? Now let’s try a more complex application including static library and dynamic library:

Static library:

$ cd staticlib# Compile source file to object without linking
# -c: Only run preprocess, compile, and assemble steps (without linking)
# -I: Add directory to include search path
$ g++ -c -o camera.o src/camera.cpp -I include/hardware
$ g++ -c -o screen.o src/screen.cpp -I include/hardware
$ g++ -c -o hardware.o src/hardware.cpp -I include/hardware
# Link the object files into a static library
$ ar ru libhardware.a screen.o camera.o hardware.o
$ ranlib libhardware.a

Dynamic library:

$ cd dynamiclib# Compile source file to object without linking
$ g++ -c -o gmail.o src/gmail.cpp -I include/software
$ g++ -c -o googlemap.o src/googlemap.cpp -I include/software
$ g++ -c -o software.o src/software.cpp -I include/software
# create dynamic library
$ g++ -shared -fPIC -o libsoftware.dylib gmail.o googlemap.o software.o

An executable:

$ cd phone# Compile source file to object without linking
$ g++ -c -o phone.o phone.cpp -I ../staticlib/include -I ../dynamiclib/include
# linking the application with static and dynamic library
$ g++ -o phone phone.o -L../staticlib -L../dynamiclib -lhardware -lsoftware
Or$ g++ -o phone phone.o ../staticlib/libhardware.a ../dynamiclib/libsoftware..dylib# remember copy dynamic library to executable file or install in in directory where the system can read it. then run your application$ ./phoneThe list software:
Gmail
GoogleMap
The list hardware
Camera
Screen

Building C++ App by makefile

With large C++ projects — which can involve thousands of separate files, including source files, object files, libraries, and executables — building from the command line is a hard task. That’s why GNU also provides an automation tool — GNU Make.

Why should we use make? check here.

A simple makefile consists of rules with the following syntax:

target ... : prerequisites (dependencies) ...
recipe (system command)
...

The makefile to build helloworld:

Helloworld:

$ cd helloworld
$ touch makefile
$ vi makefile
# create the makefile as below
$ make
g++ -o hello helloworld.cpp
$ make install$ make clean

Static library:

$ cd staticlib
$ touch makefile
$ vi makefile
# create the makefile as below
$ make
g++ -I include/hardware -c -o src/camera.o src/camera.cpp
g++ -I include/hardware -c -o src/screen.o src/screen.cpp
g++ -I include/hardware -c -o src/hardware.o src/hardware.cpp
ar ru libhardware.a src/camera.o src/screen.o src/hardware.o
ar: creating archive libhardware.a
ranlib libhardware.a
$ make install$ make clean

Dynamic library:

$ cd dynamiclib
$ touch makefile
$ vi makefile
# create the makefile as below
$ make
g++ -I include/software -c -o src/gmail.o src/gmail.cpp
g++ -I include/software -c -o src/googlemap.o src/googlemap.cpp
g++ -I include/software -c -o src/software.o src/software.cpp
c++ -shared -fPIC -I include/software -o libsoftware.dylib src/gmail.o src/googlemap.o src/software.o
$ make install$ make clean

An executable:

$ cd phone
$ touch makefile
$ vi makefile
# create the makefile as below
$ make
g++ -I ../staticlib/include -I ../dynamiclib/include -c -o phone.o phone.cpp
g++ -o phone phone.o ../staticlib/libhardware.a ../dynamiclib/libsoftware.dylib
$ make install$ make clean

Next, create a top-level makefile in the directory containing software, hardware, phone, and binaries:

$ touch makefile$ vi makefile
# create the makefile as below
$ make$ make cmd=install
$ make cmd=clean
# run binary file$ cd binaries$ ./phone 
The list software:
Gmail
GoogleMap
The list hardware:
Camera
Screen

You can pull the detail makefile at here:

Using Cmake to generate makefile

We have a makefile that works perfectly on Unix. But makefile is only for experienced developers, who are familiar with the building process as well as working with command line.

That why Cmake was born and became popular. Cmake is used to generate standard build files (e.g., makefiles on Unix and projects/workspaces in Windows MSVC) which can compatible with almost platforms (Window, Linux, macOS), IDE (Codex, MSVS, Eclipse …).

Here is the reason why we need Cmake.

In this post, I will share how to write a CMakeLists.txt to build/install this project. You also can use the Cmake GUI to generate CMakeLists.txt

Helloworld:

Static library:

Dynamic library:

An executable:

Next, create a top-level CmakeLists to build whole projects

# build directory
$ mkdir build && cd build
# generate building files
$ cmake ..
...
-- Generating done
# build
$ make
Scanning dependencies of target hello
[ 8%] Building CXX object helloworld/CMakeFiles/hello.dir/helloworld.cpp.o
...
[100%] Built target phone
# run
$ ./phone/phone
The list software:
Gmail
GoogleMap
The list hardware:
Camera
Screen

You can pull the detail CmakeList.txt at here

With my sharing, I hope you will understand the building processes for C++ App and how to build a large C++ project. This will help you a lot to troubleshoot problems in compiling and running an application.

--

--