diff --git a/README.md b/README.md index c261ce9..c519072 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,8 @@ cc -shared -o my_module.dll my_module.c Place the compiled module in the `mods/` directory (default), and `stk` will automatically load it and watch for changes. +Copy `module_template/` as a starting point, it builds cross-platform out of the box. + ### Module Metadata Modules can optionally export metadata functions: diff --git a/module_template/.gitignore b/module_template/.gitignore new file mode 100644 index 0000000..63be740 --- /dev/null +++ b/module_template/.gitignore @@ -0,0 +1,3 @@ +# Build directories +obj/ +bin/ diff --git a/module_template/README.md b/module_template/README.md new file mode 100644 index 0000000..e5c5e3a --- /dev/null +++ b/module_template/README.md @@ -0,0 +1,20 @@ +# my_module + +TODO: one-line description. + +An stk module. + +## Build + +```bash +./build.sh debug release # Linux/BSD/macOS +build.bat debug release # Windows +``` + +## Install + +Copy `bin/release/my_module.so`/`.dylib`/`.dll` into the game's `mods/` directory. + +## Dependencies + +TODO: list any, or delete this section. diff --git a/module_template/bmake.mk b/module_template/bmake.mk new file mode 100644 index 0000000..b6d5653 --- /dev/null +++ b/module_template/bmake.mk @@ -0,0 +1,43 @@ +.include "config.mk" + +UNAME_S != uname -s + +.if ${UNAME_S} == "Darwin" +MODULE_EXT = .dylib +.else +MODULE_EXT = .so +.endif + +CC ?= cc +CFLAGS_BASE = -Wall -Wpedantic -I${.CURDIR}/${INC_DIR} -fPIC + +.PHONY: all debug release clean + +all: debug + +OBJS_DEBUG = ${SRCS:S|^src/|${.CURDIR}/obj/debug/|:S/.c$/.o/} +OBJS_RELEASE = ${SRCS:S|^src/|${.CURDIR}/obj/release/|:S/.c$/.o/} + +debug: ${.CURDIR}/${BIN_DIR}/debug/${MODULE_NAME}${MODULE_EXT} +release: ${.CURDIR}/${BIN_DIR}/release/${MODULE_NAME}${MODULE_EXT} + +${.CURDIR}/${BIN_DIR}/debug/${MODULE_NAME}${MODULE_EXT}: ${OBJS_DEBUG} + @mkdir -p ${.TARGET:H} + ${CC} -shared -o ${.TARGET} ${.ALLSRC} + +${.CURDIR}/${BIN_DIR}/release/${MODULE_NAME}${MODULE_EXT}: ${OBJS_RELEASE} + @mkdir -p ${.TARGET:H} + ${CC} -shared -s -o ${.TARGET} ${.ALLSRC} + +.for _src in ${SRCS} +${.CURDIR}/obj/debug/${_src:S|^src/||:S/.c$/.o/}: ${.CURDIR}/${_src} + @mkdir -p ${.TARGET:H} + ${CC} ${CFLAGS_BASE} -g -O0 -MMD -MP -MT ${.TARGET} -MF ${.TARGET:S/.o$/.d/} -c ${.ALLSRC} -o ${.TARGET} + +${.CURDIR}/obj/release/${_src:S|^src/||:S/.c$/.o/}: ${.CURDIR}/${_src} + @mkdir -p ${.TARGET:H} + ${CC} ${CFLAGS_BASE} -O2 -MMD -MP -MT ${.TARGET} -MF ${.TARGET:S/.o$/.d/} -c ${.ALLSRC} -o ${.TARGET} +.endfor + +clean: + rm -rf ${.CURDIR}/${OBJ_DIR} ${.CURDIR}/${BIN_DIR} diff --git a/module_template/build.bat b/module_template/build.bat new file mode 100644 index 0000000..00d0faf --- /dev/null +++ b/module_template/build.bat @@ -0,0 +1,2 @@ +@echo off +make -f gmake.mk %* diff --git a/module_template/build.sh b/module_template/build.sh new file mode 100755 index 0000000..3df3691 --- /dev/null +++ b/module_template/build.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +OS=$(uname -s | tr '[:upper:]' '[:lower:]') + +if [ "$OS" = "linux" ]; then + MK_FILE="gmake.mk" +else + MK_FILE="bmake.mk" +fi + +make -f "$MK_FILE" "$@" diff --git a/module_template/compile_flags.txt b/module_template/compile_flags.txt new file mode 100644 index 0000000..008c32f --- /dev/null +++ b/module_template/compile_flags.txt @@ -0,0 +1,4 @@ +-xc +-Wall +-Wpedantic +-Iinclude diff --git a/module_template/config.mk b/module_template/config.mk new file mode 100644 index 0000000..1b3e537 --- /dev/null +++ b/module_template/config.mk @@ -0,0 +1,8 @@ +SRC_DIR = src +INC_DIR = include +OBJ_DIR = obj +BIN_DIR = bin + +MODULE_NAME = my_module + +SRCS = src/module.c diff --git a/module_template/gmake.mk b/module_template/gmake.mk new file mode 100644 index 0000000..91d42b3 --- /dev/null +++ b/module_template/gmake.mk @@ -0,0 +1,45 @@ +include config.mk + +ifeq ($(OS),Windows_NT) + SHELL := cmd.exe + MODULE_EXT = .dll + MKDIR = if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1)) + RMDIR = if exist $(subst /,\,$(1)) rd /s /q $(subst /,\,$(1)) +else + MODULE_EXT = .so + MKDIR = mkdir -p $(1) + RMDIR = rm -rf $(1) +endif + +CC = cc +CFLAGS_BASE = -Wall -Wpedantic -I$(INC_DIR) -fPIC + +.PHONY: all debug release clean + +all: debug + +debug: $(BIN_DIR)/debug/$(MODULE_NAME)$(MODULE_EXT) +release: $(BIN_DIR)/release/$(MODULE_NAME)$(MODULE_EXT) + +$(BIN_DIR)/debug/$(MODULE_NAME)$(MODULE_EXT): $(SRCS:src/%.c=obj/debug/%.o) + @$(call MKDIR,$(@D)) + $(CC) -shared -o $@ $^ + +obj/debug/%.o: src/%.c + @$(call MKDIR,$(@D)) + $(CC) $(CFLAGS_BASE) -g -O0 -MMD -MP -c $< -o $@ + +$(BIN_DIR)/release/$(MODULE_NAME)$(MODULE_EXT): $(SRCS:src/%.c=obj/release/%.o) + @$(call MKDIR,$(@D)) + $(CC) -shared -s -o $@ $^ + +obj/release/%.o: src/%.c + @$(call MKDIR,$(@D)) + $(CC) $(CFLAGS_BASE) -O2 -MMD -MP -c $< -o $@ + +-include $(wildcard obj/debug/*.d) +-include $(wildcard obj/release/*.d) + +clean: + @$(call RMDIR,$(OBJ_DIR)) + @$(call RMDIR,$(BIN_DIR)) diff --git a/module_template/include/module_version.h b/module_template/include/module_version.h new file mode 100644 index 0000000..7786601 --- /dev/null +++ b/module_template/include/module_version.h @@ -0,0 +1,16 @@ +#ifndef MODULE_VERSION_H +#define MODULE_VERSION_H + +#define MY_MODULE_VERSION_MAJOR 0 +#define MY_MODULE_VERSION_MINOR 1 +#define MY_MODULE_VERSION_PATCH 0 + +#define MY_MODULE_STRINGIFY_HELPER(x) #x +#define MY_MODULE_STRINGIFY(x) MY_MODULE_STRINGIFY_HELPER(x) + +#define MY_MODULE_VERSION_STRING \ + MY_MODULE_STRINGIFY(MY_MODULE_VERSION_MAJOR) \ + "." MY_MODULE_STRINGIFY(MY_MODULE_VERSION_MINOR) "." MY_MODULE_STRINGIFY( \ + MY_MODULE_VERSION_PATCH) + +#endif /* MODULE_VERSION_H */ diff --git a/module_template/src/module.c b/module_template/src/module.c new file mode 100644 index 0000000..7a22788 --- /dev/null +++ b/module_template/src/module.c @@ -0,0 +1,38 @@ +#include "module_version.h" +#include + +/* on load */ +int stk_mod_init(void) +{ + printf("my_module initialized!\n"); + return 0; +} + +/* on unload/reload */ +void stk_mod_shutdown(void) { printf("my_module shut down.\n"); } + +const char *stk_mod_name(void) { return "my_module"; } +const char *stk_mod_version(void) { return MY_MODULE_VERSION_STRING; } +const char *stk_mod_description(void) { return "TODO: describe this module"; } + +/* + * declares which other modules must be loaded first. + * id = dependency's filename, minus extension. + * layout must match stk_dep_t: id[64], version[32]. + * sentinel ("","") required, always last. + * + * =1.0.0 exact + * >=1.0.0 minimum (default) + * ^1.0.0 same major + */ +/* +typedef struct { + char id[64]; + char version[32]; +} dep_t; + +dep_t stk_mod_deps[] = { + { "physics", ">=2.0.0" }, + { "", "" } +}; +*/