aboutsummaryrefslogtreecommitdiffstats
path: root/mk/lang-c.mk
diff options
context:
space:
mode:
Diffstat (limited to 'mk/lang-c.mk')
-rw-r--r--mk/lang-c.mk207
1 files changed, 207 insertions, 0 deletions
diff --git a/mk/lang-c.mk b/mk/lang-c.mk
new file mode 100644
index 0000000..7e9a15a
--- /dev/null
+++ b/mk/lang-c.mk
@@ -0,0 +1,207 @@
+# Copyright (C) 2015 Mattias Andrée <maandree@member.fsf.org>
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without any warranty.
+
+
+#=== This file includes rules for C programs. ===#
+
+
+# This file is ignored unless _C_STD is defined.
+# _C_STD should be set the the version of C that
+# is used.
+#
+# If you want to compile with -pedantic, define
+# the variable _PEDANTIC.
+#
+# Define _CPPFLAGS with any additional CPP
+# flags to use, _CFLAGS with any additional CC
+# flags to use, and _LDFLAGS with any additional
+# LD flags to use.
+#
+# Defined in path.mk, you can change _ALL_DIRS
+# if you do not want CPP definitions for all
+# directories.
+#
+# Define _HEADER_DIRLEVELS to specify the directory
+# nesting level in src. It is assumed that all
+# directories contain header files. Set to '0' if
+# there are no header files.
+#
+# _BIN shall list all commands to build. These
+# should be the basenames. For each command
+# you should be the variable _OBJ_$(COMMAND)
+# that lists all objects files (without the
+# suffix and without the aux/ prefix) that
+# are required to build the command.
+
+
+ifdef _C_STD
+
+
+
+# WHEN TO BUILD, INSTALL, AND UNINSTALL:
+
+cmd: cmd-c
+install-cmd: install-cmd-c
+uninstall: uninstall-cmd-c
+
+
+# HELP VARIABLES:
+
+# Figure out whether the GCC is being used.
+ifeq ($(shell $(PRINTF) '%s\n' ${CC} | $(HEAD) -n 1),gcc)
+__USING_GCC = 1
+endif
+
+
+# BUILD VARIABLES:
+
+# Optimisation settings for C code compilation.
+ifndef OPTIMISE
+ifndef DEBUG
+OPTIMISE = -O2 -g
+endif
+ifdef DEBUG
+ifdef __USING_GCC
+OPTIMISE = -Og -g
+endif
+ifndef __USING_GCC
+OPTIMISE = -g
+endif
+endif
+endif
+
+# Warning settings for C code compilation.
+ifdef _PEDANTIC
+_PEDANTIC = -pedantic
+endif
+ifndef WARN
+ifndef DEBUG
+WARN = -Wall
+endif
+ifdef DEBUG
+ifdef __USING_GCC
+WARN = -Wall -Wextra $(_PEDANTIC) -Wdouble-promotion -Wformat=2 -Winit-self -Wmissing-include-dirs \
+ -Wtrampolines -Wmissing-prototypes -Wmissing-declarations -Wnested-externs \
+ -Wno-variadic-macros -Wsync-nand -Wunsafe-loop-optimizations -Wcast-align \
+ -Wdeclaration-after-statement -Wundef -Wbad-function-cast -Wwrite-strings -Wlogical-op \
+ -Wstrict-prototypes -Wold-style-definition -Wpacked -Wvector-operation-performance \
+ -Wunsuffixed-float-constants -Wsuggest-attribute=const -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=format -Wnormalized=nfkc -fstrict-aliasing -fipa-pure-const -ftree-vrp \
+ -fstack-usage -funsafe-loop-optimizations -Wshadow -Wredundant-decls -Winline -Wcast-qual \
+ -Wsign-conversion -Wstrict-overflow=5 -Wconversion -Wsuggest-attribute=pure -Wswitch-default \
+ -Wstrict-aliasing=1 -fstrict-overflow -Wfloat-equal -Wpadded -Waggregate-return \
+ -Wtraditional-conversion
+endif
+ifndef __USING_GCC
+WARN = -Wall -Wextra $(_PEDANTIC)
+endif
+endif
+endif
+
+# Support for internationalisation?
+ifndef WITHOUT_GETTEXT
+_CPPFLAGS += -D'USE_GETTEXT=1'
+endif
+
+# Add CPP definitions for all directories.
+_CPPFLAGS += $(foreach D,$(_ALL_DIRS),-D'$(D)="$($(D))"')
+
+
+# MORE HELP VARIABLES:
+
+# Compilation and linking flags, and command.
+ifndef CPPFLAGS
+CPPFLAGS =
+endif
+ifndef CFLAGS
+CFLAGS = $(OPTIMISE) $(WARN)
+endif
+ifndef LDFLAGS
+LDFLAGS = $(OPTIMISE) $(WARN)
+endif
+__CC = $(CC) -std=$(_C_STD) -c $(_CPPFLAGS) $(_CFLAGS)
+__LD = $(CC) -std=$(_C_STD) $(_LDFLAGS)
+__CC_POST = $(CPPFLAGS) $(CFLAGS) $(EXTRA_CPPFLAGS) $(EXTRA_CFLAGS)
+__LD_POST = $(LDFLAGS) $(EXTRA_LDFLAGS)
+
+# Header files.
+__H =
+ifdef _HEADER_DIRLEVELS
+ifeq ($(_HEADER_DIRLEVELS),1)
+__H += src/*.h
+endif
+ifneq ($(_HEADER_DIRLEVELS),1)
+ifeq ($(_HEADER_DIRLEVELS),2)
+__H += src/*.h
+__H += src/*/*.h
+endif
+ifneq ($(_HEADER_DIRLEVELS),2)
+ifneq ($(_HEADER_DIRLEVELS),0)
+__H += $(foreach W,$(shell $(SEQ) $(_HEADER_DIRLEVELS) | while read n; do $(ECHO) $$($(SEQ) $$n)" " | $(SED) 's/[^ ]* /\/\*/g'; done | $(XARGS) $(ECHO)),src$(W).h)
+endif
+endif
+endif
+endif
+
+
+# BUILD RULES:
+
+.PHONY: cmd-c
+cmd-c: $(foreach B,$(_BIN),bin/$(B))
+
+# Compile a C file into an object file.
+aux/%.o: $(v)src/%.c $(foreach H,$(__H),$(v)$(H))
+ @$(PRINTF_INFO) '\e[00;01;31mCC\e[34m %s\e[00m$A\n' "$@"
+ @$(MKDIR) -p $(shell $(DIRNAME) $@)
+ $(Q)$(__CC) -o $@ $< $(__CC_POST) #$Z
+ @$(ECHO_EMPTY)
+
+# Link object files into a command.
+# Dependencies are declared below.
+bin/%:
+ @$(PRINTF_INFO) '\e[00;01;31mLD\e[34m %s\e[00;32m$A\n' "$@"
+ @$(MKDIR) -p bin
+ $(Q)$(__LD) -o $@ $^ $(__LD_POST) #$Z
+ @$(ECHO_EMPTY)
+
+# Dependencies for the rule above.
+include aux/lang-c.mk
+aux/lang-c.mk: Makefile
+ @$(MKDIR) -p aux
+ @$(ECHO) > aux/lang-c.mk
+ @$(foreach B,$(_BIN),$(ECHO) bin/$(B): $(foreach O,$(_OBJ_$(B)),aux/$(O).o) >> aux/lang-c.mk &&) $(TRUE)
+
+
+# INSTALL RULES:
+
+.PHONY: install-cmd-c
+install-cmd-c: $(foreach B,$(_BIN),bin/$(B))
+ @$(PRINTF_INFO) '\e[00;01;31mINSTALL\e[34m %s\e[00m\n' "$@"
+ $(Q)$(INSTALL_DIR) -- "$(DESTDIR)$(BINDIR)"
+ifdef COMMAND
+ $(Q)$(INSTALL_PROGRAM) $(__STRIP) $^ -- "$(DESTDIR)$(BINDIR)"
+endif
+ifndef COMMAND
+ $(Q)$(INSTALL_PROGRAM) $(__STRIP) $^ -- "$(DESTDIR)$(BINDIR)/$(COMMAND)"
+endif
+ @$(ECHO_EMPTY)
+
+
+# UNINSTALL RULES:
+
+.PHONY: uninstall-cmd-c
+uninstall-cmd-c:
+ifdef COMMAND
+ -$(Q)$(RM) -- "$(DESTDIR)$(BINDIR)/$(COMMAND)"
+endif
+ifndef COMMAND
+ -$(Q)$(RM) -- $(foreach B,$(_BIN),"$(DESTDIR)$(BINDIR)/$(B)")
+endif
+
+
+endif
+