Compare commits

...

7 Commits

Author SHA1 Message Date
a1f1c841c0 write a CI workflow for multiple OSes, that compile and test the code using the makefile. 2025-09-13 20:27:40 +02:00
d9ddae770a fix: just use compiler builtins with endianess
this is the most portable and clean approach. Compiler built-ins should
always be present regardless, and is more maintainable, since we're not
trying to keep up with various versions of this header.
2025-09-13 20:25:38 +02:00
c2e1b67b4c seperate out library compilation from general compilation
This can help with a more nuanced compilation. (eg. use system libraries
rather than compile our own)
Furthermore, it decreases the needed compilation time, since we needn't
recompile the whole thing when having cleaned out our local sources.
2025-09-13 20:25:38 +02:00
8548c2d037 fix: log macros were using GNU extensions without them needing them.
We can optionally add `,` utilising the `__VA_OPT__` macro. However,
this lead to the next problem, which is that an empty vardiac parameter
is a C23 extension. This was solved by dropping the string parameter,
making it be part of the vardiac parameters.
2025-09-13 20:25:38 +02:00
7ec6a3b91a fix: using __bswap_X functions over bswap_X macros, which we should be using. 2025-09-13 20:25:38 +02:00
3f48a7abb2 add compile commands events to gitignore 2025-09-13 20:25:38 +02:00
667814fb72 rework makefile to put extera emphasis on us no longer performing cross-platform compilation
Furthermore, we removed a bunch of behaviour that wasn't needed, and
simplified the bunch.
2025-09-13 20:25:38 +02:00
8 changed files with 109 additions and 124 deletions

30
.github/workflows/ci.yaml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: CI
on:
push:
branches: [main]
jobs:
compile-and-test:
strategy:
matrix:
os:
- ubuntu-latest
- ubuntu-24.04-arm
- windows-latest
- windows-11-arm
- macos-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v5
with:
repository: ${{github.repository}}
submodules: true
fetch-depth: 1
- uses: actions/cache@v4
with:
path: lib/obj/
key: ${{runner.os}}-lib/obj-${{github.sha}}
restore-keys: ${{runner.os}}-lib/obj-
- run: make libs
- run: make all
- run: make test

2
.gitignore vendored
View File

@@ -18,4 +18,6 @@
*.lock *.lock
/bin/ /bin/
/obj/ /obj/
/lib/obj/
compile_commands.json compile_commands.json
compile_commands.events.json

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "lib/glfw"]
path = lib/glfw
url = https://github.com/glfw/glfw
[submodule "lib/libarchive"]
path = lib/libarchive
url = https://github.com/libarchive/libarchive

143
Makefile
View File

