Last active
November 10, 2023 16:32
-
-
Save OrangeTide/8e2adb72ea5d28b9e8ae5046fcc520a3 to your computer and use it in GitHub Desktop.
small and low-configuration project Makefile (GNU make required)
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
# small and low-configuration project Makefile (GNU make required) | |
# Nov 10 2023 - Jon | |
# usage: | |
# 1. place this in the directory of a small C/C++ project. | |
# 2. modify type= configuration option to select executable or library modes. | |
# 3. all c/c++ and assembler sources will be linked into a single | |
# executable or library. | |
# 4. adjust configuration options for desired compiler and linker flags. | |
# examples of typical usage: | |
# make clean | |
# make | |
# make RELEASE=1 all | |
# example of cross-compiling: | |
# make CC=x86_64-w64-mingw32-cc CXX=x86_64-w64-mingw32-c++ OS=Windows_NT clean-all all | |
# | |
# available at: https://gist.github.com/OrangeTide/8e2adb72ea5d28b9e8ae5046fcc520a3 | |
.SUFFIXES: | |
.PHONY:all clean clean-all | |
E:=.c .cpp .S .asm | |
OS:=$(if $(OS),$(OS),$(shell uname -o)) | |
ARCH:=$(if $(ARCH),$(ARCH),$(shell uname -a)) | |
##detection## | |
B:=$(notdir $(realpath $(dir $(lastword $(MAKEFILE_LIST))))) | |
S:=$(wildcard $(addprefix *,$E)) | |
O:=$(filter %.o,$(foreach e,$E,$(S:%$e=%.o))) | |
D:=$(patsubst %.o,%.d,$O) | |
ifeq ($(OS),Windows_NT) | |
X:=.exe | |
L:=.dll | |
A:=.lib | |
else | |
X:= | |
L:=.so | |
A:=.a | |
endif | |
.SUFFIXES:.o $E $X $L $A | |
##functions## | |
.o.c=$(CC) -c -o $@ -MMD $(CPPFLAGS) $(CFLAGS) $(CFLAGS.$(OS)) $< | |
.o.cpp=$(CXX) -c -o $@ -MMD $(CPPFLAGS) $(CFLAGS) $(CFLAGS.$(OS)) $(CXXFLAGS) $(CXXFLAGS.$(OS)) $< | |
.o.S=$(CC) -c -o $@ $(CPPFLAGS) $(ASFLAGS) $(ASFLAGS.$(OS)) $< | |
.o.asm=$(NASM) $(NASMFLAGS) $(NASMFLAGS.$(OS)) -o $@ -MD $*.d $< | |
link$X=$(cc) -o $@ $(LDFLAGS) $^ $(LDLIBS) | |
trash-%$X:; | |
link.so=$(cc) -o $@ -shared -Wl,-soname=$@.$V $(LDFLAGS) $^ $(LDLIBS) | |
trash-%.so:; | |
link.dll=$(eval trash+=lib$*.dll.a)$(cc) -o $@ -shared $(LDFLAGS) \ | |
-Wl,--out-implib=lib$*.dll.a \ | |
-Wl,--export-all-symbols \ | |
-Wl,--enable-auto-import \ | |
-Wl,--whole-archive $^ \ | |
-Wl,--no-whole-archive \ | |
$(LDLIBS) | |
trash-%.dll:;$(eval trash+=lib$*.dll.a) | |
link$A=$(if $^,$(AR) $(ARFLAGS) $@ $^,$(error No files for archive)) | |
trash-%$A:; | |
$(foreach y,$E,$(eval $y.o:;$$(.o$y))) | |
##toolchain configuration## | |
NASM=nasm | |
ifneq (${RELEASE},) | |
# Deterministic mode is preferred for release builds | |
ARFLAGS=rvD | |
else | |
CFLAGS=-g | |
# Non-deterministic mode is preferred for make dependency checking | |
ARFLAGS=rvU | |
endif | |
##target configuration## | |
#windows | |
CFLAGS.Windows_NT= | |
LDFLAGS.Windows_NT=-mconsole | |
NASMFLAGS.Windows_NT=-fwin64 | |
#linux | |
CFLAGS.Linux=-ffunction-sections -fdata-sections | |
LDFLAGS.Linux=-Wl,-gc-sections -Wl,--strip-all | |
NASMFLAGS.Linux=-felf64 | |
##project configuration## | |
#$X=executable $L=shared-library $A=static-library | |
type=$X | |
f=$B$(type) | |
all::$f | |
#$f:ASFLAGS= | |
#$f:NASMFLAGS= | |
#$f:CXXFLAGS= | |
#$f:CPPFLAGS= | |
$f:CFLAGS+=-W -Wall -O3 | |
$f:LDFLAGS+= | |
$f:LDLIBS+=-lm | |
$f:V=0.1.0 | |
##base definition## | |
$f:T:=$(type) | |
$f:S:=$S | |
$f:O:=$O | |
$f:cc:=$(if $(filter %.cpp,$S),$(CXX),$(CC)) | |
$f:$O;$(link$T) | |
$(eval clean::;$$(RM) $f $O) | |
$(eval clean-all::clean trash-$f;$$(RM) $D $$(trash)) | |
-include $D | |
$(foreach v,F S O D type,$(eval undefine $v)) | |
#$(info F=$F S=$S O=$O D=$D type=$(type)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment