Copyright © 2019-2020,2021 by Thomas E. Dickey



Here is a brief history of my early use of autoconf, and how this collection of macros grew.


Sometime (probably spring) in 1994, Kevin Buettner mentioned the existence of autoconf, to me and Paul Fox. I do not have that mail; but I have RCS archives:

This was before autoconf 2.0 (that occurred in October, and was immediately followed by 2.1 in November). The value of AC_ACVERSION in acgeneral.m4 gives a clue, but since it was not updated on a regular basis during development, I cannot simply call that “1.90

That early autoconf documented what files were needed, mentioning that one could use its autoheader script to generate, but Kevin found that to be unreliable. At the same time, building up the file was error-prone and tedious. Instead, he pointed out that the definitions were all in config.status, which could be transformed into the file. I used that feature in td_lib, after seeing his changes for vile::

1994-06-25  Thomas E. Dickey  <>

        * add/use TD_HAVE_FUNCS

        * aclocal.m4: add/use TD_HAVE_FUNCS (bug?)

        * Makefile: got rid of acconfig.h, simplified rules a bit

        * RCS_BASE

        borrowed code from vile 4.5 (kev buettner) for generating config.h
        without needing my own aclocal.h


If you read through that "borrowed code" change, you might see a few features:

In short, from the outset I used the autoconf script to not only check for the availability of features, but also to discover how to improve the type-checking done by the compiler.


Initially (before creating the my-autoconf archive in September 1997), the macros were in each program, copied as needed from one to another. That led to problems with naming convention. At first, we used AC_ as a prefix, but soon realized that might lead to problems with newer versions of autoconf. To resolve that,

However, that presented a problem in reuse. I solved it by making a better naming convention when I began the macros for tin in May 1995:

As time passed, I replaced the previous ones with the common name. In autoconf and automake, a similar process evolved, but this occurred a few years later:

Here is a summary of the configure scripts' macros, with links for a snapshot of the current source, and for the earliest labeled version. Often the labels are later than the initial date shown in the table. I get that date from the RCS archive. The macro-usage counts are as of January 1, 2020:

Macros Program/library aclocal.m4 initiated
69 XawPlus 2015/01/02 21:50:10
80 add 2002/12/27 22:23:26
47 atac 1997/11/04 01:19:44
8 bcpp 2002/11/23 16:02:52
41 byacc 2004/03/28 18:32:43
34 c_count 2001/02/27 19:48:36
115 cdk 1999/05/14 11:00:18
70 cdk-perl 2013/07/12 21:31:48
31 cindent 2010/10/05 00:57:46
31 cm_tools 1997/09/13 16:07:27
43 conflict 2002/12/29 23:49:36
29 copyrite 1998/01/13 01:21:41
40 cproto 1994/08/09 01:06:16
32 ded 1997/09/12 01:36:02
145 dialog 1999/12/26 01:53:45
50 diffstat 2003/01/04 01:29:51
78 luit 2006/08/20 16:46:31
186 lynx 1997/04/16 01:33:34
61 mawk 1996/09/04 23:40:34
28 misc_tools 2012/03/13 15:44:31
198 ncurses 1995/05/10 20:30:52
108 ncurses-Ada95 2010/02/27 00:53:29
113 ncurses-examples 2003/03/01 23:00:32
72 neXtaw 2001/12/11 07:14:56
7 pgf-vile 1994/06/17 00:43:38
37 rcshist 2015/02/28 23:11:53
37 reflex 2008/11/16 19:12:08
31 sccs_tools 1997/09/13 16:07:27
86 tack 2007/01/13 23:57:11
75 tctest 2011/07/23 12:24:30
134 td_lib 1994/05/22 23:10:57
72 tin 1996/05/24 15:55:45
158 tin-beta 1999/11/23 10:13:21
156 vile 1996/05/28 01:45:22
35 vttest 1997/05/18 20:22:12
118 xterm 1997/05/26 20:23:43
73.8 average  

A few of the table entries bear further comment:

I have RCS archives for a few other programs on my website or Git repositories that have configure scripts, which do not use my-autoconf:

I also have made improvements to other programs which are not in RCS archives (but those do not use my-autoconf):

Not all of my RCS archives have autoconf scripts. This page discusses 40 of the 172 archives at hand in January 2020. Not to ignore Git, I have about as many Git clones which I use to investigate details of other programs, such as autoconf.


I use my-autoconf to share macros and autoconf-related scripts between my programs. There is no "release" version for my-autoconf. There is only "current" (with history). It contains a few files in the top-level directory:

and there is a subdirectory “AcSplit” with all of the macros. All of the ones which I have written are named with a “CF_” prefix. There are a small number of other macros which others reused from other programs. I have modified those to make them work properly with the macros which I wrote.

When I am resync'ing a program with my-autoconf, I do this before making changes to a program's aclocal.m4 file:

When I have new changes for a program's aclocal.m4 file, I do this:

Updating config.guess and config.sub is simpler: I do not have local changes to review. My check-in comment notes the original file's check-in date (which often is more recent than the date listed in its comment header). Accessing those has become easier over the past twenty-odd years. Originally, the current versions were added by its maintainer from some private repository and others would only get one by copying from autoconf or some program that he had modified. Urs Janßsen noticed those, and used them in tin. After a while he made a CVS repository available. I made a script in 2013 to use wget to fetch from that. More recently there is a Git mirror; I have a clone of that.


Because I set up my-autoconf as a back-end infrastructure item, it was okay to call it “my autoconf” (no one would be confused). I did mention it in check-in comments. These are the first mentioned for the respective programs:

Check-in comments shown via rcs2log stating "resync with my-autoconf", usually refer to the macros. When writing a changelog entry, I may just mention "configure macros", and possibly list the macro names along with a summary of their changes. Updates for the add-ons such as config.guess usually mention the file which is updated.