@@ -1,102 +1,87 @@
# 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
.SHELLFLAGS = -O globstar -c
# 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
DEBUG ?= 0 DEBUG ?= 0
CC ?= cc CC ?= cc
LD ?= ld LD ?= ld
# compilation flags # setting default compilation flags
CFLAGS += -c -std=gnu99 -Wall -Wextra -Wpedantic -MMD -MP # some of which are able to be overwritten, others are always appended
LDFLAGS += -flto CPPFLAGS ?=
CFLAGS ?= -O2 -Wall -Wextra -Wpedantic
LDFLAGS ?= -flto
CFLAGS += -std=gnu99
# architecture/OS detection # add a few extra flags depending on whether
ifeq ($(KERNEL),) # we're debugging or not
ISWIN := $(if $(filter $(OS),Windows_NT),1,0) ifeq ($(DEBUG),0)
ifeq ($(ISWIN),1) CPPFLAGS += -DNDEBUG
KERNEL = mingw
MARCH = x86_64
else else
MARCH := $(shell uname -m) CFLAGS += -fsanitize=address -ftrapv -g
KERNEL := $(shell uname -s | tr '[:upper:]' '[:lower:]') LDFLAGS += -fsanitize=address -ftrapv
endif endif
else CPPFLAGS += -Iinclude -Ilib/glad/include -Ilib/glfw/include -Ilib/libarchive/libarchive
ISWIN := $(if $(filter $(KERNEL),mingw),1,0) LDFLAGS += -Llib/obj/glfw/src -Llib/obj/libarchive/libarchive
endif LDLIBS += -lm -lglfw -larchive
ifeq ($(MARCH),)
$(error must also set MARCH when manually setting KERNEL) # detect if we're compiling on Windows, meaning
# a lot of things considered "standard" are unavailable.
ifeq ($(OS),Windows_NT)
ISWIN = 1
NAME := $(NAME).exe
$(warning Detected Windows_NT, please refer to the documentation if you encounter issues.)
endif endif
# profiles # TODO: find a better method to find all source files
ifeq ($(DEBUG),1) # find all the source files using wildcards
PROF = dbg # NOTE: MS-DOS and MS-Windows uses backslash `\`, this might break.
CFLAGS += -UNDEBUG -Og -g -Wextra -Wpedantic RES := $(wildcard res/*)
CFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address,undefined) -ftrapv SRC := $(wildcard src/*.c src/*/*.c src/*/*/*.c src/*/*/*/*.c src/*/*/*/*/*.c src/*/*/*/*/*/*.c src/*/*/*/*/*/*/*.c src/*/*/*/*/*/*/*/*.c) lib/glad/gl.c
LDFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address,undefined) -ftrapv OBJ := $(SRC:%.c=obj/%.o) $(RES:%=obj/%.o)
# |--profile: testing TSRC := $(wildcard test/*.c test/*/*.c test/*/*/*.c test/*/*/*/*.c test/*/*/*/*/*.c test/*/*/*/*/*/*.c test/*/*/*/*/*/*/*.c test/*/*/*/*/*/*/*/*.c)
else ifeq ($(DEBUG),test) TOBJ := $(TSRC:%.c=obj/%.o)
PROF = test
CFLAGS += -UNDEBUG -O2 -g
CFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address) -ftrapv
LDFLAGS += $(if $(filter 1,$(ISWIN)),,-fsanitize=address) -ftrapv
else
PROF = rel
CFLAGS += -DNDEBUG -O2
endif
CFLAGS += $(shell pkg-config --cflags glfw3 libarchive) -Iinclude -Ilib/glad/include # TODO: potentially automatically detect whether we should compile libs, or if we can just go ahead.
LDFLAGS += $(shell pkg-config --libs glfw3 libarchive) -lm .PHONY: all libs test clean clean-libs
all: bin/$(NAME)
# get source files libs: lib/obj/glfw/ lib/obj/libarchive/
SRC := $(shell echo src/**/*.c) lib/glad/src/gl.c test: bin/TEST_$(NAME); bin/TEST_$(NAME)
RES := $(wildcard res/*.glsl)
ifeq ($(DEBUG),test)
SRC := $(filter-out src/main.c, $(SRC)) $(shell echo test/**/*.c)
endif
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)
.PHONY:
run: compile
$(if $(filter 1,$(ISWIN)),wine,) $(BIN)
.PHONY:
compile: $(BIN)
.PHONY .NOTPARALLEL:
clean: clean:
@[ -d obj/ ] && rm -rv obj/ || true @[ -d bin/ ] && rm -vr bin/ || true
@[ -d bin/ ] && rm -rv bin/ || true @[ -d obj/ ] && rm -vr obj/ || true
clean-libs:
@[ -d lib/obj/ ] && rm -vr lib/obj/
$(BIN): $(OBJ)
$(info [CC/LD] $@)
@mkdir -p $(@D)
@$(CC) -o $@ $^ $(LDFLAGS)
$(DIR_OBJ)/%.o: %.c # compiles the libraries using cmake
$(info [CC] $@) lib/obj/%/: lib/%/
@mkdir -p $(@D) cmake -S $< -B $@
@$(CC) $(CFLAGS) -o $@ $< $(MAKE) -C $@
$(DIR_OBJ)/res/%.o: res/% # link together a runtime binary
$(info [LD] $@) bin/$(NAME): $(OBJ)
$(info [CC/LD] $@)
@mkdir -p $(@D) @mkdir -p $(@D)
@$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
# link together a testing binary
bin/TEST_$(NAME): $(TOBJ) $(filter-out main.o,$(OBJ))
$(info [CC/LD] $@)
@mkdir -p $(@D)
@$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
obj/res/%.o: res/%
$(info [LD] $@)
@$(LD) -r -b binary -o $@ $< @$(LD) -r -b binary -o $@ $<
# some definitions for "default" and assumed compilers, for bulk selection obj/%.o: %.c
.PHONY: x86_64-linux-gnu-gcc x86_64-w64-mingw32-gcc $(info [CC] $@)
x86_64-linux-gnu-gcc:; $(MAKE) $(CALL) $(MAKEFLAGS) CC=$@ MARCH=x86_64 KERNEL=linux @mkdir -p $(@D)
x86_64-w64-mingw32-gcc:; $(MAKE) $(CALL) $(MAKEFLAGS) CC=$@ MARCH=x86_64 KERNEL=mingw @$(CC) -c $(CPPFLAGS) $(CFLAGS) -MMD -MP -o $@ $<
-include $(DEP) # Include the generated dependency files.
# Which creates rules for all dependencies,
# as a result updating an .o file when a .h is updated.
-include $(OBJ:%.o=%.d)

