Discussion:
generated version numbers
Harlan Stenn
2014-02-22 07:47:36 UTC
Permalink
The top few lines of NTP's configure.ac are, effectively:

m4_include([version.m4])
AC_INIT([ntp], [VERSION_NUMBER], ...)

and version.m4 consists of a single line that looks like:

m4_define([VERSION_NUMBER],[4.2.7p413])

For a long time, when it's time to roll a -dev (or a release) tarball
for NTP we'll:

- "bump" the "pNNN" number (which is master-saved in packageinfo.sh and
that value is used generate version.m4),
- do a "make distcheck" (which will first propagate the new version
number from packageinfo.sh to version.m4)
- check in all of the files that change because of the new version
number (version.m4 is *not* checked in, but packageinfo.sh is)
- "make dist" and publish the tarball

The above is a rough overview, and know that the final "make dist"
doesn't do anything that creates updated files so no further checkin is
needed. Yes, it's kinda intricate, but it's the simplest I've been able
to come up with given that I don't have to mess with it often.

The resulting tarball builds fine and needs no autotools.

If somebody does a repo checkout (or updates their existing copy)
instead of using the tarball, they run a "./bootstrap" script that:

- updates version.m4 from packageinfo.sh
- appropriately touches a bunch of files to avoid needlessly
regenerating flex/yacc targets, documentation files, etc.
- runs autoconf -vi

This last part should regenerate config.h.in because VERSION_NUMBER will
have changed, and as I wrote above, the first 2 lines of configure.ac
are:

m4_include([version.m4])
AC_INIT([ntp], [VERSION_NUMBER], ...)

and config.h.in will #define PACKAGE_VERSION.

But apparently something strange is going on, because after we run the
bootstrap script, if we run "make" we see:

