Skip to content

Instantly share code, notes, and snippets.

@bepri
Created February 28, 2024 19:46
Show Gist options
  • Save bepri/f014ad5b4fd761407e3629c02e6480fd to your computer and use it in GitHub Desktop.
Save bepri/f014ad5b4fd761407e3629c02e6480fd to your computer and use it in GitHub Desktop.
Minimal-configuration "universal" makefile for medium-scale C/C++ projects
# "Universal" Makefile
# Imani Pelton (@bepri on GitHub)
# A plug-n-play Makefile for any medium-scale C/C++ project. Probably not as powerful as CMake, but sufficient if you don't want to use all that.
# Uses a target directory with object file outputs to speed up compilation times on multi-file projects
# Modify these for your program
COMP = g++
COMPFLAGS = -g -Wall -Wpedantic -Werror -D DEBUG
PROGNAME = prog
# Fill in after the ?= if you want to skip specifying these from the command line
LINKFLAGS ?=
PROGFLAGS ?=
# Do not modify below here (unless you want to understand all this garbage)
# Select the expected source file extension
EXT = $(if $(filter $(COMP),g++),pp)
# Get a list of all the subdirectories in src/ in the form of their corresponding target/obj/ dirs
SRC_SUBDIRS = $(patsubst src/%, target/obj/%, $(sort $(dir $(wildcard src/**/*.c$(EXT)))))
.PHONY: all
all: setup target/$(PROGNAME)
# Compile the final binary, depending on all related .o files
target/$(PROGNAME): $(patsubst src/%.c$(EXT), target/obj/%.o,\
$(wildcard src/**/*.c$(EXT)))
# Compile from recipe dependencies, but ignore .h files (we wanted to track those, but they do not get compiled directly)
$(COMP) -o $@ $(filter-out %.h$(EXT),$^) $(LINKFLAGS)
# Create all the .o files
target/obj/%.o: src/%.c$(EXT) $(wildcard src/*.h$(EXT))
$(COMP) $(COMPFLAGS) -c -o $@ $<
# Create the desired structure for the target directory
.PHONY: setup
setup:
mkdir -p target/obj $(SRC_SUBDIRS)
# Clean rebuild
.PHONY: fresh
fresh: clean all
# Set up a development directory in the format this makefile expects
.PHONY: init
init: setup
mkdir src
.PHONY: run
run: all
./target/$(PROGNAME) $(PROGFLAGS)
.PHONY: clean
clean:
rm -f target/obj/* target/$(PROGNAME)
.PHONY: help
help:
@echo "Variables:"
@echo " PROGFLAGS: flags to pass to your program if executing via make"
@echo " LINKFLAGS: desired linking flags for compilation (should include the -L)"
@echo "Available recipes:"
@echo " all: build project"
@echo " setup: create build directory"
@echo " fresh: delete all build artifacts and outputs, then rebuild"
@echo " init: creates a src directory this Makefile will check"
@echo " run: runs your program. specify flags to your program like \"make run PROGFLAGS=-m\""
@echo " clean: deletes all build artifacts and outputs"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment