antimake: improvements from dev repo
authorMarko Kreen <markokr@gmail.com>
Tue, 5 Jun 2012 13:40:03 +0000 (16:40 +0300)
committerMarko Kreen <markokr@gmail.com>
Tue, 5 Jun 2012 14:36:48 +0000 (17:36 +0300)
- aclocaldir
- More tracing macros
- Rework O= support to use make functions instead shell
- Add hooks concept
- Add externally loadable features concept
- Move libusual hacks from antimake.mk to amext-libusual.mk
- amext-modes.mk: add more ways to compile one target

To load 'libusual' or 'modes' extension, add AM-FEATURES to makefile:

  AM_FEATURES = libusual modes

mk/Makefile.am
mk/amext-libusual.mk [new file with mode: 0644]
mk/amext-modes.mk [new file with mode: 0644]
mk/antimake.mk
mk/antimake.txt
mk/temos/expected/libusual2.txt
mk/temos/expected/libusual3.txt
mk/temos/expected/libusual4.txt
mk/temos/src/libusual2.temo
mk/temos/src/libusual3.temo

index b3b2d089fb5ab155bf74f90394d5efd412dbdd9a..c5dd252b7270587cf0c4eed96f224d3143156f7f 100644 (file)
@@ -1,6 +1,6 @@
 
 pkgconfig_DATA = libusual.pc
-dist_pkgdata_SCRIPTS = antimake.mk std-autogen.sh
+dist_pkgdata_SCRIPTS = antimake.mk std-autogen.sh amext-libusual.mk amext-modes.mk
 
 DISTCLEANFILES = libusual.pc
 
