diff options
Diffstat (limited to 'mk/lang-c.mk')
-rw-r--r-- | mk/lang-c.mk | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/mk/lang-c.mk b/mk/lang-c.mk new file mode 100644 index 0000000..a76a4c3 --- /dev/null +++ b/mk/lang-c.mk @@ -0,0 +1,177 @@ +# 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 obj/ 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. +ifdef DEBUG +OPTIMISE = -Og -g +else +ifndef OPTIMISE +OPTIMISE = -O2 +endif +endif + +# Warning settings for C code compilation. +ifdef _PEDANTIC +_PEDANTIC = -pedantic +endif +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 +else +WARN = -Wall -Wextra $(_PEDANTIC) +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. +__CC = $(CC) -std=$(_C_STD) $(OPTIMISE) $(WARN) $(_CPPFLAGS) $(_CFLAGS) -c +__LD = $(CC) -std=$(_C_STD) $(OPTIMISE) $(WARN) $(_LDFLAGS) +__CC_POST = $(CPPFLAGS) $(CFLAGS) +__LD_POST = $(LDFLAGS) + +# Header files. +__H = +ifdef _HEADER_DIRLEVELS +ifeq ($(_HEADER_DIRLEVELS),1) +__H += src/*.h +else +ifeq ($(_HEADER_DIRLEVELS),2) +__H += src/*.h +__H += src/*/*.h +else +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. +obj/%.o: src/%.c $(__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. +$(foreach B,$(_BIN),$(foreach O,$(_OBJ_$(B)),bin/$(B): obj/$(O).o\ +)) + + +# 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)" +else + $(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)" +else + -$(Q)$(RM) -- $(foreach B,$(_BIN),"$(DESTDIR)$(BINDIR)/$(B)") +endif + + +endif + |