### The build commands and verbosity # If we are verbose, we will show commands prefixed by $(Q) (which acts as # @ in the non-verbose mode), and we will show the "real" cmds instead of # their quiet versions (which are used in the non-verbose mode). # Inspired by the Linux kernel build system. ifdef V Q = quiet = mquiet = masq_ else Q = @ quiet = quiet_ mquiet = quiet_ endif # Colorize the build. ifdef MAKE_COLOR INFO_COLOR = $(shell tput setaf 5) CC_COLOR = $(shell tput setaf 6) LD_COLOR = $(shell tput setaf 2) PO_COLOR = $(shell tput setaf 6) LINK_COLOR = $(shell tput bold;tput setaf 4) INSTALL_COLOR = $(shell tput setaf 3) END_COLOR = $(shell tput sgr0) endif # Show the command (quiet or non-quiet version based on the assignment # just above) and then execute it. ncmd = $(if $($(quiet)cmd_$(1)),echo $($(quiet)cmd_$(1)) &&) $(cmd_$(1)) cmd = @$(if $($(quiet)cmd_$(1)),echo $($(quiet)cmd_$(1)) &&) $(cmd_$(1)) mcmd = @$(if $($(mquiet)cmd_$(1)),echo $($(mquiet)cmd_$(1)) &&) $(cmd_$(1)) ecmd = @$(if $($(mquiet)cmd_$(1)),printf "%-38s " $($(mquiet)cmd_$(1)) &&) $(cmd_$(1)) quiet_cmd_compile = ' [$(CC_COLOR)CC$(END_COLOR)] $(RELPATH)$@' masq_cmd_compile = $(COMPILE) -c $< cmd_compile = $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< # Rule to compile a set of .o files into one .o file quiet_cmd_ld_objs = " [$(LD_COLOR)LD$(END_COLOR)] $(RELPATH)$@" cmd_ld_objs = $(LD) -r -o $@ $(filter $(OBJS), $^) \ $(foreach subdir,$(sort $(filter-out src,$(SUBDIRS))), \ `test -e $(subdir)/lib.o && echo $(subdir)/lib.o`) quiet_cmd_link = ' [$(LINK_COLOR)LINK$(END_COLOR)] $(RELPATH)$@' cmd_link = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) quiet_cmd_sparse = ' [SPARSE] $(RELPATH)$(2)' cmd_sparse = $(SPARSE) $(DEFS) $(INCLUDES) $(AM_CFLAGS) $(CFLAGS) $(SPARSE_FLAGS) $(2) # Recursive make quiet_cmd_recmake = "[$(INFO_COLOR)MAKE $(3)$(END_COLOR)] $(RELPATH)$(2)" cmd_recmake = $(MAKE) -C $(2) $(3) quiet_cmd_installdata = " [$(INSTALL_COLOR)INSTALL$(END_COLOR)] $(RELPATH)$(2) -> $(3)" cmd_installdata = $(INSTALL_DATA) $(2) $(3) quiet_cmd_installprog = " [$(INSTALL_COLOR)INSTALL$(END_COLOR)] $(RELPATH)$(2) -> $(3)" cmd_installprog = $(INSTALL_PROGRAM) $(2) $(3) ### Internal build rules DEP_FILES_1 = $(foreach src,$(OBJS),.deps/$(src)) DEP_FILES = $(DEP_FILES_1:%.o=%.P) DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) ifdef OBJS -include $(DEP_FILES) endif %.o: $(srcdir)%.c $(call mcmd,compile) @-cp .deps/$(*F).pp .deps/$(*F).P; \ tr ' ' '\012' < .deps/$(*F).pp \ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ >> .deps/$(*F).P; \ rm .deps/$(*F).pp ifdef SUBDIRS-yes SUBDIRS += $(SUBDIRS-yes) endif ifdef OBJS-yes OBJS += $(OBJS-yes) endif ifneq ($(findstring cleanall,$(MAKECMDGOALS)),) INCLUDE_ALL=1 endif ifneq ($(findstring init,$(MAKECMDGOALS)),) # FIXME: Detect when $(subdir)/Makefile is $(srcdir)/$(subdir)/Makefile # and error out so the user won't overwrite the 'master' Makefiles. INCLUDE_ALL=1 endif ifdef INCLUDE_ALL ifdef SUBDIRS-no SUBDIRS += $(SUBDIRS-no) endif ifdef SUBDIRS- SUBDIRS += $(SUBDIRS-) endif ifdef OBJS-no OBJS += $(OBJS-no) endif ifdef OBJS- OBJS += $(OBJS-) endif endif ifdef OBJS lib.o: $(sort $(OBJS)) $(foreach subdir,$(sort $(filter-out src,$(SUBDIRS))), $(wildcard $(subdir)/lib.o)) $(call cmd,ld_objs) LIB_O = lib.o CLEAN += $(OBJS) $(LIB_O) endif CLEAN += $(PROG) all-default: $(LIB_O) $(PROGS) $(MAN1) $(MAN5) init-default: @$(foreach subdir,$(sort $(SUBDIRS)), \ $(MKINSTALLDIRS) $(subdir) >/dev/null; \ echo 'include $(SRC)/$(RELPATH)/$(subdir)/Makefile' > $(subdir)/Makefile;) clean-default: clean-test @-test -z "$(CLEAN)" || $(RM) $(CLEAN) cleanall-default: clean-default check-default: ifneq ($(SPARSE),) @$(foreach file, $(wildcard *.c), \ $(call ncmd,sparse,$(file));) endif ############################################################################## # # Auto-testing infrastructure # clean-test: test-default: ifdef TEST_PROGS TESTDEPS += $(TESTDEPS-yes) $(TEST_PROGS): $(TESTDEPS) $$@.o $(call cmd,link) TESTS = $(wildcard $(srcdir)test-*) $(TESTS): $(TEST_PROGS) @echo "*** $(notdir $@) ***"; \ $(call shellquote,$(SHELL)) $@ $(TEST_OPTS) test-default: $(TESTS) clean-test: @rm -fr trash CLEAN += $(TEST_PROGS) $(patsubst %,%.o,$(TEST_PROGS)) endif .PHONY: $(TESTS) .NOPARALLEL: # sparse is architecture-neutral, which means that we need to tell it # explicitly what architecture to check for. Fix this up for yours.. SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ install-default: all-default ifdef PROGS @$(MKINSTALLDIRS) $(DESTDIR)$(bindir) @$(foreach file,$(PROGS), \ $(call ncmd,installprog,$(file),$(DESTDIR)$(bindir));) endif ifdef MAN1 @$(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man1 @$(foreach file,$(MAN1), \ $(call ncmd,installdata,$(file),$(DESTDIR)$(mandir)/man1);) endif ifdef MAN5 @$(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man5 @$(foreach file,$(MAN5), \ $(call ncmd,installdata,$(file),$(DESTDIR)$(mandir)/man5);) endif # Recursion: .PHONY: all-recursive install-recursive clean-recursive cleanall-recursive init-recursive check-recursive test-recursive all-recursive install-recursive clean-recursive cleanall-recursive init-recursive check-recursive test-recursive: ifdef SUBDIRS @$(foreach subdir,$(sort $(SUBDIRS)), \ $(call ncmd,recmake,$(subdir),$(subst -recursive,,$@)) || exit 1;) endif all: all-recursive all-default all-local install: install-recursive install-default install-local check: check-recursive check-default check-local clean: clean-recursive clean-default clean-local test: test-recursive test-default test-local cleanall: cleanall-recursive cleanall-default init: init-default init-recursive all-local: install-local: clean-local: check-local: test-local: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Shell quote; # Result of this needs to be placed inside '' # XXX: Placed here because Vim cannot highlight things right afterwards shq = $(subst ','\'',$(1)) # This has surrounding '' shellquote = '$(call shq,$(1))' # vim:syntax=make