Basic Usage: Generators, Building#

Single Monolithic Executable#

  • Simple toolchain demo follows (see Toolchain: Basics)

  • Simplest; default output name: a.out

    $ gcc hello-single.c
    $ ./a.out
    Hello World
    
  • Explicit output name hello-single

    $ gcc -o hello-single hello-single.c
    $ ./hello-single
    Hello World
    
  • Wish list item: out-of-source build. Why?

    • Output files like hello-world need to be added to .gitignore

    • Source might be on a medium that is more expensive; RAID for example.

    • Build for multiple architectures ⟶ cannot mix all in one single directory

    • All in all: source tree must be read-only (if only for hygiene)

  • ⟶ CMake

Building With CMake#

cmake_minimum_required(VERSION 3.16)
project(Demo)
add_executable(hello-single hello-single.c)
  • CMakeLists.txt in each subdirectory that participates in the build

    • We have only one so far, and that is trivial

  • cmake_minimum_required(): required by CMake; used to declare which features we will need (or fail)

  • project(): used in many corners, e.g. package names

    • VERSION parameter (optional); will use it later

  • add_executable()

Building With CMake: Separate Source And Build Directories#

  • Source directory, e.g. ~/My-Projects/01-single

    • Version controlled

  • Build directory, e.g. ~/My-Builds/01-single-x86_64

    • Not version controlled ⟶ does not interfere with version control (no need to .gitignore build directory)

    • Completely resurrectable

    • Not subject to backups

    • Cheap/fast storage medium (RAM filesystem?)

  • Simplest way of building

    • Change to build directory

    • Call cmake to build Makefile skeleton (or ninja) from the source directory

    • Call make (or ninja, for that matter) in the build directory

Create Makefile structure#
$ cd ~/My-Builds/01-single-x86_64
$ cmake ~/My-Projects/01-single
-- The C compiler identification is GNU 12.2.1
-- The CXX compiler identification is GNU 12.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /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: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.7s)
-- Generating done (0.0s)
-- Build files have been written to: /home/jfasch/My-Builds/01-single-x86_64
Build using make#
$ make
[ 50%] Building C object CMakeFiles/hello-single.dir/hello-single.c.o
[100%] Linking C executable hello-single
[100%] Built target hello-single

Executables Consisting Of Multiple Sources#

  • Programs are rarely so simple

  • Separate compilation units

  • ⟶ potential code re-use

  • add_executable() can take more than one source file parameters

cmake_minimum_required(VERSION 3.16)
project(Demo)

add_executable(hello-modular hello-main.c hello.c) # <-- two compilation units

Problem: Duplicate Compilation#

  • Duplication of build rules (hello.c is built twice)

  • Show CMakeFiles/

cmake_minimum_required(VERSION 3.16)
project(Demo)

add_executable(hello-first hello-first.c hello.c)
add_executable(hello-second hello-second.c hello.c)

Problem: More Functionality#

  • Quick look into hello-name.[hc], and hello-second.c

  • Both hello.o and hello-name.o are compiled twice ⟶ quadratic build time explosion

cmake_minimum_required(VERSION 3.16)
project(Demo)

add_executable(hello-first hello-first.c hello.c hello-name.c)
add_executable(hello-second hello-second.c hello.c hello-name.c)

Solution: Libraries#