diff --git a/mk/amext-libusual.mk b/mk/amext-libusual.mk
new file mode 100644 (file)
index 0000000..ac8efab
--- /dev/null
@@ -0,0 +1,65 @@
+#
+# Merge libusual sources with target sources
+#
+# Usage:
+#   USUAL_DIR = <libusual source tree>
+#
+#   <target>_EMBED_LIBUSUAL = 1
+#
+# It adds module sources into <target>_SOURCES
+# and -I$(USUAL_DIR) to _CPPFLAGS.
+#
+
+##
+## Utility functions for libusual link
+##
+
+_USUAL_DIR = $(call JoinPath,$(srcdir),$(USUAL_DIR))
+
+# module names from sources (plus headers)
+UsualMods = $(trace1)$(shell $(_USUAL_DIR)/find_modules.sh $(_USUAL_DIR) $(wildcard $(addprefix $(srcdir)/,$(1))))
+
+# full-path sources based on module list
+UsualSrcsFull = $(trace1)$(wildcard $(addprefix $(_USUAL_DIR)/usual/,$(addsuffix *.[ch],$(1))))
+
+# remove USUAL_DIR
+UsualStrip = $(trace1)$(subst $(_USUAL_DIR)/,,$(1))
+
+# simple-path sources based on module list
+UsualSrcs = $(call UsualStrip,$(call UsualSrcsFull,$(1)))
+
+# usual sources from user source file list
+UsualSources = $(if $(1),$(call UsualSrcsFull,$(call UsualMods,$(1))))
+
+# 1=cleantgt,2=rawtgt,3=prim,4=dest,5=flags
+define EmbedLibUsual
+$(trace5)
+
+# embed libusual objects directly
+$(IFEQ) ($$($(1)_EMBED_LIBUSUAL),1)
+
+$(1)_SOURCES := $$($(1)_SOURCES) $$(call UsualSources, $$($(1)_SOURCES))
+EXTRA_$(1)_SOURCES := $$(EXTRA_$(1)_SOURCES) \
+       $$(call UsualSources, \
+               $$(EXTRA_$(1)_SOURCES) \
+               $$(nodist_$(1)_SOURCES) \
+               $$(nodist_EXTRA_$(1)_SOURCES))
+
+$(1)_CPPFLAGS += -I$$(USUAL_DIR)
+
+# add libusual to vpath
+$(IFEQ) ($$(filter $$(USUAL_DIR),$$(VPATH)),)
+VPATH += $$(USUAL_DIR)
+$(IFNEQ) ($$(srcdir),$$(builddir),)
+VPATH += $$(call JoinPath,$$(srcdir),$$(USUAL_DIR))
+$(ENDIF)
+$(ENDIF)
+
+$(ENDIF)
+
+endef
+
+AM_TARGET_HOOKS += EmbedLibUsual
+
+EXTRA_DIST += $(_USUAL_DIR)/find_modules.sh $(_USUAL_DIR)/usual/config.h.in
+
diff --git a/mk/amext-modes.mk b/mk/amext-modes.mk
new file mode 100644 (file)
index 0000000..050d511
--- /dev/null
@@ -0,0 +1,83 @@
+#
+# Custom compilation modes
+#   Compile one target several times with different
+#   configuration variables.
+#
+# Sample:
+#    CFLAGS = -O2
+#    bin_PROGRAM = prog
+#    prog_SOURCES = prog.c
+#
+#    AM_MODES = debug
+#    CFLAGS_debug = -O0 -g
+#
+# Result:
+#   prog       - compiled with -O2
+#   prog-debug - compiled with -O0 -g
+#
+
+AM_MODES ?= 
+
+# Variables that can be overrided with $(var)_$(mode)
+AM_MODE_OVERRIDE += CC CXX CFLAGS CPPFLAGS DEFS LDFLAGS LIBS
+
+## add "-MODE" string before file extension
+# 1-mode, 2-filename
+ModeName = $(basename $(2))-$(1)$(suffix $(2))
+
+## add mode suffix to all plain filenames
+# 1-mode, 2-file names, options
+ModeFilter = $(foreach f,$(2),$(if $(filter /% -%,$(f)),$(f),$(call ModeName,$(1),$(f))))
+
+## set per-target var
+# 1-dbgvar, 2-var, 3-final
+ModeVarX = $(3): $(2) = $$($(1))$(NewLine)
+
+# 1-mode, 2-var, 3-final
+ModeVarOverride = $(if $($(2)_$(1)),$(call ModeVarX,$(2)_$(1),$(2),$(3)))
+
+# 1-mode, 2-final
+ModeVarOverrideAll = $(foreach v,$(AM_MODE_OVERRIDE),$(call ModeVarOverride,$(1),$(v),$(2)))
+
+## copy target, replace vars
+# 1=cleantgt,2=rawtgt,3=prim,4=dest,5=flags,6=mode,7-newtgt,8-cleantgt,9-list
+define AddModes4
+$(trace8)
+
+$(IFEQ) ($$(filter $(9),$$(am_TARGETLISTS)),)
+am_TARGETLISTS += $(9)
+$(ENDIF)
+
+# add new target to old list
+$(9) += $(7)
+
+# copy details, change library names
+$(8)_SOURCES := $$($(1)_SOURCES)
+nodist_$$(8)_SOURCES := $$(nodist_$(1)_SOURCES)
+$(8)_CPPFLAGS := $$($(1)_CPPFLAGS)
+$(8)_CFLAGS := $$($(1)_CFLAGS)
+$(8)_LDFLAGS := $$($(1)_LDFLAGS)
+$(8)_LIBADD := $$(call ModeFilter,$(6),$$($(1)_LIBADD))
+$(8)_LDADD := $$(call ModeFilter,$(6),$$($(1)_LDADD))
+
+# add variable replacements
+$(call ModeVarOverrideAll,$(6),$(call FinalTargetFile,$(8),$(7),$(3)))
+
+endef
+
+## add clean name, list name
+# 1=cleantgt,2=rawtgt,3=prim,4=dest,5=flags,6-mode,7-raw tgt
+AddModes3 = $(call AddModes4,$(1),$(2),$(3),$(4),$(5),$(6),$(7),$(call CleanName,$(7)),$(subst $(Space),_,$(5)_$(4)_$(3)))
+
+## loop over modes
+# 1=cleantgt,2=rawtgt,3=prim,4=dest,5=flags
+AddModes2 = $(trace5)$(foreach m,$(AM_MODES),$(call AddModes3,$(1),$(2),$(3),$(4),$(5),$(m),$(call ModeName,$(m),$(2))))
+
+## ignore small primaries
+# 1=cleantgt,2=rawtgt,3=prim,4=dest,5=flags
+AddModes = $(trace5)$(if $(filter $(3),$(AM_BIG_PRIMARIES)),$(call AddModes2,$(1),$(2),$(3),$(4),$(5)))
+
+# Install hook
+AM_TARGET_HOOKS += AddModes
+
+
index e90e6459418b3bcfff81f39e71ce224b94887fd4..fe343407aeca3c49f2229525bba5a4dd37c9832a 100755 (executable)
@@ -147,6 +147,7 @@ libdir = @libdir@
 localedir = @localedir@
 pkgdatadir = @pkgdatadir@
 pkgconfigdir = @pkgconfigdir@
+aclocaldir = @aclocaldir@
 
 # autoconf values for top dir
 abs_top_srcdir ?= @abs_top_srcdir@