View File

@@ -1,46 +1,9 @@
/* 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 */
#ifndef PORTABLE_ENDIAN_H #ifndef PORTABLE_ENDIAN_H
#define PORTABLE_ENDIAN_H 1 #define PORTABLE_ENDIAN_H 1
#if defined(__GNUC__) #if defined(__GNUC__)
/* test for the byteswap header */
#if __has_include(<byteswap.h>)
#include <byteswap.h>
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define le16toh(x) (x)
#define le32toh(x) (x)
#define le64toh(x) (x)
#define htole16(x) (x)
#define htole32(x) (x)
#define htole64(x) (x)
#define be16toh(x) __bswap_16(x)
#define be32toh(x) __bswap_32(x)
#define be64toh(x) __bswap_64(x)
#define htobe16(x) __bswap_16(x)
#define htobe32(x) __bswap_32(x)
#define htobe64(x) __bswap_64(x)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define le16toh(x) __bswap_16(x)
#define le32toh(x) __bswap_32(x)
#define le64toh(x) __bswap_64(x)
#define htole16(x) __bswap_16(x)
#define htole32(x) __bswap_32(x)
#define htole64(x) __bswap_64(x)
#define be16toh(x) (x)
#define be32toh(x) (x)
#define be64toh(x) (x)
#define htobe16(x) (x)
#define htobe32(x) (x)
#define htobe64(x) (x)
#else
#error machine architecture unsupported! Expected either big-endian or little-endian, make sure to use a compiler which defines __BYTE_ORDER__ (like clang or gcc)
#endif /* byte order */
/* otherwise, utilise the compiler built-ins */
#else
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define le16toh(x) __uint16_identity(x) #define le16toh(x) __uint16_identity(x)
#define le32toh(x) __uint32_identity(x) #define le32toh(x) __uint32_identity(x)
@@ -71,10 +34,7 @@
#error machine architecture unsupported! Expected either big-endian or little-endian, make sure to use a compiler which defines __BYTE_ORDER__ (like clang or gcc) #error machine architecture unsupported! Expected either big-endian or little-endian, make sure to use a compiler which defines __BYTE_ORDER__ (like clang or gcc)
#endif /* byte order */ #endif /* byte order */
#endif /* has byteswap.h */
#else #else
#error GNU C is unavailable #error GNU C is unavailable
#endif /* __GNUC__ */ #endif /* __GNUC__ */
#endif /* PORTABLE_ENDIAN_H */ #endif /* PORTABLE_ENDIAN_H */

1
lib/glfw Submodule

Submodule lib/glfw added at 7b6aead9fb

1
lib/libarchive Submodule

Submodule lib/libarchive added at 9525f90ca4

View File

@@ -15,8 +15,8 @@ void error_war(uint ln, const char *restrict file, const char *restrict fmt, ...
void error_err(uint ln, const char *restrict file, const char *restrict fmt, ...); void error_err(uint ln, const char *restrict file, const char *restrict fmt, ...);
void error_fat(uint ln, const char *restrict file, const char *restrict fmt, ...) NORET; void error_fat(uint ln, const char *restrict file, const char *restrict fmt, ...) NORET;
#define debug(s, ...) error_dbg(__LINE__, __FILE__, s, ##__VA_ARGS__) #define debug(...) error_dbg(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
#define info(s, ...) error_inf(__LINE__, __FILE__, s, ##__VA_ARGS__) #define info(...) error_inf(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
#define warn(s, ...) error_war(__LINE__, __FILE__, s, ##__VA_ARGS__) #define warn(...) error_war(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
#define error(s, ...) error_err(__LINE__, __FILE__, s, ##__VA_ARGS__) #define error(...) error_err(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)
#define fatal(s, ...) error_fat(__LINE__, __FILE__, s, ##__VA_ARGS__) #define fatal(...) error_fat(__LINE__, __FILE__ __VA_OPT__(, ) __VA_ARGS__)