This tutorial is about building a typical C/C++ Linux project, an application linked against one static library and one shared library, using three different compilation methods: Makefiles, Autotools and CMake. A complete source code is available for download.
This tutorial is meant as a short technical guide for beginners looking for ready-to-use basic samples that they can easily study, understand and extend.
The typical C/C++ project is composed of an application, a shared library and a static library respectively coded in helloworld, helloshared and hellostatic folders.
The three compilation methods are illustrated as the following figure:
Each folder (the name is self-explanatory) refers to a compilation method and contains two scripts hello_clean_all.sh and hello_build_all.sh that can be called to, respectively, clean and build each project from scratch. The main.cc, helloshared.h, helloshared.cc, hellostatic.h, hellostatic.h source and header files are identical in all folders. Theses projects also show how to set RPATH to load a shared library (an alternative to the LD_LIBRARY_PATH environment setting, built in directories, updating /etc/ld.so.conf …).
I used Ubuntu 11.04 (Natty) as a development platform. I assume that you are familiar with installing packages. You need to install:
$ sudo apt-get install build-essential $ sudo apt-get install automake $ sudo apt-get install libtool $ sudo apt-get install cmake
Makefile based project
A makefile is a text file that consists of a set of targets, dependencies and rules. Dependecies are statements to make a target (a target is usually an executable, a library or object file name). Rules are commands needed to construct the target. The contents are basically arranged as:
target: dependencies [tab] commands
A Makefile based project is built using the make command. This command keeps track of which portions of the entire program have been changed and compiles only those parts which have changed by comparing the last-modification times.
A minimal Makefile based project requires only one file: The Makefile (a programmer-defined file).
Building and installing a Makefile based project is usually done as follows:
$ make $ make install
Writing and debugging complex makefiles can be difficult due to their syntax. Many C/C++ projects still rely on makefiles for their automated builds. Consequently, reading and writing them is a valuable skill.
Autotools based project
Autotools make it easy for developers to create portable softwares across many Unix/Linux operating systems. They mainly refer to a collection of three tools: Autoconf, Automake, and Libtool.
Autoconf is used to generate a configure script.
Automake creates portable Makefiles that will be processed by the make utility.
Libtool manages the creation of static and dynamic libraries platform-independently.
A minimal Autotools based project requires only two files:
– Makefile.am: a programmer-defined file and an input file to automake. It specifies build requirements.
– configure.in: an input file to autoconf. It contains macro invocations and ordinary shell code that autoconf uses to build a configure script.
Building and installing an Autotols based project is usually done as follows:
$ ./configure $ make $ make install
The Autotools are sometimes hard to debug due to the interdependencies between M4 macros, automake and make constructs. Moreover, automake is very slow when dealing with large projects.
CMake based project
CMake is an open-source and a cross-platform tool that generates native build environments (Makefiles for UNIX/Linux, Visual Studio projects for Windows and Xcode for Apple). It also has minimal dependencies, requiring only C++ on the build system.
A minimal CMake based project requires only one file: The CMakeLists.txt (a programmer-defined file that contains the project settings and describes the flow control of the build process).
Building and installing a CMake based project is usually done as follows:
$ cmake ./
CMake is more intuitive than writing a standard Makefile or using Autotools. It also significantly reduces the complexity of cross-platform software development and maintenance processes. For all these reasons, this tool is highly recommended.
Complete source code at typical_cc++_linux_project (save the file locally as typical_cc++_linux_project.tar.gz).
Several items covered in this document would require their own tutorials. A good starting point is to start studying the hello_clean_all.sh and hello_build_all.sh scripts because they show all the required steps to compile each project type.