@@ -231,6 +232,7 @@ libdir ?= ${exec_prefix}/lib
 localedir ?= ${datarootdir}/locale
 pkgdatadir ?= ${datarootdir}/${PACKAGE_TARNAME}
 pkgconfigdir ?= ${libdir}/pkgconfig
+aclocaldir ?= ${datarootdir}/aclocal
 
 # autoconf values for top dir
 abs_top_srcdir ?= $(CURDIR)
@@ -339,7 +341,7 @@ AM_SMALL_PRIMARIES += HEADERS SCRIPTS DATA MANS
 # list of destinations per primary
 AM_DESTINATIONS += bin lib libexec sbin \
                   data doc include locale man sysconf \
-                  pkgdata pkgconfig \
+                  pkgdata pkgconfig aclocal \
                   noinst EXTRA
 
 # primaries where 'dist' is default
@@ -521,6 +523,10 @@ trace2=$(warning $0('$1','$2'))
 trace3=$(warning $0('$1','$2','$3'))
 trace4=$(warning $0('$1','$2','$3','$4'))
 trace5=$(warning $0('$1','$2','$3','$4','$5'))
+trace6=$(warning $0('$1','$2','$3','$4','$5','$6'))
+trace7=$(warning $0('$1','$2','$3','$4','$5','$6','$7'))
+trace8=$(warning $0('$1','$2','$3','$4','$5','$6','$7','$8'))
+trace9=$(warning $0('$1','$2','$3','$4','$5','$6','$7','$8','$9'))
 endif
 
 # for use inside $(eval)
@@ -574,11 +580,14 @@ DepFiles = $(wildcard $(addsuffix .d,$(1)))
 # per-target var override, 1=target, 2=varname
 # if foo_VAR exists, expand to:
 #   build_foo install_foo clean_foo: AM_VAR = $(foo_VAR)
-#TgtVar = $(if $($(1)_$(2)),build_$(1): AM_$(2) = $($(1)_$(2)))
-TgtVar = $(if $($(1)_$(2)),$$($(1)_FINAL): AM_$(2) = $($(1)_$(2)))
 
-# loop TgtVar over AM_TARGET_VARIABLES, 1=target
-VarOverride = $(foreach var,$(AM_TARGET_VARIABLES),$(eval $(call TgtVar,$(1),$(var))))
+
+# 1-tgt, 2-var, 3-final
+TgtVar2 = $(3): AM_$(2) = $$($(1)_$(2))$(NewLine)
+TgtVar = $(if $($(1)_$(2)),$(call TgtVar2,$(1),$(2),$(3)))
+
+# loop TgtVar over AM_TARGET_VARIABLES, 1=target, 2-final
+VarOverride = $(foreach var,$(AM_TARGET_VARIABLES),$(call TgtVar,$(1),$(var),$(2)))
 
 # check if actual target (.h, .exe) is nodist based on primary and flags
 # 1-prim 2-flags
