# Nathan's generic Makefile -*- mode:Makefile -*- # Copyright (C) 2019-2020 Nathan Sidwell, nathan@acm.org # License: Apache v2.0 ifeq (0,$(MAKELEVEL)) ifneq (,@tools@) $(info Prepending @tools@/bin to PATH) PATH := @tools@/bin:$(PATH) export PATH endif ifeq (,$(SERIAL)) # Figure out if we should set parallelism ifeq (,$(filter clean%,$(MAKECMDGOALS))) PARALLELISM := @NUM_CPUS@ endif endif endif ifeq (00,$(MAKELEVEL)$(if $(PARALLELISM),0,1)) # Although Make 4.3 documentation suggests I can set parallelism just # by appending to MAKEFLAGS, it doesn't seem to work. It's also not # possible to figure out the current Make invocation's parallelism, # the -j option doesn't appear in MAKEFLAGS and is magically inserted # when that is expanded in a rule. I can't figure how to get a rule # expansion into a variable to test. Fortunately, Make propagates an # incoming -j option rather than the one you attempted to append $(info Parallelizing $(PARALLELISM) ways) MAKEFLAGS += -j$(PARALLELISM) ifneq (,$(MAKECMDGOALS)) $(MAKECMDGOALS): recurse endif recurse: $(MAKE) -r$(MAKEFLAGS) $(MAKECMDGOALS) .PHONY: recurse else srcdir := @srcdir@ prefix := @prefix@ exec_prefix := @exec_prefix@ bindir := @bindir@ libdir := @libdir@ includedir := @includedir@ SUBDIRS := @SUBDIRS@ # autoconf doesn't seem to like setting SHELL SHELL := $(shell which zsh 2>/dev/null >/dev/null && echo zsh \ || (echo "No ZSH, maybe flakey" >&2 && echo sh)) # We have to place the -I paths last, so that building will see -I paths to us CXX := $(filter-out -I%,@CXX@) AR := @AR@ INSTALL := $(srcdir)/build-aux/install-sh # C++ compiler options CXXFLAGS := @CXXFLAGS@ CXXINC := $(filter -I%,@CXX@) CXXOPTS := $(CXXFLAGS) @PICFLAG@ ifeq ($(notdir $(firstword $(CXX))),g++) # It's GCC, or pretending to be it -- so it better smell like it! # Code generation CXXOPTS += -fno-enforce-eh-specs CXXOPTS += -fno-stack-protector -fno-threadsafe-statics ifneq (@EXCEPTIONS@,yes) CXXOPTS += -fno-exceptions -fno-rtti endif ifeq ($(filter -fdebug-prefix-map=%,$(CXXOPTS)),) CXXOPTS += -fdebug-prefix-map=${srcdir}/= endif # Warning options CXXOPTS += -W -Wall ifeq (no,) # just turn off for now CXXOPTS += -Woverloaded-virtual -Wshadow CXXOPTS += -Wno-invalid-offsetof -Wno-unused-variable CXXOPTS += -Wno-missing-field-initializers # Diagnostic options, look at controlling terminal so that piping # through more works MLEN := $(shell stty size /dev/null | cut -d' ' -f2) ifneq (,$(MLEN)) CXXOPTS += -fmessage-length=$(MLEN) endif CXXOPTS += -fdiagnostics-color=always -fno-diagnostics-show-option endif else ifeq ($(notdir $(firstword $(CXX))),clang++) CXXOPTS += -fno-stack-protector -fno-threadsafe-statics ifneq (@EXCEPTIONS@,yes) CXXOPTS += -fno-exceptions -fno-rtti endif # Warning options CXXOPTS += -W -Wall -Woverloaded-virtual -Wshadow CXXOPTS += -Wno-invalid-offsetof -Wno-unused-variable CXXOPTS += -Wno-missing-field-initializers else # Add different compiler's options here endif endif # Config CXXOPTS += $(filter-out -DHAVE_CONFIG_H,@DEFS@) -include config.h # Linker options LDFLAGS := -L. @LDFLAGS@ LIBS := @LIBS@ # Per-source & per-directory compile flags (warning: recursive) SRC_CXXFLAGS = $(CXXFLAGS$(patsubst $(srcdir)%,%,$1)) \ $(if $(filter-out $(srcdir)/,$1),\ $(call $0,$(dir $(patsubst %/,%,$1)))) ifneq ($(MAINTAINER),) override MAINTAINER += $1 endif ifeq (@MAINTAINER@,yes) MAINTAINER = $2 else MAINTAINER = \# --enable-maintainer-mode to rebuild $1, or make MAINTAINER=touch endif vpath %.in $(srcdir) vpath %.cc $(srcdir) .SUFFIXES: .o .cc %.o: %.cc @mkdir -p $(dir $@) $(CXX) $(strip $(CXXOPTS) $(call SRC_CXXFLAGS,$<) $(CXXINC)) \ -MMD -MP -MF ${@:.o=.d} -c -o $@ $< all:: Makefile $(addprefix all.,$(SUBDIRS)) check:: Makefile $(addprefix check.,$(SUBDIRS)) clean:: Makefile $(addprefix clean.,$(SUBDIRS)) revision.stamp: $(addprefix $(srcdir)/,. $(SUBDIRS)) @revision=$$(git -C $(srcdir) rev-parse HEAD 2>/dev/null) ;\ if test -n "$$revision" ;\ then revision=git-$$revision ;\ if git -C $(srcdir) status --porcelain 2>/dev/null | grep -vq '^ ' ;\ then revision+=M ;\ fi ;\ else revision=unknown ;\ fi ;\ echo $$revision > $@ revision: revision.stamp @cmp -s $< $@ || cp -f $< $@ clean:: rm -f revision.stamp revision distclean:: clean rm -f config.log config.status rm -rf $(SUBDIRS) $(srcdir)/configure: $(srcdir)/configure.ac \ $(patsubst %,$(srcdir)/%/config.m4,. $(SUBDIRS)) $(call MAINTAINER,$@,cd $(@D) && autoconf -W all,error) $(srcdir)/config.h.in: $(srcdir)/configure.ac \ $(patsubst %,$(srcdir)/%/config.m4,. $(SUBDIRS)) $(call MAINTAINER,$@,cd $(@D) && autoheader -f -W all,error) config.h: config.status config.h.in ./$< --header=$@ touch $@ ifeq ($(filter %clean,$(MAKECMDGOALS)),) @CONFIG_FILES@: %: config.status %.in ./$< --file=$@ touch $@ endif config.status: $(srcdir)/configure $(srcdir)/config.h.in if test -x $@; then ./$@ -recheck; else $< @configure_args@; fi distclean:: clean rm -f config.h maintainer-clean:: distclean rm -f $(srcdir)/config.h.in clean:: rm -f $(shell find $(srcdir) -name '*~') .PHONY: all check clean distclean maintainer-clean -include $(addsuffix /Makesub,. $(SUBDIRS)) -include $(addsuffix /tests/Makesub,. $(SUBDIRS)) endif