autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] autoheader: check templates of all config headers


From: Daniel Elstner
Subject: [PATCH] autoheader: check templates of all config headers
Date: Fri, 09 Oct 2015 23:24:40 +0200

Hi,

sorry for being annoying about this -- sending this here now since I
never got any response on autoconf-patches. I'd greatly appreciate if
someone could have a look at my patch and tell me whether it's
acceptable. I already completed the copyright assignment process.

Perhaps I should provide some more detail about the use case for this
change. In a nutshell:

Autoconf already allows for more than one config header. This feature is
useful e.g. for libraries which need to install a machine-specific
configuration header that is included by the library's public header
files. Apart from system configuration, this is also useful for version
number defines. I've been using this scheme successfully for many years
in a number of C and C++ libraries I've worked on.

However, only the first configuration header passed as argument to
AC_CONFIG_HEADERS() has its template generated by Autoheader. Secondary
configuration headers have to use hand-written template files. This is
just fine for the library use case, where it is important to tightly
control the symbols put into the installed config header, since user
code will be indirectly exposed to it.

So all would be just fine if it weren't for the problem that Autoheader
doesn't really handle the situation correctly. In order to appease
Autoheader's sanity checking (which cannot be disabled), it is currently
necessary to use the three-argument version of AC_DEFINE() even for
defines which already appear in a manually written header template file.
Using the three-argument AC_DEFINE() of course also means that the
define is duplicated into the first config header, too.

Even so it is still usable, and I've lived with that problem for years.
However, I've recently run into a situation which prompted me to create
this patch to fix Autoheader. The issue is with auto-generated version
defines, which may include a git revision hash and thus change with
every commit. Due to the duplication of all defines into the first
configuration header, which is included by every source file in the
project, this causes the entire project to be rebuild on every change.

If the version defines could be limited to the secondary config header,
the dependencies could be contained and the need to rebuild minimized.
Incidentally, the goal to reduce rebuilds is also the reason why a
proper configuration header is preferable over using AC_SUBST for this,
since the latter mechanism does not have the update-avoiding check for
changed content.

Long story short, my patch makes Autoheader behave like it probably
should have from the beginning. That is, the hand-written template files
of secondary config headers are considered during the sanity check
whether all defines have a corresponding template. This makes it
possible to use the two-argument version of AC_DEFINE() for defines with
a hand-written template, thereby avoiding the spill into the first
config header. This change should have no effect on existing code.

Is this acceptable? I'd be delighted if it could be part of the next
release.

Cheers,
--Daniel

* bin/autoheader.in: When checking for missing templates, take
all config headers into account, not just the one generated by
autoheader.  This makes it possible to use AC_DEFINE() for
secondary headers without duplicating the template into the
first header.
* tests/tools.at: Add a check for autoheader with multiple
config headers.
* NEWS: Document the new behavior.
---
 NEWS              |  5 +++++
 bin/autoheader.in | 37 ++++++++++++++++++++++++++-----------
 tests/tools.at    | 25 +++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index f691179..ceda4a0 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,11 @@ GNU Autoconf NEWS - User visible changes.
    is now deprecated.  If you really need that behavior use
    AC_PREPROC_IFELSE.
 
+** When checking for missing templates, autoheader now takes any
+   templates defined in the inputs of secondary config headers into
+   account.  This makes it possible to use AC_DEFINE for secondary
+   headers without duplicating the template in the main config header.
+
 ** Macros
 
 - New macro AC_C__GENERIC.
diff --git a/bin/autoheader.in b/bin/autoheader.in
index 8c70663..fe06774 100644
--- a/bin/autoheader.in
+++ b/bin/autoheader.in
@@ -191,11 +191,21 @@ unless ($config_h)
     exit 1;
   }
 
-# We template only the first CONFIG_HEADER.
-$config_h =~ s/ .*//;
 # Support "outfile[:infile]", defaulting infile="outfile.in".
-($config_h, $config_h_in) = split (':', $config_h, 2);
-$config_h_in ||= "$config_h.in";
+sub templates_for_header ($)
+{
+  my ($spec) = @_;
+  my ($header, @templates) = split(':', $spec);
+
+  return @templates if (@templates);
+  return $header . '.in';
+}
+
+my @config_templates = map(templates_for_header($_), split(' ', $config_h));
+
+# We template only the first CONFIG_HEADER.
+$config_h_in = shift(@config_templates);
+$config_h =~ s/[ :].*//;
 
 # %SYMBOL might contain things like 'F77_FUNC(name,NAME)', but we keep
 # only the name of the macro.
@@ -261,14 +271,20 @@ $out->close;
 
 # Check that all the symbols have a template.
 {
-  my $in = new Autom4te::XFile ("< " . open_quote ("$tmp/config.hin"));
-  my $suggest_ac_define = 1;
-  while ($_ = $in->getline)
+  foreach my $template ("$tmp/config.hin", @config_templates)
     {
-      my ($symbol) = /^\#\s*\w+\s+(\w+)/
-       or next;
-      delete $symbol{$symbol};
+      my $in = new Autom4te::XFile ("< " . open_quote ($template));
+
+      while ($_ = $in->getline)
+       {
+         my ($sym) = /^\#\s*\w+\s+(\w+)/
+           or next;
+         delete $symbol{$sym};
+       }
     }
+
+  my $suggest_ac_define = 1;
+
   foreach (sort keys %symbol)
     {
       msg 'syntax', "warning: missing template: $_";
@@ -277,7 +293,6 @@ $out->close;
          msg 'syntax',  "Use AC_DEFINE([$_], [], [Description])";
          $suggest_ac_define = 0;
        }
-
     }
   exit 1
     if keys %symbol;
diff --git a/tests/tools.at b/tests/tools.at
index 24173c9..d5a919c 100644
--- a/tests/tools.at
+++ b/tests/tools.at
@@ -860,6 +860,31 @@ config.h.in:0
 AT_CLEANUP
 

+# autoheader should take all config header inputs into account when
+# checking for missing templates.
+AT_SETUP([autoheader with multiple headers])
+
+AT_DATA([config-extra.h.in],
+[[/* Define this to whatever you want. */
+#undef HANNA
+]])
+AT_DATA([configure.ac],
+[[AC_INIT
+AC_CONFIG_HEADERS([config.h config-extra.h])
+AC_DEFINE([HANNA], ["Hanna"])
+AC_DEFINE([SEAN], ["Sean"], [Sean's name])
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF
+AT_CHECK_AUTOHEADER
+AT_CHECK([grep HANNA configure], [0], [ignore], [ignore])
+AT_CHECK([grep HANNA config.h.in], [1], [ignore], [ignore])
+AT_CHECK([grep SEAN configure], [0], [ignore], [ignore])
+AT_CHECK([grep SEAN config.h.in], [0], [ignore], [ignore])
+
+AT_CLEANUP
+
 

 ## ------------ ##





reply via email to

[Prev in Thread] Current Thread [Next in Thread]