@@ -662,31 +671,6 @@ ForEachTarget2 = $(foreach tgt,$($(1)),$(call $(5),$(call CleanName,$(tgt)),$(tg
 ForEachTarget = $(call ForEachList,ForEachTarget2,$(2),$(1))
 
 
-##
-## Utility functions for libusual link
-##
-
-_USUAL_DIR = $(call JoinPath,$(srcdir),$(USUAL_DIR))
-
-# module names from sources (plus headers)
-UsualMods = $(trace1)$(shell $(_USUAL_DIR)/find_modules.sh $(_USUAL_DIR) $(wildcard $(addprefix $(srcdir)/,$(1))))
-
-# full-path sources based on module list
-UsualSrcsFull = $(trace1)$(wildcard $(addprefix $(_USUAL_DIR)/usual/,$(addsuffix *.[ch],$(1))))
-
-# remove USUAL_DIR
-UsualStrip = $(trace1)$(subst $(_USUAL_DIR)/,,$(1))
-
-# simple-path sources based on module list
-UsualSrcs = $(call UsualStrip,$(call UsualSrcsFull,$(1)))
-
-# objs with objdir from source file list (1-cleantgt, 2-src list)
-UsualObjs = $(call SourceObjs,$(1),$(call UsualSrcs,$(call UsualMods,$(2))))
-
-# usual sources from user source file list
-UsualSources = $(call UsualSrcsFull,$(call UsualMods,$(1)))
-
-
 ## EMBED_SUBDIRS relocations
 
 ## add subdir to files
@@ -904,6 +888,10 @@ endef
 ## Rules for big target
 ##
 
+# calculate target file name
+# 1-clean, 2-raw, 3-prim
+FinalTargetFile = $(if $(filter PROGRAMS,$(3)$($(1)_EXT)),$(2)$($(1)_EXT),$(2)$(EXEEXT))
+
 # 1=cleantgt,2=rawtgt,3=prim,4=dest,5=flags
 define BigTargetBuild
 $(trace5)
@@ -925,19 +913,6 @@ $(1)_OBJS += $$(filter-out -%,$$($(1)_LIBADD))
 $(1)_LIBS += $$(filter -%,$$($(1)_LIBADD))
 $(ENDIF)
 
-# embed libusual objects directly
-$(IFEQ) ($$($(1)_EMBED_LIBUSUAL),1)
-$(1)_USUAL_SRCS = $$(call UsualSources,$$($(1)_ALLSRCS))
-$(1)_OBJS += $$(call UsualObjs,$(1),$$($(1)_SOURCES) $$(nodist_$(1)_SOURCES))
-$(1)_CPPFLAGS += -I$$(USUAL_DIR)
-$(IFEQ) ($$(filter $$(USUAL_DIR),$(VPATH)),)
-VPATH += $$(USUAL_DIR)
-$(ENDIF)
-$(IFNEQ) ($$(srcdir),$$(builddir),)
-VPATH += $$(call JoinPath,$$(srcdir),$$(USUAL_DIR))
-$(ENDIF)
-$(ENDIF)
-
 # autodetect linker, unless given
 $(IFEQ) ($($(1)_LINK),)
 $(1)_LINKVAR := $$(call DetectLinkVar,$$($(1)_ALLSRCS))
@@ -946,11 +921,7 @@ $(1)_LINKVAR := $(1)_LINK
 $(ENDIF)
 
 # calculate target file name
-$(IFEQ) ($(3)$($(1)_EXT),PROGRAMS)
-$(1)_FINAL = $(2)$$(EXEEXT)
-$(ELSE)
-$(1)_FINAL = $(2)$$($(1)_EXT)
-$(ENDIF)
+$(1)_FINAL = $(call FinalTargetFile,$(1),$(2),$(3))
 
 # hook libtool into LTLIBRARIES cleanup
 $(IFEQ) ($(3),LTLIBRARIES)
@@ -970,7 +941,7 @@ $(1)_CFLAGS := $$(call FixIncludes,$$(srcdir),$$($(1)_CFLAGS))
 .PHONY: build_$(1) clean_$(1)
 
 # allow target-specific variables
-$$(call VarOverride,$(1))
+$(call VarOverride,$(1),$(call FinalTargetFile,$(1),$(2),$(3)))
 
 # build and clean by default, unless flagged EXTRA
 $(IFNEQ) ($(4),EXTRA)
@@ -1076,29 +1047,34 @@ endif
 
 
 ##
-## Actual rules start
+## O=<tgtdir>
+##    if given, create wrapper makefiles in target dir
+##    that include makefiles from source dir, then run
+##    make from target dir.
 ##
 
-# if output is redirected, prepare target dir and launch submake
-
 ifneq ($(O),)
 
-ABS_DST := $(call JoinPath,$(CURDIR),$(O))
-.PHONY: $(MAKECMDGOALS)
-
-all $(filter-out all,$(MAKECMDGOALS)):
-       @test -d $(O) || { echo "Directory $(O) does not exist"; exit 1; }
-       @for mk in $(filter-out /%,$(MAKEFILE_LIST)); do \
-           if ! test -f $(O)/$${mk}; then \
-               printf '%s\n%s\n%s\n%s\n%s\n' \
+# 1-makefile
+define WrapMakeFileCmd
+       @$(MKDIR_P) '$(dir $(O)/$(1))'
+       @printf '%s\n%s\n%s\n%s\n%s\n' \
                'abs_top_srcdir = $(CURDIR)' \
-               'abs_top_builddir = $(ABS_DST)' \
+               'abs_top_builddir = $(call JoinPath,$(CURDIR),$(O))' \
                'nosub_top_srcdir = $(call UpDir,$(O))' \
                'nosub_top_builddir = .' \
-               'include $$(abs_top_srcdir)/'"$${mk}" \
-               > $(O)/$${mk}; \
-           fi; \
-       done
+               'include $(abs_top_srcdir)/$(1)' \
+               > $(O)/$(1)
+endef
+
+# 1-makefile
+WrapMakeFile = $(if $(wildcard $(O)/$(1)),,$(call WrapMakeFileCmd,$(1))$(NewLine))
+
+# redirect whatever rule was given
+.PHONY: all $(MAKECMDGOALS)
+all $(filter-out all,$(MAKECMDGOALS)):
+       $(if $(wildcard $(O)),,$(error O=$(O): Directory '$(O)' does not exist))
+       $(foreach mk,$(filter-out /%,$(MAKEFILE_LIST)),$(call WrapMakeFile,$(mk)))
        $(Q) $(MAKE) O= -C $(O) $(MAKECMDGOALS)
 
 # O=empty, this is main makefile
@@ -1196,6 +1172,25 @@ AM_FLAGS += real
 
 ## EMBED_SUBDIRS end
 
+##
+## Launch target hooks
+##
+
+amdir = $(dir $(realpath $(filter %/antimake.mk antimake.mk,$(MAKEFILE_LIST))))
+
+# 1-feat name
+FeatFile = $(amdir)/amext-$(1).mk
+
+
+# 1- fname
+LoadFeature = $(if $(wildcard $(call FeatFile,$(1))),$(eval include $(call FeatFile,$(1))),$(error Feature "$(call FeatFile,$(1))" is not available.))
+
+$(foreach f,$(AM_FEATURES),$(call LoadFeature,$(f)))
+
+
+
+$(eval $(foreach hook,$(AM_TARGET_HOOKS),$(call ForEachTarget,$(hook),$(am_TARGETLISTS))))
+
 
 ##
 ## Now generate the rules
index e628fb54a7cf05fcb403ff26fe759d505c8cdd71..896e055f3fdab6c704d37a074ea5f474dad20ea3 100644 (file)
@@ -221,9 +221,10 @@ EMBED_SUBDIRS::
        The fragment is included in main makefile and file
        and variable names are converted and merged with top-level targets.
 
-USUAL_DIR::
-       Location of libusual tree, used for embedding libusual
-       sources.
+AM_FEATURES::
+       List of extensions to load.  Extensions are Makefile fragments
+       that are loaded before actual rules are generated, so they
+       can change or add targets.
 
 === More details on EMBED_SUBDIRS ===
 
index 1ec68e3ac5a991da8d1e4c06781fdd71e934bf31..baf7483244a1d7fb6b444916b98eb50bd3bae869 100644 (file)
@@ -136,6 +136,7 @@ USUAL_DIR = lib
 
 # mention that 'prog' wants embedded libusual
 prog_EMBED_LIBUSUAL = 1
+AM_FEATURES = libusual
 
 # launch Antimake
 include $(USUAL_DIR)/mk/antimake.mk
index 1a90aaaa2e3d1119368652bb334c69b58bcaca39..2664909507355d127a1fbbd7ecf1351cd2d03b38 100644 (file)
@@ -77,6 +77,7 @@ USUAL_DIR = lib
 
 # mention that 'prog' wants embedded libusual
 prog_EMBED_LIBUSUAL = 1
+AM_FEATURES = libusual
 
 # clean configured files
 DISTCLEANFILES = config.status config.log \
index 4841e29bcd3162da09cd240ebd22dca891abcb99..5106b31b6d11cbc1679bc29f63ad6cddfb4fd107 100644 (file)
@@ -44,6 +44,7 @@ inst/include/usual/fileutil.h
 inst/include/usual/getopt.h
 inst/include/usual/hashtab-impl.h
 inst/include/usual/heap.h
+inst/include/usual/hmac.h
 inst/include/usual/list.h
 inst/include/usual/logging.h
 inst/include/usual/lookup3.h
@@ -82,6 +83,8 @@ inst/share/aclocal/antimake.m4
 inst/share/aclocal/usual.m4
 inst/share/libusual
 inst/share/libusual/Setup.mk
+inst/share/libusual/amext-libusual.mk
+inst/share/libusual/amext-modes.mk
 inst/share/libusual/antimake.mk
 inst/share/libusual/find_modules.sh
 inst/share/libusual/std-autogen.sh
index 5cedcd3f296fef1d978a9db263deb707fbce077b..299ea202043944a40387c05ab766c03c5ffa254b 100644 (file)
@@ -119,6 +119,7 @@ cat_file Makefile <<"EOF"
 
        # mention that 'prog' wants embedded libusual
        prog_EMBED_LIBUSUAL = 1
+       AM_FEATURES = libusual
 
        # launch Antimake
        include $(USUAL_DIR)/mk/antimake.mk
index 4d2aeb01a0961ec8cd49af294740675b30b84643..2419a8833e61bf3cd16479f5337202422373c8cc 100644 (file)
@@ -69,6 +69,7 @@ cat_file Makefile <<"EOF"
 
        # mention that 'prog' wants embedded libusual
        prog_EMBED_LIBUSUAL = 1
+       AM_FEATURES = libusual
 
        # clean configured files
        DISTCLEANFILES = config.status config.log \