Occasionally I did mention this on mailing lists. Here are a couple of examples:

Date: Wed, 22 Jan 2003 05:42:35 -0500
From: Thomas Dickey <>
Subject: Re: [UnixOS2] Multiple Autoconfs

On Wed, Jan 22, 2003 at 09:57:41AM +0000, John Poltorak wrote:
> It is apparent that I need to have multiple versions of Autoconf to be 
> able to build a wide variety of apps.
> Can anyone suggest the best way of setting up an environment for catering 
> with having more than a single installation of Autoconf?

I manipulate the program-prefix (also requires overriding the location
of the macros), e.g.,

cfg-normal \
        --prefix=$TOP \
        --program-prefix=my- \
        --datadir=$TOP/share/my-autoconf \
        --sharedstatedir=$TOP/share/my-autoconf $*
Some people find it simpler to install into entirely different directory
trees.  Since the autoconf 2.5x series is interdependent with specific
versions of automake and libtool, that's what you'll have to do.  For
instance, I have a set (all mutually incompatible ;-) for autoconf 2.54,
2.65 and 2.56 undef /usr/local/TEST.

> Currently I have the most recent version in \usr\local\bin and v2.13 in 
> \usr\local1\bin. How do people handle this on Unix?
> -- 
> John

Thomas E. Dickey <>

on an OS/2 mailing list (showing a script which I used to configure my fork of autoconf 2.52), and this one

From: Thomas Dickey <>
Subject: Re: RCS&SCCS: any way to make content of file checked out with/without lock different?
Newsgroups: comp.os.linux.misc
References: <> <>
Organization: RadixNet Internet Services
User-Agent: tin/1.4.4-20000803 ("Vet for the Insane") (UNIX) (SunOS/5.8 (sun4u))
Status: RO
Content-Length: 1467
Lines: 41

Steve Kirkendall <> wrote:
> John Opezdol wrote:
>> Is there any way to make $Id: my-autoconf.html,v 1.66 2021/03/14 20:01:07 tom Exp $ or something like that not expand when file
>> is checked out with a lock? (-l)
>> The idea is to be able to tell by running strings on executable whether
>> all files that
>> used for compilation were checked in at the time compilation was done or
>> some files
>> there were being modified made their way into the executable.

> Add a $Locker:  $ keyword to the source files.  It is expanded to include
> the name of the person who has locked it or, if the file isn't locked,
> then $Locker:  $ is expanded to "$Locker:  $" (with two spaces instead of
> a username after the colon).

That won't tell if someone was simply editing the file (relies on some
discipline on the part of all related developers).  I use a utility that
compares timestamps on the build tree to pick up cases where this is not
true.  (It also shows locks ;-)

Here's a sample (relative to a local RCS archive):

** path = .
   1:   ./
   2:   |-- AcSplit/
   3:   |-- MANIFEST (not archived)
   4:   |-- aclocal.m4 (newer than 1.157)
   5:   |-- (not archived)
   6:   |-- configure (not archived)
   7:   |-- tektests/
   8:   |-- unicode/
   9:   |-- vttests/
  10:   |-- xterm.log.html (not archived)

Though generally I pipe the result into my directory editor so I can
inspect the odd cases.

Thomas E. Dickey

on a Linux mailing list (showing an in-progress resync with my-autoconf).

About ten years after I had started this archive, Emanuele Giaquinta asked about the macros (looking for reliable checks for ncurses). We exchanged several messages. This one outlines the process:

Date: Tue, 19 Jun 2007 10:23:04 -0400 (EDT)
From: Thomas Dickey <>
To: Emanuele Giaquinta <>
Subject: Re: irssi ncurses bug

On Tue, 19 Jun 2007, Emanuele Giaquinta wrote:

> Does the tool acmerge handle dependencies, and is it available?

It doesn't handle dependencies - I do that manually, by merging, running 
autoconf and looking for stray "CF_" names that autoconf doesn't see are 

acsplit splits aclocal.m4, creating a "", which contains the 
comments and one line for each macro; acmerge uses the "" 
file to decide what to pull out of the AcSplit directory.  They assume 
some things about the macro syntax (quoting can't be _too_ complicated, 
and I use "dnl" comments rather than "#" outside the macro definitions).

The files in the "my-autoconf" tree are in an RCS archive that I construct 
symbolic links to (link2rcs in cm_tools in the ded stuff).  It's a few 
seconds to setup and when synchronizing things I double-check if I 
overlooked updating a macro from the current program, then pull the 
current version, etc.  Checkin's are done with a script which makes the 
version line.  The MANIFEST file is generated by another script.

(I made the changelog using rcs2log, which has a fix for the symbolic 
links that its maintainer - rcs maintainer too - refused on the excuse 
that no one uses RCS ;-)

Probably sounds complicated...

I can make it available.

Thomas E. Dickey

Since then, I have made sources available from my autoconf page, and more recently, added Git snapshots which correspond to those sources.


My autoconf macros grew to satisfy my needs for the interrelated programs which I develop. In some cases, there are clusters of related macros which I use, e.g., to work with different implementations of curses or to properly enable compiler warnings with various versions of compilers. Scanning down the list of macros for just those two topics, these form the clusters that I mentioned:

Besides that, I made adjustments to some of my macros to work (using CF_ACVERSION_CHECK) with old and new versions of autoconf:

Some macros are actually obsolete. I stopped supporting K&R compilers around 2005:

Urs Janßsen used my macros in autoconf 2.13 for many years. But 2.52 supports cross-compiling (and is where I have developed for just as many years). He switched to my autoconf 2.52 version in March 2019.

