complete overhaul of makefile

- removed logic for creating `compile_commands.json` (programmer must
figure out)
- set to specific shell
- enable globstar to replace `find`
- replace `:=` with `=` where appropriate.
- remove reliance on `vcpkg`
This commit is contained in:
2025-08-11 12:10:12 +02:00
parent 916e81aaad
commit c2c4afb49f

190
makefile
View File

@@ -1,149 +1,107 @@
# Copyright (c) 2025 Quinn # Copyright (c) 2025 Quinn
# Licensed under the MIT Licence. See LICENSE for details # Licensed under the MIT Licence. See LICENSE for details
SHELL = bash
# dependencies: .SHELLFLAGS = -O globstar -c
# - make
# - C compiler
# - glfw3 (install glfw3:x64-mingw-dynamic via vcpkg for cross compilation)
# - xxd (tinyxxd recommended; faster)
# - (windows) git bash (recommended)
# build configuration, information about the current build process # build configuration, information about the current build process
NAME := mcaselector-lite NAME = mcaselector-lite
VERSION := 0.0.0 VERSION = 0.0.0
DEBUG ?= 0 DEBUG ?= 0
CC ?= cc CC ?= cc
LD ?= ld LD ?= ld
CFLAGS += -c -std=gnu99 -Wall -Wextra -Wpedantic -Ilib -MMD -MP CFLAGS += -c -std=gnu99 -Wall -MMD -MP
CFLAGS += -Ilib/glad/include
LDFLAGS += -flto -lm LDFLAGS += -flto -lm
MARCH ?= $(shell uname -m) MARCH ?= $(shell uname -m)
KERNEL ?= $(shell uname -s | tr '[:upper:]' '[:lower:]') KERNEL ?= $(shell uname -s | tr '[:upper:]' '[:lower:]')
# check whether KERNEL is something nonsensical # compilation flags
ISWIN := $(if $(filter linux darwin freebsd netbsd openbsd,$(KERNEL)),0,1) CFLAGS = -c -std=gnu99 -Wall -Wextra -Wpedantic -MMD -MP
LDFLAGS = -flto
# architecture/OS detection
ifeq ($(KERNEL),)
ISWIN := $(if $(filter $(OS),Windows_NT),1,0)
ifeq ($(ISWIN),1)
KERNEL = mingw
MARCH = x86_64
else
MARCH := $(shell uname -m)
KERNEL := $(shell uname -s | tr '[:upper:]' '[:lower:]')
endif
else
ISWIN := $(if $(filter $(KERNEL),mingw),1,0)
endif
ifeq ($(MARCH),)
$(error must also set MARCH when manually setting KERNEL)
endif
# profiles # profiles
ifeq ($(DEBUG),1) # check whether we're debugging ifeq ($(DEBUG),1)
CFLAGS += -UNDEBUG -Og -g PROF = dbg
PROF := dbg CFLAGS += -UNDEBUG -Og -g -Wextra -Wpedantic
ifeq ($(ISWIN),0) CFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address,undefined)
CFLAGS += -fsanitize=address,undefined LDFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address,undefined)
LDFLAGS += -fsanitize=address,undefined # |--profile: testing
endif else ifeq ($(DEBUG),test)
else ifeq ($(DEBUG),test) # check whether we're perhaps testing PROF = test
CFLAGS += -UNDEBUG -O2 -g CFLAGS += -UNDEBUG -O2 -g
PROF := test CFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address)
ifeq ($(ISWIN),0) LDFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address)
CFLAGS += -fsanitize=address
LDFLAGS += -fsanitize=address
endif
else # otherwise, assume release
CFLAGS += -DNDEBUG -O2
PROF := rel
endif
# setup the VCPKG_TRIPLET
# because microsoft thinks they should use a different method of classifying stuff than the standard
ifneq ($(VCPKG_ROOT),)
VCPKG_TRIPLET ?= $(strip \
$(if $(filter x86_64,$(MARCH)),x64, \
))-$(strip \
$(if $(filter linux,$(KERNEL)),linux-dynamic, \
$(if $(filter darwin,$(KERNEL)),osx-dynamic, \
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
$(info using PKG_CONFIG_PATH: '$(PKG_CONFIG_PATH)')
else ifneq ($(shell which pkg-config),)
$(warning couldn't find VCPKG_ROOT, attempting to use system packages using pkg-config!)
else else
$(error neither VCPKG_ROOT nor pkg-config were available!) PROF = rel
CFLAGS += -DNDEBUG -O2
endif endif
# use pkg-config to set the include and linker information CFLAGS += $(shell pkg-config --cflags glfw3 libarchive) -Ilib/glad/include
CFLAGS += $(shell pkg-config --cflags glfw3 libarchive) LDFLAGS += $(shell pkg-config --libs glfw3 libarchive) -lm
LDFLAGS += $(shell pkg-config --libs glfw3 libarchive)
# 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 # get source files
ifneq ($(DEBUG),test) SRC := $(shell echo src/**/*.c) lib/glad/src/gl.c
SRC := $(shell find src/ -name '*.c') RES := $(wildcard res/*.glsl)
else ifeq ($(DEBUG),test)
SRC := $(filter-out src/main.c, $(shell find test/ src/ -name '*.c')) SRC := $(filter-out src/main.c, $(SRC)) $(shell echo test/**/*.c)
endif endif
RES := $(shell find res/ -type f)
NAME += $(if $(filter 1,$(ISWIN)),.exe,)
DIR_BIN := bin/$(MARCH)-$(KERNEL)/$(VERSION)/$(PROF)
DIR_OBJ := obj/$(MARCH)-$(KERNEL)/$(VERSION)/$(PROF)
# output files # output files
BIN := $(DIR_BIN)/$(NAME) BIN := $(DIR_BIN)/$(NAME)
OBJ := $(SRC:%.c=$(DIR_OBJ)/%.o) $(RES:%=$(DIR_OBJ)/%.o) OBJ := $(SRC:%.c=$(DIR_OBJ)/%.o) $(RES:%=$(DIR_OBJ)/%.o)
DEP := $(OBJ:.o=.d) DEP := $(OBJ:%.o=%.d)
COMPILE_COMMANDS := $(DIR_OBJ)/compile_commands.json .PHONY:
run: compile
$(if $(filter 1,$(ISWIN)),wine,) $(BIN)
.PHONY: run compile echo .PHONY:
run: echo compile_commands $(BIN) compile: $(BIN)
ifeq ($(ISWIN),0)
$(BIN)
else
wine $(BIN)
endif
compile: echo compile_commands $(BIN)
echo:
$(info $(shell printf "\033[36m")compiling for: $(MARCH), $(KERNEL)$(shell printf "\033[0m"))
$(info $(shell printf "\033[36m")using compiler: $(CC)$(shell printf "\033[0m"))
# some definitions for "default" and assumed compilers, for bulk selection
.PHONY: all x86_64-linux-gnu-gcc x86_64-w64-mingw32-gcc
all: x86_64-linux-gnu-gcc x86_64-w64-mingw32-gcc
x86_64-linux-gnu-gcc:; $(MAKE) $(CALL) $(MAKEFLAGS) CC=$@ MARCH=x86_64 KERNEL=linux NOCMDS=1
x86_64-w64-mingw32-gcc:; $(MAKE) $(CALL) $(MAKEFLAGS) CC=$@ MARCH=x86_64 KERNEL=mingw NOCMDS=1
# creates the binary (linking step)
$(BIN): $(OBJ)
@mkdir -p $(@D)
$(CC) -o $@ $^ $(LDFLAGS)
# compilation rule
$(DIR_OBJ)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -o $@ $<
# use linker to embed the resources into the final binary
$(DIR_OBJ)/res/%.o: res/%
@mkdir -p $(@D)
$(LD) -r -b binary -o $@ $<
.PHONY .NOTPARALLEL: .PHONY .NOTPARALLEL:
clean: clean:
rm -rf obj bin compile_commands.json @rm -rv obj/
@rm -rv bin/
# update compile commands if the makefile has been updated (for linting) $(BIN): $(OBJ)
compile_commands: # default, empty rule $(info [CC/LD] $@)
ifneq ($(shell which bear),) @mkdir -p $(@D)
ifneq ($(COMPILE_COMMANDS),) @$(CC) -o $@ $^ $(LDFLAGS)
ifeq ($(NOCMDS),)
.PHONY .NOTPARALLEL:
compile_commands: $(COMPILE_COMMANDS)
ln -sf $< compile_commands.json
.NOTPARALLEL: $(DIR_OBJ)/%.o: %.c
$(COMPILE_COMMANDS): makefile $(info [CC] $@)
@$(warning regenerating compile_commands.json thus recompiling.) @mkdir -p $(@D)
@mkdir -p ${@D} # ensure the target directory exists @$(CC) $(CFLAGS) -o $@ $<
@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 $(DIR_OBJ)/res/%.o: res/%
endif $(info [LD] $@)
endif @mkdir -p $(@D)
endif @$(LD) -r -b binary -o $@ $<
# some definitions for "default" and assumed compilers, for bulk selection
.PHONY: x86_64-linux-gnu-gcc x86_64-w64-mingw32-gcc
x86_64-linux-gnu-gcc:; $(MAKE) $(CALL) $(MAKEFLAGS) CC=$@ MARCH=x86_64 KERNEL=linux
x86_64-w64-mingw32-gcc:; $(MAKE) $(CALL) $(MAKEFLAGS) CC=$@ MARCH=x86_64 KERNEL=mingw
-include $(DEP) -include $(DEP)