...
Prerequisite `../version.m4' is newer than target `../config.h.in'.
Prerequisite `../aclocal.m4' is newer than target`../config.h.in'.
Must remake target `../config.h.in'.
...

And this makes no sense to me because:

- version.m4 is updated *first* in the bootstrap script
- autoreconf (which updates aclocal) is done after that

so obviously I'm missing something.

I'm continuing to dig into this, and if anybody has any ideas I'd love
to hear them.
--
Harlan Stenn <***@ntp.org>
http://networktimefoundation.org - be a member!
Patrick Welche
2014-02-22 11:14:58 UTC
Permalink
Post by Harlan Stenn
But apparently something strange is going on, because after we run the
...
Prerequisite `../version.m4' is newer than target `../config.h.in'.
Prerequisite `../aclocal.m4' is newer than target`../config.h.in'.
Must remake target `../config.h.in'.
...
- version.m4 is updated *first* in the bootstrap script
- autoreconf (which updates aclocal) is done after that
so obviously I'm missing something.
I'm continuing to dig into this, and if anybody has any ideas I'd love
to hear them.
Only - what do the timestamps on version.m4 and config.h.in look like?
Is the bootstrap script too fast? (Clutching at straws)

Cheers,

Patrick
Harlan Stenn
2014-02-23 23:18:12 UTC
Permalink
Post by Patrick Welche
Post by Harlan Stenn
But apparently something strange is going on, because after we run the
...
Prerequisite `../version.m4' is newer than target `../config.h.in'.
Prerequisite `../aclocal.m4' is newer than target`../config.h.in'.
Must remake target `../config.h.in'.
...
- version.m4 is updated *first* in the bootstrap script
- autoreconf (which updates aclocal) is done after that
so obviously I'm missing something.
I'm continuing to dig into this, and if anybody has any ideas I'd love
to hear them.
Only - what do the timestamps on version.m4 and config.h.in look like?
Is the bootstrap script too fast? (Clutching at straws)
The version.m4 file gets updated first, then 3 sets of "touches" happen
with a 1 second sleep between them. After that I run autoreconf.

Using the actual filenames now, after a repo update but before running
the "bootstrap" script:

***@hms-mbp11% ls -l config.h.in aclocal.m4 sntp/m4/version.m4
-rw-rw-r-- 1 harlan staff 41166 Feb 4 21:40 aclocal.m4
-rw-rw-r-- 1 harlan wheel 41299 Jan 28 02:07 config.h.in
-rw-rw-r-- 1 harlan wheel 40 Feb 21 23:20 sntp/m4/version.m4
***@hms-mbp11% ./bootstrap
...
***@hms-mbp11% ls -lT config.h.in aclocal.m4 sntp/m4/version.m4
-rw-rw-r-- 1 harlan staff 41166 Feb 23 15:10:10 2014 aclocal.m4
-rw-rw-r-- 1 harlan wheel 41378 Feb 23 15:10:30 2014 config.h.in
-rw-rw-r-- 1 harlan wheel 40 Feb 23 15:10:03 2014 sntp/m4/version.m4
***@hms-mbp11%

... and *this* time it didn't rebuild the top-level config.in.h .

I'm about to roll another release; I'll try again after that's done and
include the 2nd instance of config.h.in in the list (we have a nested
project, too).

H
Harlan Stenn
2014-02-26 18:47:49 UTC
Permalink
Adding automake to the list, as with the information below this is now
looking like an automake issue.

I rolled another release and here's what I see:

***@hms-mbp11% ls -ltrT config.h.in sntp/config.h.in aclocal.m4 sntp/aclocal.m4 sntp/m4/version.m4
-rw-rw-r-- 1 harlan wheel 40 Feb 23 15:10:03 2014 sntp/m4/version.m4
-rw-rw-r-- 1 harlan staff 41166 Feb 23 15:10:10 2014 aclocal.m4
-rw-rw-r-- 1 harlan staff 40943 Feb 23 15:10:15 2014 sntp/aclocal.m4
-rw-rw-r-- 1 harlan wheel 41378 Feb 23 15:10:30 2014 config.h.in
-rw-rw-r-- 1 harlan wheel 25706 Feb 23 15:14:16 2014 sntp/config.h.in
***@hms-mbp11% (update the repo)
***@hms-mbp11% ls -ltrT config.h.in sntp/config.h.in aclocal.m4 sntp/aclocal.m4 sntp/m4/version.m4
-rw-rw-r-- 1 harlan wheel 40 Feb 23 15:10:03 2014 sntp/m4/version.m4
-rw-rw-r-- 1 harlan staff 41166 Feb 23 15:10:10 2014 aclocal.m4
-rw-rw-r-- 1 harlan staff 40943 Feb 23 15:10:15 2014 sntp/aclocal.m4
-rw-rw-r-- 1 harlan wheel 41378 Feb 23 15:10:30 2014 config.h.in
-rw-rw-r-- 1 harlan wheel 25706 Feb 23 15:14:16 2014 sntp/config.h.in
***@hms-mbp11% ./bootstrap
(update version.m4 if needed)
(touch man pages, sleep 1)
(touch .texi and .menu pages, sleep 1)
(touch .html pages)
(run autoreconf-vi)
autoreconf: Leaving directory `.'
***@hms-mbp11% ls -ltrT config.h.in sntp/config.h.in aclocal.m4 sntp/aclocal.m4 sntp/m4/version.m4
-rw-rw-r-- 1 harlan wheel 41378 Feb 23 15:10:30 2014 config.h.in
-rw-rw-r-- 1 harlan wheel 25706 Feb 23 15:14:16 2014 sntp/config.h.in
-rw-rw-r-- 1 harlan wheel 40 Feb 26 10:06:09 2014 sntp/m4/version.m4
-rw-rw-r-- 1 harlan staff 41166 Feb 26 10:06:15 2014 aclocal.m4
-rw-rw-r-- 1 harlan staff 40943 Feb 26 10:06:21 2014 sntp/aclocal.m4
***@hms-mbp11%

so there it is - for some reason the config.h.in files are not being
regenerated. Just to be clear, the script that generates m4/version.m4
only updates that file if the version number is different. Right now,
version.m4 contains:

m4_define([VERSION_NUMBER],[4.2.7p425])

while the two config.h.in files contain:

***@hms-mbp11% grep VERSION sntp/config.h.in config.h.in
sntp/config.h.in:#undef PACKAGE_VERSION
sntp/config.h.in:#undef VERSION
config.h.in:#undef PACKAGE_VERSION
config.h.in:#undef VERSION
***@hms-mbp11%

There is no dependency on version.m4 for anything in the Makefile.am .

So automake has am__aclocal_m4_deps that does contain:

$(top_srcdir)/sntp/m4/version.m4

which makes sense because the first line of configure.ac is:

m4_include([sntp/m4/version.m4])

So while the filestamps are technically correct, the generated Makefile
*will* see that version.m4 is newer than config.h.in and regenerate it
via Makefile dependencies.

I suspect the answer is that at the end of the bootstrap script, if the
aclocal.m4 file is newer than the config.h.in file we need to touch
the config.h.in file.

H
Peter Johansson
2014-02-26 23:34:04 UTC
Permalink
Post by Harlan Stenn
So while the filestamps are technically correct, the generated Makefile
*will* see that version.m4 is newer than config.h.in and regenerate it
via Makefile dependencies.
I suspect the answer is that at the end of the bootstrap script, if the
aclocal.m4 file is newer than the config.h.in file we need to touch
the config.h.in file.
Hi Harlan

