.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 [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"