Earlier (January 2019) there was one issue (which was outside the scope of those versions). In 2015, as mentioned in the release notes for ncurses 6.0, I dropped support for one of the pre-POSIX shell features in my macros. Dennis Preiser is still running machines old enough to require that (e.g., Ultrix 4.3). So I wrote a script to convert the current scripts to the XPG3 version which he uses.

A couple of macros are really obsolete. I keep them around, just for discussion purposes:

Rather than copy/paste the action-script for AC_OUTPUT to generate config.h, I made macros which used a configure-time utility program. As I recall it, there were still problems with quoting that I was not able to resolved. According to report-acdeps, I tried the former with more than one configure script (atac, ncurses, td_lib and vile). Once I had patched autoconf 2.13, those were simply ideas that did not work well enough.

Going forward with my patched autoconf, I used the AC_OUTPUT feature in most of the configure scripts. The exceptions were those which were hosted on systems where I might expect to share the source-tree with other developers:


If you don't know where you've been, you can't tell where you're going
(origin unknown).

I write scripts and programs to analyze what I am working on, to (try to) see how to improve the programs.

Comparing size

On revisiting this in 2014, I collected some numbers to gauge the size of my-autoconf versus some other collections of macros. I used Debian 8's packages for this comparison, and my lex-metrics script:

More to the point, very little of the work that I have done is performed in the autoconf archive.
The interested reader may start by comparing its checks for ncurses, compiler warnings, etc.

Checking dependencies

While acsplit and acmerge helped with my copy/paste approach to macro reuse, they could not tell me if a macro was no longer used.

I wrote (and use) a script acdeps which inspects the and aclocal.m4 files, and reports all of the macro names which are defined in those files, and notes the ones which are unused.

Using that helped clean up the places where I had begun a new aclocal.m4 file by copying one with similar requirements.

Checking usage

Still, acdeps gave me only a picture of one program's use of macros. I wanted to know how many of the (as of January 2020) 570 macros were in use. So I wrote a more complicated script report-acdeps which inspects all of my RCS archives which have autoconf scripts, and combines the information into a CSV-file which I can use in further analysis. You may find the log file amusing.


Some nuisances arise in development. Documenting these properly for autoconf is harder than it should be. I used to rely upon the mailing list archives for autoconf during its early stages of develpment. However, in September 2000, the mailing lists were switched to use Mailman and the existing mail archives (apparently) discarded.

I have mail from September 10, 2000 using the old system, showing the amount of mail lost:

As a result, in this discussion I rely on the mail which I found interesting at the time, as well as upon the program source-archives. I would have more to say if I had those mail archives at hand.


After David MacKenzie wandered off, there was no maintainer for autoconf. I was interested in doing that, because it would provide a way to incorporate my change to AC_OUTPUT. However, that was not achievable. Stallman rejected my proposal to handle this under my existing agreement, and it was not possible to renegotiate the agreement under which I develop programs outside my $dayjob.

That left a void, temporarily filled by Ben Elliston (who released autoconf 2.13 early in 1999). He was replaced by a committee:

To: Autoconf List <> 
Subject: Autoconf Maintenance 
From: Akim Demaille <> 
Date: 16 Dec 1999 18:31:01 +0100 
The older master Obiwan Elliston has retired from the maintenance of 
Autoconf.  The maintenance of Autoconf is now handled by a committee 
of five people : 
- Akim Demaille 
- Paul Eggert  
- Jim Meyering 
- Alexandre Oliva 
- Tom Tromey   
This committee is in charge of evaluating patches sent to  To be accepted a patch needs two approvals, 
but if any maintainer objects to (some aspect of) a patch, the patch 
is put on hold until either the objection or the patch is withdrawn, 
and/or the patch is modified to accommodate the objection. 
In a near future Autoconf will move from to 
We currently have a large backlog of patches waiting for inclusion, so 
please tolerate some unresponsiveness until the backlog is processed. 
On the behalf of the team, 

Others had patches to discuss, and I noticed that one was related to one of the fixes that I had proposed. I replied to the mailing list thread:

From dickey Fri Dec 17 05:56:18 1999
Subject: Re: Delayed macro expansion bug with AC_REQUIRE and diversions
To: (Akim Demaille <>)
Date: Fri, 17 Dec 1999 05:56:18 -0500 (EST)

> >>>>> "Axel" == Axel Thimm <> writes: 
> Axel> some parts of the patch which were (re)submitted by other 
> Axel> people, but not the main part of the patch, fixing the ordering 
> Axel> bug in nested AC_REQUIREs 
> Hey, what bug?  Could you submit your patch again on 

along the same lines, I have submitted my patch for directly-generating
config.h (rather than via a template) at least 3 times and been told it
would be incorporated "soon".  (I happened to think about it because it
includes a change that uses an extra diversion to handle shells with
limited environment space, on which my configure scripts otherwise will
not function).
> Axel> and extending autoconf to have more than a few level nesting. 
> I've always wondered about this part.  4 levels i quit small, but 
> otoh, even with ferocious testing I never saw it in the third level. 
> And IIRC, djm had carefully chosen the order so that the (wrong) fifth 
> level would be good anyway. 
> So are you motivated by fear, or by bad experience with this 
> limitation? 
> AFAIC I'd like that there is a check that makes sure we're not getting 
> out of the way. 
> Akim 

Thomas E. Dickey

Although I attempted to discuss this on the autoconf mailing list, more than one person replied directly to me. None of the three whose email I saved actually read the patch itself, nor did they experiment with it. Rather, they read (and interpreted) my description of the patch. Here is my reply to one of those:

From dickey Fri Dec 17 09:50:32 1999
Subject: Re: Delayed macro expansion bug with AC_REQUIRE and diversions
To: (Akim Demaille <>)
Date: Fri, 17 Dec 1999 09:50:32 -0500 (EST)

> >>>>> "T" == T E Dickey <> writes: 
> A> What are the advantages you'd win with this approach?  How fast is 
> A> it? 
> T> It reduces maintenance effort by eliminating duplication and is no 
> T> slower to generate than the conventional scheme (it simply 
> T> implements the same amount of sed scripts differently). 
> But you add: 
>         A> Do you mean to replace the existing system, or to implement 
>         A> two? 
>         T> two (my patch adds a chunk of else-clause to the existing 
>         T> autoconf macros, activated by supplying an additional 
>         T> parameter to AC_OUTPUT). 
> How can duplicating the mechanism reduce the maintenance effort?  The 

I think you misunderstand: autoconf will have two chunks of sed script;
the application selects one.  It reduces maintenance effort for autoconf
users.  Only one flavor is in the generated configure script (though in
principle that doesn't have to be true).

> famous `else chunks' you are talking about are `AC_UNDEF' like?  Isn't 
> this a sign that your change cannot be backward compatible to be 
> sound?  I mean, aren't you saying that any macro must be revisited, 
> which is not OK for user macros. 

no - only AC_OUTPUT is affected.  Take a look at the resync patch I
made for 2.13 (I made a more recent one but it's not online):

> T> As I said, I use the conventional substitution with the same 
> T> patched autoconf for Lynx - it isn't impacted by the patch.  I 
> T> don't recall if there is a problem with @BOTTOM@ and @TOP@ (but 
> T> since those iirc are done in a different stage, it's probably not a 
> T> problem). 
> Since you don't seem to rely on, you probably can't honor 
> them.  I must miss something on your relationship with (I usually make it config.hin since I do port to machines where
multiple dots in a name are a problem ;-) is still used.
> >> Is it still possible to leave the #undef (this seems hard, since 
> >> there is no AC_UNDEF, only AC_DEFINE).  To me, the fact that you 
> >> still have a means to check set/unset items in config.h is vital. 
> >> In fact, I 
> T> I check set/unset items by diff'ing config.h files from different 
> T> runs.  So that's not a problem. 
> Not a problem for you, agreed, but config.h has this wonderful 
> property that even non Autoconf expert can see what are the 
> conclusions of configure.  We ought to keep this.  Yes, there is 
> config.log and better yet, config.cache but... 

perhaps (we don't have to agree - I don't find the templated version useful,
it's the single most common source of errors in configure scripts, just
ahead of people using config.cache for the wrong platform ;-).
> It is not clear to me what are the fundamental motivations. 
> Performances?  Features? 
> Akim 

Thomas E. Dickey

A few more messages in the thread ended the discussion. Akim sent mail to me and Alexandre Oliva, stating that as long as he was associated with autoconf, he would make certain that none of my changes would be incorporated.


Concurrently with that episode (starting before, ending after) there was another issue with autoconf involving work I had done.

From my saved email,

Date: Wed, 2 Jun 1999 15:38:40 -0400 (EDT) 
From: "Kaveh R. Ghazi" <> 
Subject: Patch for new autoconf macros AC_CHECK_FUNC_DECL{S} ... 

        This patch adds support for two new macros, AC_CHECK_FUNC_DECL 
        These macros determine whether a function (or functions) are 
declared in a set of header files.  Many packages roll their own 
versions of this, I think it would be good to supply a standardized 
These macros are partly based on AC_CHECK_FUNC{S} and also on 
jm_CHECK_DECLARATIONS from sh-utils-1.16k.  Here's an example of how 
to use it in 
 > headers='#ifdef HAVE_UNISTD_H 
 > #include <unistd.h> 
 > #endif 
 > #ifdef HAVE_STDLIB_H 
 > #include <stdlib.h> 
 > #endif 
 > ' 
 > AC_CHECK_FUNC_DECLS(unlink malloc free, $headers) 
        I'd like get these or something like them installed before the 
next release of autoconf, if that's possible. 

The latter function was something along the lines of CF_CHECK_1_DECL and CF_CHECK_DECL (which Kevin Buettner and I had written for vile), but less rigorous. Here is what Ghazi's macro looked like:

