On this page

Make / CMake / Meson Build Systems

Coverage: GNU Make (pattern rules) → CMake (target-based) → Meson (declarative) → pkg-config → Build system selection Applicable to: C/C++ project builds

GNU Make

Core Syntax

# Basic rule: target: prerequisites → recipe
prog: main.o lib.o
    gcc -o $@ $^            # $@=target, $^=all prerequisites

%.o: %.c                    # pattern rule
    gcc -c -o $@ $<         # $<=first prerequisite

# Variables:
CC := gcc
CFLAGS := -O2 -Wall
LDFLAGS := -lm

# Automatic dependency generation:
%.d: %.c
    gcc -MM -MF $@ $<
-include $(OBJS:.o=.d)     # include dependency files

CMake: Target-Based

# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(myproj C)

add_library(mylib STATIC lib.c lib.h)
target_compile_features(mylib PRIVATE c_std_11)

add_executable(prog main.c)
target_link_libraries(prog PRIVATE mylib)

# Find external dependencies:
find_package(PkgConfig REQUIRED)
pkg_check_modules(ZLIB REQUIRED zlib)
target_link_libraries(prog PRIVATE ${ZLIB_LIBRARIES})
target_include_directories(prog PRIVATE ${ZLIB_INCLUDE_DIRS})

Meson: Declarative

# meson.build
project('myproj', 'c', version: '1.0')

zlib_dep = dependency('zlib')

mylib = static_library('mylib', 'lib.c', 'lib.h')
executable('prog', 'main.c',
           link_with: mylib,
           dependencies: zlib_dep,
           c_args: ['-O2', '-Wall'])

Comparison of the Three

GNU MakeCMakeMeson
Modelimperative (how to do it)target-baseddeclarative (what is needed)
Dependency ManagementManualfind_package + pkg-configBuilt-in dependency()
Compilation SpeedBaselineSlow (configure phase)Fast (ninja + caching)
Learning CurveMediumMedium-HighLow
IDE IntegrationWeakStrong (CLion, VSCode)Medium
Gentoo ebuildCommonCommonIncreasing

pkg-config

# Query installed libraries:
pkg-config --cflags --libs zlib     # -I/usr/include -lz
pkg-config --modversion zlib         # 1.2.13

# .pc file locations:
ls /usr/lib64/pkgconfig/   # system libraries
ls /usr/share/pkgconfig/   # arch-independent

# Custom .pc file:
prefix=/usr/local
Name: mylib
Version: 1.0
Cflags: -I${prefix}/include
Libs: -L${prefix}/lib -lmylib

References

  • Documentation: info make, cmake.org/documentation, mesonbuild.com
  • Gentoo: man 5 ebuild (Make integration)

Keywords: Make, CMake, Meson, pattern rule, target-based, pkg-config, ninja