http://invisible-island.net/personal/
Copyright © 2014-2023,2024 by Thomas E. Dickey


As a software developer, I use many tools. Here are some comments about some of the command-line build tools which I have encountered. I have used most of these (a few exceptions are noted).

According to Matthew B. Doar in Practical Development Environments, (O'Reilly, 2005, page 59):

The are numerous implementations of make for almost every platform created in the last 25 years. The original make first became widely used with System V Release 2 Unix in 1984 but had been available since 1977. Compatible versions of make since then include a distributed make called dmake (1990), gmake (1991), BSD NET2 make (1991), and SunOS make (1989).

The date for gmake is incorrect. Noting the misspelling in the first sentence, and apparent lack of reference to reliable sources of information, the rest of the comment is suspect. The comment, by the way, is copied from a paper by the author of Jam.

In writing this page, there are many sources which contain inconsistencies. I have tried to point out discrepancies and point to the most likely "good" data on these programs.

*nix Tools

This section uses the colloquial term “*nix” because it covers more than POSIX.

AT&T make

Although I first encountered make on a BSD system, I really began development of makefile using an AT&T system (SVr2).

When building a program with many source-files, each produces an object file. That doubles the number of files in a directory and (providing motivation to work on a directory editor) makes it hard to see what files are present.

Reading the (paper) manual, I found a solution in the make program. By putting the object files in a library, it was possible to move them out of sight. Quoting from the manual's Libraries section:

The most common use of the archive interface follows. Here, we assume the source files are all C type source:

lib:    lib(filel.o) lib(file2.0) lib(file3.0)
        @echo lib is now up-to-date
.c.a:
        $(CC) -c $(CFLAGS) $<
        ar rv $@ $*.0
        rm -f $*.0

In fact, the .c.a rule listed above is built into make and is unnecessary in this example.

Later, at the SPC, I continued developing ded, using this feature in the makefiles for its library. The make manual for SunOS 4.1.3 (September 1989) documented it in the Library Maintenance section:

   Library Maintenance
       A target name  of the form:

              lib(member ...)

       refers  to a member, or a space-separated list of members, in an ar(1V)
       library.

       The dependency of the library member on the corresponding file must  be
       given  as  an explicit entry in the makefile.  This can be handled by a
       pattern matching rule of the form:

              lib(%.s): %.s

       where .s is the suffix of the member; this suffix is typically  .o  for
       object libraries.

       A target name of the form

              lib((symbol))

       refers  to  the  member  of a randomized object library (see ranlib(1))
       that defines the entry point named symbol.

I found that that the make program on most Unix systems provided this feature.

There was one exception: OSF/1's make program did not support it.

Since then, the feature has become part of the standard. POSIX describes it in similar terms:

If a target or prerequisite contains parentheses, it shall be treated as a member of an archive library. For the lib( member .o) expression lib refers to the name of the archive library and member .o to the member name. The application shall ensure that the member is an object file with the .o suffix. The modification time of the expression is the modification time for the member as kept in the archive library; see ar. The .a suffix shall refer to an archive library. The .s2.a rule shall be used to update a member in the library from a file with a suffix .s2.

Only obsolescent or non-standard implementations of make lack this feature.

BSD make

OSF/1 used the make program from 4.3BSD, along with several other utility programs and libraries, probably to reduce licensing costs. SunOS started from 4.2BSD (with the same make program), but continued developing it, as Sun worked with AT&T to develop SVr4 (i.e., Solaris).

Meanwhile, the other BSDs (4.4BSD, etc.), made improvements to the make program, but did not provide the library maintenance feature. As a developer of portable software, I am not really interested in the other changes because none of those are standardized.

The current (as of 2023) BSD make program is a continuation of 4.3BSD, based on work by Adam de Boor (1988-1989, 1993). Adam de Boor provided an overview in PMake — A Tutorial (1993).

Most developers read the manual page rather than tutorials. In NetBSD #40115: make(1) behaviour is inconsistent across parallel and ordinary builds, Christos Zoulas added a comment to the manual page:

+This
+.Nm
+implementation is based on Adam De Boor's pmake program which was written
+for Sprint at Berkeley.
+It was designed to be a parallel distributed make running jobs on different
+machines using a daemon called
+.Dq customs .

Adam de Boor's pmake program has been used outside of NetBSD:

The name “pmake” was also used by Rick Johnson, in the same era (1988 to 1993). In this case, it is derived from GNU make rather than BSD make. Johnson's program was used at LLNL during the 1990s. Its webpage, dated July 7, 2003, says

Currently, we recommend using GNU make's feature for parallel execution. GNU make can be found at /usr/local/bin/gmake on our IBM machines. Note that GNU make's parallel feature can only make use of the CPUs on a single node. Thus, an example make command for use on an eight CPU machine would be

gmake -j 8

While GNU make allows users to execute a parallel make on a single node, the pmake utility was designed to use MPI to coordinate a parallel make across multiple nodes.

Please note that although pmake (described below) is available for use, it is no longer supported by the Development Environment Group.

As of October 2023, none of the variations of Adam de Boor's pmake are known to support the POSIX library maintenance feature. Actually, some cosmetic work was done several years ago to allow it to support the syntax, but because the program does nothing with the timestamps nothing has changed. I use a configure script check to work around this problem, in CF_MAKE_AR_RULES.

The problem noted in NetBSD #40115 is harder to deal with, because it causes unpredictable behavior in makefiles. No configure script can reliably detect that. Any makefile rule which has more than one line in the action is subject to having those executed “in parallel” (and possibly changing their order). Very few makefiles are written with that in mind, but a few years ago, FreeBSD developers chose to turn parallel builds on in some of the ports for my programs. In this case, the workaround to force consecutive lines to be treated as a single line by adding backslashes at the end of lines was inadequate. I found that pmake would “parallelize” a commonly-used idiom, i.e., switching temporarily to a subdirectory to run a command. I changed those to run in a subprocess:

--- makefile.in 2020/09/09 00:22:49     1.290
+++ makefile.in 2021/02/22 08:56:41     1.291
@@ -20,7 +20,7 @@
 #
 # gnu autoconf support by kevin buettner, 5/94
 #
-# $Id: make-tools.html,v 1.134 2023/11/05 10:47:39 tom Exp $
+# $Id: make-tools.html,v 1.134 2023/11/05 10:47:39 tom Exp $
 
 SHELL          = @SHELL@
 
@@ -360,14 +360,14 @@
 @MAKE_FILTERS@install-full \
 @MAKE_FILTERS@uninstall-full \
 @MAKE_FILTERS@install :: $(BUILTHDRS)
-@MAKE_FILTERS@ cd filters && $(MAKE) $(MAKE_RECUR) $@
+@MAKE_FILTERS@ ( cd filters && $(MAKE) $(MAKE_RECUR) $@ )
 
 all :: $(ALL)
 
 sources : $(BUILTHDRS)
 
 filters/@LIB_PREFIX@vlflt.a : $(BUILTHDRS)
-       cd filters && $(MAKE) $(MAKE_RECUR) @LIB_PREFIX@vlflt.a
+       ( cd filters && $(MAKE) $(MAKE_RECUR) @LIB_PREFIX@vlflt.a )
 
 $(PROGRAM): $(BUILTHDRS) $(OBJ) $(OBJ2) $(BUILTLIBS)
        - $(SHELL) -c "if test -f $(PROGRAM); then mv $(PROGRAM) o$(PROGRAM); fi"
@@ -739,7 +739,7 @@
 mostlyclean \
 clean \
 distclean ::
-       - test -f filters/makefile && cd filters && $(MAKE) $(MAKE_RECUR) $@
+       - ( test -f filters/makefile && cd filters && $(MAKE) $(MAKE_RECUR) $@ )
 
 mostlyclean ::
        -@ $(RM) -rf *.dSYM

GNU make

In The GNU make Utility: Chapter 16 - Unix in a Nutshell Fourth Edition (O'Reilly, 2005), Arnold Robbins says

GNU make is the standard version for GNU/Linux and Mac OS X.

With Linux, that is easily verifiable. GNU make is required for building the Linux kernel, as noted in various places:

Likewise, it is assumed by developers in related builds, e.g., Linux build instructions – Oracle VM VirtualBox.

An old (no longer accessible as of 2023) copy of Apple's documentation confirmed Arnold's comment—for Xcode 5.0— but it is still possible to find GNU make on MacOS. If you have Xcode installed on a MacOS system, it is provided by the “gnumake” and “make” aliases of the tool-shim in the command-line tools package:

If Xcode is installed on your machine, then there is no need to install them. Xcode comes bundled with all your command-line tools. macOS 10.9 and later includes shims or wrapper executables. These shims, installed in /usr/bin, can map any tool included in /usr/bin to the corresponding one inside Xcode. xcrun is one of such shims, which allows you to find or run any tool inside Xcode from the command line. Use it to invoke any tool within Xcode from the command line as shown in Listing 1.

GNU make has been required for building gcc since version 3.4 (whose last update was in 2006).

This manpage (dated 1989) looks fairly close to the original make program. However it omits most discussion of the makefile syntax. This is not unusual—much vendor documentation suffers from the same deficiency. Over the years, GNU make's manual page has grown only slightly: most of the documentation is in “info” form such as this.

GNU make provides several extensions over the original program, such as conditionals. It also provides many built-in functions which can be used to eliminate the need for shell-scripting in the makefile rules as well as to manipulate the variables set and used in the makefile. For example, the documentation for the foreach function gives an example of setting a variable to the list of all files in a given directory.

Like all make programs with extensions, this makes GNU make incompatible with other implementations. For example, the built-in functions are executed directly by GNU make rather than by a shell, and the syntax is different. Early on, some common features such as

cd foo && make

were executed as built-in, transparently to the user.

Early in my exposure to GNU make, I had a makefile which did not work properly (i.e., as with Sun make). This was in the late 1990s, for my $dayjob, which used a suffix-rule which should have matched the source file, but GNU make chose its built-in rule for RCS over the rule given in the makefile. Reading the documentation, it turned out that this was intentional, a side-effect of the way % patterns were matched. Some changes use the same syntax, but (like the pmake “jobs” feature) some modify the behavior in unexpected ways.

Syntactic changes are not transparent. For example, Steven J. Hathaway (developer for Xalan-C) comments here on GNU make (the tool used for that project) versus BSD and Solaris:

GNU make is required to build the XALAN-C library on UNIX platforms.

The Makefile files use GNU specific macros for assignments. The BSD make
uses incompatible macro rules. The Solaris make probably uses similar
incompatible macro rules.

Incidentally, GNU make does not have built-in a feature for automatically determining dependencies (such as header files referenced by a given module). There are pros and cons and advice given, such as this page entitled Automatically generate makefile dependencies which mentions gcc, make and automake.

Non-*nix Tools

In contrast to dired, where I had a make program which I could (more or less) take for granted, on non-*nix systems the tools were less consistent and sometimes missing altogether.

MMS

The preface of the user manual for MMS says

This guide explains how to use the Module Management System for OpenVMS (MMS). The guide provides both tutorial and reference material to show basic and advanced techniques.

MMS is patterned after the UNIX make utility. For details, see Appendix B.

ACM SIGSOFT Software Engineering Notes Vol 10 No 5 Oct 1985 page 41, gives some background:

3.4. Other Events of the Era

At about the time that MAKE, SCCS and RCS were being used with UNIX, DEC developed a set of programs with similar capabilities (CMS/MMS}. MMS is similar to Make and added nothing significant to the technology. CMS is an enhanced version of SCCS. One of the nicest features was that version numbering and retrieval of files was part of the operating system. The fact that the manufacturer of the most popular UNIX hardware (DEC) had recognized the need for these tools in their VAX VMS operating system helped bless their use [DEC 82].

Like make (with built-in rules for SCCS) and GNU make (with built-in rules for RCS), MMS had built-in rules for CMS. This was considered a desirable feature, e.g., in PAGESWAPPER - March 1985 - Volume 6 Number 9, Using MMS for Day-to-day Development, Charles Connell wrote

I will assume that the reader is familiar with  MMS  in  general
and has used it to describe the linkage of executable images.  I
will also assume that MMS is being used in conjunction with  CMS
(DEC's  Code  Management System).  This combined usage is a good
idea because links that are complex enough to  warrant  building
under  MMS probably represent systems that are complex enough to
warrant control by CMS.  I should point out however that the two
MMS features I discuss can also be used without CMS.

but he went on to comment that it was slow:

MMS works very well for creating "official" release images.   It
never  fails  to  compile a source for which an include file has
changed, or to make sure every library has the  latest  copy  of
everything.   MMS  has a drawback however in that it can be very
tedious to use for day-to-day links.  If a programmer is linking
an  image 20 times in an afternoon to test an attempted bug fix,
MMS is prohibitively slow except with the smallest builds.

The usual solution to this problem is to link programs the  "old
way"  during  development  (i.e.   by using command procedures),
then to perform the final release build using MMS.

For porting a program, CMS is not very useful because the source archives reside on other machines. Availability of MMS is the deciding factor. However, as a licensed product, MMS was not universally available.

In 1992, Matthew Madison began writing a clone of MMS, called MMK (see DECUS source). MMS is distributed with a permissive license. As of 2023, it is still being maintained (see Github source).

For examples, see

wmake (Watcom)

The make program provided with the Watcom compiler was named wmake. It was developed by Sybase, which made it freely available in 2002. Since then, as Open Watcom, it has been used in a few niche environments such as UnixOS2 and eComStation.

For reference:

nmake (Microsoft)

According to Raymond Chen's blog, this is Microsoft's “new make” introduced in the late 1980s. The blog does not give a date, but the copyright/version message from nmake 1.20 cites 1988-1992.

EDM/2 relates this to the joint effort by IBM and Microsoft to produce OS/2:

A make like build management tool that comes with sundry IBM and Microsoft development tools for DOS, OS/2 and Microsoft Windows. It allows the user to define code dependencies and specify actions to resolve them.

While the NMAKE tool shares it conceptual origins with the UNIX derived make tools it should be noted that neither the NMAKE tools from IBM or the Microsoft equivalent are compatible with the UNIX versions. In a few respects differ quite a lot. With the later NMAKE versions such as used within the WorkFrame environment the tool is not intended to be scripted by hand, but rather the make files are generated automatically with the "build" tools, although that does not preclude you creating your own NMAKE scripts. With their later development tools IBM stopped using NMAKE in favour of more advanced source and dependency tools derived from their VisualAge Smalltalk environment.

Microsoft has continued to use NMake and updated it sporadically although it also offers alternative build tools. It has usually offered it as an optional download rather than have it installed with their development products, but it should be present in all modern Visual Studio releases under the xxx\VC}bin or xxx\VC\bin\AMD64 folders.

I used the tool in my $dayjob beginning mid-1994, in a project which built a mixture of 16-bit and 32-bit applications. For the latter, Watcom was used for its support of win32s. The documentation from that time period is very limited. Here are some relevant links:

Although Microsoft moved away from nmake, I continued using it, because their approach to IDEs was bulky, inflexible — and for several years the corresponding project files contained a multitude of embedded pathnames which made it awkward to move a project to a different directory.

vcbuild

VCBuild appeared in Visual Studio.

In 2005, my $dayjob entailed getting several applications using Visual Studio 2003 to build automatically, e.g., using scripting. Most of the applications were written in C++. I found that I could run Visual Studio from the command line. The Visual Studio 2005 C++ reference says

Building on the Command Line

Visual C++ provides command-line tools for programmers who prefer to build their applications from the command prompt. If you want to use the command line to build a project created in Visual C++, you can use one of the following:

When you build from the command line, you can get help on warnings, errors, and messages by starting the development environment and clicking either Index or Search on the Help menu.

That is, I had a choice. The simplest (nmake) was not valid because the other developers had project- and solution-files which were needed. Both devenv and vcbuild can be run in a batch file, with suitable options for selecting the configuration to be built, and the operation to perform, e.g., /build, /clean. The devenv executable acts as a front end to several build tools:

Visual Studio Commands and Switches

Visual Studio commands allow direct interaction with the integrated development environment (IDE) from the keyboard. Many dialog boxes, windows, and menu commands within the IDE have a command-line equivalent that you can type into the Command Window, the Immediate Window, or the Find/Command Box to display a dialog box or execute a command.

Visual Studio commands follow certain general syntax rules that are explained below. The set of available commands includes all commands listed in the Keyboard, Environment, Options Dialog Box and on the Commands Tab, Customize Dialog Box (Visual Studio), as well as user-defined aliases and macros.

Building from the Command Line

For information on building projects in Visual Studio programming languages from the command line, see Building from the Command Line (Visual Basic), Command-Line Building (Visual C#), VCBUILD Options (Visual C++), and Building from the Command Line. For information on configuring an MSBuild XML schema file to build projects, see the MSBuild Reference.

The configuration information was stored in the project files. If all of the applications had been written in C++, I might have used vcbuild directly, but one used Visual Basic 6. For consistency, I used devenv.

In my own projects such as Lynx, I used Visual Studio Express. Jason Turner's page notes that while devenv was not provided in the express versions, vcbuild was:

If you search around for how to build Visual Studio projects from the command line you will find references to the DevEnv executable. When working with Visual C++ Express, however, that tool does not exist.

An equivalent tool, vcbuild, does exist and can be used.

Start by opening the Visual Studio command prompt (Program Files->Microsoft Visual C++ 2008 Express Edition->Visual Studio Tools->Visual Studio 2008 Command Prompt).

Typing “vcbuild” gives you the command line help:

However, doing that ties the program to the IDE. I chose to just use nmake to eliminate that dependency.

msbuild

Initially, MSBuild did not support C++ projects. Noel Llopis's 2005 page on build systems said:

MSBuild, the Ant clone that Microsoft has been hailing as the next great thing to come, doesn't yet support C++ builds. It's a matter of priorities, I suppose. In the meanwhile, MSBuild will use the standalone VCBuild tool to compile Visual Studio solutions.

VCBuild was superceded by MSBuild with Visual Studio 2010:

Visual Studio C++ projects and MSBuild

Visual Studio C++ projects are now based on the MSBuild tool. Consequently, project files use a new XML file format and a .vcxproj file suffix. Visual Studio 2010 automatically converts project files from earlier versions of Visual Studio to the new file format. An existing project is affected if it depends on the previous build tool, VCBUILD.exe, or project file suffix, .vcproj.

The resulting configuration was more complex, as outlined in VCBuild vs. MSBuild: Build system changes in Visual Studio 2010:

In Visual Studio 2008 and earlier, a rule file is an XML-based file that has a .rules file name extension. A rule file lets you define custom build rules and incorporate them into the build process of a Visual Studio C++ project. A custom build rule, which can be associated with one or more file name extensions, lets you pass input files to a tool that creates one or more output files.

In the MSBuild system, custom build rules are represented by three file types, .xml, .props, and .targets, instead of a .rules file. When a .rules file that was created by using an earlier release of Visual C++ is migrated to Visual Studio 2010, equivalent .xml, .props, and .targets files are created and stored in your project together with the original .rules file.

MSBuild is nearly as old as VCBuild, having begun with the .NET environments. The documentation for Visual Studio 2005 (retired...) presented MSBuild:

Microsoft Build Engine

The Microsoft Build Engine (MSBuild) is the new build platform for Microsoft and Visual Studio. MSBuild introduces a new XML-based project file format that is simple to understand, easy to extend, and fully supported by Microsoft. The MSBuild project file format enables developers to fully describe what items need to be built as well as how they need to be built with different platforms and configurations. In addition, the project file format enables developers to author re-usable rules that can be factored into separate files so that builds can be done consistently across different projects within their product. The MSBuild build process is defined by atomic units of build, called tasks. You can author your own tasks in any .NET language in order to extend the build process. Visual Studio projects are now stored in the MSBuild project file format, providing the ability to customize the Visual Studio build process. MSBuild is completely transparent with regards to how it processes and builds software, enabling developers to build projects on computers without Visual Studio. For more information, see MSBuild.

MSBuild continued to provide for running vcbuild.exe, but Visual Studio uses different project-files, for better integration with MSBuild. Either way, Visual Studio used XML for the project files, but the newer versions changed the character set from Windows 1252 to UTF-8, and (of course) changed the tag names.

Simon Horrell's article on developerFusion Customising your build process with MSBuild notes:

The MSBuild engine and its project file format are loosely based on Ant, the build engine of choice in the Java world. Finally, Visual Studio 2005 uses the MSBuild project file format for its project files, so MSBuild is much better integrated with the IDE.

...

It turns out that Visual Studio 2005 project files are just MSBuild project files. They actually import the MSBuild common target files, which essentially define the Visual Studio build process for these projects.

Here are a few examples of project files from Lynx which I used in setting up a debugging environment:

Portable Tools

MMS, wmake, nmake are variations of portable tools. MSBuild (cited as an ant clone) is used only on the Windows platform, and is not regarded as portable.

ant

Apache ant is a Java library that provides an interpreter for a list of tasks in an XML file.

Portability is relative. Some people suppose that Java is portable because a jar-file can be run (interpreted) on any platform where the Java runtime is available, and in turn that makes an ant build.xml more portable than a makefile.

There is a lot to disagree in that statement. For amusement, read Ant vs Make.

The nice features of make are that

In contrast, ant has only non-file “tasks” i.e., targets for which the production rules must be constructed. Like make, the developer has to do the analysis to construct the build.xml file. An IDE can do dependency analysis to help decide if some tasks are unnecessary, but that analysis is specialized, and as a result ant is useful as a means of extending the IDE.

Successors to ant such as maven and gradle address some aspects of ant's limitations.

automake

XXX who, what when

   803 /usr/bin/autoconf-dickey
   368 /usr/bin/autoheader-dickey
   418 /usr/bin/autoreconf-dickey
   659 /usr/bin/autoscan-dickey
  1135 /usr/bin/autoupdate-dickey
   134 /usr/bin/ifnames-dickey
  3517 total

  1673 /usr/share/autoconf-dickey/autoconf/acfunctions.m4
  4743 /usr/share/autoconf-dickey/autoconf/acgeneral.m4
   456 /usr/share/autoconf-dickey/autoconf/acheaders.m4
  2190 /usr/share/autoconf-dickey/autoconf/aclang.m4
    86 /usr/share/autoconf-dickey/autoconf/acoldnames.m4
  1112 /usr/share/autoconf-dickey/autoconf/acspecific.m4
   562 /usr/share/autoconf-dickey/autoconf/actypes.m4
     7 /usr/share/autoconf-dickey/autoconf/acversion.m4
    67 /usr/share/autoconf-dickey/autoconf/autoconf.m4
   731 /usr/share/autoconf-dickey/autoconf/m4sh.m4
  1740 /usr/share/autoconf-dickey/autoconf/m4sugar.m4
 13367 total

total: 16884

autoconf2.69
   505 /usr/bin/autoconf2.69	shell (others are all perl)
   303 /usr/bin/autoheader2.69
  1088 /usr/bin/autom4te2.69
   719 /usr/bin/autoreconf2.69
   678 /usr/bin/autoscan2.69
  1063 /usr/bin/autoupdate2.69
   153 /usr/bin/ifnames2.69
  4509 total

  254 /usr/share/autoconf2.69/Autom4te/C4che.pm
  390 /usr/share/autoconf2.69/Autom4te/ChannelDefs.pm
  836 /usr/share/autoconf2.69/Autom4te/Channels.pm
  127 /usr/share/autoconf2.69/Autom4te/Configure_ac.pm
  452 /usr/share/autoconf2.69/Autom4te/FileUtils.pm
  426 /usr/share/autoconf2.69/Autom4te/General.pm
  115 /usr/share/autoconf2.69/Autom4te/Getopt.pm
  114 /usr/share/autoconf2.69/Autom4te/Request.pm
  319 /usr/share/autoconf2.69/Autom4te/XFile.pm
 3033 total

   105 /usr/share/autoconf2.69/autoconf/autoconf.m4
    78 /usr/share/autoconf2.69/autoconf/autoheader.m4
    50 /usr/share/autoconf2.69/autoconf/autoscan.m4
    77 /usr/share/autoconf2.69/autoconf/autotest.m4
   108 /usr/share/autoconf2.69/autoconf/autoupdate.m4
  2031 /usr/share/autoconf2.69/autoconf/c.m4
   320 /usr/share/autoconf2.69/autoconf/erlang.m4
  1862 /usr/share/autoconf2.69/autoconf/fortran.m4
  2032 /usr/share/autoconf2.69/autoconf/functions.m4
  3081 /usr/share/autoconf2.69/autoconf/general.m4
   177 /usr/share/autoconf2.69/autoconf/go.m4
   895 /usr/share/autoconf2.69/autoconf/headers.m4
   721 /usr/share/autoconf2.69/autoconf/lang.m4
   478 /usr/share/autoconf2.69/autoconf/libs.m4
    92 /usr/share/autoconf2.69/autoconf/oldnames.m4
   902 /usr/share/autoconf2.69/autoconf/programs.m4
   481 /usr/share/autoconf2.69/autoconf/specific.m4
  1782 /usr/share/autoconf2.69/autoconf/status.m4
  1077 /usr/share/autoconf2.69/autoconf/types.m4
 16349 total

   362 /usr/share/autoconf2.69/m4sugar/foreach.m4
  2168 /usr/share/autoconf2.69/m4sugar/m4sh.m4
  3301 /usr/share/autoconf2.69/m4sugar/m4sugar.m4
    12 /usr/share/autoconf2.69/m4sugar/version.m4
  5843 total

   26 /usr/share/autoconf2.69/autotest/autotest.m4
 2215 /usr/share/autoconf2.69/autotest/general.m4
   74 /usr/share/autoconf2.69/autotest/specific.m4
 2315 total

total: 32049

automake-1.16        
	8468 /usr/bin/automake-1.16        
	1217 /usr/bin/aclocal-1.16
	1882 /usr/share/aclocal-1.16
	7983 /usr/share/automake-1.16/Automake/* 
	4427 /usr/share/automake-1.16/am/*
total: 23977

total: 56026 automake + autoconf, is 3.3 times as large as autoconf-252

XXX encroachment on autoconf's namespace
XXX size of script relative to gmake

XXX mine info from FreeBSD ports or NetBSD pkgsrc to show who uses it.

pkgsrc 2024/02/24
	19587 packages 
	3253 use GNU_CONFIGURE
	496 use autoreconf
	309 use automake|autoreconf via USE_TOOLS

macports
	19102 portfiles
	3488 set configure.args
	558 use "autoreconf." or "autogen."

freebsd
	32584 ports
	4284 use GNU_CONFIGURE
	1013 use autoreconf
	2875 use cmake
	576 use meson
	494 use ncurses
	176 use imake
	68 use autogen.sh

dmake

XXX .include vs include - http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa600%2Fbpxza680111.htm
XXX targets-including-other-makefiles

The most well-known program called “dmake” was written by Dennis Vadura (computer science department, University of Waterloo) in 1989 or 1990.

The "readme" with dmake 3.6 (October 8, 1990) states:

This is the DMAKE version 3.6 distribution.  DMAKE is a Make like tool that
has been written by me and has been used by individuals at the University of
Waterloo for about a year and a half now.  This release replaces the previous
version 3.5 release which is no longer supported.  Please read the file
'readme/release' which accompanies this distribution and describes details
of this release (This note is found in readme/cover).

In the version 3.6 manual page (formatted to 44 pages), Vadura commented on similarities and differences from other versions of make:

COMPATIBILITY
     There are two notable differences between dmake and the
     standard version of BSD UNIX 4.2/4.3 Make.

          1. BSD UNIX 4.2/4.3 Make supports wild card filename
             expansion for prerequisite names.  Thus if a direc-
             tory contains a.h, b.h and c.h, then a line like

                  target: *.h

             will cause UNIX make to expand the *.h into "a.h b.h
             c.h".  dmake does not support this type of filename
             expansion.

          2. Unlike UNIX make, touching a library member causes
             dmake to search the library for the member name and
             to update the library time stamp.  This is only
             implemented in the UNIX version.  MSDOS and other
             versions may not have librarians that keep file time
             stamps, as a result dmake touches the library file
             itself, and prints a warning.

     dmake is not compatible with GNU Make.  In particular it
     does not understand GNU Make's macro expansions that query
     the file system.

     dmake is fully compatible with SYSV AUGMAKE, and supports
     the following AUGMAKE features:

          1. The word include appearing at the start of a line
             can be used instead of the ".INCLUDE :" construct
             understood by dmake.

          2. The macro modifier expression $(macro:str=sub) is
             understood and is equivalent to the expression
             $(macro:s/str/sub), with the restriction that str
             must match the following regular expression:

                  str[ |\t][ |\t]*

             (ie. str only matches at the end of a token where
             str is a suffix and is terminated by a space, a tab,
             or end of line)

          3. The macro % is defined to be $@ (ie. $% expands to
             the same value as $@).

          4. The AUGMAKE notion of libraries is handled
             correctly.

          5. When defining special targets for the inference
             rules and the AUGMAKE special target handling is
             enabled then the special target .X is equivalent to
             the %-rule "% : %.X".

          6. Makefiles that utilize virtual targets to force mak-
             ing of other targets work as expected if AUGMAKE
             special target handling is enabled.  For example:

                  FRC:
                  myprog.o : myprog.c $(FRC) ; ...

             Works as expected if you issue the command

                  'dmake -A FRC=FRC'

             but fails with a 'don't know how to make FRC' error
             message if you do not specify AUGMAKE special target
             handling via the -A flag (or by setting AUGMAKE:=yes
             internally).

Like GNU make (and reportedly nmake, according to this email thread) like gnu make, dmake provides parallelism on a single machine.

Makefiles written for dmake rely on its extensive set of special targets (referred to as "attributes"), and conditionals.

Here are the principal releases and comments on ports ordered by date:

Other uses and mentions include:

cmake

XXX needed for what?  (ImageMagick)

gnatmake

XXX rare instance of compiler-integrated make tool (contrast with Verdix Ada)
XXX first encountered in ncurses gnat 3.15 September/October 1996
XXX http://goanna.cs.rmit.edu.au/~dale/ada/gnat_docs/gnat_ug.html
XXX http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/DDJ/1997/9712/9712j/9712j.htm

gprbuild

  XXX https://github.com/AdaCore/gprbuild
  

imake

XXX preprocessor, like automake
XXX relate to jhbuild

jam

XXX ?
        Jam: make(1) redux
        Christopher Seiwald
        INGRES Corporation
        April 1994
        UNIX'94: Proceedings of the USENIX Applications Development Symposium Proceedings on USENIX Applications Development Symposium Proceedings
XXX http://dl.acm.org/citation.cfm?id=1267402
XXX http://dl.acm.org/author_page.cfm?id=81410595362&coll=DL&dl=ACM&trk=0&cfid=353441612&cftoken=20775776
XXX used for what (Boost)
XXX http://www.boost.org/doc/libs/1_31_0/tools/build/jam_src/index.html
XXX http://opendylan.org/documentation/hacker-guide/build-system.html
XXX http://www.informatik.uni-trier.de/~ley/pers/hd/s/Seiwald:Christopher
XXX https://www.haiku-os.org/guides/building/jam
XXX https://opensource.apple.com/source/jam/jam-294/Jambase
XXX http://www.mathematik.uni-ulm.de/help/boost/jam.html

qmake

XXX used for Qt

Other Tools

XXX

debbuild

XXX

dmake (Sun)

-- SunOS dmake uses Rogue Wave Software from 1996
-- Boost vs RWS?

Sun (now Oracle) also has a program named “dmake”. It is not the first so-named (see note), nor the best-known. It is a component of the add-on developer's tools.

Almost all of the discussion of dmake is part of vendor documentation.

Neither list provides links to the actual documentation. Some of that is accessible online. Bear in mind that most of the documentation for dmake is the same 20-25 page manual page:

Date Product Component html pdf
2012 Solaris Studio 12.3 Distributed Make (dmake)
2010 Sun Studio 12 Distributed Make (dmake) HTML PDF
2005 Sun Studio 11 Documentation Distributed Make (dmake) HTML PDF
2005 Sun Studio 10 Documentation Distributed Make (dmake) HTML PDF
2004 Sun Studio 9 Collection Distributed Make (dmake) HTML PDF
2004 Sun Studio 8 Collection Distributed Make (dmake) HTML PDF
1999 Using Sun WorkShop Appendix C Using the dmake Utility
1999 Sun WorkShop TeamWare 2.1 User's Guide Chapter 18 Using the dmake Utility
1996 Oracle Product Library Documentation Sun WorkShop TeamWare: User's Guide PDF

Release notes and news letters give a history:

Before dmake, Sun provided MakeTool:

DSEE (Apollo)

XXX
XXX http://www.google.com/patents/US4809170
http://techpubs.sgi.com/library/dynaweb_docs/0530/SGI_EndUser/books/ClrC_UG/sgi_html/ch17.html

nmake (AT&T)

There are several papers by Glenn Fowler, but little commentary from users:

rpmbuild

XXX

smake

XXX
XXX http://www.inovia.com/products/directory/trademarks-number-74296325/sunpro-trademark-owned-by-sun-microsystems-inc
XXX http://www.trademarkia.com/sunpro-74296325.html
XXX http://www.tmquest.com/results.asp?maxFiles=10&sort=1&adv=1&owner=Sun+Microsystems%2C+Inc.&nPage=14
XXX sunpro (trademark - http://www.sunpro.com/index.php)
XXX http://ftp.lanet.lv/ftp/sun-info/sunflash/1991/Sep/33.21.sunpro
XXX http://www.linuxmisc.com/3-solaris/a907cb8af601af35.htm
XXX www.std.com/obi/SUG/Conf.Papers/92/you_and_your_compiler_handout.ps.Z
XXX ftp://ftp.ntplx.net/pub/sun-faq/Docs/SUN-papers/
XXX https://groups.google.com/forum/#!search/sunpro$20make$20sunos3|sort:relevance|spell:false/comp.sys.pyramid/qrXTP2r-gKs/m8sMFhAVRfYJ
XXX http://dlc.sun.com/osol/devpro/downloads/20081119/
XXX https://www.mail-archive.com/discuss@lists.illumos.org/msg00248.html
XXX http://lwn.net/Articles/514046/
XXX Schily claims about "SunPro make"
SunOS 3.2
http://gunkies.org/wiki/SunOS
claims it was September 1986; Schily says "summer 1986"
* point this out in rebuttal

Schily would have a better reputation if he wrote <anonymously>.
* Schily asserts that SunOS 3.2 manpages are "archived". Where's the archive?
* there are no sources to corroborate most of what he says, and some statements contradict existing sources and my own experience

Term "Pattern rules" in gmake vs topic "Pattern matching rules" in Sun/etc

In sun-dmake, note of manpage for "make" that it does not mention "dmake", but has this
.PARALLEL:
Currently of no effect, but reserved for future use.
Also note that dmake is built using an old (1996) version of Rogue Wave Software (C++ - find web-url describing the product)
-- "Pattern replacement macro references cannot be used in the dependency list of a pattern matching rule."
-- Notice that only one `%' can appear in a target, dependency-name, or pattern-replacement macro reference.
---- compare with gmake

XXX dates in manpages are a comment.  For instance, the SunOS 4.1.3 make manpage begins
'\" t
.\".ds ~ ~
.\" @(#)make.1 1.57 90/02/15 SMI; from UCB 4.3 BSD
.TH MAKE 1 "15 September 1989"
.SH NAME
make \- maintain, update, and regenerate related programs and files
--- it asserts a given date, but the filedate is July 23, 1992
XXX Schily claims about gmake
XXX SunPro make

My involvement

XXX comment on nmake role for automatically determining dependencies taken over in Visual Studio 5
XXX generally use gmake when I want archive-rule and don't have it
XXX note OSF1 as first to be a problem with archive-rule, and BSD progress (FreeBSD first, NetBSD lagging)
XXX in POSIX http://pubs.opengroup.org/onlinepubs/009695399/utilities/make.html
XXX see if I can identify gmake breakage in suffix rule ~1999
XXX section on includes
XXX section on dependency generation
XXX hmm http://git.savannah.gnu.org/cgit/make.git/commit/?id=2153102725b08205a6e186824bb6c0c50062de1b
    says "Changed `Features' chapter, giving credit to some" (Roland McGrath)
XXX does Schily give attribution to anyone?

I first used “make” in 1983 at ITT to build and modify dired. I used that program to explore the BSD system. The system administrator had a copy of all of the sources under his home directory, including the curses source code. That was several months after this announcement:

Newsgroups: net.sources
Path: utzoo!decvax!genrad!linus!allegra!eagle!harpo!utah-cs!lepreau
X-Path: utzoo!decvax!genrad!linus!allegra!eagle!harpo!utah-cs!lepreau
From: utah-cs!lepreau
Date: Sat May 14 02:22:20 1983
Subject: New Curses from Berkeley
Posted: Thu May 12 00:17:29 1983
Received: Sat May 14 02:22:20 1983

Relay-Version:version B 3/9/83; site harpo.UUCP
Message-ID:<1582@utah-cs.UUCP>
Date:Thu, 12-May-83 00:17:29 EDT

Apparently Ken Arnold's posting of the new curses didn't make it to much
of the net, including here, so he has asked me to post it from here to
avoid possible problems at the Berkeley end of Usenet.  He expresses his
apologies to those of you who get this twice.

Note: this is in Berkeley archive format, and needs only this leading
garbage removed, not any trailing \n's.

which began with a makefile:

Makefile        421036356   162   10    100644  2419      `
#
# cursor package maker
#
# %W% (Berkeley) %G%
#
HEADERS=curses.h unctrl.h curses.ext
CFILES= box.c clear.c initscr.c endwin.c mvprintw.c mvscanw.c mvwin.c \
        newwin.c overlay.c overwrite.c printw.c scanw.c refresh.c \
        touchwin.c erase.c clrtobot.c clrtoeol.c cr_put.c cr_tty.c \
        longname.c delwin.c insertln.c deleteln.c scroll.c getstr.c \
        getch.c addstr.c addch.c move.c curses.c unctrl.c standout.c \
        tstp.c insch.c delch.c
 
OBJS=   box.o clear.o initscr.o endwin.o mvprintw.o mvscanw.o mvwin.o \
        newwin.o overlay.o overwrite.o printw.o scanw.o refresh.o \
        touchwin.o erase.o clrtobot.o clrtoeol.o cr_put.o cr_tty.o \
        longname.o delwin.o insertln.o deleteln.o scroll.o getstr.o \
        getch.o addstr.o addch.o move.o curses.o unctrl.o standout.o \
        tstp.o insch.o delch.o
 
POBJS=  box.p clear.p initscr.p endwin.p mvprintw.p mvscanw.p mvwin.p \
        newwin.p overlay.p overwrite.p printw.p scanw.p refresh.p \
        touchwin.p erase.p clrtobot.p clrtoeol.p cr_put.p cr_tty.p \
        longname.p delwin.p insertln.p deleteln.p scroll.p getstr.p \
        getch.p addstr.p addch.p move.p curses.p unctrl.p standout.p \
        tstp.p insch.p delch.p
 
 
CTAGS=  ctags
CC=     cc
LINT=   lint
LPASS1= /usr/lib/lint/lint1
AR=     ar
RM=     rm
LN=     ln
CFL=
CFLAGS= -O ${CFL}
LDFLAGS=-n
.SUFFIXES: .p
 
.c.p:
        rm -f x.c
        ln $*.c x.c
        ${CC} ${CFLAGS} -p -c x.c
        mv x.o $*.p
 
.DEFAULT:
        sccs get $@
 
libcurses${HEADERS} crlib
 
crlib${OBJS}
        ${AR} rv crlib $?
        ranlib crlib
 
pcrlib${POBJS}
        rm -f x.c
        ${AR} rv pcrlib $?
        ranlib pcrlib
 
test:   crlib test.o
        ${CC} ${LDFLAGS} ${CFLAGS} -o test test.o -lcurses -ltermlib
 
cat.o:  curses.h
        ${CC} -c ${CFLAGS} cat.c
 
new:    cleanup ctags
        ${CC} -c ${CFLAGS} ${CFILES}
        ${AR} qv crlib ${OBJS}
        ${RM} /ya/staff/arnold/=eye/crlib /ya/staff/arnold/=hacks/crlib \
              /ya/staff/arnold/=eye/curses.h /ya/staff/arnold/=hacks/curses.h
 
clean:
        rm ${OBJS} crlib
 
ctags:
        ${CTAGS} ${CFILES} curses.h
 
lint:
        ${LINT} -hxb ${CFL} ${CFILES} -lcurses > lint.out
 
lpr:
        -pr curses.h ${CFILES} | lpr
        -lpq
 
tp:
        tp crm0 Makefile tags ${HEADERS} ${CFILES} llib-lcurses
 
tar:
        tar crvf curses.tar Makefile tags ${HEADERS} ${CFILES} llib-lcurses
 
ar:
        ar crv curses.ar Makefile tags ${HEADERS} ${CFILES} llib-lcurses
 
llib-lcurses.ln: llib-lcurses
        -(/lib/cpp -C -Dlint llib-lcurses | ${LPASS1} > llib-lcurses.ln ) 2>&1 | grep -v warning
 
install:
        install -c crlib ${DESTDIR}/usr/lib/libcurses.a
        ranlib ${DESTDIR}/usr/lib/libcurses.a

A little later, I wrote a font editor, which “of course” needed a makefile. Makefiles were simpler then. For context (while at ITT/ATC):

Later, in 1985 I moved to a project using SVr2 workstations (along with an assortment of machines used for porting the application). At the outset I took over a set of programs with about 50 makefiles, which grew to about 150. As noted, the original set of programs was written by hackers. Among other efficiences which they devised:

I fixed those issues, and got involved with SCCS. That project lasted for a couple of years. Along the way (we had printed manuals), I noticed and incorporated into my makefiles the "archive rule" which was supported by the AT&T make, but not the older versions. Briefly, that refers to makefile targets which refer to object files stored within archives. The make program works with the timestamps of the files within the archive rather than the archive file's timestamp. Using this feature, it is possible to write suffix rules which

See this page for an example.

Moving on to the Software Productivity Consortium in late 1987, the environment was more diverse: we had a mixture of Sun3's, Sun4's and Apollo workstations. Additionally, there were a few large machines including Gould and VAX/VMS systems. With respect to makefiles, this was relatively unevenful, except for the VAX/VMS system:

During the same time at the Software Productivity Consortium, I was doing other types of development, mainly with Apollo and SunOS workstations. For example:

In the background (not my main task), I did tool development. Part of that was improvements to ded and the related cm_tools (RCS and SCCS). Apollo SR10 supported three runtime environments: native Apollo, as well as two "real Unix": System V, and BSD 4.3. I found that the System V environment (which was less used) could handle the makefiles which I had written for ded. The BSD environment could not, but most of the applications from the comp.sources.* newsgroups were written for BSD. This announcement for ncurses 1.8.5 which appears to incorporate the relevant information about Apollo which I sent in a bug report a month or so earlier agrees with that.

During the same period (late 1980s to early 1990s), the Software Productivity Consortium had a license for DSEE, and I spent some time studying it (and modifying ded to work with its versioned filesystem). As it happened, I could only study DSEE since managing it took administrator's rights which our organization limited to the group which maintained the network. None of them were developers.

A little later (1992-1993), as I started collecting and improving tools, I investigated dmake and jam (as well as cook) as possibly better ways to do builds. Cook fell by the wayside over the years (and appears to be little used), but dmake and jam are still with us.

After I left the Software Productivity Consortium, I continued collecting tools to support my projects. Initially (1994-1998), those were multiplatform, using diverse sets of development tools (and different make programs), e.g., for paid work:

For my own projects, I encountered the same variety (and more). My preference was to work with the native tools rather than dragging in a copy of some “portable” make. But as noted, not all Unix system's make supported archive rules. The first that I noticed was OSF/1 (later known as Tru64). Later, I would find on the Unix-alikes (the BSDs) this feature absent. These two cases have correspondingly different explanations:

My own projects were done on my machines—or on machines (such as the OSF/1 system) where I was a guest developer. For the former, I could install GNU make. For the latter, since I built ded only a few times (getting the port working properly), I could work around the missing functionality on the command-line. From my point of view however, archive rules were a solved problem for several years, and make programs lacking them were a little obsolete.

In other programs, I made more accommodations to achieve portability. Starting with vile in 1994, I began converting my programs to use autoconf. Not all of these projects used simple/portable makefiles

XXX note some issues: FreeBSD make after a while implemented archive-rule. XXX otoh, NetBSD pruned out portability aids citing "POSIX" - discuss.

Toward the end of the 1990s, I started working in Java. For command-line builds, we used ant. In terms of functionality, that was a step backwards, to something like the scripts which I wrote for VMS in the 1980s, because timestamps were no longer important.

Other tools used XXX:

Recap of systems without archive rule (and still requiring use of gmake for ded) XXX:

Notes

XXX http://bioinfo.mbb.yale.edu/fom/cache/37.html
XXX http://www.megalextoria.com/usenet-archive/news060f1/b80/comp/os/misc/00000291.html

augmake

augmake
XXX that comment about augmake "special inference rules" vs "%" shows it predates SunPro make (see doi=10.1.45.1573)
XXX https://archive.org/details/bitsavers_unisoftuniupportToolsGuide1984_9198554
XXX (see comp.sources.unix volume 19, issue 44 for "shape", which includes paper mentioning augmake)
XXX augmake 1989 - http://dl.acm.org/citation.cfm?id=64137.64142
XXX augmake 1988 - http://www.tenox.net/docs/microport_sysv286_development_system_vol1.pdf
XXX augmake 1988 - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.55.6969
XXX augmake 1983 - http://citeseerx.ist.psu.edu/showciting;jsessionid=140A5520166311895A34CC21E8260779?cid=7884707
http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa600%2Fbpxza680111.htm
http://pic.dhe.ibm.com/infocenter/zvm/v6r2/index.jsp?topic=%2Fcom.ibm.zvm.v620.dmsp4%2Fhcsp4c00114.htm
http://www.linuxmisc.com/9-unix-programmer/42358c81216740bf.htm
http://www.decuslib.com/DECUS/freewarev40/mesa/startup.mk

dmake

Finding information about dmake requires multiple keywords in a search to get good results, as shown in a naive approach.

Dennis Vadura's dmake program is the most well-known. Sun's dmake (introduced in the late 1990s) comes in as a distant second, competing for one's attention with

nmake

Generally, “nmake” refers to the Microsoft implementation, with about 90% of the Google hits.

After that, there are references to the IBM version of nmake, e.g., beginning with OS/2. For example:

Finally, the AT&T (Glen Fowler) program accounts for much of the remainder.

pmake

pmake
-- I recall being told about this, and/or reading in mailing list/newsgroup
XXX reviewing email, "parallel make" shows up in XFree86 during 1997
XFree86 3.2Ah (23 February 1997)
 483. Gnu parallel make update for loadable server (#64, H.J. Lu).
https://software.intel.com/sites/default/files/article/373040/ipt-tech-wp-final-11-30-2012.pdf
ftp://ftp.cs.cmu.edu/usr/ai/pubs/timeline/parallel.tex
http://legacy.earlham.edu/~peters/fos/2003_07_13_fosblogarchive.html
http://www.bswd.com/AMW-35thWorkshopBooklet-DoubleSidedVersion.pdf
-- The Scholarly Publishing & Academic Resources Coalition
http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=ACE5170BE3A7DACFBB88F2018417E342?doi=10.1.1.31.1926&rep=rep1&type=pdf

Adam de Boor?
http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/make/make.1 (here)
http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Tahoe/usr/src/bin/make (not here) \
http://minnie.tuhs.org/cgi-bin/utree.pl?file=Net2/usr/src/usr.bin/make/make.1 (not here)
http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/src/usr.bin/make/make.1 (not here)
http://minnie.tuhs.org/cgi-bin/utree.pl?file=Ultrix-3.1/src/cmd/make (not here)

XXX Tie slang together with dmake/smake
XXX mention my attempt to provide glibc module vs one-big-makefile (45 minutes)
XXX relate that (glibc module) to automake: there never was side-by-side comparison

perhaps useful
https://unix.stackexchange.com/questions/144424/restricting-gnu-make-to-posix-make-behaviour
-- deleted post recommended using bmake, but iirc it didn't honor library rule
https://stackoverflow.com/questions/2278151/how-similar-different-are-gnu-make-microsoft-nmake-and-posix-standard-make
http://nmake.alcatel-lucent.com/faq/gmake.html

From: William Parsons <gyliamos@gmail.com>
To: freebsd-questions@freebsd.org
Subject: old Makefile for building library no longer works
Date: Sun, 21 Oct 2018 17:52:33 -0400
-- noticed that it doesn't work

aminet.net/package/dev/misc/dvmake-3.8p4

notes from td_lib:
        180108 port to NetBSD 7.1 reminded me of NetBSD "POSIX" make.  fwiw, it
        doesn't recognize .SCCS_GET (XSI...), but I ran into no useful setting
        for ARFLAGS (it was empty, causing "ar" to spit out a usage message).

20210503
        do not forget this gem from GNU ar (get date/developer):
       D   Operate in deterministic mode.  When adding files and the archive
           index use zero for UIDs, GIDs, timestamps, and use consistent file
           modes for all files.  When this option is used, if ar is used with
           identical options and identical input files, multiple runs will
           create identical output files regardless of the input files'
           owners, groups, file modes, or modification times.

           If binutils was configured with --enable-deterministic-archives,
           then this mode is on by default.  It can be disabled with the U
           modifier, below.

           '(that would break building ded, just like the BSD bmake)