dnl ### Checking for function declarations in header files 
[AC_MSG_CHECKING([whether $1 is declared]) 
#ifndef $1 
char *(*pfn) = (char *(*)) $1 
        eval "ac_cv_func_decl_$1=yes", 
        eval "ac_cv_func_decl_$1=no")]) 
  if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then 
    ifelse([$3], , :, [$3]) 
  ifelse([$4], , , [$4 
[for ac_func_decl in $1 ; do 
  AC_CHECK_FUNC_DECL($ac_func_decl, $2, 
  [changequote(, )dnl 
    ac_tr_func_decl=HAVE_DECL_`echo $ac_func_decl | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` 
changequote([, ])dnl 
    AC_DEFINE_UNQUOTED($ac_tr_func_decl) $3], $4)dnl 

That is, Ghazi's macro passed the list of header-files which should be included (to trigger compiler errors) when test-compiling the function miscast to a pointer to a character-pointer. You can derive this explanation at

cast $1 into pointer to pointer to char

In vile (and tin) we used a similar check to decide whether to supply our own function prototypes for system functions when the system's header files were only K&R (no prototypes). Probably Ghazi had the same intention.

A few months later, someone asked about this same issue, mentioning tin (wanting to incorporate that into autoconf). I pointed out that I was the person who had implemented the macros in tin. As Akim Demaille mentioned in a later message, there was a fairly lengthy thread involving the choices between various naming conventions for the symbol that should be defined when a prototype was wanted but absent. I did not save that thread (perhaps stretching from September to October), but also recall expressing my opinion about the choices, and exchanging at least a couple of messages with Akim on that topic. I had a few variants of this in my macro collection for

In February, Akim gave an update (and it was probably then that I inspected the changes made):

To: Autoconf List <> 
Cc: "Kaveh R. Ghazi" <> 
Subject: NEED_foo_DECL vs HAVE_DECL_foo 
From: Akim Demaille <> 
Date: 11 Feb 2000 12:01:38 +0100 

Hi People, 
Some time ago there was a huge thread on AC_CHECK_DECLS on just the 
name of the CPP macro which should be defined when a symbol is 
declared or not. 
There are two questions: NEED vs. HAVE and `infix' vs. `postfix'.  For 
the latter, I think we ought to move to `infix', i.e. HAVE_DECL_ or 
The first issue is much more important than it first seems, as was 
pointed out by Kaveh: consider 
        #if !HAVE_DECL_FOO 
        void foo (void); 
        #if NEED_DECL_FOO 
        void foo (void); 
in the case where AC_CHECK_DECLS((foo)) was not run, the first decl is 
triggered which might lead to conflicts, while in the second case it 
does not.  Based on this argument, NEED_ was elected. 
Let's bring the topic again, one last time. 
For HAVE_ 
First of all, because it is more uniform we the rest of Autoconf, 
which is something I am really attached to. 
Secondly, because the problem which Kaveh raised is a false problem: 
if there is a conflict, it is because the tests were not performed. 
What needs to be fixed is the fact that the tests were not made! 
Thirdly, I don't think the risks of conflicts are serious.  I know for 
sure that Jim Meyering is using the HAVE_ thingy, and if it were 
really dangerous, he would have noticed long ago. 
Fourthly, it is now possible to any user to extend the set of header 
prototypes, so even if Kaveh has a need for DECL_, it is still 
possible for him to implement his own AC_CHECK_DECLS *without* having 
to fork Autoconf.  This is precisely the main motivation for the 
overhaul of the autoheader tool chain. 
For NEED_ 
There is one issue we must not overlook: system.h.  As I see things, 
in a medium term Autoconf will provide a means to automatically build 
system.h.  Then (and in fact it is already possible now), ideally the 
``default includes'' used in the various tests will be that system.h. 
I think it is a good thing, since we will really test things in the 
conditions they are used in, while currently what we test is not what 
we use. 
Still, under these conditions it is extremely likely that at some 
point you check for the existence of a header, include it, and later 
in system.h provide a conflicting declaration because you have not yet 
tested whether the declaration was not needed.  Exactly what was 
predicted by Kaveh.  In this case, we do care about incompletely 
performed tests! 
But to take this argument into account, you need to believe system.h 
will be used like this some day, which is still science fiction. 
In between 
It is possible to use a three state value for HAVE_DECL_ (suggested by 
Alexandre IIRC): in addition to undefined and 1, using 0.  Then, you 
keep the HAVE_, which you can use exactly like the other HAVE_ if you 
are not concerned with incompletely performed tests: 
        #if !HAVE_DECL_foo 
        proto foo 
If you do matter, then you have to write: 
        #if defined HAVE_DECL_foo && !HAVE_DECL_foo 
        proto foo 
It seems to me that this solution provides everything we want: it is 
still light and clean in our C code, and the needed robustness is 
hidden in a no programmer's land: in system.h *if* it is used by 
configure.  Since it is likely that system.h be automatically 
generated, we even won't have to write that :) 
Well, that was the akim --verbose version of it.  Now for akim -q: 
        [ ] 2 state NEED_DECL_FOO 
        [ ] 2 state HAVE_DECL_FOO 
        [ ] 3 state HAVE_DECL_FOO 
I vote for 
        [ ] 2 state NEED_DECL_FOO 
        [ ] 2 state HAVE_DECL_FOO 
        [X] 3 state HAVE_DECL_FOO 

I followed up, recommending “NEED, but investigated to see the code we were discussing. It had changed. Looking now (in 2020), I see first that Akim had checked in a succession of 5 changes in one commit in the experimental branch of autoconf.

1999-09-21 Akim Demaille <>
        * NEWS: Updated.
        * THANKS: Likewise.

        * acgeneral.m4 (AC_CHECK_HEADER): Use AC_VAR_*.
        (AC_CHECK_HEADERS): Adapted.

        * acgeneral.m4 (AC_TR): Remove, it is useless.
        (AC_TR_CPP): Updated version of formerly AC_TR_DEFINE, based on
        the model of AC_TR_SH.
        All callers changed.

        * (Checking for Bugs): Remove the indirection that
        made the `sort -u' useless.

1999-09-21  Akim Demaille  <>

        * (Last sed cmd): Change also @PND@ to `#', since this
        is also a symbol very hard to quote in m4.

        * acgeneral.m4 (AC_CHECK_LIB): Use AC_VAR_*.

        * acgeneral.m4: Use `m4_BUILTIN' instead of indirection via

1999-09-21  Akim Demaille  <>

        * autoconf.texi (Particular Structures): Move documentation of
        AC_HEADER_STAT and AC_HEADER_TIME from here...
        (Particular Headers): to here.
        (Declarations): New section.
        (Particular Headers): Move doc of AC_DECL_SYS_SIGLIST from here...
        (Particular Declarations): to here.

1999-09-21  Kaveh R. Ghazi  <>

        * acgeneral.m4 (AC_CHECK_FUNC_DECL, AC_CHECK_FUNC_DECLS): New

        * autoconf.texi (AC_CHECK_FUNC_DECL, AC_CHECK_FUNC_DECLS):

        * autoheader.m4: Add support for AC_CHECK_FUNC_DECLS.

        * Likewise.

1999-09-21  Akim Demaille  <>

        * acgeneral.m4 (AC_SHELL_IFELSE): New macro.
        (AC_VAR_IF_SET): Use it.
        (AC_CHECK_FUNC): Likewise.

        * (${srcdir}/configure): Use to build
        Autoconf's configure. Before the building was performed running
        m4 at hand, but much was not done (e.g., __oline__,
        @BKL@... expansion)

Ghazi's original change was not in the updated acgeneral.m4. Instead, it had this:

dnl ### Checking for declared symbols
dnl              [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl --------------------------------------------------------
dnl Check if SYMBOL (a variable or a function) is declared.
[AC_VAR_PUSHDEF([ac_var], [ac_cv_decl_$1])dnl
AC_CACHE_CHECK([whether $1 is declared], ac_var,
[#ifndef $1
char *p = (char *) $1;
AC_VAR_SET(ac_var, yes), AC_VAR_SET(ac_var, no))])
AC_SHELL_IFELSE(test AC_VAR_GET(ac_var) = yes,
               [$3], [$4])dnl
dnl              [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
[for ac_sym in $1
              [AC_DEFINE_UNQUOTED(AC_TR_CPP(${ac_sym}_DECLARED)) $3],
dnl ### Checking for library functions

Well, that is one change. But then a few days later, on September 27, Akim checked in another change, completely rewriting the macro:

1999-09-27  Akim Demaille  <>

        * acgeneral.m4 (AC_CHECK_DECL): Renamed as...
        (AC_NEED_DECL): This.
        (AC_CHECK_DECLS): Renamed as...
        (AC_NEED_DECLS): This.
        (AC_NEED_DECL): Include <stdio.h>, <memory.h>, <string.h>,
        <strings.h>, <stdlib.h>, <stddef.h>, and <unistd.h>.

        * autoconf.texi (Generic Declarations): Updated.

Now the macro looked like this:

dnl ### Checking for declared symbols
dnl              [, INCLUDES,]]])
dnl ------------------------------------------------------------
dnl Check if SYMBOL (a variable or a function) is declared.
dnl This macro is not a _CHECK_, because it is better not to declare
dnl a symbol if you don't really need it.
[AC_VAR_PUSHDEF([ac_Symbol], [ac_cv_decl_$1])dnl
AC_CACHE_CHECK([whether $1 is declared], ac_Symbol,
[AC_TRY_COMPILE([#include <stdio.h>
#  include <memory.h>
# endif
# include <string.h>
#  include <strings.h>
# endif
# include <stdlib.h>
# include <stddef.h>
#  include <stdlib.h>
# endif
# include <unistd.h>
[#ifndef $1
char *p = (char *) $1;
AC_VAR_SET(ac_Symbol, yes), AC_VAR_SET(ac_Symbol, no))])
AC_SHELL_IFELSE(test AC_VAR_GET(ac_Symbol) = yes,
               [$2], [$3])dnl
dnl               [, INCLUDES,]]])
dnl -------------------------------------------------------------
[AC_FOREACH([ac_Symbol], [$1],

Compare that with the macros from the "vctin960524" label in tin:

dnl ---------------------------------------------------------------------------
dnl Check for missing declarations in the system headers (adapted from vile).
AC_MSG_CHECKING([for missing "$1" extern])
CF_MSG_LOG([for missing "$1" external])
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#ifdef HAVE_LIBC_H
# include <libc.h>
# include <unistd.h>
# include <stdarg.h>
#  include <varargs.h>
# endif
# include <unistd.h>
# include <stdlib.h>
# include <stddef.h>
# include <string.h>
  /* An ANSI string.h and pre-ANSI memory.h might conflict.  */
#  include <memory.h>
# endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#  include <strings.h>
  /* memory.h and strings.h conflict on some systems */
# endif
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
/* unistd.h defines _POSIX_VERSION on POSIX.1 systems.  */
#if defined(HAVE_DIRENT_H) || defined(_POSIX_VERSION)
# include <dirent.h>
#else /* not (HAVE_DIRENT_H or _POSIX_VERSION) */
#  include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
#  include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
#  include <ndir.h>
# endif /* HAVE_NDIR_H */
#endif /* not (HAVE_DIRENT_H or _POSIX_VERSION) */
# include <sys/file.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <time.h>
#  include <sys/time.h>
# else
#  include <time.h>
# endif
# include <sys/times.h>
# include <sys/param.h>
# include <sys/wait.h>
# include <sys/select.h>
# include <curses.h>
# include <ioctl.h>
#  include <sys/ioctl.h>
# endif
#undef $1
struct zowie { int a; double b; struct zowie *c; char d; };
extern struct zowie *$1();
[eval 'cf_cv_func_'$1'=yes'],
[eval 'cf_cv_func_'$1'=no'])])
eval 'cf_result=$cf_cv_func_'$1
test $cf_result = yes && AC_DEFINE_UNQUOTED(DECL_$2)
dnl ---------------------------------------------------------------------------
[for ac_func in $1
CF_CHECK_1_DECL(${ac_func}, ${ac_tr_func})dnl

Rather than only using the includes which were passed as a parameter, the changed macro now (like tin) did a good-enough check for most purposes (and deprecating the includes parameter by moving it to the end of the parameter list). It appeared that Akim looked at the macros which I had developed, and adapted this idea from those macros into his work, without mentioning it.

Well yes, tin has more includes in its check. Akim limited it to the standard headers that are checked via AC_STDC_HEADERS, and a few others that "every" system should have. The set of includes in vile was originally much longer (see pgf-vile's copy). I had improved that by devising a way to use the program's header files during the configuration process to focus on the includes that would actually be used (see this change to CF_MISSING_CHECK, which was used in vile in November 1997).

Copying the “zowie” line as well would have been blatant. I chatted with Kevin about the reasons for the elaborate prototype, curious if he thought the lesser example by Ghazi was sufficient. He was definite about that:

Date: Mon, 14 Feb 2000 11:11:06 -0700 
From: Kevin Buettner <kev@xxxxxxxxxxxx> 
To: "T.E.Dickey" <>, 
        kev@xxxxxxxxxxxx (Kevin Buettner <kev@xxxxxxxxxxxx>) 
Subject: Re: ["T.E.Dickey" <>] Re: NEED_foo_DECL vs HAVE_DECL_foo (fwd) 

On Feb 14, 11:34am, T.E.Dickey wrote: 
> >  
> > Hi Tom,  
> >   
> > We're looking at CF_MISSING_CHECK in aclocal.m4, right?  
> right - my recollection was also that char* was itself not a good type to 
> test, since some compilers would be more forgiving about that than a 
> struct*. 
Plus char* is actually likely to be returned as the type of many 
things that we'd like to learn about.  The nice thing about using a 
struct is that we can construct one that is unlikely to look like 
any of the structs in the system header files.  That was one reason 
for the choice of the name ``zowie''.  Also, the layout of struct 
zowie will likely make it unique in the event that the compiler 
doesn't care about the name.  (The compiler might let the isomorphic 
structures by.) 
> So I was wondering if your recollection corresponded (otherwise, 
> I'll see if one of my current compilers does that - though I've different 
> machines to test on than in 1994/1995 ;-) 
Yes.  Back in 1994, I had a several crappy compilers I had to work with 
in addition to the system header files being an absolute mess.  These 
days the situation is a little bit more civilized.  But there is certainly 
still a need for a mechanism which tests for missing declarations.  I 
encountered two cases recently where I needed such a mechanism; one in 
expect, the other in the mmalloc library.  In the mmalloc case, I ended 
up using something called BFD_NEED_DECLARATION which comes from the 
bfd library.  (sbrk was causing a problem.) 
I don't think BFD_NEED_DECLARATION works as well as the machinery that 
we devised for vile, but it works well enough, so far, for my purposes. 
I'm somewhat concerned though because I think BFD_NEED_DECLARATION only 
tests against a handful (two, I think) of header files.  I'd feel much 
better about it if it'd check in more of them.  If you can get the 
precise header files used by the program included in the order that 
they'll appear in the application along with the -D switches used to 
build the application, so much the better.   
I.e, there is probably no such thing as overkill when it comes to designing 
these tests.  
Kevin Buettner 
kev@xxxxxxxxxxxx, kevinb@xxxxxxxxxxxx


The change for AC_OUTPUT was one of four changes in the patch which I submitted for review (spending a year in the process of getting nowhere). Quoting from the patch header (which no one read):

autoconf 2.13 - patch 19990117 - T.Dickey <>
This is a resync against autoconf 2.13 of my changes to autoconf 2.12:
        + improve the AC_OUTPUT macro by allowing it to generate the contents
          of the config.h file rather than simply substituting in a template.
        + change the autoconf logic that builds up & displays the --help
          message.  This is a workaround for shells with limited environment
        + changes (from the lynx project) to config.guess and config.sub to
          work with CLIX and os390 platforms.
        + correct autoconf 2.13's "make distclean" rule, which did not clean
          the .m4f files.

Revisiting this, none were applied. Urs Janßsen had submitted an earlier version of my config.{guess|sub} change for CLIX. But my updated change included a change for os390 (originally from Paul Gilmarten). Ben Elliston did not apply a related patch until almost two years had passed (November 2001).

The second item on my list is more interesting. The autoconf logic may have been improved, but no one can tell. That is because the developers do not document what they did.

I wanted the improvement to support the CF_HELP_MESSAGE macro. I use that in lynx, ncurses, vile and xterm configure scripts to make the configure script's --help message readable. The one for vile is the shortest. Here is the section of the help-message with the desired text highlighted:

Optional Features:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]

  --with-build-cc=XXX     the build C compiler ($BUILD_CC)
  --with-build-cpp=XXX    the build C preprocessor ($BUILD_CPP)
  --with-build-cflags=XXX the build C compiler-flags ($BUILD_CFLAGS)
  --with-build-cppflags=XXX the build C preprocessor-flags ($BUILD_CPPFLAGS)
  --with-build-ldflags=XXX the build linker-flags ($BUILD_LDFLAGS)
  --with-build-libs=XXX   the build libraries (${BUILD_LIBS})
  --disable-echo          do not display "compiling" commands
  --disable-extensions    test: build only core functions
  --disable-shell         test: disable shell/external commands
  --with-CFLAGS=value     set default for $CFLAGS
  --with-cflags=value     (same as --with-CFLAGS)
  --with-perl             enable use of Perl as an extension language
Options for syntax filters
  --disable-filters       do not build syntax filters
  --with-builtin-filters=XX specify filters to compile built-in vs external.
                          Give an option value to specify only certain filters,
                          i.e., a comma-separated list of filter-names.
                          The default, if no value is given is 'all'.
                          The default if the option is not given is 'none'
  --with-loadable-filters=XX specify filters to dynamically load at runtime.
                          Give an option value to specify only certain filters,
                          i.e., a comma-separated list of filter-names.
                          The default, if no value is given is 'all'.
                          The default if the option is not given is 'none'
  --with-libdir-path=LIST specify locations to search for filters, etc. (default: $cf_default)
  --with-startup-path=LIST specify locations to search for vile.hlp, etc. (default: $cf_default)
  --with-pkg-config{=path} enable/disable use of pkg-config
Select screen-type
  --with-screen=value     specify terminal driver.  The default is tcap, for
                          the termcap/terminfo driver.  Other values include:
                              curses, ncurses, ncursesw,
                              X11, Motif, Athena, Xaw, Xaw3d, neXtaw,
                              DOS, Windows and ansi.
  --with-scr=value        (same as --with-screen)
Options specific to screen-types
  --with-x                use the X Window System
  --enable-narrowproto    enable narrow prototypes for X libraries
  --disable-imake         disable use of imake for definitions
  --enable-freetype       enable freetype library-support
  --with-freetype-config  configure script to use for FreeType
  --with-freetype-cflags  -D/-I options for compiling with FreeType
  --with-freetype-libs    -L/-l options to link FreeType
  --enable-fontsets       enable fontset-support
  --with-Xaw3d            link with Xaw 3d library
  --with-Xaw3dxft         link with Xaw 3d xft library
  --with-neXtaw           link with neXT Athena library
  --with-XawPlus          link with Athena-Plus library
  --with-curses-dir=DIR   directory in which (n)curses is installed
  --with-ncurses          use ncurses rather than termcap/terminfo
  --with-xpm=DIR          use Xpm library for colored icon, may specify path
  --enable-colored-menus  enable colored-menus
  --with-Xaw-scrollbars   use Xaw scrollbars rather than our own
  --with-drag-extension   use drag/scrolling extension with Xaw
  --with-icon-name=XXXX   override icon name (default: vile)
Miscellaneous features
  --enable-plugins        compile-in plugin support
  --disable-largefile     omit support for large files
  --disable-link-prefix   do not trim unneeded libraries from link command
  --with-symlink=XXX      make symbolic link to installed application
  --with-exec-macros=N    specify count of numbered macros
  --with-locale           use i18n support for character-types
  --with-iconv            use iconv() support for character-types
                          search for libiconv in DIR/include and DIR/lib
  --with-man2html=XXX     use XXX rather than groff
Debugging/development options
  --with-dmalloc          test: use Gray Watson's dmalloc library
  --with-dbmalloc         test: use Conor Cahill's dbmalloc library
  --with-purify           test: use Purify
  --with-valgrind         test: use valgrind
  --with-no-leaks         test: free permanent memory, analyze leaks
  --with-fakevms          test: use fake VMS I/O module
  --with-trace            test: turn on debug-tracing
  --with-warnings         test: turn on gcc warnings
  --disable-stripping     do not strip (debug info) installed executables
Options for XVile installation directories
  --with-app-class=XXX    override X applications class (default XVile)
  --with-app-defaults=DIR directory in which to install resource files (EPREFIX/lib/X11/app-defaults)
  --with-pixmapdir=DIR    directory in which to install pixmaps (DATADIR/pixmaps)
  --with-icondir=DIR      directory in which to install icons for desktop
  --with-icon-theme=XXX   install icons into desktop theme (hicolor)
  --disable-desktop       disable install of X desktop files
  --disable-rpath-hack    don't add rpath options for additional libraries

I revisited this area in December 2019, to see what progress (or regress) had been made. That involved ensuring that autoheader would handle my existing macros, by adding a parameter for autoheader to use as a comment line. Adrian Bunk pointed this out in the context of byacc, in October 2012, but I had not gone through all of my configure scripts for this detail. Having done that, this one surfaced as an impediment to discovering other incompatibilities which the autoconf developers may have provided.

About half of my change to acgeneral.m4 was to support this feature. The proposed entrypoint AC_DIVERT_HELP is just a wrapper around scripting which has changed. In investigating the newer scripting, I encountered a warning message that autoconf prefers named diversions. The documentation provides no insight, but an autoconf-bugs mailing list thread from 2009 helps:

divert()/m4_divert() broken in autoconf-2.64+

Quoting the interesting parts:

> > m4_divert(1)
> There's the bug - in the user's script and not in autoconf.  Diversion 1
> is too low, and gets output PRIOR to initialization text that autoconf
> assumes will be present.  By using a raw number, instead of a named
> diversion, the user has violated constraints.  According to the manual,
> you should rely on named diversions rather than mucking with raw diversion
> numbers.  Fix the bug in the user's by instead using a named
> diversion reserved for application initialization:
> m4_divert([INIT_PREPARE]).  If the user still insists on a raw number, at
> least use something in the range of 300-1000, since autoconf assumes that
> all diversions prior to 300 (aka INIT_PREPARE) are reserved for autoconf's
> initialization; the user's output normally starts at 1000 (aka BODY).
the autoconf documentation here is a far cry from anything you can point at
and say "this is a bug in your code".  all it says:
        it is nicer to associate a name with each diversion; the diversion number
        associated with a particular diversion name is an implementation detail, so
        you should only use diversion names

which is not the same as "you must never use numbers less than 300 or your
script will break".  especially because things have worked just fine without
any warnings, and even now there are no warnings.  just ugly shell errors (and
in some larger scripts, infinite loops of them).

if there are reserved numerical regions, then autoconf really needs to
warn/error out here. 

the reader can see that the documentation was inadequate. Another response tended to agree with that assessment:

> On Saturday 21 November 2009 17:46:19 Eric Blake wrote:
> > According to Mike Frysinger on 11/21/2009 3:47 PM:
> > > the autoconf documentation here is a far cry from anything you can point
> > > at and say "this is a bug in your code".  all it says:
> > > it is nicer to associate a name with each diversion; the diversion
> > > number associated with a particular diversion name is an implementation
> > > detail, so you should only use diversion names
> >
> > Documentation patches welcome.
> as i said earlier, i dont really get this diversion stuff, nor do i know the
> actual limits that are in play here.  you seem to.

The manual already states a bit further down:

     For now, the named diversions of Autoconf and Autoheader, and the
  remaining diversions of Autotest, are not documented.  In other words,
  intentionally outputting text into an undocumented diversion is subject
  to breakage in a future release of Autoconf.

What's more, the example as you originally posted it (and I remember a
very similar real-world example) used diversions "by accident" so to
speak: there was no real need or intentional exploitation of diversion
functionality at all.  It would be a lot easier to argue for a better
API from the Autoconf side if there was some legitimate use case.

The developer solved his problem by making the warning message and caveats more visible.