mirror of
https://github.com/thepigeongenerator/mcaselector-lite.git
synced 2025-12-17 11:05:45 +01:00
rework makefile to be more os- and compiler-agnostic.
alongside removing non-crucial complexity and attempting to simplify things as much as I can.
This commit is contained in:
165
makefile
165
makefile
@@ -1,118 +1,112 @@
|
|||||||
# dependencies:
|
# dependencies:
|
||||||
# - make
|
# - make
|
||||||
# - clang
|
# - C compiler
|
||||||
# - glfw3 (install glfw3:x64-mingw-dynamic via vcpkg for win cross compilation)
|
# - glfw3 (install glfw3:x64-mingw-dynamic via vcpkg for cross compilation)
|
||||||
# - vcpkg (win cross-compilation)
|
# - (windows) git bash (recommended)
|
||||||
NAME := mcaselector-lite
|
|
||||||
DEBUG ?= 0
|
|
||||||
ARCH ?= 0
|
|
||||||
|
|
||||||
# C compiler options
|
# build configuration, information about the current build process
|
||||||
CC := clang
|
NAME := mcaselector-lite
|
||||||
CSTD := c17
|
VERSION := 0.0.0
|
||||||
CFLAGS := -Wall -Wextra -Wpedantic -Wno-pointer-arith -Ilib
|
DEBUG ?= 0
|
||||||
LDFLAGS :=
|
CC ?= cc
|
||||||
|
CFLAGS += -c -std=c17 -Wall -Wextra -Wpedantic -Ilib -MMD -MP
|
||||||
|
LDFLAGS +=
|
||||||
|
MARCH ?= $(shell uname -m)
|
||||||
|
KERNEL ?= $(shell uname -s | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
# check whether KERNEL is something nonsensical
|
||||||
|
ISWIN := $(if $(filter linux darwin freebsd netbsd openbsd,$(KERNEL)),0,1)
|
||||||
|
|
||||||
# profiles
|
# profiles
|
||||||
ifneq ($(DEBUG),0)
|
ifeq ($(DEBUG),1) # check whether we're debugging
|
||||||
CFLAGS += -g -Og -fsanitize=address,undefined
|
CFLAGS += -Og -g -fsanitize=address,undefined
|
||||||
LDFLAGS += -fsanitize=address,undefined
|
LDFLAGS += -fsanitize=address,undefined
|
||||||
PROF := dbg
|
PROF := dbg
|
||||||
else
|
else ifeq ($(DEBUG),test) # check whether we're perhaps testing
|
||||||
CFLAGS += -DNDEBUG -O2 -Werror
|
CFLAGS += -O2
|
||||||
|
PROF := test
|
||||||
|
else # otherwise, assume release
|
||||||
|
CFLAGS += -O2 -DNDEBUG
|
||||||
PROF := rel
|
PROF := rel
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# targets
|
# setup the VCPKG_TRIPLET
|
||||||
ifneq ($(MAKECMDGOALS),clean)
|
# because microsoft thinks they should use a different method of classifying stuff than the standard
|
||||||
ifeq ($(ARCH),linux-x86_64)
|
ifneq ($(VCPKG_ROOT),)
|
||||||
CFLAGS += -target x86_64-pc-linux-gnu $(shell pkg-config --cflags glfw3)
|
VCPKG_TRIPLET ?= $(strip \
|
||||||
LDFLAGS += -target x86_64-pc-linux-gnu $(shell pkg-config --libs glfw3)
|
$(if $(filter x86_64,$(MARCH)),x64, \
|
||||||
else ifeq ($(ARCH),win-x86_64)
|
))-$(strip \
|
||||||
CFLAGS += -target x86_64-pc-windows-gnu -I$(VCPKG_ROOT)/installed/x64-mingw-dynamic/include
|
$(if $(filter linux,$(KERNEL)),linux-dynamic, \
|
||||||
LDFLAGS += -target x86_64-pc-windows-gnu -L$(VCPKG_ROOT)/installed/x64-mingw-dynamic/lib -lglfw3dll -fuse-ld=lld
|
$(if $(filter darwin,$(KERNEL)),osx-dynamic, \
|
||||||
EXT := .exe
|
mingw-static)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
# override the pkg config path, so it is used instead of system packages
|
||||||
|
export PKG_CONFIG_PATH := $(VCPKG_ROOT)/installed/$(VCPKG_TRIPLET)/lib/pkgconfig
|
||||||
|
else ifneq ($(shell which pkg_config),)
|
||||||
|
$(warning couldn't find VCPKG_ROOT, attempting to use system packages using pkg-config!)
|
||||||
else
|
else
|
||||||
$(error you must set the ARCH environment variable to one of these: 'linux-x86_64' 'win-x86_64')
|
$(error neither VCPKG_ROOT nor pkg_config were available!)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# use pkg-config to set the include and linker information
|
||||||
|
CFLAGS += $(shell pkg-config --cflags glfw3)
|
||||||
|
LDFLAGS += $(shell pkg-config --libs glfw3)
|
||||||
|
|
||||||
|
# windows specific handling
|
||||||
|
ifeq ($(ISWIN),1)
|
||||||
|
NAME := $(NAME).exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
# build directory structure
|
||||||
|
DIR_BIN := bin/$(MARCH)-$(KERNEL)/$(VERSION)/$(PROF)
|
||||||
|
DIR_OBJ := obj/$(MARCH)-$(KERNEL)/$(VERSION)/$(PROF)
|
||||||
|
|
||||||
|
# get source files
|
||||||
|
ifneq ($(DEBUG),test)
|
||||||
|
SRC := $(shell find src/ -name '*.c')
|
||||||
|
else
|
||||||
|
SRC := $(filter-out src/main.c, $(shell find test/ src/ -name '*.c'))
|
||||||
|
CFLAGS += -DGLFW_DLL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# output files
|
# output files
|
||||||
ifneq ($(ARCH),0)
|
BIN := $(DIR_BIN)/$(NAME)
|
||||||
DIR_BIN := bin/$(ARCH)/$(PROF)
|
OBJ := $(SRC:%.c=$(DIR_OBJ)/%.o)
|
||||||
DIR_OBJ := obj/$(ARCH)/$(PROF)
|
DEP := $(OBJ:.o=.d)
|
||||||
BIN := $(DIR_BIN)/$(NAME)$(EXT)
|
|
||||||
|
|
||||||
C_SRC := $(shell find src/ -name '*.c')
|
|
||||||
C_OBJ := $(patsubst src/%,$(DIR_OBJ)/%,$(C_SRC:.c=.o))
|
|
||||||
C_DEP := $(C_OBJ:.o=.d)
|
|
||||||
C_TSRC := $(shell find test/src/ -name '*.c')
|
|
||||||
C_TOBJ := $(patsubst test/src/%,test/$(DIR_OBJ)/%,$(C_TSRC:.c=.o))
|
|
||||||
C_TDEP := $(C_TOBJ:.o=.d)
|
|
||||||
C_TOBJ += $(filter-out $(DIR_OBJ)/main.o, $(C_OBJ))
|
|
||||||
|
|
||||||
COMPILE_COMMANDS := $(DIR_OBJ)/compile_commands.json
|
COMPILE_COMMANDS := $(DIR_OBJ)/compile_commands.json
|
||||||
endif
|
|
||||||
|
|
||||||
define log_col
|
.PHONY: run compile
|
||||||
@printf "\033[%sm%s\033[0m\n" $(2) $(1)
|
run: compile_commands $(BIN); $(BIN)
|
||||||
endef
|
compile: compile_commands $(BIN)
|
||||||
comp = $(call log_col,$(1),92)
|
|
||||||
mesg = $(call log_col,$(1),94)
|
|
||||||
warn = $(call log_col,$(1),93)
|
|
||||||
fail = $(call log_col,$(1),91)
|
|
||||||
|
|
||||||
# creates the binary (linking step)
|
# creates the binary (linking step)
|
||||||
define link_bin
|
$(BIN): $(OBJ)
|
||||||
$1: $2
|
@mkdir -p $(@D)
|
||||||
@$$(call mesg,"CC: '$$(CC)'")
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
@$$(call mesg,"CFLAGS: '$$(CFLAGS)'")
|
|
||||||
@$$(call mesg,"LDFLAGS: '$$(LDFLAGS)'")
|
|
||||||
@$$(call comp,"linking to: '$$@'")
|
|
||||||
|
|
||||||
@mkdir -p $$(@D)
|
# compilation rule
|
||||||
@$$(CC) $$(LDFLAGS) -o $$@ $$^
|
$(DIR_OBJ)/%.o: %.c
|
||||||
@$$(call mesg,"current profile: '$$(PROF)'")
|
@mkdir -p $(@D)
|
||||||
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
endef
|
.PHONY .NOTPARALLEL:
|
||||||
|
|
||||||
# creates .o and .d files
|
|
||||||
define compile_obj
|
|
||||||
$1/%.o: $2/%.c
|
|
||||||
@$$(call comp,"compiling $$@ from $$<")
|
|
||||||
@mkdir -p $$(@D)
|
|
||||||
@$$(CC) $$(CFLAGS) -c -MD -MP -std=$$(CSTD) -x c -o $$@ $$<
|
|
||||||
endef
|
|
||||||
|
|
||||||
# compiles and executes the produced binary
|
|
||||||
run: compile; cd $(DIR_BIN) && ./$(NAME)$(EXT)
|
|
||||||
compile: compile_commands $(BIN)
|
|
||||||
run-test: compile-test; cd test/$(DIR_BIN) && ./test$(EXT)
|
|
||||||
compile-test: test/$(DIR_BIN)/test$(EXT)
|
|
||||||
|
|
||||||
.NOTPARALLEL:
|
|
||||||
clean:
|
clean:
|
||||||
@$(call warn,"cleaning!")
|
rm -rf obj bin compile_commands.json
|
||||||
rm -rf bin/ obj/ test/obj test/bin compile_commands.json
|
|
||||||
|
|
||||||
# compilation macros
|
|
||||||
$(eval $(call link_bin,$(BIN),$(C_OBJ))) # link the binary
|
|
||||||
$(eval $(call compile_obj,$(DIR_OBJ),src)) # compile the objects for the binary
|
|
||||||
$(eval $(call link_bin,test/$(DIR_BIN)/test$(EXT),$(C_TOBJ))) # link the testing binary
|
|
||||||
$(eval $(call compile_obj,test/$(DIR_OBJ),test/src)) # compile the objects for the testing binary
|
|
||||||
|
|
||||||
# update compile commands if the makefile has been updated (for linting)
|
# update compile commands if the makefile has been updated (for linting)
|
||||||
compile_commands: # default, empty rule
|
compile_commands: # default, empty rule
|
||||||
ifneq ($(shell which bear),)
|
ifneq ($(shell which bear),)
|
||||||
ifneq ($(COMPILE_COMMANDS),)
|
ifneq ($(COMPILE_COMMANDS),)
|
||||||
ifeq ($(NOCMDS),)
|
ifeq ($(NOCMDS),)
|
||||||
.NOTPARALLEL .PHONY:
|
.PHONY .NOTPARALLEL:
|
||||||
compile_commands: $(COMPILE_COMMANDS)
|
compile_commands: $(COMPILE_COMMANDS)
|
||||||
@[ "$(readlink compile_commands.json)" != "$<" ] && ln -sf $< compile_commands.json
|
ln -sf $< compile_commands.json
|
||||||
|
|
||||||
.NOTPARALLEL:
|
.NOTPARALLEL:
|
||||||
$(COMPILE_COMMANDS): makefile
|
$(COMPILE_COMMANDS): makefile
|
||||||
@$(call warn,"regenerating compile_commands.json thus recompiling.")
|
@$(warning regenerating compile_commands.json thus recompiling.)
|
||||||
@mkdir -p ${@D} # ensure the target directory exists
|
@mkdir -p ${@D} # ensure the target directory exists
|
||||||
@touch $@ # create the file so it isn't retriggered (will just change modification time if already exists)
|
@touch $@ # create the file so it isn't retriggered (will just change modification time if already exists)
|
||||||
@bear --output $@ -- make -B compile NOCMDS=1 # rebuild the current target using bear, to create the compile commands
|
@bear --output $@ -- make -B compile NOCMDS=1 # rebuild the current target using bear, to create the compile commands
|
||||||
@@ -120,9 +114,4 @@ endif
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# disable implicit rules
|
-include $(DEP)
|
||||||
.SUFFIXES:
|
|
||||||
|
|
||||||
# include the dependencies
|
|
||||||
-include $(C_DEP)
|
|
||||||
-include $(C_TDEP)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user