Build Systems¶
Build systems are tools to automate the process of compiling source code, managing dependencies, and generating executable artifacts.
1. Category¶
1.1. Make¶
Make is a build system in Unix-like environments to build targets from rules declared in a Makefile, and updates only what is out of date based on file dependencies and timestamps.
Note
Makefile recipes require tab indentation (not spaces).
-
Project Layout and Directory Structure
-
Files and Folders
-
MakefileRoot build definition. Declares targets, dependencies, compiler flags, and utility targets such as
clean.CC = gcc CFLAGS = -Wall -Wextra -Werror -std=c11 TARGET = myprogram OBJ = main.o utility.o TAB := $(shell printf '\t') .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJ) $(TAB)$(CC) $(CFLAGS) -o $@ $^ main.o: src/main.c src/utility.h $(TAB)$(CC) $(CFLAGS) -c $< -o $@ utility.o: src/utility.c src/utility.h $(TAB)$(CC) $(CFLAGS) -c $< -o $@ clean: $(TAB)rm -f $(OBJ) $(TARGET) -
src/main.cEntry point that calls functionality from
utility. -
src/utility.cImplementation file for reusable helper functions.
-
src/utility.hPublic declarations shared between translation units.
-
-
Instructions and Commands
-
Build
Compile and link the default target.
-
Run
Execute the generated binary.
-
Clean
Remove generated objects and binaries.
-
1.2. CMake¶
CMake is a cross-platform build system generator for C, C++, and other languages. Modern CMake emphasizes target-based design (properties, include paths, and links attached to targets), reproducible configuration via CMake presets, and clear separation of source and build trees.
-
Project Layout and Directory Structure
-
Files and Folders
-
CMakeLists.txtRoot build entry point. Defines global project metadata and includes subdirectories. Keep this file small and delegate target definitions to child directories.
-
CMakePresets.jsonStandardized, shareable configure/build presets. Improves reproducibility across local machines and CI.
{ "version": 7, "cmakeMinimumRequired": { "major": 3, "minor": 30, "patch": 0 }, "configurePresets": [ { "name": "dev-debug", "displayName": "Development Debug", "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { "CMAKE_EXPORT_COMPILE_COMMANDS": true, "CMAKE_BUILD_TYPE": "Debug" } }, { "name": "dev-release", "displayName": "Development Release", "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { "CMAKE_EXPORT_COMPILE_COMMANDS": true, "CMAKE_BUILD_TYPE": "Release" } } ], "buildPresets": [ { "name": "build-debug", "configurePreset": "dev-debug" }, { "name": "build-release", "configurePreset": "dev-release" } ] } -
src/CMakeLists.txtAggregates subdirectories that define their own targets and dependencies.
-
src/app/CMakeLists.txtDefines executable and links against internal library targets.
-
src/foo/CMakeLists.txtDefines a reusable library and publishes the root-level
include/directory with proper visibility. -
src/app/main.cppApplication entry point that consumes the
foolibrary using a namespaced include path (foo/foo.hpp). -
src/foo/foo.cppImplementation for the library API.
-
include/foo/foo.hppPublic header for the
foolibrary target. When installed this header should be available asfoo/foo.hppso consumers use namespaced includes.
-
-
Instructions and Commands
-
Configure
Configure the project using the debug preset.
-
Build
Build all targets defined by the selected preset.
-
Run
Execute the generated binary from the build tree.
-
Clean
Remove generated artifacts by deleting the build directory.
-
1.3. Gradle¶
Gradle is a build automation tool commonly used for Java, Kotlin, and Android projects. It uses a declarative build model and supports dependency management, incremental builds, and task orchestration.
-
Project Layout and Directory Structure
-
Files and Folders
-
settings.gradleDeclares the root project name and included modules.
-
build.gradleDefines plugins, dependencies, Java toolchain settings, and custom tasks.
plugins { id 'application' } group = 'com.example' version = '1.0.0' repositories { mavenCentral() } java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } dependencies { implementation 'com.google.guava:guava:33.4.8-jre' testImplementation 'org.junit.jupiter:junit-jupiter:5.12.0' } application { mainClass = 'com.example.MyApplication' } tasks.test { useJUnitPlatform() } -
src/main/java/com/example/MyApplication.javaApplication entry point.
-
src/test/java/com/example/MyApplicationTest.javaUnit test verifying basic behavior.
-
-
Instructions and Commands
-
Build
Compile and package the project.
-
Run
Execute the application configured by the
applicationplugin. -
Test
Run unit tests.
-
Clean
Remove generated build outputs.
-
1.4. Maven¶
Maven is a build and dependency management tool for Java projects. It uses a standardized project layout and a lifecycle-based model configured through pom.xml.
-
Project Layout and Directory Structure
-
Files and Folders
-
pom.xmlProject Object Model (POM) file that defines coordinates, Java version, dependencies, and plugins.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>myproject</artifactId> <version>1.0.0</version> <properties> <maven.compiler.release>21</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.12.0</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.5.2</version> </plugin> </plugins> </build> </project> -
src/main/java/com/example/MyApp.javaMain class for the application.
-
src/test/java/com/example/MyAppTest.javaUnit test class.
-
-
Instructions and Commands
-
Build
Compile, test, and package the project.
-
Run Tests
Execute the test phase only.
-
Clean
Remove generated artifacts.
-
1.5. Ant¶
Ant (Another Neat Tool) is an XML-based Java build tool. It provides explicit control over build steps through named targets and dependencies.
-
Project Layout and Directory Structure
-
Files and Folders
-
build.xmlMain Ant script that defines properties and targets such as
clean,compile, andjar.<project name="MyProject" default="build"> <property name="src.dir" value="src"/> <property name="build.dir" value="build"/> <property name="dist.dir" value="dist"/> <target name="clean"> <delete dir="${build.dir}"/> <delete dir="${dist.dir}"/> </target> <target name="compile" depends="clean"> <mkdir dir="${build.dir}"/> <javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false"/> </target> <target name="jar" depends="compile"> <mkdir dir="${dist.dir}"/> <jar destfile="${dist.dir}/MyProject.jar" basedir="${build.dir}"> <manifest> <attribute name="Main-Class" value="com.example.MyApp"/> </manifest> </jar> </target> <target name="build" depends="jar"/> </project> -
src/com/example/MyApp.javaApplication entry point.
-
-
Instructions and Commands
-
Build
Run the default target (
build), which compiles and packages the JAR. -
Run
Execute the generated JAR.
-
Clean
Remove generated build and distribution directories.
-
1.6. Bazel¶
Bazel is a scalable build system designed for monorepos and multi-language projects. It uses declarative targets, strict dependency graphs, and aggressive caching for reproducible builds.
-
Project Layout and Directory Structure
-
Files and Folders
-
WORKSPACEDeclares the workspace and external dependencies.
-
BUILDDefines top-level targets such as executables and their dependencies.
-
src/BUILDDefines package-level library targets.
-
src/main.ccEntry point that consumes the internal library.
-
-
Instructions and Commands
-
Build
Build the binary target.
-
Run
Build and run the binary target.
-
Clean
Remove Bazel output state (expensive, use only when needed).
-
1.7. Ninja¶
Ninja is a fast, low-level build system focused on minimal overhead and fast incremental rebuilds. It is commonly used as an execution backend generated by tools such as CMake and Meson.
Note
Ninja relies on external tools to generate the build.ninja file that declares rules and targets.
-
Project Layout and Directory Structure
-
Files and Folders
-
build.ninjaDeclares variables, rules, and targets used by the Ninja executor.
-
src/main.cppMinimal source file compiled by Ninja.
-
-
Instructions and Commands
-
Build
Execute the default target.
-
Run
Execute the generated binary.
-
Clean
Remove generated outputs known to Ninja.
-