Created
February 28, 2024 19:46
-
-
Save bepri/f014ad5b4fd761407e3629c02e6480fd to your computer and use it in GitHub Desktop.
Minimal-configuration "universal" makefile for medium-scale C/C++ projects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# "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