Skip to content

DMsuDev/Basic-Makefile-Template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

96 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Modern C++ Makefile Template

Make Platform C C++ Status

MSVC Clang GCC

A clean, lightweight, and cross-platform Makefile for C++ projects.
Supports Windows (MinGW-w64/MSYS2), Linux, and macOS with minimal configuration.

Designed to be simple, readable, and easy to extend, ideal for game engines, tools, small-to-medium applications, learning projects, or as a starting point.

Demo

⭐ Features

  • βœ… Cross-Platform: Windows, Linux, macOS with automatic detection
  • βœ… Build Types: Multiple configurations (release, debug, relwithdebinfo, analyze) with proper optimization levels
  • βœ… Architecture Optimization: Architecture-specific optimization via ARCH variable (native, skylake, znver4, armv8-a, etc.)
  • βœ… Link-Time Optimization (LTO): Control LTO with USE_LTO flag (disabled by default in release builds)
  • βœ… Static Analysis: Built-in make analyze target for static code analysis
  • βœ… Dependency Tracking: Automatic .d file generation
  • βœ… Assembly Output: Generate assembly files (make asm) and disassembly (make disassemble)
  • βœ… Parallel Builds: Multi-core compilation support with automatic verbosity reduction
  • βœ… Sanitizers: AddressSanitizer and UndefinedBehaviorSanitizer support in debug builds (Linux/macOS)
  • βœ… Improved UI: Better build output with status indicators and build type information
  • βœ… Two Templates: Basic (simple) and Advanced (feature-rich)

🚩 Quick Start - Run the Examples

In the root directory is a main Makefile for building three complete examples:

  • Spinning ASCII Donut: A terminal-based 3D donut animation (in examples/donut-basic/)
  • ImGui + GLFW Demo: A graphical window using ImGui and GLFW (in examples/ImGui/)
  • Task Manager CLI: An advanced command-line task management system with JSON persistence (in examples/task-manager/)

Clone the repository

git clone https://github.com/DMsuDev/Basic-Makefile-Template.git
cd Basic-Makefile-Template

Steps to build and run the examples

# Option 1: View the spinning ASCII donut (terminal animation)
make run-donut

# Option 2: Open the ImGui window (graphical demo with GLFW)
make run-imgui

# Option 3: Run the task manager CLI example
make run-tm

# Option 4: Build all examples
make all

# Option 5: See available examples
make list

# Option 6: Get help
make help

Note: To run the ImGui example, copy the required glfw3.dll from the lib/ folder to the build/app/ directory after building.

For help: Type make help in the terminal to see all available commands.

πŸ“ Build Output Structure (v1.0.3+)

project/
β”œβ”€β”€ build/
β”‚   β”œβ”€β”€ app/          ← Executables
β”‚   β”œβ”€β”€ obj/          ← Object files (.o)
β”‚   β”œβ”€β”€ dep/          ← Dependency files (.d)
β”‚   └── asm/          ← Assembly files (.s) and disassembly
└── src/

Note: In v1.0.2 and earlier, executables were in build/bin/. Update scripts if needed.

Main Commands

Command Description When to use
make Release build (default target) Everyday development
make release Explicit Release build with optimizations Final/performance builds
make debug Debug build + symbols + sanitizers Bug hunting, ASan/UBSan
make relwithdebinfo Release with debug info (best of both) Profiling with symbol debugging
make analyze Static analysis build Code quality checks
make run Release build + execute binary Quick testing
make run-debug Debug build + execute binary Debugging sessions
make asm Generate Intel-syntax .s assembly files Inspecting compiler output
make disassemble Disassemble final binary (objdump) Optimization / reverse engineering
make clean Remove objects, deps, asm, binary Fresh start for current config
make clean-all Delete entire ./build/ directory Changing compiler or major flags
make help Show help message Quick reference
make info Show project configuration summary Verify paths, compiler, sources count

πŸš€ Parallel / Multi-Core Builds (Recommended for Speed)

The Makefile fully supports parallel compilation to use multiple CPU cores and dramatically reduce build times on modern machines.

How to Use It

# Use all available cores (recommended)
make -j$(nproc) run     # Linux/WSL/macOS
make -j8 run            # Windows or fixed number (adjust to your CPU)

# Example: build with 8 cores (rule `all` by default)
make -j8

# Or with run
make run -j12
  • Automatic behavior: When you use -j (parallel mode), the Makefile automatically reduces verbosity to avoid chaotic interleaved output.

    • No fancy colors or status icon per file
    • Only essential messages and errors are shown
    • This prevents the terminal from becoming a mess when compiling dozens/hundreds of files at once.
  • Note: Start with -j4 or -j8 and increase until you find the sweet spot for your machine (too high can cause memory thrashing if RAM is limited).

  • On linux: The verbose mode not deactivates automatically, so you can use -s to reduce output if needed.

βš™οΈ Customization

Basic project settings

These variables control the behavior of the project and can be overridden directly from the command line:

Variable Description Default
APP_NAME Output executable name (no extension) ProjectName
SRC_EXT Source file extension cpp
CXX_STD C/C++ standard c++23
CXX Compiler to use g++
USE_CONSOLE Show console window on Windows true
BUILD_TYPE Build variant (release/debug/relwithdebinfo) release
USE_LTO Enable Link-Time Optimization false
ANALYZE Enable static analysis flags false
ARCH Target architecture (-march=) native
WARN_LEVEL Warning strictness (minimal/normal/strict) minimal
LIBS Libraries to link (-l)
LDFLAGS Library search paths (-L) -L./lib/
SOURCE_DIRS Source directories src include
INCLUDE_DIRS Include directories include
OPT_RELEASE Optimization flags (Release) -O3
OPT_DEBUG Optimization flags (Debug) -Og
# Change app name
make APP_NAME=MyApp

# Use Clang++ and C++20 instead of G++ and C++23 (default values)
make CXX=clang++ CXX_STD=c++20

# Build without console window on Windows
make release USE_CONSOLE=false

# Optimize for specific CPU architecture
make release ARCH=znver4          # AMD Zen 4
make release ARCH=skylake         # Intel 6th–9th gen
make release ARCH=armv8-a         # ARM (requires cross-compiler)

# Build with debug symbols and optimizations (best for profiling)
make relwithdebinfo

# Build with static analysis enabled
make ANALYZE=true release

# Debug build with all sanitizers and verbose output
make debug VERBOSE=1

# Release build without Link-Time Optimization (faster linking)
make release USE_LTO=false

# Compiler-aware LTO (automatic: thin for Clang, auto for GCC)
make release CXX=clang++        # Uses -flto=thin (optimized for Clang)
make release CXX=g++            # Uses -flto=auto (optimized for GCC)

# Parallel build with 8 cores (release configuration)
make -j8 release

πŸ”— Link-Time Optimization (LTO)

The Makefile automatically selects the best LTO variant based on your compiler:

Compiler LTO Type Benefit
Clang/clang++ -flto=thin Faster compilation, good optimization
GCC/g++ -flto=auto Best optimization, slower linking
Disabled (none) Fastest build time
# Enable LTO (default in release builds)
make release USE_LTO=true CXX=clang++    # Automatically uses thin LTO

# Disable LTO if linking is too slow
make release USE_LTO=false

Parallel build with 8 cores (release configuration)

πŸ” Compiler Warning Levels

Control compiler warning strictness with the WARN_LEVEL variable. Perfect for managing warnings in different project phases or integrating with CI/CD pipelines.

Available Levels

Level Flags Use Case
minimal Base warnings only (-Wall -Wextra -pedantic-errors) Legacy code, third-party libraries
normal + Type conversion, logic, and safety checks Standard development (recommended)
strict + Code quality warnings (-Wshadow, -Wunused, etc) New projects, CI/CD pipelines (default)

Examples

# Production: Strict + Optimization
make release WARN_LEVEL=strict ARCH=native

# Cross-platform: Balanced with specific compiler
make WARN_LEVEL=normal CXX=clang++ -j8

What Each Level Includes

minimal:

-Wall -Wextra -pedantic-errors

normal (minimal +):

-Wconversion -Wsign-conversion -Wdouble-promotion
-Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wrestrict
-Wnull-dereference -Wformat=2 -Wunreachable-code

strict (normal +):

-Wshadow -Wunused -Wunused-parameter

Warning Behavior by Build Type

  • Release builds: Warnings become errors (-Werror) regardless of WARN_LEVEL
  • Debug builds: Warnings remain as warnings for easier iteration
# Warnings as errors
make release WARN_LEVEL=minimal

# Warnings only
make debug WARN_LEVEL=strict

Adding Libraries manually on Makefile (example: GLFW + OpenGL)

Uncomment/add in the libraries section:

ifeq ($(OS),Windows_NT)
    LIBS += -lglfw3dll -lopengl32 -lgdi32
endif

ifeq ($(OS_NAME),Linux)
    LIBS += -lglfw -lGL -ldl -lpthread
endif

ifeq ($(OS_NAME),macOS)
    LIBS += -lglfw -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
endif

πŸ—‚οΈ Recommended Project Structure

MyProject/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.cpp
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   └── engine.cpp
β”‚   └── renderer/
β”œβ”€β”€ include/
β”‚   └── myproject/
β”œβ”€β”€ lib/                  # optional: .a, .lib, .dll files
β”œβ”€β”€ build/
β”‚   β”œβ”€β”€ app/              # final executable
β”‚   β”œβ”€β”€ obj/              # object files
β”‚   β”œβ”€β”€ dep/              # .d dependency files
β”‚   └── asm/              # assembly & disassembly output
└── Makefile

πŸ“¦ Requirements

πŸͺŸ Windows

  • MSYS2 (recommended): UCRT64 or MINGW64
  • Compilers: g++ (MinGW‑w64) or clang++

🐧 Linux / WSL

  • gcc or clang
  • make
  • Dev packages depending on your project (e.g., build-essential, libglfw3-dev, libgl1-mesa-dev)

🍎 macOS

  • Xcode Command Line Tools: xcode-select --install
  • Homebrew packages (optional): brew install gcc clang

πŸ”§ Optional Tools

  • objdump (for make disasm)
  • gdb or lldb (debugging)
  • pkg-config (optional)

⚠️ Troubleshooting

  • Linking errors on Linux β†’ Install missing dev packages (e.g., libglfw3-dev on Ubuntu/WSL)
  • make not found on Windows β†’ Use mingw32-make (included with MinGW-w64).
  • No rule to make target β†’ Verify source files exist in src/ (or added folders)
  • Sanitizers not working on Windows β†’ Disabled by design (partial support in MinGW)
  • Double slashes in paths β†’ Usually harmless; caused by empty variables in some shells
  • Colors broken in CI β†’ Parallel mode auto-disables fancy output
  • Too much output with -j β†’ Use -jN -s or redirect to log
  • clear command not found (rare) β†’ On some Windows shells, fallback to cls happens automatically

Note: This project has been primarily developed and tested on Windows and Linux/WSL. Support for macOS is not guaranteed and may require adjustments.

If you encounter any issues, platform-specific bugs, or inconsistencies, your feedback is extremely valuable. πŸ™

🀝 Contributing

Contributions, issues and feature requests are welcome.
Feel free to check the issues page.

πŸ“œ License

License

Happy coding! ❀️