Files
makemake/makefile
2026-08-31 17:20:26 +02:00

182 lines
5.9 KiB
Makefile

.POSIX:
all: help
help:
@echo "Please use: 'make init', 'make debug', 'make build', or 'make clean'"
@echo "Note: parallel builds (via 'make -jN' where N is some number of how many jobs to generate)"
@echo "This is supported via recursive build shell calls. Not actually passing -j to make so should work even on a pure POSIX system."
init:
@mkdir -p output source_code includes config
@touch source_code/main.c
@printf '%s\n' \
'# POSIX Virtual Environment for C Build System.' \
'# Usage: . config/activate' \
'' \
'# Prevents double-sourcing.' \
'if [ -n "$$_OLD_VIRTUAL_CC" ]; then' \
' deactivate' \
'fi' \
'' \
'_OLD_VIRTUAL_CC="$$CC"' \
'_OLD_VIRTUAL_LIBS="$$LIBS"' \
'_OLD_VIRTUAL_CFLAGS="$$CFLAGS"' \
'_OLD_VIRTUAL_DEBUG_FLAGS="$$DEBUG_FLAGS"' \
'_OLD_VIRTUAL_BUILD_FLAGS="$$BUILD_FLAGS"' \
'_OLD_VIRTUAL_VERSION="$$VERSION"' \
'_OLD_VIRTUAL_PS1="$$PS1"' \
'' \
'# Base configuration variables (Updated by "env_set VARIABLE value")' \
'export CC="c99"' \
'export LIBS=""' \
'export CFLAGS=""' \
'export DEBUG_FLAGS=""' \
'export BUILD_FLAGS=""' \
'export VERSION=""' \
'export C_VENV_ACTIVE="true"' \
'' \
'# Prepend (directory_name_env) to the shell prompt' \
'ENV_NAME="$$(basename "$$PWD")"' \
'PS1="($${ENV_NAME}_env) $$PS1"' \
'export PS1' \
'' \
'# Function to dynamically set variables in the terminal AND save them to this file.' \
'env_set() {' \
' if [ -z "$$1" ]; then' \
' echo "Usage: env_set <CC|LIBS|CFLAGS|DEBUG_FLAGS|BUILD_FLAGS|VERSION> [value]"' \
' return 1' \
' fi' \
' ' \
' VAR_NAME="$$1"' \
' shift' \
' VAR_VALUE="$$*"' \
' ' \
' # Update the active shell session' \
' export "$$VAR_NAME"="$$VAR_VALUE"' \
' ' \
' # Update this activate file using POSIX sed. To ensure the new value persists the next activate.' \
' sed "s|^export $$VAR_NAME=.*|export $$VAR_NAME=\"$$VAR_VALUE\"|" config/activate > config/activate.tmp' \
' mv config/activate.tmp config/activate' \
' ' \
' echo "Updated $$VAR_NAME to '\''$$VAR_VALUE'\''"' \
'}' \
'' \
'deactivate() {' \
' # Restore prior environment variables' \
' if [ -n "$$_OLD_VIRTUAL_CC" ]; then' \
' export CC="$$_OLD_VIRTUAL_CC"' \
' else' \
' unset CC' \
' fi' \
'' \
' if [ -n "$$_OLD_VIRTUAL_LIBS" ]; then' \
' export LIBS="$$_OLD_VIRTUAL_LIBS"' \
' else' \
' unset LIBS' \
' fi' \
'' \
' if [ -n "$$_OLD_VIRTUAL_CFLAGS" ]; then' \
' export CFLAGS="$$_OLD_VIRTUAL_CFLAGS"' \
' else' \
' unset CFLAGS' \
' fi' \
'' \
' if [ -n "$$_OLD_VIRTUAL_DEBUG_FLAGS" ]; then' \
' export DEBUG_FLAGS="$$_OLD_VIRTUAL_DEBUG_FLAGS"' \
' else' \
' unset DEBUG_FLAGS' \
' fi' \
'' \
' if [ -n "$$_OLD_VIRTUAL_BUILD_FLAGS" ]; then' \
' export BUILD_FLAGS="$$_OLD_VIRTUAL_BUILD_FLAGS"' \
' else' \
' unset BUILD_FLAGS' \
' fi' \
'' \
' if [ -n "$$_OLD_VIRTUAL_VERSION" ]; then' \
' export VERSION="$$_OLD_VIRTUAL_VERSION"' \
' else' \
' unset VERSION' \
' fi' \
'' \
' if [ -n "$$_OLD_VIRTUAL_PS1" ]; then' \
' export PS1="$$_OLD_VIRTUAL_PS1"' \
' fi' \
' ' \
' unset _OLD_VIRTUAL_CC' \
' unset _OLD_VIRTUAL_LIBS' \
' unset _OLD_VIRTUAL_CFLAGS' \
' unset _OLD_VIRTUAL_DEBUG_FLAGS' \
' unset _OLD_VIRTUAL_BUILD_FLAGS' \
' unset _OLD_VIRTUAL_VERSION' \
' unset _OLD_VIRTUAL_PS1' \
' unset C_VENV_ACTIVE' \
' unset ENV_NAME' \
' unset -f env_set' \
' unset -f deactivate' \
'}' > config/activate
@echo "Project initialized. type '. config/activate', or 'source config/activate' to enter the virtual environment."
clean:
@rm -rf output/obj_debug output/obj_release config/*.mk
@rm -f output/*
@echo "Project Cleaned"
# Dynamic Build Graph Generators
debug:
@if [ -z "$$C_VENV_ACTIVE" ]; then \
echo "Error: Virtual environment not active."; \
echo "Please run: '. config/activate' (or 'source config/activate') before building."; \
exit 1; \
fi
@mkdir -p config output/obj_debug
@PROJ_NAME=$$(basename "$$(pwd)"); \
OUT="output/$${PROJ_NAME}$${VERSION}"; \
MK="config/debug.mk"; \
ACTIVE_CC=$${CC:-c99}; \
ACTIVE_LIBS=$${LIBS:-}; \
ACTIVE_CFLAGS=$${CFLAGS:-}; \
ACTIVE_DEBUG_FLAGS=$${DEBUG_FLAGS:-}; \
echo ".POSIX:" > $$MK; \
OBJS=""; \
SRCS=$$(find source_code -type f -name '*.c' 2>/dev/null); \
for SRC in $$SRCS; do \
OBJ="output/obj_debug/$${SRC}.o"; \
OBJS="$$OBJS $$OBJ"; \
echo "$$OBJ: $$SRC" >> $$MK; \
echo " @mkdir -p $$(dirname $$OBJ)" >> $$MK; \
echo " $$ACTIVE_CC $$ACTIVE_CFLAGS $$ACTIVE_DEBUG_FLAGS -I includes -c $$SRC -o $$OBJ $$ACTIVE_LIBS" >> $$MK; \
done; \
echo "$$OUT: $$OBJS" >> $$MK; \
echo " $$ACTIVE_CC $$ACTIVE_CFLAGS $$ACTIVE_DEBUG_FLAGS -o $$OUT $$OBJS $$ACTIVE_LIBS" >> $$MK; \
$(MAKE) -f $$MK "$$OUT"
build:
@if [ -z "$$C_VENV_ACTIVE" ]; then \
echo "Error: Virtual environment not active."; \
echo "Please run: '. config/activate' (or 'source config/activate') before building."; \
exit 1; \
fi
@mkdir -p config output/obj_release
@PROJ_NAME=$$(basename "$$(pwd)"); \
OUT="output/$${PROJ_NAME}$${VERSION}"; \
MK="config/build.mk"; \
ACTIVE_CC=$${CC:-c99}; \
ACTIVE_LIBS=$${LIBS:-}; \
ACTIVE_CFLAGS=$${CFLAGS:-}; \
ACTIVE_BUILD_FLAGS=$${BUILD_FLAGS:-}; \
echo ".POSIX:" > $$MK; \
OBJS=""; \
SRCS=$$(find source_code -type f -name '*.c' 2>/dev/null); \
for SRC in $$SRCS; do \
OBJ="output/obj_release/$${SRC}.o"; \
OBJS="$$OBJS $$OBJ"; \
echo "$$OBJ: $$SRC" >> $$MK; \
echo " @mkdir -p $$(dirname $$OBJ)" >> $$MK; \
echo " $$ACTIVE_CC $$ACTIVE_CFLAGS $$ACTIVE_BUILD_FLAGS -I includes -c $$SRC -o $$OBJ $$ACTIVE_LIBS" >> $$MK; \
done; \
echo "$$OUT: $$OBJS" >> $$MK; \
echo " $$ACTIVE_CC $$ACTIVE_CFLAGS $$ACTIVE_BUILD_FLAGS -o $$OUT $$OBJS $$ACTIVE_LIBS" >> $$MK; \
$(MAKE) -f $$MK "$$OUT"