File 'config.h.in' is generated by autoheader [I assume]. Autoheader
will not touch the time-stamp of 'config.h.in' if the content doesn't
change. This can be annoying, and is the reason Automake generated rule
has a 'touch $@' after autoheader is called

$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@

In my bootstrap script I issue autoreconf with option '--force', so I
don't see this problem. If you think that is too expensive, you could
set environment
variable AUTOHEADER with something like:

AUTOHEADER="autoheader -f" autoreconf -vi

Changing the behaviour of autoheader, I suspect will be met by some
significant resistance.


Cheers,
--
Peter Johansson
Harlan Stenn
2014-02-27 01:05:04 UTC
Permalink
Hi Peter,
Post by Peter Johansson
Post by Harlan Stenn
So while the filestamps are technically correct, the generated
Makefile *will* see that version.m4 is newer than config.h.in and
regenerate it via Makefile dependencies.
I suspect the answer is that at the end of the bootstrap script, if
the aclocal.m4 file is newer than the config.h.in file we need to
touch the config.h.in file.
File 'config.h.in' is generated by autoheader [I assume]. Autoheader
will not touch the time-stamp of 'config.h.in' if the content doesn't
change. This can be annoying, and is the reason Automake generated rule
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
In my bootstrap script I issue autoreconf with option '--force', so I
don't see this problem. If you think that is too expensive, you could
set environment
AUTOHEADER="autoheader -f" autoreconf -vi
Changing the behaviour of autoheader, I suspect will be met by some
significant resistance.
Yes, understood. And the problem is that am__configure_deps includes
am__aclocal_m4_deps, which includes aclocal.m4.

So we have a case where as a result of autoreconf running, aclocal.m4
gets updated and config.h.in does not get updated. But the resulting
directory will require autotools (apparently the 'missing' stuff is
insufficient) because make *will* force a rebuild of config.h.in because
aclocal.m4 is newer.

So perhaps autoreconf needs a late test that if aclocal.m4 is newer than
config.h.in, we touch config.h.in .

This way, if nothing is updated then nothing gets touched. But if
aclocal.m4 gets updated we'll avoid this particular problem.

I think. This stuff is, of course, intricate.

H
Peter Johansson
2014-02-27 01:48:50 UTC
Permalink
Post by Harlan Stenn
Yes, understood. And the problem is that am__configure_deps includes
am__aclocal_m4_deps, which includes aclocal.m4.
Inaccurate. am__configure_deps includes aclocal,m4 via variable
$(ACLOCAL_M4). am__aclocal_m4_deps describes which files 'aclocal.m4'
depends on and depending on itself would probably have caused Make to
implode.
Post by Harlan Stenn
So we have a case where as a result of autoreconf running, aclocal.m4
gets updated and config.h.in does not get updated. But the resulting
directory will require autotools (apparently the 'missing' stuff is
insufficient) because make*will* force a rebuild of config.h.in because
aclocal.m4 is newer.
Correct. Are you saying that these time-stamps get propagated to a
distribution tarball. If so, it smells like the 'make dist' target could
get improved???


Cheers,
Peter
Post by Harlan Stenn
So perhaps autoreconf needs a late test that if aclocal.m4 is newer than
config.h.in, we touch config.h.in .
This way, if nothing is updated then nothing gets touched. But if
aclocal.m4 gets updated we'll avoid this particular problem.
--
Peter Johansson
Harlan Stenn
2014-02-27 07:19:01 UTC
Permalink
Post by Peter Johansson
Post by Harlan Stenn
Yes, understood. And the problem is that am__configure_deps includes
am__aclocal_m4_deps, which includes aclocal.m4.
Inaccurate. am__configure_deps includes aclocal,m4 via variable
$(ACLOCAL_M4). am__aclocal_m4_deps describes which files 'aclocal.m4'
depends on and depending on itself would probably have caused Make to
implode.
OK.
Post by Peter Johansson
Post by Harlan Stenn
So we have a case where as a result of autoreconf running, aclocal.m4
gets updated and config.h.in does not get updated. But the resulting
directory will require autotools (apparently the 'missing' stuff is
insufficient) because make*will* force a rebuild of config.h.in because
aclocal.m4 is newer.
Correct. Are you saying that these time-stamps get propagated to a
distribution tarball. If so, it smells like the 'make dist' target could
get improved???
I'm saying that with the MAINTAINER_MODE stuff being different, now that
"missing" is no longer used by default there is a case where auto*'s
dependency rules for aclocal.m4 still require an autoheader run *after*
autoreconf has been run, and that seems to me to clearly be a bug.

H

Loading...