BUILD_PREFIX ?= LIBDIR_SUFFIX ?=64 FLEX ?=flex LFLAGS ?= CFLAGS +=-Wall -g -O3 CXXFLAGS +=-Wall -g -O3 DOCRA ?=docra ASCIIDOCTOR ?=asciidoctor define INST_template #file, dst, mode INSTALL +=$(BUILD_PREFIX)$(2)/$(notdir $(1)) ifeq (,$(wildcard $(HERE)/$(1))) # Installing using absolute path $(BUILD_PREFIX)$(2)/$(notdir $(1)): $(1) @install -m 755 -d $(BUILD_PREFIX)$(2) install -m $(3) $$< $(BUILD_PREFIX)$(2) else # Installing using relative path $(BUILD_PREFIX)$(2)/$(notdir $(1)): $(HERE)/$(1) @install -m 755 -d $(BUILD_PREFIX)$(2) install -m $(3) $$< $(BUILD_PREFIX)$(2) endif endef %.out/_dir: $(HERE)/Makefile $(TOP)/rules.mk $(TOP)/flags.mk mkdir -p $*.out && touch $@ define ODIR_template #var, [nodefault] ifneq ($(2),nodefault) DEFAULT +=$$($(1)) endif $(1)_ODIR :=$$($(1)).out $(1)_ODOT :=$$($(1)_ODIR)/_dir -include $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS:.o=.d)) ODIRS +=$$($(1)_ODIR) ifeq (,$(wildcard $(shell pwd)/Makefile)) # Out-of-tree build, external libraries are built locally ifdef $(1)_LIBS_S $$($(1)): $$(notdir $$($(1)_LIBS_S)) endif else # In-tree build, external libraries are in their source dir $$($(1)): $$($(1)_LIBS_S) endif ifdef $(1)_DEPS $$($(1)): $$($(1)_DEPS) endif ###################### ifdef $(1)_CXXFLAGS $(1)_CXXFLAGS +=-I$$($(1)_ODIR) $$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $(HERE)/%.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@ $$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: %.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@ $$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $$($(1)_ODIR)/%.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@ $$($(1)_ODIR)/%.o: %.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: %.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.o: $(HERE)/%.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: $(HERE)/%.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.o: $$($(1)_ODIR)/%.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: $$($(1)_ODIR)/%.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.o: %.c $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: %.c $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.o: $(HERE)/%.c $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: $(HERE)/%.c $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.l.cpp $$($(1)_ODIR)/%.l.hpp: $(HERE)/%.lpp $$($(1)_ODOT) $(FLEX) $(LFLAGS) --outfile=$$($(1)_ODIR)/$$*.l.cpp --header-file=$$($(1)_ODIR)/$$*.l.hpp $$< $$($(1)_ODIR)/%.l.o: $$($(1)_ODIR)/%.l.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -Wno-sign-compare -c -o $$@ $$< $$($(1)_ODIR)/%.l.pic.o: $$($(1)_ODIR)/%.l.cpp $$($(1)_ODOT) $$(CXX) $$($(1)_CXXFLAGS) -fPIC -Wno-sign-compare -c -o $$@ $$< ifeq (,$(wildcard $(shell pwd)/Makefile)) # Out-of-tree build, external libraries are built locally ifdef $(1)_LIBS_S $$($(1)): $$(notdir $$($(1)_LIBS_S)) endif else # In-tree build, external libraries are in their source dir $$($(1)): $$($(1)_LIBS_S) endif ifdef $(1)_DEPS $$($(1)): $$($(1)_DEPS) endif ifdef $(1)_ARFLAGS $$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS)) $(AR) $$($(1)_ARFLAGS) $$@ $$(filter %.o %.a,$$^) else $$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS)) $(CXX) $$($(1)_CXXFLAGS) $$(filter %.o %.a,$$^) -o $$@ $$($(1)_LDFLAGS) endif ###################### else ifdef $(1)_CFLAGS $(1)_CFLAGS +=-I$$($(1)_ODIR) $$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $(HERE)/%.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@ $$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: %.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@ $$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $$($(1)_ODIR)/%.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@ $$($(1)_ODIR)/%.o: %.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: %.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.o: $(HERE)/%.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: $(HERE)/%.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -c -o $$@ $$< $$($(1)_ODIR)/%.pic.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -fPIC -c -o $$@ $$< $$($(1)_ODIR)/%.l.c $$($(1)_ODIR)/%.l.h: $(HERE)/%.lpp $$($(1)_ODOT) $(FLEX) $(LFLAGS) --outfile=$$($(1)_ODIR)/$$*.l.c --header-file=$$($(1)_ODIR)/$$*.l.h $$< $$($(1)_ODIR)/%.l.o: $$($(1)_ODIR)/%.l.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -fPIC -Wno-sign-compare -c -o $$@ $$< $$($(1)_ODIR)/%.l.pic.o: $$($(1)_ODIR)/%.l.c $$($(1)_ODOT) $$(CC) $$($(1)_CFLAGS) -Wno-sign-compare -c -o $$@ $$< ifdef $(1)_ARFLAGS $$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS)) $(AR) $$($(1)_ARFLAGS) $$@ $$^ else $$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS)) $(CC) $$($(1)_CFLAGS) $$^ -o $$@ $$($(1)_LDFLAGS) endif ###################### else #$$(error no compilation flags defined for target $(1)) endif ifdef $(1)_INSTALL ifdef $(1)_ARFLAGS $$(eval $$(call INST_template,$($(1)),$($(1)_INSTALL),644)) else $$(eval $$(call INST_template,$($(1)),$($(1)_INSTALL),755)) endif endif endef define HDRS_template #var $(foreach hdr,$($(1)_HDRS),$(eval $(call INST_template,$(hdr),$($(1)_HDRS_INSTALL),644))) endef define COPY_template #var, chmod $(foreach hdr,$($(1)),$(eval $(call INST_template,$(hdr),$($(1)_INSTALL),$(2)))) endef define LINK_template #var INSTALL +=$(BUILD_PREFIX)$($(1)_INSTALL)/$($(1)) $(BUILD_PREFIX)$($(1)_INSTALL)/$($(1)): $(BUILD_PREFIX)$($(1)_LINK) @install -m 755 -d $(BUILD_PREFIX)$($(1)_INSTALL) ln -s $($(1)_LINK) $$@ endef define DEP_template #file DEP_DIRS +=$(dir $(1)) ifeq (,$(wildcard $(shell pwd)/Makefile)) # Out-of-tree build, all targets go to the local folder DEFAULT +=$(notdir $(1)) $(notdir $(1)): $(MAKE) $(notdir $(1)) -f $(dir $(1))Makefile .PHONY: $(notdir $(1)) else # In-tree build, each target goes into its source folder DEFAULT +=$(1) $(1): $(MAKE) $(notdir $(1)) -C $(dir $(1)) .PHONY: $(1) endif endef define MAN_template #var, mansection $(1)_ODIR :=$$($(1)).out $(1)_ODOT :=$$($(1)_ODIR)/_dir $(1)_MAN.ADOC :=$$($(1)_ODIR)/$$(patsubst %.dcrt,%.adoc,$$(notdir $$($(1)_MAN_DCRT))) $(1)_MAN :=$$($(1)_ODIR)/$$($(1)).$(2) $(1)_MAN.GZ :=$$($(1)_ODIR)/$$($(1)).$(2).gz MAN +=$$($(1)_MAN.GZ) ifeq ($(ENABLE_DOCRA), true) $$($(1)_MAN.ADOC): $$($(1)_ODOT) docra -l 0 -o $$($(1)_ODIR) $$($(1)_MAN_FLAGS) $$(dir $$($(1)_MAN_DCRT)) $$($(1)_MAN_DCRT) $$($(1)_MAN): $$($(1)_MAN.ADOC) $(ASCIIDOCTOR) -b manpage $$< $$($(1)_MAN.GZ): $$($(1)_MAN) gzip -f $$^ ifdef $(1)_MAN_INSTALL MANINSTALL +=$(BUILD_PREFIX)$($(1)_MAN_INSTALL)/man$(2)/$$($(1)).$(2).gz $(BUILD_PREFIX)$$($(1)_MAN_INSTALL)/man$(2)/$$($(1)).$(2).gz: $$($(1)_MAN.GZ) @install -m 755 -d $(BUILD_PREFIX)$$($(1)_MAN_INSTALL)/man$(2) @cp -v $$< $$@ endif endif .PHONY: $$($(1)_MAN.ADOC) $$($(1)_MAN) $$($(1)_MAN.GZ) endef define ALIAS_template #aliasvar, var, mansection ifdef $(2)_INSTALL INSTALL +=$(BUILD_PREFIX)$($(2)_INSTALL)/$($(1)) $(BUILD_PREFIX)$$($(2)_INSTALL)/$($(1)): @install -m 755 -d $(BUILD_PREFIX)$$($(2)_INSTALL) ln -s $$($(2)_INSTALL)/$$($(2)) $$@ endif ifdef $(2)_MAN_INSTALL MANINSTALL +=$(BUILD_PREFIX)$($(2)_MAN_INSTALL)/man$(3)/$($(1)).$(3).gz $(BUILD_PREFIX)$$($(2)_MAN_INSTALL)/man$(3)/$$($(1)).$(3).gz: @install -m 755 -d $(BUILD_PREFIX)$$($(2)_MAN_INSTALL)/man$(3) ln -s $$($(2)_MAN_INSTALL)/man$(3)/$$($(2)).$(3).gz $$@ endif endef #dg`make.sub` Each subfolder containing a ``Makefile`` can be build individually by simply issuing ``make`` from there. Dependencies on targets built in other subfolders will be built automatically. This can be used during development to quickly iterate on a single subproject. # By default, a sub-project ``Makefile`` implements at least the following targets: _ # *default*:: # Builds all library and executable targets. # *install*:: # Copies installable files to their destination. # *uninstall*:: # Removes files copied by both *install* and *maninstall*. # *man*:: # Builds man pages. # *maninstall*:: # Installs man pages under ``$(PREFIX)/share/man``. # *clean*:: # Cleans build directory and deletes final targets. # *depclean*:: # Makes the *clean* target in every dependency of this subproject. define DEFAULT_template default: $$(DEFAULT) install: $$(INSTALL) uninstall: $$(RM) $$(INSTALL) $$(MANINSTALL) man: $$(MAN) maninstall: $$(MANINSTALL) clean: $(RM) -r *.out/ $(ODIRS) $(RM) $(DEFAULT) depclean: for dep_dir in ${DEP_DIRS}; do $(MAKE) -C $$$${dep_dir} clean; done .PHONY: install uninstall man maninstall clean depclean endef default: .PHONY: default