Skip to content

Instantly share code, notes, and snippets.

@wrpaape
Created May 27, 2016 23:39
Show Gist options
  • Save wrpaape/51d6cb52f24a8983f6be8fd55eb4f3b7 to your computer and use it in GitHub Desktop.
Save wrpaape/51d6cb52f24a8983f6be8fd55eb4f3b7 to your computer and use it in GitHub Desktop.
.PHONY: all clean
# ENVIRONMENT CONFIG
# ══════════════════════════════════════════════════════════════════════════════
# USER_BIN = ~/bin = export main binary dest dir
# C_LIBRARY_SOURCES = ~C_LIBRARIES/src = root of all module directories
# C_LIBRARY_HEADERS = ~C_LIBRARIES/include = export header root dir
# C_SHARED_LIBRARIES = ~C_LIBRARIES/shared = export shared libraries dest dir
# C_STATIC_LIBRARIES = ~C_LIBRARIES/static = export static libraries dest dir
# UNITY_SCRIPTS = ~C_ROOT/unity/auto = Unity scripts folder
# SHELL = /bin/zsh (for ** match recursive subdirs glob)
SHELL := /bin/zsh
# UTILITY CONFIG
# ══════════════════════════════════════════════════════════════════════════════
# C Compiler
# ──────────────────────────────────────────────────────────────────────────────
CC := gcc
CC_FLAGS := -I. -g -std=c99 -Wall -D__USE_FIXED_PROTOTYPES__
# Linker
# ──────────────────────────────────────────────────────────────────────────────
LD := ld
LD_FLAGS := -L$(C_STATIC_LIBRARIES) -L$(C_SHARED_LIBRARIES)
LD_ARG_LIST := -Wl,-rpath,$(C_SHARED_LIBRARIES)
# Archiver
# ──────────────────────────────────────────────────────────────────────────────
AR := ar
AR_FLAGS := rcs
# Merge Libraries, Objects
# ──────────────────────────────────────────────────────────────────────────────
LIBTOOL := libtool
LIBTOOL_FLAGS := $(LD_FLAGS)
# Make Directory
# ──────────────────────────────────────────────────────────────────────────────
MKDIR := mkdir
MKDIR_FLAGS := -p
# Copy File
# ──────────────────────────────────────────────────────────────────────────────
CP := cp
CP_FLAGS := $(EMPTY)
# Copy Relative Path
# ──────────────────────────────────────────────────────────────────────────────
RSYNC := rsync
RSYNC_FLAGS := -R
# Cleaner
# ──────────────────────────────────────────────────────────────────────────────
RM := rm
RM_FLAGS := -rf
# Ruby
# ──────────────────────────────────────────────────────────────────────────────
RUBY := ruby
RUBY_FLAGS := $(EMPTY)
# PATH CONFIGURATION
# ══════════════════════════════════════════════════════════════════════════════
# Module
# ─────────────── source ───────────────────────────────────────────────────────
HEADER_PATH = $(call TRIM,./$1.h)# interface
SOURCE_PATH = $(call TRIM,./$1.c)# implementation
MAIN_SOURCE_PATH = $(call TRIM,./$1_main.c)# entry point
# ─────────────── build ────────────────────────────────────────────────────────
OBJECT_PATH = $(call TRIM,../obj/$1.o)# object files
PIC_OBJECT_PATH = $(call TRIM,../obj/$1_pic.o)# "position independent code" object files
MAIN_OBJECT_PATH = $(call TRIM,../obj/$1_main.o)# main entry object file
MAIN_BINARY_PATH = $(call TRIM,../bin/$1)# binary executable output
SHARED_LIBRARY_PATH = $(call TRIM,../shared/lib$1_shared.so)# shared library output
STATIC_LIBRARY_PATH = $(call TRIM,../static/lib$1_static.a)# static library output
# ─────────────── export ────────────────────────────────────────────────────────
EXPORT_HEADER_DIRECTORY = $(call TRIM,$(C_LIBRARY_HEADERS)/$1)# user library header
EXPORT_HEADER_PATH = $(call TRIM,$(call EXPORT_HEADER_DIRECTORY,$1)/$1.h)# user library header
EXPORT_SUPPORT_HEADER_PATH = $(call TRIM,$(call EXPORT_HEADER_DIRECTORY,$1)/$2.h)# user library support header
EXPORT_MAIN_BINARY_PATH = $(call TRIM,$(USER_BIN)/$1)# user binary
EXPORT_SHARED_LIBRARY_PATH = $(call TRIM,$(C_SHARED_LIBRARIES)/lib$1_shared.so)# user shared library
EXPORT_STATIC_LIBRARY_PATH = $(call TRIM,$(C_STATIC_LIBRARIES)/lib$1_static.a)# user static library
# Testing
# ─────────────── source ───────────────────────────────────────────────────────
TEST_SOURCE_PATH = $(call TRIM,../test/$1_test.c)# Unity unit tests
TEST_RUNNER_SOURCE_PATH = $(call TRIM,../test/test_runners/$1_test_runner.c)# Unity test runners
# ─────────────── build ────────────────────────────────────────────────────────
TEST_OBJECT_PATH = $(call TRIM,../obj/$1_test.o)# Unity unit test object files
TEST_RUNNER_OBJECT_PATH = $(call TRIM,../obj/$1_test_runner.o)# Unity test runner object files
TEST_BINARY_PATH = $(call TRIM,../test/$1_test)# binary executable output
# User Libraries
# ─────────────── source ───────────────────────────────────────────────────────
# ─────────────── build ────────────────────────────────────────────────────────
# USER_OBJECT_PATH = $(call TRIM,$(C_LIBRARY_SOURCES)/$1/obj/$2.o)# object files
# USER_PIC_OBJECT_PATH = $(call TRIM,$(C_LIBRARY_SOURCES)/$1/obj/$2_pic.o)# "position independent code" object files
# SIMPLE RULES - expands to a single rule, updates 'TARGETS'
# ══════════════════════════════════════════════════════════════════════════════
# Base Rules
define GENERATE_TEST_RUNNER
$(NEWLINE)
$(strip $1: $2)
$(strip $(RUBY) $(RUBY_FLAGS) $(UNITY_SCRIPTS)/generate_test_runner.rb $$< $$@)
TARGETS += $1
$(NEWLINE)
endef
define COMPILE_SOURCE
$(NEWLINE)
$(strip $1: $2)
$(strip $(CC) $(CC_FLAGS) $3 -c $$< -o $$@)
TARGETS += $1
$(NEWLINE)
endef
define LINK_OBJECTS
$(NEWLINE)
$(strip $1: $2)
$(strip $(CC) $(CC_FLAGS) $(LD_ARG_LIST) $$^ $3 $(LD_FLAGS) -o $$@)
TARGETS += $1
$(NEWLINE)
endef
define ARCHIVE_OBJECTS
$(NEWLINE)
$(strip $1: $2)
$(strip $(AR) $(call TRIM,$(AR_FLAGS)$3) $$@ $$^)
TARGETS += $1
$(NEWLINE)
endef
define MAKE_DIRECTORY
$(NEWLINE)
$(strip $1:)
$(strip $(MKDIR) $(MKDIR_FLAGS) $2 $$@)
TARGETS += $1
$(NEWLINE)
endef
define COPY_FILE
$(NEWLINE)
$(strip $1: $2)
$(strip $(CP) $(CP_FLAGS) $3 $$< $$@)
TARGETS += $1
$(NEWLINE)
endef
define RSYNC_FILE
$(NEWLINE)
$(strip $1: $2)
$(strip $(RSYNC) $(RSYNC_FLAGS) $3 $$< $$@)
TARGETS += $1
$(NEWLINE)
endef
define INTO_LIBRARY
$(NEWLINE)
$(strip $1: $2)
$(strip $(LIBTOOL) $(LIBTOOL_FLAGS) $$^ $3 -o $$@)
TARGETS += $1
$(NEWLINE)
endef
# Derivative Rules
define COPY_FILE_TO_DIRECTORY
$(call COPY_FILE,$(call TRIM,$2/$(notdir $1)),\
$1 $2,\
$3)
endef
#
# ──────────────────────────────── EXPORT_GLOB_TO_DIRECTORY/1..5 ─────────────────────────────────
# $(call EXPORT_GLOB_TO_DIRECTORY,<glob>,\
# <path/to/export/directory>,\
# <(optional) additional $(MKDIR) flags>,\
# <(optional) additional $(RSYNC) flags>)
#
# rule for:
# 1) export directory with glob <absolute/path/to/export/directory/glob/matches>
# prerequisites:
define EXPORT_GLOB_TO_DIRECTORY
$(NEWLINE)
$(strip $2: $(shell echo $1))
$(strip $(MKDIR) $(MKDIR_FLAGS) $3 $$@)
$(strip $(RSYNC) $(RSYNC_FLAGS) $4 $1 $$@)
TARGETS += $2
$(NEWLINE)
endef
# COMPOUND RULES - expands to multiple 'simple' rules
# ══════════════════════════════════════════════════════════════════════════════
#
# ──────────────────────────────── EXPORT_FILE/1..4 ─────────────────────────────────
# $(call EXPORT_FILE,<absolute/path/to/file.ext>,\
# <absolute/path/to/export/directory>,\
# <(optional) additional $(MKDIR) flags>,\
# <(optional) additional $(CP) flags>)
#
# rules for:
# 1) export directory <absolute/path/to/export/directory>
# 2) copied file <absolute/path/to/export/directory/file>
# prerequisites:
# 1) original file <absolute/path/to/file>
define EXPORT_FILE
$(NEWLINE)
$(call COPY_FILE_TO_DIRECTORY,$1,$2,$4)
$(call MAKE_DIRECTORY,$2,$3)
$(NEWLINE)
endef
# SIMPLE MODULE RULES - convenience API for expanding a SINGLE 'simple' rule
# ══════════════════════════════════════════════════════════════════════════════
#
# ──────────────────────────────── OBJECT/1..3 ─────────────────────────────────
#
# $(call OBJECT,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>)
#
# rule for:
# 1) main binary ../obj/<module>.o
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
define OBJECT
$(call COMPILE_SOURCE,$(call OBJECT_PATH,$1),\
$(call SOURCE_HEADER_PATHS,$1) $2,\
$3)
endef
#
# ────────────────────────────── MAIN_OBJECT/1..3 ──────────────────────────────
#
# $(call MAIN_OBJECT,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>)
#
# rule for:
# 1) main binary ../obj/<module>.o
# prerequisites:
# 1) main module source ../src/<module>_main.c
# 2) module source ../src/<module>.c
# 3) module header ../src/<module>.h
define MAIN_OBJECT
$(call COMPILE_SOURCE,$(call MAIN_OBJECT_PATH,$1),\
$(call MAIN_SOURCE_PATH,$1) $(call SOURCE_HEADER_PATHS,$1) $2,\
$3)
endef
#
# ────────────────────────────── PIC_OBJECT/1..3 ───────────────────────────────
#
# $(call PIC_OBJECT,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>)
#
# rule for:
# 1) module PIC object ../obj/<module>_pic.o
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
define PIC_OBJECT
$(call COMPILE_SOURCE,$(call PIC_OBJECT_PATH,$1),\
$(call SOURCE_HEADER_PATHS,$1) $2,\
-fpic $3)
endef
#
# ────────────────────────────── TEST_OBJECT/1..3 ───────────────────────────────
#
# $(call TEST_OBJECT,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>)
#
# rule for:
# 1) unit test object ../obj/<module>_test.o
# prerequisites:
# 1) unit test source ../test/<module>_test.c
# 2) module source ../src/<module>.c
# 3) module header ../src/<module>.h
define TEST_OBJECT
$(call COMPILE_SOURCE,$(call TEST_OBJECT_PATH,$1),\
$(call TEST_SOURCE_PATH,$1) $(call SOURCE_HEADER_PATHS,$1) $2,\
-DUNITY_INCLUDE_CONFIG_H $3)
endef
#
# ────────────────────────────── TEST_RUNNER_SOURCE/1 ───────────────────────────────
#
# $(call TEST_RUNNER_SOURCE,<module>)
#
# rule for:
# 1) test runner source ../test/test_runners/<module>_test_runner.c
# prerequisites:
# 1) unit test source ../test/<module>_test.c
define TEST_RUNNER_SOURCE
$(call GENERATE_TEST_RUNNER,$(call TEST_RUNNER_SOURCE_PATH,$1),\
$(call TEST_SOURCE_PATH,$1))
endef
#
# ────────────────────────────── TEST_RUNNER_OBJECT_SIMPLE/1..3 ───────────────────────────────
#
# $(call TEST_RUNNER_OBJECT,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>)
#
# rule for:
# 1) test runner object ../obj/<module>_test_runner.o
# prerequisites:
# 1) test runner source ../test/test_runners/<module>_test_runner.c
# 2) unit test object ../obj/<module>_test.o
define TEST_RUNNER_OBJECT
$(call COMPILE_SOURCE,$(call TEST_RUNNER_OBJECT_PATH,$1),\
$(call TEST_RUNNER_SOURCE_PATH,$1) $(call TEST_OBJECT_PATH,$1) $2,\
-DUNITY_INCLUDE_CONFIG_H $3)
endef
#
# ────────────────────────────── MAIN_BINARY_SIMPLE/1..3 ──────────────────────────────
#
# $(call MAIN_BINARY_SIMPLE,<module>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>)
#
# rule for:
# 1) main binary ../bin/<module>
# prerequisites:
# 1) main object ../obj/<module>_main.o
# 2) module object ../obj/<module>.o
define MAIN_BINARY_SIMPLE
$(call LINK_OBJECTS,$(call MAIN_BINARY_PATH,$1),\
$(call MAIN_OBJECT_PATH,$1) $(call OBJECT_PATH,$1) $2,\
$3)
endef
#
# ────────────────────────────── TEST_BINARY_SIMPLE/1..3 ──────────────────────────────
#
# $(call TEST_BINARY_SIMPLE,<module>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>)
#
# rule for:
# 1) test binary ../test/<module>_test
# prerequisites:
# 1) test object ../obj/<module>_test.o
# 2) test runner object ../obj/<module>_test_runner.o
# 3) module object ../obj/<module>.o
define TEST_BINARY_SIMPLE
$(call LINK_OBJECTS,$(call TEST_BINARY_PATH,$1),\
$(call TEST_RUNNER_OBJECT_PATH,$1) $(call TEST_OBJECT_PATH,$1) $(call OBJECT_PATH,$1) $2,\
-lunity_shared $3)
endef
#
# ─────────────────────────── SHARED_LIBRARY_SIMPLE/1..3 ────────────────────────────
#
# $(call SHARED_LIBRARY_SIMPLE,<module>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>)
#
# rule for:
# 1) shared library ../shared/lib<module>_shared.so
# prerequisites:
# 1) PIC module object ../obj/<module>_pic.o
define SHARED_LIBRARY_SIMPLE
$(call LINK_OBJECTS,$(call SHARED_LIBRARY_PATH,$1),\
$(call PIC_OBJECT_PATH,$1) $2,\
-shared $3)
endef
#
# ─────────────────────────── STATIC_LIBRARY_SIMPLE/1..3 ────────────────────────────
#
# $(call STATIC_LIBRARY_SIMPLE,<module>,\
# <(optional) $(LIBTOOL) prerequisites>,\
# <(optional) $(LIBTOOL) flags>)
#
# rule for:
# 1) static library ../static/lib<module>_static.a
# prerequisites:
# 1) module object ../obj/<module>.o
define STATIC_LIBRARY_SIMPLE
$(call INTO_LIBRARY,$(call STATIC_LIBRARY_PATH,$1),\
$(call OBJECT_PATH,$1) $2,\
-static $3)
endef
# COMPOUND MODULE RULES - convenience API for expanding multiple 'simple' rules
# ══════════════════════════════════════════════════════════════════════════════
#
# ────────────────────────────── MAIN_BINARY/1..5 ──────────────────────────────
#
# $(call MAIN_BINARY,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>)
#
# rules for:
# 1) main binary ../bin/<module>
# 2) main object ../obj/<module>_main.o
# 3) object ../obj/<module>.o
# prerequisites:
# 1) main source ../src/<module>_main.c
# 2) module source ../src/<module>.c
# 3) module header ../src/<module>.h
define MAIN_BINARY
$(call MAIN_BINARY_SIMPLE,$1,$4,$5)
$(call MAIN_OBJECT,$1,$2,$3)
$(call OBJECT,$1,$2,$3)
endef
# ────────────────────────────── USER_BINARY_NO_OBJECT/1..6 ──────────────────────────────
#
# $(call USER_BINARY_NO_OBJECT,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>,\
# <(optional) $(CP) flags>)
#
# rules for:
# 1) main binary copy $(USER_BIN)/<module>
# 2) main binary ../bin/<module>
# 3) main object ../obj/<module>_main.o
# prerequisites:
# 1) main source ../src/<module>_main.c
# 2) module source ../src/<module>.c
# 3) module header ../src/<module> .h
# 4) module object ../obj/<module>.o
define USER_BINARY_NO_OBJECT
$(call EXPORT_MAIN_BINARY,$1,$6)
$(call MAIN_BINARY_SIMPLE,$1,$4,$5)
$(call MAIN_OBJECT,$1,$2,$3)
endef
# ────────────────────────────── USER_BINARY/1..6 ──────────────────────────────
#
# $(call USER_BINARY,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(CP) flags>)
#
# rules for:
# 1) main binary copy $(USER_BIN)/<module>
# 2) main binary ../bin/<module>
# 3) main object ../obj/<module>_main.o
# 4) module object ../obj/<module>.o
# prerequisites:
# 1) main source ../src/<module>_main.c
# 2) module source ../src/<module>.c
# 3) module header ../src/<module>.h
define USER_BINARY
$(call EXPORT_MAIN_BINARY,$1,$6)
$(call MAIN_BINARY,$1,$2,$3,$4,$5)
endef
#
# ────────────────────────────── SHARED_LIBRARY/1..5 ──────────────────────────────
#
# $(call SHARED_LIBRARY,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>)
#
# rules for:
# 1) shared_library ../shared/lib<module>_shared.so
# 2) PIC object ../obj/<module>_pic.o
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
define SHARED_LIBRARY
$(call SHARED_LIBRARY_SIMPLE,$1,$4,$5)
$(call PIC_OBJECT,$1,$2,$3)
endef
#
# ────────────────────────────── USER_SHARED_LIBRARY/1..8 ──────────────────────────────
#
# $(call USER_SHARED_LIBRARY,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>,\
# <(optional) $(CP) flags>,\
# <(optional) $(MKDIR) flags>,\
# <(optional) $(RSYNC) flags>)
#
# rules for:
# 1) module header copy $(C_LIBRARY_HEADERS)/<module>/<module>.h
# 2) module header directory $(C_LIBRARY_HEADERS)/<module>
# 3) shared library copy $(C_SHARED_LIBRARIES)/lib<module>_shared.so
# 4) shared library directory $(C_SHARED_LIBRARIES)/<module>
# 5) shared_library ../shared/lib<module>_shared.so
# 6) PIC object ../obj/<module>_pic.o
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
define USER_SHARED_LIBRARY
$(call EXPORT_ALL_HEADERS,$1,$7,$8)
$(call EXPORT_SHARED_LIBRARY,$1,$6)
$(call SHARED_LIBRARY,$1,$2,$3,$4,$5)
endef
#
# ────────────────────────────── STATIC_LIBRARY/1..5 ──────────────────────────────
#
# $(call STATIC_LIBRARY,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LIBTOOL) prerequisites>,\
# <(optional) $(LIBTOOL) flags>)
#
# rules for:
# # 1) static_library ../static/lib<module>_static.a
# # 2) object ../obj/<module>.o
# # prerequisites:
# # 1) module source ../src/<module>.c
# # 2) module header ../src/<module>.h
define STATIC_LIBRARY
$(call STATIC_LIBRARY_SIMPLE,$1,$4,$5)
$(call OBJECT,$1,$2,$3)
endef
#
# ────────────────────────────── USER_STATIC_LIBRARY/1..8 ──────────────────────────────
#
# $(call USER_STATIC_LIBRARY,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LIBTOOL) prerequisites>,\
# <(optional) $(LIBTOOL) flags>,\
# <(optional) $(CP) flags>,\
# <(optional) $(MKDIR) flags>,\
# <(optional) $(RSYNC) flags>)
#
# rules for:
# 1) module header copy $(C_LIBRARY_HEADERS)/<module>/<module>.h
# 2) module header directory $(C_LIBRARY_HEADERS)/<module>
# 3) static library copy $(C_STATIC_LIBRARIES)/lib<module>_static.a
# 4) static_library ../static/lib<module>_static.a
# 5) object ../obj/<module>.o
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
define USER_STATIC_LIBRARY
$(call EXPORT_ALL_HEADERS,$1,$7,$8)
$(call EXPORT_STATIC_LIBRARY,$1,$6)
$(call STATIC_LIBRARY,$1,$2,$3,$4,$5)
endef
#
# ────────────────────────────── LIBRARIES/1..7 ──────────────────────────────
#
# $(call LIBRARIES,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LIBTOOL) prerequisites>,\
# <(optional) $(LD) flags>,\
# <(optional) $(LIBTOOL) flags>)
#
# rules for:
# 1) shared_library ../shared/lib<module>_shared.so
# 2) static_library ../static/lib<module>_static.so
# 3) PIC object ../obj/<module>_pic.o
# 4) object ../obj/<module>.o
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
define LIBRARIES
$(call SHARED_LIBRARY,$1,$2,$3,$4,$6)
$(call STATIC_LIBRARY,$1,$2,$3,$5,$7)
endef
#
# ────────────────────────────── USER_LIBRARIES/1..10 ──────────────────────────────
#
# $(call USER_LIBRARIES,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LIBTOOL) prerequisites>,\
# <(optional) $(LD) flags>,\
# <(optional) $(LIBTOOL) flags>,\
# <(optional) $(CP) flags>,\
# <(optional) $(MKDIR) flags>,\
# <(optional) $(RSYNC) flags>)
#
# rules for:
# 1) module header copy $(C_LIBRARY_HEADERS)/<module>/<module>.h
# 2) module header directory $(C_LIBRARY_HEADERS)/<module>
# 3) shared library copy $(C_SHARED_LIBRARIES)/lib<module>_shared.so
# 4) static library copy $(C_STATIC_LIBRARIES)/lib<module>_static.so
# 5) shared_library ../shared/lib<module>_shared.so
# 6) static_library ../static/lib<module>_static.so
# 7) PIC object ../obj/<module>_pic.o
# 8) object ../obj/<module>.o
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
define USER_LIBRARIES
$(call EXPORT_ALL_HEADERS,$1,$9,$(10))
$(call EXPORT_LIBRARIES,$1,$8)
$(call LIBRARIES,$1,$2,$3,$4,$5,$6,$7)
endef
#
# ───────────────────────────── EXPORT_HEADER/1..3 ─────────────────────────────
#
# $(call EXPORT_HEADER,<module>,\
# <(optional) $(MKDIR) flags>,\
# <(optional) $(CP) flags>)
#
# rules for:
# 1) module header copy $(C_LIBRARY_HEADERS)/<module>/<module>.h
# 2) export directory $(C_LIBRARY_HEADERS)/<module>
# prerequisites:
# 1) module header ../src/<module>.h
define EXPORT_HEADER
$(call EXPORT_FILE,$(call HEADER_PATH,$1),\
$(call EXPORT_HEADER_DIRECTORY,$1),\
$2,$3)
$(NEWLINE)
$(call COPY_FILE_TO_DIRECTORY,$1,$2,$4)
$(call MAKE_DIRECTORY,$2,$3)
$(NEWLINE)
endef
# ───────────────────────────── EXPORT_SIBLING_HEADERS/1..2 ─────────────────────────────
#
# $(call EXPORT_SIBLING_HEADERS,<module>,\
# <(optional) $(MKDIR) flags>,\
# <(optional) $(RSYNC) flags>)
#
# rules for:
# 1) copy header glob $(C_LIBRARY_HEADERS)/<module>/*.h
# 2) export directory $(C_LIBRARY_HEADERS)/<module>
# prerequisites:
define EXPORT_SIBLING_HEADERS
$(call EXPORT_GLOB_TO_DIRECTORY,*.h,\
$(call EXPORT_HEADER_DIRECTORY,$1),\
$2,$3)
endef
#
# ───────────────────────────── EXPORT_ALL_HEADERS/1..2 ─────────────────────────────
#
# $(call EXPORT_ALL_HEADERS,<module>,\
# <(optional) $(MKDIR) flags>,\
# <(optional) $(RSYNC) flags>)
#
# rules for:
# 1) copy header glob $(C_LIBRARY_HEADERS)/<module>/**/*.h
# 2) export directory $(C_LIBRARY_HEADERS)/<module>
# prerequisites:
define EXPORT_ALL_HEADERS
$(call EXPORT_GLOB_TO_DIRECTORY,**/*.h,\
$(call EXPORT_HEADER_DIRECTORY,$1),\
$2,$3)
endef
#
#───────────────────────── EXPORT_MAIN_BINARY/1..2 ─────────────────────────
#
# $(call EXPORT_MAIN_BINARY,<module>,\
# <(optional) additional $(CP) flags>)
#
# rules for:
# 1) main binary copy $(USER_BIN)/<module>
# prerequisites:
# 1) main binary ../bin/<module>
define EXPORT_MAIN_BINARY
$(call COPY_FILE_TO_DIRECTORY,$(call MAIN_BINARY_PATH,$1),\
$(value USER_BIN),\
$2)
endef
#
# ────────────────────────────── EXPORT_LIBRARIES/1..2 ──────────────────────────────
#
# $(call EXPORT_LIBRARIES,<module>,\
# <(optional) $(CP) flags>)
#
# rules for:
# 1) shared library copy $(C_SHARED_LIBRARIES)/lib<module>_shared.so
# 2) static library copy $(C_STATIC_LIBRARIES)/lib<module>_static.a
# prerequisites:
# 1) shared library ../shared/lib<module>_shared.so
# 2) static library ../static/lib<module>_static.a
define EXPORT_LIBRARIES
$(call EXPORT_SHARED_LIBRARY,$1,$2)
$(call EXPORT_STATIC_LIBRARY,$1,$2)
endef
#───────────────────────── EXPORT_SHARED_LIBRARY/1..2 ─────────────────────────
#
# $(call EXPORT_SHARED_LIBRARY,<module>,\
# <(optional) $(CP) flags>)
#
# rules for:
# 1) shared library copy $(C_SHARED_LIBRARIES)/lib<module>_shared.so
# prerequisites:
# 1) shared library ../shared/lib<module>_shared.so
define EXPORT_SHARED_LIBRARY
$(call COPY_FILE_TO_DIRECTORY,$(call SHARED_LIBRARY_PATH,$1),\
$(value C_SHARED_LIBRARIES),\
$2)
endef
#
#───────────────────────── EXPORT_STATIC_LIBRARY/1..2 ─────────────────────────
#
# $(call EXPORT_STATIC_LIBRARY,<module>,\
# <(optional) $(CP) flags>)
#
# rules for:
# 1) static library copy $(C_STATIC_LIBRARIES)/lib<module>_static.a
# prerequisites:
# 1) static library ../static/lib<module>_static.a
define EXPORT_STATIC_LIBRARY
$(call COPY_FILE_TO_DIRECTORY,$(call STATIC_LIBRARY_PATH,$1),\
$(value C_STATIC_LIBRARIES),\
$2)
endef
#
# ───────────────────────── TEST_BINARY/1..5 ───────────────────────────
#
# $(call TEST_BINARY,<module>,\
# <(optional) $(CC) prerequisites>,\
# <(optional) $(CC) flags>,\
# <(optional) $(LD) prerequisites>,\
# <(optional) $(LD) flags>)
#
# rules for:
# 1) test binary ../obj/<module>.o
# 2) test object ../obj/<module>_test.o
# 3) test runner object ../obj/<module>_test_runner.o
# 4) test runner source ../test/test_runners/<module>_test_runner.c
# prerequisites:
# 1) module source ../src/<module>.c
# 2) module header ../src/<module>.h
# 3) module object ../obj/<module>.o
# 4) test source ../test/<module>_test.c
define TEST_BINARY
$(call TEST_BINARY_SIMPLE,$1,$4,$5)
$(call TEST_OBJECT,$1,$2,$3)
$(call TEST_RUNNER_OBJECT,$1,$2,$3)
$(call TEST_RUNNER_SOURCE,$1)
endef
# MISC
# ══════════════════════════════════════════════════════════════════════════════
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
TAB := $(EMPTY) $(EMPTY)
define NEWLINE :=
endef
TRIM = $(subst $(SPACE),$(EMPTY),$1)
SOURCE_HEADER_PATHS = $(call SOURCE_PATH,$1) $(call HEADER_PATH,$1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment