|
From: <kin...@us...> - 2025-08-28 05:17:13
|
Revision: 7329
http://sourceforge.net/p/teem/code/7329
Author: kindlmann
Date: 2025-08-28 05:17:10 +0000 (Thu, 28 Aug 2025)
Log Message:
-----------
With a second modernization of how CMake is used to build Teem, one might think
that the older GNUmake-based build system is obsolete. In fact, GLK still
prefers it for Teem hacking, since it offers more incremental per-library
builds, and building of per-library test programs. This build system was first
written in ~2001, before CMake was useful or popular. It was needlessly
complicated, in part because it was designed for having multiple architectures
share a networked filesystem. For Teem V2, GLK revisited all the GNUmakefiles
and simplified and cleaned them up: there are no more per-archicture
teem/src/make/foo.mk files, and there is no effort to make the monolithic
("megalib") libteem library, or any kind of shared library.
More details. This simplification meant removing (from everywhere)
env var TEEM_ARCH
env var TEEM_DEST (because now any "install" should be done via CMake)
make vars ARCH, SUBARCH
everything about shared libraries: TEEM_LINK_SHARED, SHEXT
as well as variables TEEM_EXT_IPATH and TEEM_EXT_LPATH (for all EXT externals
PNG ZLIB BZIP2 PTHREAD LEVMAR FFTW3, e.g TEEM_ZLIB_IPATH, TEEM_ZLIB_LPATH);
these have become EXT.DASHI and EXT.DASHL set in make/externals.mk
Also gone: file errorCheck.mk (so simple, nothing left to error check)
make var KNOWN_ARCH,
make funcs checkArchSet, checkArchValid,
checkArchLinux, checkArchLinux64, checkArchNetbsd64, checkArchDarwin
per-"architecture" files in make/
aix.mk cygwin.mk darwin.mk irix6.mk linux.mk netbsd.mk solaris.mk win32.mk
Instead, a new single make/arch.mk contains the information that used to be there,
or at least variables from which to hang this info.
Modified Paths:
--------------
teem/trunk/src/GNUmakefile
teem/trunk/src/air/GNUmakefile
teem/trunk/src/alan/GNUmakefile
teem/trunk/src/bane/GNUmakefile
teem/trunk/src/biff/GNUmakefile
teem/trunk/src/bin/GNUmakefile
teem/trunk/src/coil/GNUmakefile
teem/trunk/src/dye/GNUmakefile
teem/trunk/src/echo/GNUmakefile
teem/trunk/src/elf/GNUmakefile
teem/trunk/src/ell/GNUmakefile
teem/trunk/src/gage/GNUmakefile
teem/trunk/src/hest/GNUmakefile
teem/trunk/src/hoover/GNUmakefile
teem/trunk/src/limn/GNUmakefile
teem/trunk/src/make/arch.mk
teem/trunk/src/make/externals.mk
teem/trunk/src/make/template.mk
teem/trunk/src/meet/GNUmakefile
teem/trunk/src/mite/GNUmakefile
teem/trunk/src/moss/GNUmakefile
teem/trunk/src/nrrd/GNUmakefile
teem/trunk/src/pull/GNUmakefile
teem/trunk/src/push/GNUmakefile
teem/trunk/src/seek/GNUmakefile
teem/trunk/src/ten/GNUmakefile
teem/trunk/src/tijk/GNUmakefile
teem/trunk/src/unrrdu/GNUmakefile
Modified: teem/trunk/src/GNUmakefile
===================================================================
--- teem/trunk/src/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -1,6 +1,6 @@
#
# Teem: Tools to process and visualize scientific data and images
-# Copyright (C) 2009--2023 University of Chicago
+# Copyright (C) 2009--2025 University of Chicago
# Copyright (C) 2005--2008 Gordon Kindlmann
# Copyright (C) 1998--2004 University of Utah
#
@@ -20,122 +20,144 @@
####
#### top-level GNUmakefile: Master makefile for teem
####
+#### NOTE: You should probably be using CMake instead of this GNU Makefile! CMake builds
+#### Teem by creating one monolithic library (libteem) and the executables (e.g. unu)
+#### that link with that, which is very likely what you want.
+####
+#### This GNUmakefile logic was first written by GLK in ~2001, before CMake was useful or
+#### popular. It builds Teem one library at a time (not a single monolithic library like
+#### from CMake), and handles the per-library "test" programs (distinct from the nascent
+#### efforts at using CTest). Because this remains useful for debugging and developing
+#### Teem, it persists, and GLK uses it.
+####
+#### For TeemV2, all the GNUMakefile machinery was simplified to remove any notion of
+#### "architecture" and the environment variable "TEEM_ARCH" that declared it. It was
+#### never exactly the CPU architecture, but rather some mix of the architecture and the
+#### OS around it. And, it only made sense for settings where one (network) file system
+#### was being used on a variety of different machines. This was the case in where Teem
+#### was first developed at University of Utah (Scientific Computing and Imaging group):
+#### SGI, Linux (32-bit x86, ia64 and amd64), and Solaris hosts all talked on the same
+#### filesystem. Development builds needed to put binaries in different places depending
+#### on platform, and this was determined by environment variable TEEM_ARCH, which in
+#### turn chose an architecture-specific subdirectory of teem/src/arch to put things
+#### in. Even if these kinds of heterogeneous environments still exist, Teem development
+#### no longer happens there. Also in the interests of simplicity: everything about
+#### shared libraries was dropped. The only shared library that matters is libteem.so or
+#### libteem.dylib, and making that is better handled by CMake than by anything here.
+####
+#### This simplification meant removing:
+#### (from everywhere)
+#### env var TEEM_ARCH
+#### env var TEEM_DEST (because now any "install" should be done via CMake)
+#### make vars ARCH, SUBARCH
+#### everything about shared libraries: TEEM_LINK_SHARED, SHEXT
+#### as well as variables TEEM_EXT_IPATH and TEEM_EXT_LPATH (for all EXT externals
+#### PNG ZLIB BZIP2 PTHREAD LEVMAR FFTW3, e.g TEEM_ZLIB_IPATH, TEEM_ZLIB_LPATH);
+#### these have become EXT.DASHI and EXT.DASHL set in make/externals.mk
+####
+#### file errorCheck.mk gone (so simple, nothing left to error check)
+#### make var KNOWN_ARCH
+#### make funcs checkArchSet, checkArchValid,
+#### checkArchLinux, checkArchLinux64, checkArchNetbsd64, checkArchDarwin
+####
+#### With this simplification, these files in make/ stopped being used:
+#### aix.mk cygwin.mk darwin.mk irix6.mk linux.mk netbsd.mk solaris.mk win32.mk
+#### and are thus removed. Instead, a new single make/arch.mk contains the
+#### information that used to be there, or at least variables from which to hang
+#### this info.
-## ".SUFFIXES :" speeds debugging with make -d (and probably make in
-## general) by eliminating the list of suffixes checked by implicit
-## pattern rules. The rest of the rules are to tell make to forget
-## about trying to automatically update the files that we "include"
+ifndef Top.Included
+Top.Included := yes
+
+## ".SUFFIXES :" speeds debugging with "make -d" (and probably make in general) by
+## eliminating the list of filename extensions (.y, .l, etc) checked by implicit pattern
+## rules.
##
.SUFFIXES :
-% : %,v
-% : RCS/%,v
-% : RCS/%
-% : s.%
-% : SCCS/s.%
-%.c : %.w # this doesn't seem to work, unfortunately
-## TEEM_ROOT: a relative path to the directory which contains the
-## "src", "include", and all the architecture-specific directories
-## (which in turn contain "bin", "lib", and "obj"). Whether
-## make started on this makefile or on an individual library's
-## makefile determines who gets to set TEEM_ROOT first. Same for
-## TEEM_SRC, a relative path to the "src" directory
-##
-TEEM_ROOT ?= ..
-TEEM_SRC ?= .
+# avoids "make -d" perseverating with "Trying implicit prerequisite `....w'."
+# (.w files are for Knuth's cweave/ctangle)
+MAKEFLAGS += -r
-## When making Windows project files, set TEEM_ARCH to cygwin
-ifeq (project, $(MAKECMDGOALS))
-TEEM_ARCH ?= cygwin
-endif
-
-## read in the check* functions, and check on TEEM_ARCH
+## TeemRoot: a relative path to directory containing "src", "include", "built" subdirs
+## Whether make started on this GNUmakefile, or that of a subdirectory, determines who
+## gets to set TeemRoot first. Same for TeemSrc, a relative path to the "src" subdir
##
-include $(TEEM_SRC)/make/errorCheck.mk
-$(checkArchSet)
-$(checkArchLinux)
-$(checkArchLinux64)
-$(checkArchNetbsd64)
-$(checkArchDarwin)
-$(checkArchValid)
-$(checkTeemDest)
+TeemRoot ?= ..
+TeemSrc ?= .
-## the architecture name may have two parts, ARCH and SUBARCH,
-## seperated by one period
+## Enstate the architecture-dependent settings by reading through the file specific to
+## the chosen architecture
##
-ARCH = $(basename $(TEEM_ARCH))
-SUBARCH = $(patsubst .%,%,$(suffix $(TEEM_ARCH)))
-
-## Before we read in the architecture-dependent stuff, take a stab at
-## defining the various programs we'll need, and some of their flags.
-## If these are not over-written, we assume that they'll work.
+## We assume that arch.mk will finish with these all being set:
+## CC, LD, AR, ARFLAGS, RANLIB, RM, CP, CHMOD, CFLAGS, BIN_CFLAGS
##
-CC ?= cc
-LD = ld
-AR = ar
-ARFLAGS = ru
-RM = rm -f
-CP = cp
-CHMOD = chmod
-SLEEP = sleep
+include $(TeemSrc)/make/arch.mk
-## Enstate the architecture-dependent settings by reading through the
-## file specific to the chosen architecture, then check the things that
-## are set there.
-##
-include $(TEEM_SRC)/make/$(ARCH).mk
-$(checkShext)
+## Now that CMake-based compilation is the default, the (GNUmake) non-CMake building has
+## to a little extra work to keep working: this extra -DTEEM_NON_CMAKE flag says to $(CC)
+## "we're not building with cmake" (so e.g. don't look for teem/airExistsConf.h)
+CFLAGS += -DTEEM_NON_CMAKE
-## information about optional external ("xtern") libraries to link with
+## information about optional external libraries to link with
##
-include $(TEEM_SRC)/make/externals.mk
+include $(TeemSrc)/make/externals.mk
-## LIBS: all the teem libraries we'll try to build
-## NUMS: "numbering" of all the libraries in dependency order
-## RNUMS: in link order, and "top-dep" order needed by bin/GNUmakefile
-## {R}NUM/LIBS: used for craziness below
+## Libs: all the teem libraries we'll try to build
+## DepNums: indices numbering all the libs, in *Dep*endency order
+## RevNums: indices for numbering libs in (reverse) order for linking
+## DepLibs, RevLibs: strings of N/L (number/library) pairs, in either order
## (TEEM_LIB_LIST)
##
-LIBS = air hest biff nrrd ell moss unrrdu alan tijk gage dye bane limn echo hoover seek ten elf pull coil push mite meet
-NUMS = 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M
-RNUMS = M L K J I H G F E D C B A 9 8 7 6 5 4 3 2 1 0
+Libs := air hest biff nrrd ell moss unrrdu alan tijk gage dye bane limn echo hoover seek ten elf pull coil push mite meet
+DepNums := 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M
+ifneq ($(words $(Libs)),$(words $(DepNums)))
+ $(error |Libs| == $(words $(Libs)) != $(words $(DepNums)) == |DepNums|)
+endif
+ifneq ($(DepNums),$(sort $(DepNums)))
+ $(error Not already sorted? DepNums == $(DepNums))
+endif
+# https://stackoverflow.com/questions/52674/simplest-way-to-reverse-the-order-of-strings-in-a-make-variable
+reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
+RevNums := $(strip $(call reverse,$(DepNums)))
+DepLibs := $(join $(DepNums),$(Libs:%=/%))
+RevLibs := $(join $(RevNums),$(Libs:%=/%))
-NUM/LIBS = $(join $(NUMS),$(LIBS:%=/%))
-RNUM/LIBS = $(join $(RNUMS),$(LIBS:%=/%))
+## Modes: the purpose of running make:
+## bild = compiling/building/making something from source files
+## test = (depends on bild) builds intra-library "test" programs
+## clean = removing whatever bild and test does
+## Declaring all these modes as phony saves make the effort of trying implicit rules to
+## update them.
+.PHONY : bild test clean
+Modes := bild test clean
+# expands to: teem.bild teem.test teem.clean air.bild air.test air.clean ... bin.bild bin.test bin.clean
+# (even though bin.test is never actually a target)
+.PHONY : $(foreach L,teem $(Libs) bin,$(Modes:%=$(L).%))
-## MODES: the different kinds of builds that we support. Declaring
-## these modes (for all libraries) as phony saves make the effort of
-## trying implicit rules to update them.
+## Top-level default rules. If make started with this file, then these will be the first
+## rules that make sees, so that "make" defaults to "make teem.bild" If make started in
+## subdirectory for library L, then default target "bild" will depend on L.bild, and
+## "clean" will depend on L.clean.
##
-MODES = install dev clean clobber
-.PHONY : $(foreach LIB,teem $(LIBS),$(MODES:%=$(LIB)/%)) teem.dsp
-
-## Top-level/default rules. If make started with this file, then
-## these will be the first rules that make sees, so that "make"
-## defaults to "make X/install" for *every* library X. If make
-## started in a library subdirectory, these won't be seen at all.
-##
-ifeq (,$(DEF_TARGETS))
- install : teem/install
- dev : teem/dev
- clean : teem/clean
- clobber : teem/clobber
- DEF_TARGETS := true
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : teem.bild
+ # kind of a crazy (test are for helping write one library) but allowed
+ test : teem.test
+ clean : teem.clean
endif
-## Top-level rules, available regardless of where make started
+## Top-level rules, available regardless of where make started:
+## teem.M (for mode M) depends on X.M for all libs X and on bin.M
##
-teem/install : $(addsuffix /install,$(LIBS) bin) megalibs
-teem/dev : $(addsuffix /dev,$(LIBS) bin)
-teem/clean : $(addsuffix /clean,$(LIBS) bin)
- $(if $(TEEM_LITTER),$(RM) $(TEEM_ROOT)/src/$(TEEM_LITTER))
-teem/clobber : teem/clean $(addsuffix /clobber,$(LIBS) bin) unmegalibs
-nothing : ;
+teem.bild : $(addsuffix .bild,$(Libs) bin)
+teem.test : $(addsuffix .test,$(Libs)) # there is no bin.test
+teem.clean : $(addsuffix .clean,$(Libs) bin)
-## if.missing(stuff): returns $stuff if one or more of the files
-## listed in stuff don't exist
+## if.missing(path): returns "missing" if path does not exist
##
-if.missing = $(if $(strip $(foreach x,$(1),$(if $(wildcard $(x)),,no))),$(1))
+if.missing = $(if $(wildcard $(1)),,missing)
## create.if.missing(dir): creates directory dir if it doesn't exist,
## and gives a warning to that effect
@@ -145,211 +167,155 @@
$(warning *** WARNING ***: Creating needed directory $(1)) \
$(shell mkdir $(1)))
-## Set directory-related variables: where to install things, as well
-## as the directories used in conjunction with the -I and -L path
-## flags for cc and ld
-##
-ifeq (undefined,$(origin TEEM_DEST))
- IDEST = $(TEEM_ROOT)/include
- LDEST = $(TEEM_ROOT)/arch/$(TEEM_ARCH)/lib
- BDEST = $(TEEM_ROOT)/arch/$(TEEM_ARCH)/bin
-else
- IDEST = $(TEEM_DEST)/include
- LDEST = $(TEEM_DEST)/lib
- BDEST = $(TEEM_DEST)/bin
- $(foreach dir,$(IDEST) $(LDEST) $(BDEST),\
- $(call create.if.missing,$(dir)))
-endif
-## create IDEST/teem if necessary
-$(call create.if.missing,$(IDEST)/teem)
-ODEST = $(TEEM_ROOT)/arch/$(TEEM_ARCH)/obj
-IPATH += -I$(IDEST)
-LPATH += -L$(LDEST)
-ifneq (undefined,$(origin TEEM_DEST))
- # we still need this for the teem*.h headers (such as teemEndian.h)
- IPATH += -I$(TEEM_ROOT)/include
-endif
+## Set variables connected to directories where things go
+## ObjPath: where the .o object files go
+## HdrPath: where .h header files go (for #include <>)
+## LibPath: where the .a library files go
+## BinPath: where executables go
+ObjPath := $(TeemRoot)/built/obj
+HdrPath := $(TeemRoot)/built/include
+LibPath := $(TeemRoot)/built/lib
+BinPath := $(TeemRoot)/built/bin
+$(foreach dir,$(ObjPath) $(HdrPath) $(HdrPath)/teem $(LibPath) $(BinPath),\
+ $(call create.if.missing,$(dir)))
+dashI += -I$(HdrPath)
+# we still need this for the teem*.h headers (such as teemPng.h)
+dashI += -I$(TeemRoot)/include
+dashL += -L$(LibPath)
-## By giving a list of library extensions we care about, LIBEXTS determines
-## what kinds of libraries are built (just static, or both static and
-## shared)
-##
-ifdef TEEM_SHEXT
- LIBEXTS = $(TEEM_SHEXT)
-endif
-LIBEXTS += a
-
#######################################
-## Flags
+## "Functions": The bread and butter of how template.mk works. Each of these can be
+## $(call)ed with a library name, as the one and only argument, in order to get a list of
+## files or flags related to library.
##
-ifneq (undefined,$(origin TEEM_LINK_SHARED))
- # If we ever have absolutify-this-path working, then having an
- # absolute TEEM_DEST path is no longer a pre-requisite
- BIN_CFLAGS += $(SHARED_CFLAG) $(if $(TEEM_DEST),$(if $(SHARED_RPATH),$(SHARED_RPATH)$(LDEST),),)
-else
- BIN_CFLAGS += $(STATIC_CFLAG)
-endif
-
-## CMake is how most people will compile Teem, but these GNUMakefiles are
-## still what GLK uses day-to-day when working with Teem, with their finer
-## per-library granularity. Some additions to CFLAGS are adaptions help these
-## GNUMakfiles adapt to the CMake world around them. -DTEEM_NON_CMAKE says:
-## this isn't being build by cmake (so, don't look for teem/airExistsConf.h)
-CFLAGS += -DTEEM_NON_CMAKE $(OPT_CFLAG) $(ARCH_CFLAG)
-LDFLAGS += $(ARCH_LDFLAG) $(SHARED_LDFLAG)
-
-## SGI's C pre-processor errors aren't fatal by default
+## NOTE: In all of these, "File" could be singular or plural
+## SrcHdrFile(L): paths to all (public and private) headers in souce for lib L
+## HdrFile(Ls): paths to all public headers "installed" for lib L in Ls
+## ObjFile(L): paths to all object files to combine to make library L
+## LibFile(L): path to .a library file "installed" for library L
+## TestFile(L): paths to debugging tests for library L, built in-place
##
-CFLAGS += $(TEEM_CPP_ERROR_DIE)
+SrcHdrFile = $(addprefix $(TeemSrc)/$(1)/,$($(1).PublicHdr) $($(1).PrivateHdr))
+HdrFile = $(foreach lib,$(1),$(addprefix $(HdrPath)/teem/,$($(lib).PublicHdr)))
+ObjFile = $(addprefix $(ObjPath)/,$($(1).Obj))
+LibFile = $(LibPath)/lib$(1).a
+TestFile = $(addprefix $(TeemSrc)/$(1)/test/,$($(1).Test))
-#######################################
-## "Functions"
-## The bread and butter of how template.mk works.
-
-## Each of these can be $(call)ed with a library name, as the one
-## and only argument, in order to get a list of files or flags related to
-## library.
+## Need(L): All the libraries that L needs. L's GNUmakefile declares its immediate
+## dependencies in $(L).Depends, but Need(L) is the recursive-ish expansion.
+## MeNeed(L): L and Need(L), in dependency order
##
-## {libs,hdrs}.inst(L): installed libs and headers for library L
-## hdrs.dev(L): the local (original) copies of public and private headers
-## tests.dev(L): library L tests for debugging, built in-place
-## {libs,objs}.dev(L): object files for library L, and the libs used
-## when compiling the tests
-##
-libs.inst = $(foreach ext,$(LIBEXTS),$(LDEST)/lib$(1).$(ext))
-hdrs.inst = $(addprefix $(IDEST)/teem/,$($(1).PUBLIC_HEADERS))
-hdrs.dev = $(addprefix $(TEEM_SRC)/$(1)/,\
- $($(1).PUBLIC_HEADERS) $($(1).PRIVATE_HEADERS))
-tests.dev = $(addprefix $(TEEM_SRC)/$(1)/,$($(1).TESTS))
-libs.dev = $(foreach ext,$(LIBEXTS),$(ODEST)/lib$(1).$(ext))
-objs.dev = $(addprefix $(ODEST)/,$($(1).OBJS))
-hdrs.dev = $(addprefix $(TEEM_SRC)/$(1)/,\
- $($(1).PUBLIC_HEADERS) $($(1).PRIVATE_HEADERS))
-
-## need(L): pseudo-recursive expansion of all the libraries which
-## library L depends on, either directly or indirectly. Because make
-## doesn't allow recursive functions, and because I can't figure out
-## how to do fixed-point determination in gmake, I'm only doing a few
-## levels of prerequisite expansion. Each level is done by "dmnl"
-## (discover more needed libs). The number of levels is more than
-## enough for the current teem; and adding more levels later is
+## Yes, the whole point of "make" is to keep track of dependencies, so this would seem to
+## be a little pointless. But the issue is linking with -llib for every library lib: how
+## do you assemble the complete link command? It needs to be the transitive closure of
+## the libs depended on. I (GLK) can't figure out how to do this implicitly via make,
+## hence the stuff below. Because I can't figure out how to do fixed-point determination
+## as part of a recursive function call, I'm only doing a few levels of explicit
+## prerequisite expansion. Each level is done by "dmnl" (discover more needed libs). The
+## number of levels is more than enough for current Teem; adding more levels later is
## trivial.
##
-## Since we rely on $(sort) to remove redundancies, we need a way of
-## putting the libraries back in dependency order (!= lexical order).
-## So, we prefix the needed library names with [0..D] (via $(join)) to
-## create NUM/LIBS (above), re-sort them, and then lose the prefix
-## with $(notdir). This is done by "deporder". On the link line,
-## however, the ordering needs to be reversed, this is done by
-## "linkorder".
+## Since we rely on $(sort) to remove redundancies, we need a way of putting the
+## libraries back in dependency order (!= lexical order). So, we prefix the needed
+## library names with 0/,1/,...,9/,A/,B/,... (via $(join)) to create DepLibs (above),
+## re-sort them, and then lose the prefix with $(notdir). This is done by "DepOrder". On
+## the link line, however, the ordering needs to be reversed, this is done by "RevOrder".
##
-dmnl = $(sort $(foreach LIB,$(1),$(LIB) $($(LIB).NEED)))
-deporder = $(notdir $(sort $(foreach LIB,$(1),\
- $(filter %/$(LIB),$(NUM/LIBS)))))
-linkorder = $(notdir $(sort $(foreach LIB,$(1),\
- $(filter %/$(LIB),$(RNUM/LIBS)))))
-need = $(call deporder,\
+dmnl = $(sort $(foreach lib,$(1),$(lib) $($(lib).Depends)))
+DepOrder = $(notdir $(sort $(foreach lib,$(1),$(filter %/$(lib),$(DepLibs)))))
+RevOrder = $(notdir $(sort $(foreach lib,$(1),$(filter %/$(lib),$(RevLibs)))))
+Need = $(call DepOrder,\
$(call dmnl,\
$(call dmnl,\
$(call dmnl,\
-$(foreach LIB,$(1),$($(LIB).NEED))))))
-meneed = $(call deporder,$(1) $(call need,$(1)))
+$(foreach lib,$(1),$($(lib).Depends))))))
+MeNeed = $(call DepOrder,$(1) $(call Need,$(1)))
-## link(libs): "-lLIB" for all LIBs in libs, in correct link order
+## More utilities
+## llink(LIBS): "-lL" for all L in LIBS, in correct link order
+## banner(L): progress indication for compiling library L; used in template.mk.
##
-link = $(foreach LIB,$(call linkorder,$(1)),-l$(LIB))
+llink = $(foreach L,$(call RevOrder,$(1)),-l$(L))
+banner = echo -e "\n-------" $(1) "-------" $(1) "-------" $(1) "-------" $(1) "-------\n"
-## banner(L) is progress indication for compiling library L; see
-## template.mk. The double colon rules previously used to print this
-## fatally confused parallel builds
+## For optional external libraries we can depend on (e.g. png, zlib, levmar)
+## Read make/externals.mk for context and full list AllExterns
##
-banner = echo "--------------------" $(1) "--------------------"
-
-#src2lib = $(notdir $(patsubst %/,%,$(dir $(1:.c=))))
-#HDR2LIB = $(notdir $(patsubst %/,%,$(dir $(1:.h=))))
-#STL2LIB = $(patsubst lib%,%,$(notdir $(1:.a=)))
-#SHL2LIB = $(patsubst lib%,%,$(notdir $(1:.$(TEEM_SHEXT)=)))
-
-#used.hdrs = $(foreach lib,$(1),$(call hdrs.inst,$(lib)))
-#used.libs = $(foreach lib,$(1),$(call libs.inst,$(lib)))
-#used = $(call used.libs,$(1)) $(call used.hdrs,$(1))
-
-## related to external optional libraries. Called "xtern"s to avoid
-## similarities to library filename extensions ("ext"s) above.
+## These two reflect the circumstances of running make, not any library:
+## wantsExtern(X): returns X if TEEM_<X> has been set (as a shell variable,
+## but not set to "0"), otherwise nothing
+## Externs: list of all wanted externs (a subset of AllExterns)
+## forExtern(libs,patt): for all external X in Externs,
+## and for all L in libraries $(libs) that benefit from external X,
+## replace "XXX" in $(patt) with X
+## Externs.dashD: the compile-time -D flags needed to enable external
+## library X when compiling objects in libraries $(libs)
+## evallist(list): utility to evaluate each element of list as a variable
+## (in the following, $(libs) which should probably be MeNeed(L) for some lib L)
+## Externs.dashI(libs): the external-specific -I flags needed for compiling
+## objects in libraries $(libs)
+## (using the X.dashI set in make/externals.mk for external X)
+## Externs.dashL(libs): the external-specific -L flags needed for compiling
+## executables that uses libraries $(libs)
+## (using the X.dashL set in make/externals.mk for external X)
+## Externs.llink(libs): the external-specific -l flags needed to link an
+## executable that uses libraries $(libs)
+## (using the X.llink set in make/externals.mk for external X)
##
-## wants.xtern(XTERN): returns XTERN if TEEM_<XTERN> has been set,
-## otherwise nothing
-## xterns: list of all wanted XTERNs (a subset of $(XTERNS))
-## for.xtern(libs,patt): for all xtern in xterns, for all libraries
-## in $(libs) that benefit from $(xtern),
-## replace XXX in $(patt) with $(xtern)
-## evallist(list): evaluates each element of list as a variable
-## xtern.Ipath(LIB): the external-specific -I flags needed for compiling
-## objects in library LIB
-## xtern.Dflag(LIB): the -D flags turned on for library LIB in order to
-## enable the desired externals
-## xtern.Lpath(libs): paths -Lblah for any wanted xterns whose base
-## teem dependency is within libs. libs should probably be $($(L).meneed)
-## for some library L
-## xtern.link(libs): -l link flags for any wanted externals whose base
-## teem dependency is within libs.
-##
-wants.xtern = $(if $(findstring undefined,$(origin TEEM_$(1))),,$(1))
-xterns = $(foreach xtern,$(XTERNS),$(call wants.xtern,$(xtern)))
-for.xtern = $(strip $(foreach xtern,$(xterns),$(foreach lib,$(1),\
- $(if $(filter $(xtern),$($(lib).XTERN)),\
- $(subst XXX,$(xtern),$(2))))))
+# if TEEM_X is undefined, then nothing, else if 0 matches TEEM_X then nothing, else X
+wantsExtern = $(if $(findstring undefined,$(origin TEEM_$(1))),\
+ ,\
+ $(if $(filter 0,$(TEEM_$(1))),\
+ ,\
+ $(1)))
+Externs = $(strip $(foreach X,$(AllExterns),$(call wantsExtern,$(X))))
+# foreach X in Externs and L in libs (only using $(L).Externs if defined)
+forExtern = $(strip $(foreach X,$(Externs),$(foreach L,$(1),\
+ $(if $(findstring undefined,$(origin $(L).Externs)),\
+ ,\
+ $(if $(filter $(X),$($(L).Externs)),\
+ $(subst XXX,$(X),$(2)))))))
+Externs.dashD = $(call forExtern,$(1),-DTEEM_XXX=1)
evallist = $(foreach var,$(1),$($(var)))
-xtern.Ipath = $(call evallist,$(call for.xtern,$(1),TEEM_XXX_IPATH))
-xtern.Dflag = $(call for.xtern,$(1),-DTEEM_XXX=1)
-xtern.Lpath = $(call evallist,$(call for.xtern,$(1),TEEM_XXX_LPATH))
-xtern.link = $(call evallist,$(call for.xtern,$(1),XXX.LINK))
+maybe.prefix = $(if $(2),$(1)$(2))
+Externs.dashI = $(call maybe.prefix,-I,$(call evallist,$(call forExtern,$(1),TEEM_XXX_DASHI)))
+Externs.dashL = $(call maybe.prefix,-L,$(call evallist,$(call forExtern,$(1),TEEM_XXX_DASHL)))
+Externs.llink = $(call evallist,$(call forExtern,$(1),XXX.llink))
+## DEBUG
+#X = PNG
+#$(warning wantsExtern($(X))=$(call wantsExtern,$(X)))
+#$(warning Externs=$(Externs))
+#$(warning forExtern(nrrd ten air tijk,-DTEEM_XXX=1): $(call forExtern,nrrd ten air tijk,-DTEEM_XXX=1))
+#L = ten
+#$(warning Externs.dashI($(L)): $(call Externs.dashI,$(L)))
+#$(warning Externs.dashL($(L)): $(call Externs.dashL,$(L)))
+#$(warning Externs.llink($(L)): $(call Externs.llink,$(L)))
+#$(error STOPPING)
+# TEEM_PTHREAD= TEEM_PNG= TEEM_LEVMAR=1 make --warn-undefined-variables
#######################################
-## Read in the makefiles for all the libraries, and the bins. Run-away
-## recursive inclusion is prevented by having set DEF_TARGETS.
-## Note: "include" is a directive, not a function, which eliminates
-## the possibility of iterating through the libraries, reading the
-## make file, and then setting variables based on what was just read.
+## Read in the makefiles for all the libraries, and the bins. Run-away recursive
+## inclusion is prevented by the Top.Included and other guards. Note: "include" is a
+## directive, not a function, which eliminates the possibility of iterating through the
+## libraries, reading the make file, and then setting variables based on what was just
+## read.
##
-## Lsave is used to preserve the value of L, in case we're being included
-## from a lower-level makefile which set a value for L. If we didn't put
-## L back the way it was, L would have to be set twice in the lower level
-## makefiles
+## Unfortunate trickiness: Lsave preserves the value of L, in case we're being included
+## from a lower-level GNUmakefile which set a value for L. If we didn't put L back the
+## way it was, L would have to be set twice in the lower level.
##
-INCLUDED = true
-ifneq (,$(L))
- ifeq (undefined,$(origin Lsave))
+ifdef L
+ ifndef Lsave
+ # "It's such a fine line, between stupid ...
Lsave := $(L)
endif
endif
-include $(foreach LIB,$(LIBS),$(TEEM_SRC)/$(LIB)/GNUmakefile)
-ifneq (,$(Lsave))
+include $(foreach LIB,$(Libs) bin,$(TeemSrc)/$(LIB)/GNUmakefile)
+ifdef Lsave
+ # ... and clever"
L := $(Lsave)
- INCLUDED =
-else
- # Lsave wasn't set, which means that make was invoked on this file,
- # and since the library make files do not include the bin makefile,
- # we do so now
- include $(TEEM_SRC)/bin/GNUmakefile
endif
-## megalibs: libteem.a and libteem.$(TEEM_SHEXT)
-##
-megalibs : $(foreach ext,$(LIBEXTS),$(LDEST)/libteem.$(ext))
-$(LDEST)/libteem.a : $(foreach lib,$(LIBS),$(call objs.dev,$(lib)))
- $(AR) $(ARFLAGS) $@ $^
-ifdef TEEM_SHEXT
-$(LDEST)/libteem.$(TEEM_SHEXT) : $(foreach lib,$(LIBS),$(call objs.dev,$(lib)))
- $(LD) -o $@ \
- $(if $(TEEM_DEST),$(if $(SHARED_LINK_NAME),$(SHARED_LINK_NAME)$@,),) \
- $(LDFLAGS) $(LPATH) $^ \
- $(foreach X,$(xterns),$(TEEM_$(X)_LPATH)) \
- $(foreach X,$(xterns),$($(X).LINK))
-endif
-unmegalibs:
- $(RM) $(foreach ext,$(LIBEXTS),$(LDEST)/libteem.$(ext))
-
-include $(TEEM_SRC)/make/win32.mk
+endif # ifndef Top.Included
Modified: teem/trunk/src/air/GNUmakefile
===================================================================
--- teem/trunk/src/air/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/air/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,44 +17,39 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := air
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
+#### Describe library L here
####
####
-$(L).NEED =
-$(L).PUBLIC_HEADERS = air.h
-$(L).PRIVATE_HEADERS = privateAir.h
-$(L).OBJS = 754.o randMT.o randJSF.o array.o miscAir.o parseAir.o math.o \
+$(L).Depends =
+$(L).PublicHdr = air.h
+$(L).PrivateHdr = privateAir.h
+$(L).Obj = 754.o randMT.o randJSF.o array.o miscAir.o parseAir.o math.o \
endianAir.o mop.o enum.o sane.o string.o threadAir.o heap.o
-$(L).TESTS = test/floatprint test/doubleprint test/tok \
- test/tmop test/tline test/fp test/trand test/trandJSF test/tmisc \
- test/bessy test/tarr test/texp test/logrice test/tprint
+$(L).Test = floatprint doubleprint tok tmop tline fp trand trandJSF tmisc \
+ bessy tarr texp logrice tprint
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/alan/GNUmakefile
===================================================================
--- teem/trunk/src/alan/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/alan/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,40 +17,37 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
+
+#### Describe library L here
####
####
-L := alan
+$(L).Depends = air biff ell nrrd
+$(L).PublicHdr = alan.h
+$(L).PrivateHdr =
+$(L).Obj = methodsAlan.o enumsAlan.o coreAlan.o
+$(L).Test =
####
####
####
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
-####
-$(L).NEED = air biff ell nrrd
-$(L).PUBLIC_HEADERS = alan.h
-$(L).PRIVATE_HEADERS =
-$(L).OBJS = methodsAlan.o enumsAlan.o coreAlan.o
-$(L).TESTS =
-####
-####
-####
-
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/bane/GNUmakefile
===================================================================
--- teem/trunk/src/bane/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/bane/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,45 +17,41 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := bane
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
+#### Describe library L here
####
####
-$(L).NEED = gage unrrdu nrrd biff air
-$(L).PUBLIC_HEADERS = bane.h
-$(L).PRIVATE_HEADERS = privateBane.h
-$(L).OBJS = defaultsBane.o rangeBane.o inc.o clip.o measr.o methodsBane.o \
+$(L).Depends = gage unrrdu nrrd biff air
+$(L).PublicHdr = bane.h
+$(L).PrivateHdr = privateBane.h
+$(L).Obj = defaultsBane.o rangeBane.o inc.o clip.o measr.o methodsBane.o \
valid.o trnsf.o scat.o hvol.o trex.o \
gkmsFlotsam.o \
gkmsHvol.o gkmsScat.o gkmsInfo.o gkmsPvg.o gkmsOpac.o \
gkmsMite.o gkmsTxf.o
-$(L).TESTS = test/tinfo test/sigma test/pos test/opac
+$(L).Test = tinfo sigma pos opac
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/biff/GNUmakefile
===================================================================
--- teem/trunk/src/biff/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/biff/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,41 +17,37 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := biff
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
+#### Describe library L here
####
####
-$(L).NEED = air
-$(L).PUBLIC_HEADERS = biff.h
-$(L).PRIVATE_HEADERS = privateBiff.h
-$(L).OBJS = biffmsg.o biffbiff.o
-$(L).TESTS = test/test
+$(L).Depends = air
+$(L).PublicHdr = biff.h
+$(L).PrivateHdr = privateBiff.h
+$(L).Obj = biffmsg.o biffbiff.o
+$(L).Test = test
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/bin/GNUmakefile
===================================================================
--- teem/trunk/src/bin/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/bin/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,117 +17,89 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Name of the library goes here.
-####
-####
-L := bin
-####
-#### ha ha actually we're not a library at all ...
-####
-
-# boilerplate: default targets (except usable) and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
+# boilerplate: default targets, include, and guarding per-"lib" rules
+ifndef bin.Included
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : bin.bild
+ clean : bin.clean
endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-#### By the ordering and guarding of includes, this will ALWAYS be the
-#### last "library" makefile to be parsed, regardless of the directory
-#### in which make started.
+#### By the ordering and guarding of includes, this will ALWAYS be the last "library"
+#### makefile to be parsed, regardless of the directory in which make started.
-## BINS: all the command-line executables associated with teem
+## Bins: all the command-line executables associated with teem
##
-BINS = airSanity cubic nrrdSanity overrgb emap talkweb \
- unu pprobe vprobe gprobe qbert mrender miter gkms ungantry ilk \
- tend spots ninspect deconv puller
+Bins := airSanity nrrdSanity overrgb talkweb unu cubic qbert ilk \
+ emap gkms ungantry spots tend miter mrender pprobe vprobe gprobe \
+ deconv puller
-## _binD(bins): list of development locations for given bins
-## (With TeemV2 simplification, there is no "install" anything anymore)
+## BinsBild: full paths to all built and "installed" binaries
##
-_binD = $(foreach bin,$(1),$(TEEM_SRC)/bin/$(bin))
+#$(warning BinsBild := $(foreach bin,$(Bins),$(BinPath)/$(bin)))
+BinsBild := $(foreach bin,$(Bins),$(BinPath)/$(bin))
-## BINS.DEV: full paths to development versions
-##
-BINS.DEV := $(call _binD,$(BINS))
-
## Entry-point targets for binaries.
##
-bin/dev: $(BINS.DEV)
-bin/clean:
- $(RM) $(addsuffix $(DOTEXE),$(BINS.DEV))
+#$(warning bin.bild: $(BinsBild))
+bin.bild: $(BinsBild)
+bin.clean:
+ $(RM) $(BinsBild)
+ifdef LITTER
+ $(RM) -r $(foreach bin,$(BinsBild),$(bin)$(LITTER))
+endif
-## All the prerequisite usables of the bins, **RECURSIVELY EXPANDED** (or not? since
-## things here are depending on meet, and yet not all Teem libraries are listed here).
-## The calls to need() will work correctly because we've gotten here only after going
-## through all the other library makesfiles. The arguments to need() are libraries for
-## which we need a header and/or libraries we need to link against.
+## Each bin needs to know the libraries it immediately depends on.
+## We do *not* need to manually find the transitive closure here
##
-airSanity.need = $(call meneed,air)
-cubic.need = $(call meneed,ell)
-nrrdSanity.need = $(call meneed,nrrd biff)
-undos.need = $(call meneed,hest air)
-overrgb.need = $(call meneed,nrrd hest biff air)
-qbert.need = $(call meneed,bane gage nrrd hest air)
-ilk.need = $(call meneed,moss unrrdu nrrd ell biff hest air)
-emap.need = $(call meneed,limn nrrd ell biff hest air)
-gkms.need = $(call meneed,bane nrrd biff air)
-ninspect.need = $(call meneed,nrrd biff hest air)
-unu.need = $(call meneed,unrrdu nrrd biff hest air)
-miter.need = $(call meneed,mite hoover limn nrrd ell biff air)
-ungantry.need = $(call meneed,gage nrrd biff hest air)
-talkweb.need = $(call meneed,nrrd biff hest air)
-tend.need = $(call meneed,ten limn gage dye unrrdu nrrd ell biff air)
-mrender.need = $(call meneed,meet ten hoover limn gage nrrd biff hest air)
-vprobe.need = $(call meneed,meet ten limn gage nrrd ell biff hest air)
-gprobe.need = $(call meneed,meet ten limn gage nrrd ell biff hest air)
-deconv.need = $(call meneed,meet ten limn gage nrrd ell biff hest air)
-pprobe.need = $(call meneed,meet ten limn gage nrrd ell biff hest air)
-spots.need = $(call meneed,alan nrrd ell biff hest air)
-puller.need = $(call meneed,meet pull ten gage nrrd ell biff hest air)
+# HEY should be generating this by some sort of grep on each bin.c
+airSanity.Depends := air
+nrrdSanity.Depends := nrrd biff
+overrgb.Depends := nrrd hest biff air
+talkweb.Depends := nrrd biff hest air
+unu.Depends := unrrdu nrrd biff hest air
+cubic.Depends := ell
+qbert.Depends := bane gage nrrd hest air
+ilk.Depends := moss unrrdu nrrd ell biff hest air
+emap.Depends := limn nrrd ell biff hest air
+gkms.Depends := bane nrrd biff air
+ungantry.Depends := gage nrrd biff hest air
+spots.Depends := alan nrrd ell biff hest air
+tend.Depends := ten limn gage dye unrrdu nrrd ell biff air
+miter.Depends := mite hoover limn nrrd ell biff air
+mrender.Depends := meet
+pprobe.Depends := meet
+vprobe.Depends := meet
+gprobe.Depends := meet
+deconv.Depends := meet
+puller.Depends := meet
-## Old: "We need some way of expressing the fact that a given binary (install and dev)
-## depends on the usable of its top dependency."
-## Problem: Its not sufficient to use the "top dependency" because the dependencies are
-## not strict subsets/supersets: mrender's "top" dependency is hoover, but hoover doesn't
-## depend on gage, which mrender needs
-##
-$(call _binDI,airSanity) : $(call used,$(airSanity.need))
-$(call _binDI,cubic) : $(call used,$(cubic.need))
-$(call _binDI,nrrdSanity) : $(call used,$(nrrdSanity.need))
-$(call _binDI,undos) : $(call used,$(undos.need))
-$(call _binDI,overrgb) : $(call used,$(overrgb.need))
-$(call _binDI,qbert) : $(call used,$(qbert.need))
-$(call _binDI,ilk) : $(call used,$(ilk.need))
-$(call _binDI,emap) : $(call used,$(emap.need))
-$(call _binDI,vprobe) : $(call used,$(vprobe.need))
-$(call _binDI,gprobe) : $(call used,$(gprobe.need))
-$(call _binDI,deconv) : $(call used,$(deconv.need))
-$(call _binDI,pprobe) : $(call used,$(pprobe.need))
-$(call _binDI,gkms) : $(call used,$(gkms.need))
-$(call _binDI,ninspect) : $(call used,$(ninspect.need))
-$(call _binDI,unu) : $(call used,$(unu.need))
-$(call _binDI,mrender) : $(call used,$(mrender.need))
-$(call _binDI,miter) : $(call used,$(miter.need))
-$(call _binDI,ungantry) : $(call used,$(ungantry.need))
-$(call _binDI,talkweb) : $(call used,$(talkweb.need))
-$(call _binDI,tend) : $(call used,$(tend.need))
-$(call _binDI,spots) : $(call used,$(spots.need))
-$(call _binDI,puller) : $(call used,$(puller.need))
+# Binary B depends on building the libraries it depends on (and we let
+# make figure out the transitive closure), but/and,
+# when linking binary B we need to know all (the transitive closure of)
+# the libraries that B depends on, and we only want to compute that once,
+# so we save it in a target-specific variable B.needs
+# We express both inside a multi-line function:
+#$(warning $(BinPath)/$1 : $(foreach lib,$($(1).Depends),$(lib).bild))
+#$(warning $(BinPath)/$1 : $1.needs := $(sort $(foreach lib,$($(1).Depends),$($(lib).MeNeed))))
+define bin-deps
+$(BinPath)/$1 : $(foreach lib,$($(1).Depends),$(lib).bild)
+$(BinPath)/$1 : $1.needs := $(sort $(foreach lib,$($(1).Depends),$($(lib).MeNeed)))
+endef
-## How to make bins.dev: link against the same libraries and include the same
-## (installed) headers, so the commands aren't actually any different ...
+# For each binary B, state B's library dependencies, and compute B.needs
+$(foreach bin,$(Bins),$(eval $(call bin-deps,$(bin))))
+
+## How to make binary B from B.c
##
-$(BDEST)/% : $(TEEM_SRC)/bin/%.c
- $(P) $(CC) $(CFLAGS) $(BIN_CFLAGS) $(IPATH) -o $@ $< \
- $(LPATH) $(call link,$($(notdir $@).need)) \
- $(call xtern.Lpath,$($(notdir $@).need)) \
- $(call xtern.link,$($(notdir $@).need)) -lm
+$(BinPath)/% : $(TeemSrc)/bin/%.c
+ $(CC) $(CFLAGS) $(BIN_CFLAGS) $(dashI) -o $@ $< \
+ $(dashL) $(call llink,$($(notdir $@).needs)) \
+ $(call Externs.dashL,$($(notdir $@).needs)) $(call Externs.llink,$($(notdir $@).needs)) -lm
# we're not a library; template.mk doesn't apply to us
-endif
+endif # ifndef bin.Included
Modified: teem/trunk/src/coil/GNUmakefile
===================================================================
--- teem/trunk/src/coil/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/coil/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,42 +17,39 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
+
+#### Describe library L here
####
####
-L := coil
-####
-####
-####
-
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
-#### (ell for macros)
-####
-$(L).NEED = ten ell nrrd biff air
-$(L).PUBLIC_HEADERS = coil.h
-$(L).PRIVATE_HEADERS =
-$(L).OBJS = defaultsCoil.o enumsCoil.o scalarCoil.o tensorCoil.o \
+# (ell for macros)
+$(L).Depends = ten ell nrrd biff air
+$(L).PublicHdr = coil.h
+$(L).PrivateHdr =
+$(L).Obj = defaultsCoil.o enumsCoil.o scalarCoil.o tensorCoil.o \
realmethods.o methodsCoil.o coreCoil.o
-$(L).TESTS = test/coiler
+$(L).Test = coiler
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/dye/GNUmakefile
===================================================================
--- teem/trunk/src/dye/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/dye/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,42 +17,38 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
+
+#### Describe library L here
####
####
-L := dye
+# (needs ell for macros)
+$(L).Depends = ell biff air
+$(L).PublicHdr = dye.h
+$(L).PrivateHdr =
+$(L).Obj = methodsDye.o convertDye.o
+$(L).Test = conv bow mchist iconv
####
####
####
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
-#### (needs ell for macros)
-####
-$(L).NEED = ell biff air
-$(L).PUBLIC_HEADERS = dye.h
-$(L).PRIVATE_HEADERS =
-$(L).OBJS = methodsDye.o convertDye.o
-$(L).TESTS = test/conv test/bow test/mchist test/iconv
-
-####
-####
-####
-
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/echo/GNUmakefile
===================================================================
--- teem/trunk/src/echo/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/echo/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,42 +17,38 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := echo
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
+#### Describe library L here
####
####
-$(L).NEED = limn ell nrrd biff air
-$(L).PUBLIC_HEADERS = echo.h
-$(L).PRIVATE_HEADERS = privateEcho.h
-$(L).OBJS = enumsEcho.o methodsEcho.o objmethods.o bounds.o set.o model.o \
+$(L).Depends = limn ell nrrd biff air
+$(L).PublicHdr = echo.h
+$(L).PrivateHdr = privateEcho.h
+$(L).Obj = enumsEcho.o methodsEcho.o objmethods.o bounds.o set.o model.o \
matter.o intx.o sqd.o list.o color.o lightEcho.o renderEcho.o
-$(L).TESTS = test/test test/trend
+$(L).Test = test trend
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/elf/GNUmakefile
===================================================================
--- teem/trunk/src/elf/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/elf/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,41 +17,37 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := elf
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
+#### Describe library L here
####
####
-$(L).NEED = ten tijk limn ell nrrd air
-$(L).PUBLIC_HEADERS = elf.h
-$(L).PRIVATE_HEADERS =
-$(L).OBJS = ballStickElf.o ESHEstimElf.o glyphElf.o maximaElf.o
-$(L).TESTS =
+$(L).Depends = ten tijk limn ell nrrd air
+$(L).PublicHdr = elf.h
+$(L).PrivateHdr =
+$(L).Obj = ballStickElf.o ESHEstimElf.o glyphElf.o maximaElf.o
+$(L).Test =
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/ell/GNUmakefile
===================================================================
--- teem/trunk/src/ell/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/ell/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,42 +17,37 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := ell
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
+#### Describe library L here
####
####
-$(L).NEED = nrrd biff air
-$(L).PUBLIC_HEADERS = ell.h ellMacros.h
-$(L).PRIVATE_HEADERS =
-$(L).OBJS = cubicEll.o eigen.o miscEll.o vecEll.o mat.o quat.o genmat.o
-$(L).TESTS = test/sort3 test/invert test/tq test/wheel test/rot2aa \
- test/inter test/mmul test/es6
+$(L).Depends = nrrd biff air
+$(L).PublicHdr = ell.h ellMacros.h
+$(L).PrivateHdr =
+$(L).Obj = cubicEll.o eigen.o miscEll.o vecEll.o mat.o quat.o genmat.o
+$(L).Test = sort3 invert tq wheel rot2aa inter mmul es6
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/gage/GNUmakefile
===================================================================
--- teem/trunk/src/gage/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/gage/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,46 +17,41 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := gage
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).test
+ clean : $(L).clean
+endif # ifndef DefaultTargets
+.PHONY: $(TeemSrc)/GNUmakefile
+include $(TeemSrc)/GNUmakefile
-# boilerplate: default targets and include tricks
-TEEM_ROOT ?= ../..
-TEEM_SRC ?= ..
-ifeq (,$(DEF_TARGETS))
-DEF_TARGETS = true
-dev : $(L)/dev
-clean : $(L)/clean
-include ../GNUmakefile
-endif
-ifeq (,$($(L).SEEN))
-$(L).SEEN := true
-
-#### Describe library here
+#### Describe library L here
####
####
-$(L).NEED = ell nrrd biff air
-$(L).PUBLIC_HEADERS = gage.h
-$(L).PRIVATE_HEADERS = privateGage.h
-$(L).OBJS = defaultsGage.o miscGage.o scl.o kind.o \
+$(L).Depends = ell nrrd biff air
+$(L).PublicHdr = gage.h
+$(L).PrivateHdr = privateGage.h
+$(L).Obj = defaultsGage.o miscGage.o scl.o kind.o \
shape.o pvl.o update.o deconvolve.o \
print.o sclanswer.o sclprint.o sclfilter.o \
vecGage.o vecprint.o twovecGage.o st.o filter.o ctx.o \
stack.o stackBlur.o optimsig.o
-$(L).TESTS = test/ctfix test/demo test/vh test/aalias test/indx \
- test/genoptsig test/ssc test/maxes test/tplot
+$(L).Test = ctfix demo vh aalias indx genoptsig ssc maxes tplot
####
####
####
-# boilerplate: declare rules for this library
-include $(TEEM_SRC)/make/template.mk
-endif
-ifeq (,$(INCLUDED))
- include $(TEEM_SRC)/bin/GNUmakefile
-endif
+# boilerplate: declare rules for L via template, finish include guard
+.PHONY: $(TeemSrc)/make/template.mk
+include $(TeemSrc)/make/template.mk
+endif # ifndef $(L).Included
Modified: teem/trunk/src/hest/GNUmakefile
===================================================================
--- teem/trunk/src/hest/GNUmakefile 2025-08-27 21:42:50 UTC (rev 7328)
+++ teem/trunk/src/hest/GNUmakefile 2025-08-28 05:17:10 UTC (rev 7329)
@@ -17,42 +17,37 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-#### Library name
-####
-####
-L := hest
-####
-####
-####
+# boilerplate: start include guard based on containing dir, then
+# set library name L, define default targets, include top-level GNUmakefile
+pardir := $(notdir $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
+ifndef $(pardir).Included
+######## HERE is where L is set to library name
+L := $(pardir)
+$(L).Included := yes
+TeemRoot ?= ../..
+TeemSrc ?= ..
+ifndef DefaultTargets
+ DefaultTargets := yes
+ bild : $(L).bild
+ test : $(L).t...
[truncated message content] |