diff --git a/makefile b/makefile index 5cf3ff6..6092ad6 100644 --- a/makefile +++ b/makefile @@ -1,149 +1,107 @@ # Copyright (c) 2025 Quinn # Licensed under the MIT Licence. See LICENSE for details - -# dependencies: -# - make -# - C compiler -# - glfw3 (install glfw3:x64-mingw-dynamic via vcpkg for cross compilation) -# - xxd (tinyxxd recommended; faster) -# - (windows) git bash (recommended) +SHELL = bash +.SHELLFLAGS = -O globstar -c # build configuration, information about the current build process -NAME := mcaselector-lite -VERSION := 0.0.0 +NAME = mcaselector-lite +VERSION = 0.0.0 DEBUG ?= 0 CC ?= cc 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 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) +# compilation flags +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 -ifeq ($(DEBUG),1) # check whether we're debugging -CFLAGS += -UNDEBUG -Og -g -PROF := dbg -ifeq ($(ISWIN),0) -CFLAGS += -fsanitize=address,undefined -LDFLAGS += -fsanitize=address,undefined -endif -else ifeq ($(DEBUG),test) # check whether we're perhaps testing +ifeq ($(DEBUG),1) +PROF = dbg +CFLAGS += -UNDEBUG -Og -g -Wextra -Wpedantic +CFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address,undefined) +LDFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address,undefined) +# |--profile: testing +else ifeq ($(DEBUG),test) +PROF = test CFLAGS += -UNDEBUG -O2 -g -PROF := test -ifeq ($(ISWIN),0) -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!) +CFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address) +LDFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address) else -$(error neither VCPKG_ROOT nor pkg-config were available!) +PROF = rel +CFLAGS += -DNDEBUG -O2 endif -# use pkg-config to set the include and linker information -CFLAGS += $(shell pkg-config --cflags glfw3 libarchive) -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) +CFLAGS += $(shell pkg-config --cflags glfw3 libarchive) -Ilib/glad/include +LDFLAGS += $(shell pkg-config --libs glfw3 libarchive) -lm # 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')) +SRC := $(shell echo src/**/*.c) lib/glad/src/gl.c +RES := $(wildcard res/*.glsl) +ifeq ($(DEBUG),test) +SRC := $(filter-out src/main.c, $(SRC)) $(shell echo test/**/*.c) 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 BIN := $(DIR_BIN)/$(NAME) 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 -run: echo compile_commands $(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: +compile: $(BIN) .PHONY .NOTPARALLEL: 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) -compile_commands: # default, empty rule -ifneq ($(shell which bear),) -ifneq ($(COMPILE_COMMANDS),) -ifeq ($(NOCMDS),) -.PHONY .NOTPARALLEL: -compile_commands: $(COMPILE_COMMANDS) - ln -sf $< compile_commands.json +$(BIN): $(OBJ) + $(info [CC/LD] $@) + @mkdir -p $(@D) + @$(CC) -o $@ $^ $(LDFLAGS) -.NOTPARALLEL: -$(COMPILE_COMMANDS): makefile - @$(warning regenerating compile_commands.json thus recompiling.) - @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) - @bear --output $@ -- make -B compile NOCMDS=1 # rebuild the current target using bear, to create the compile commands -endif -endif -endif +$(DIR_OBJ)/%.o: %.c + $(info [CC] $@) + @mkdir -p $(@D) + @$(CC) $(CFLAGS) -o $@ $< + +$(DIR_OBJ)/res/%.o: res/% + $(info [LD] $@) + @mkdir -p $(@D) + @$(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)