Discussion:
Conditional AC_DEFINE with m4_define variable?
Eric Blake
2012-12-22 15:18:35 UTC
Permalink
[adding autoconf, as this question technically is independent of automake]
Hi,
m4_define([dc_version_suffix],[devel])
m4_define([dc_version_suffix],[])
And then try to conditionally call AC_DEFINE based on whether the
AS_IF([test "x$dc_version_suffix" = "xdevel"], [
AC_DEFINE(ENABLE_PTY, [1], [Enable pseudo terminal support.])
])
This will expand to either:

test "x$" = "xdevel"

or

test "x$devel" = "xdevel"

based on the macro value. Probably not what you wanted.
However if I use m4_isset, then it does kind of work, except that the
USE_REVISION macro in the config.h is either defined, or not present at
all.
m4_ifset([dc_version_suffix],[
AC_DEFINE(USE_REVISION, [1], [Use the revision number.])
])
Indeed, this actually does what _I_ would want - since dc_version_suffix
is known at m4 time, we might as well use that information to generate
the smallest possible configure.

But if you _insist_ on delaying the decision until shell time, even
though the condition being tested is known at m4 time, then you probably
want to use something like this:

AS_IF([test "x]dc_version_suffix[" = "xdevel"], [
AC_DEFINE([USE_REVISION], [1], [Use the revision number.])
])

which expands the literal contents of the macro in place, so that your
configure will then either contain:

test "x" = "xdevel"

or

test "xdevel" = "xdevel"

Or, if you _want_ a shell variable rather than an m4 variable as the
source of your decision, then be sure you set up that shell variable:

[dc_version_suffix]=dc_version_suffix
AS_IF([[test "x$dc_version_suffix" = "xdevel"]], [
AC_DEFINE([USE_REVISION], [1], [Use the revision number.])
])

where the extra quoting is necessary to ensure that your configure file
will look like either:

dc_version_suffix=
test "x$dc_version_suffix" = "xdevel"

or

dc_version_suffix=devel
test "x$dc_version_suffix" = "xdevel"

Using a different shell variable name than the m4 macro name will make
it easier to type, without quite so much quoting:

version_suffix=dc_version_suffix
AS_IF([test "x$version_suffix" = "xdevel"], [
AC_DEFINE([USE_REVISION], [1], [Use the revision number.])
])
Does anyone know how to implement this correctly?
It really depends on what you are trying to accomplish by deciding
something at m4 time, but deferring the action on that decision until
configure time.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Jef Driesen
2012-12-22 16:29:55 UTC
Permalink
Post by Eric Blake
[adding autoconf, as this question technically is independent of automake]
Hi,
m4_define([dc_version_suffix],[devel])
m4_define([dc_version_suffix],[])
And then try to conditionally call AC_DEFINE based on whether the
AS_IF([test "x$dc_version_suffix" = "xdevel"], [
AC_DEFINE(ENABLE_PTY, [1], [Enable pseudo terminal support.])
])
test "x$" = "xdevel"
or
test "x$devel" = "xdevel"
based on the macro value. Probably not what you wanted.
That explains very well, why it doesn't work. I wasn't really aware of the
difference between m4 and shell variables.
Post by Eric Blake
However if I use m4_isset, then it does kind of work, except that the
USE_REVISION macro in the config.h is either defined, or not present at
all.
m4_ifset([dc_version_suffix],[
AC_DEFINE(USE_REVISION, [1], [Use the revision number.])
])
Indeed, this actually does what _I_ would want - since dc_version_suffix
is known at m4 time, we might as well use that information to generate
the smallest possible configure.
But if you _insist_ on delaying the decision until shell time, even
though the condition being tested is known at m4 time, then you probably
I do not insist on doing things in a particular way. I just want something that
works and preferably done the right way See below for an explanation of what
I'm trying to achieve.
Post by Eric Blake
Does anyone know how to implement this correctly?
It really depends on what you are trying to accomplish by deciding
something at m4 time, but deferring the action on that decision until
configure time.
What I want to accomplish is as follows. I have a dc_version() function in my
library which returns the version number. The main part of the version number is
generated directly from configure.ac (with AC_SUBST and a version.h.in file).
But I also generate a revision.h file at build time containing the git SHA1. So
far no problem. But now I'm trying to append this git revision info for
non-release builds (e.g. dc_version_suffix not empty). So my version.c file
contains roughly this:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <libdivecomputer/version.h> /* Defines the DC_VERSION macro. */

#ifdef USE_REVISION
#include "revision.h"/* Defines the DC_VERSION_REVISION macro. */
#endif

const char *
dc_version (dc_version_t *version)
{
#ifdef USE_REVISION
return DC_VERSION " (" DC_VERSION_REVISION ")";
#else
return DC_VERSION;
#endif
}

So I wanted to have this USE_REVISION macro somehow end up in the config.h
header, such that the above code would work.

The m4_ifset based test does that, but if the dc_version_suffix is empty, the
USE_REVISION macro is not present in the config.h file at all. Usually when you
define any sort of tests (e.g. AC_CHECK_*), then the corresponding macros always
ends up in the config.h file, but uncommented when not available. Like this:

/* Use the revision number. */
/* #undef USE_REVISION */

When using an AS_IF based test, that's the case too. So that's why I thought the
m4_ifset test was not the right tool.

Jef
Eric Blake
2012-12-31 21:21:21 UTC
Permalink
Post by Jef Driesen
Post by Eric Blake
[adding autoconf, as this question technically is independent of automake]
What I want to accomplish is as follows. I have a dc_version() function
in my library which returns the version number. The main part of the
version number is generated directly from configure.ac (with AC_SUBST
and a version.h.in file). But I also generate a revision.h file at build
time containing the git SHA1. So far no problem. But now I'm trying to
append this git revision info for non-release builds (e.g.
dc_version_suffix not empty).
You may be interested in seeing how GNU Coreutils approaches this. It
uses a tool git-version-gen from gnulib, as well as some hooks into
configure.ac and Makefile.am, so that if you are building from
coreutils.git, then the git version is injected as a suffix into the
generated version string via a file version.[ch], and if you are
building from a tarball, then the information is hard-coded and there is
no suffix. By sticking the version information in a separate .c file,
it becomes merely a matter of linking to the new .o file (rather than
recompiling the world) when the version number changes.
Post by Jef Driesen
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Within a single project, you should know whether you are using config.h;
being conditional only matters for libraries like libtool that are
designed to work even without autoconf. That is, these days, most
people _don't_ need #ifdef HAVE_CONFIG_H, but can blindly assume that it
is in use.
Post by Jef Driesen
#include <libdivecomputer/version.h> /* Defines the DC_VERSION macro. */
#ifdef USE_REVISION
#include "revision.h"/* Defines the DC_VERSION_REVISION macro. */
#endif
Makes sense.
Post by Jef Driesen
So I wanted to have this USE_REVISION macro somehow end up in the
config.h header, such that the above code would work.
The m4_ifset based test does that, but if the dc_version_suffix is
empty, the USE_REVISION macro is not present in the config.h file at
all. Usually when you define any sort of tests (e.g. AC_CHECK_*), then
the corresponding macros always ends up in the config.h file, but
/* Use the revision number. */
/* #undef USE_REVISION */
Ah, so you want the template to be visible to autoheader, even when the
template is not in use from a tarball.
Post by Jef Driesen
When using an AS_IF based test, that's the case too. So that's why I
thought the m4_ifset test was not the right tool.
Yeah, m4_ifset hides the entire AC_DEFINE from view of any other tool,
like autoheader, that scans for m4 calls. If you want the template to
appear unconditionally, but only be defined when needed, you might try:

if m4_ifset([dc_version_suffix], [:], [false]); then
AC_DEFINE([USE_REVISION], [1], [Use the revision number.])
fi

which then makes the AC_DEFINE() unconditionally expanded at m4 time (so
autoheader will list the template), but the shell decision on whether to
do anything is now minimized.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Jef Driesen
2013-01-02 15:02:31 UTC
Permalink
Post by Eric Blake
Post by Jef Driesen
Post by Eric Blake
[adding autoconf, as this question technically is independent of automake]
What I want to accomplish is as follows. I have a dc_version() function
in my library which returns the version number. The main part of the
version number is generated directly from configure.ac (with AC_SUBST
and a version.h.in file). But I also generate a revision.h file at build
time containing the git SHA1. So far no problem. But now I'm trying to
append this git revision info for non-release builds (e.g.
dc_version_suffix not empty).
You may be interested in seeing how GNU Coreutils approaches this. It
uses a tool git-version-gen from gnulib, as well as some hooks into
configure.ac and Makefile.am, so that if you are building from
coreutils.git, then the git version is injected as a suffix into the
generated version string via a file version.[ch], and if you are
building from a tarball, then the information is hard-coded and there is
no suffix. By sticking the version information in a separate .c file,
it becomes merely a matter of linking to the new .o file (rather than
recompiling the world) when the version number changes.
I already have something like this in place.
Post by Eric Blake
Post by Jef Driesen
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Within a single project, you should know whether you are using config.h;
being conditional only matters for libraries like libtool that are
designed to work even without autoconf. That is, these days, most
people _don't_ need #ifdef HAVE_CONFIG_H, but can blindly assume that it
is in use.
I also support building my project with msvc, and in that case there is no
autoconf...
Post by Eric Blake
Post by Jef Driesen
So I wanted to have this USE_REVISION macro somehow end up in the
config.h header, such that the above code would work.
The m4_ifset based test does that, but if the dc_version_suffix is
empty, the USE_REVISION macro is not present in the config.h file at
all. Usually when you define any sort of tests (e.g. AC_CHECK_*), then
the corresponding macros always ends up in the config.h file, but
/* Use the revision number. */
/* #undef USE_REVISION */
Ah, so you want the template to be visible to autoheader, even when the
template is not in use from a tarball.
It's not a must, but because that appeared to be the normal behavior, I thought
I might be doing this the wrong way, and I just don't want to rely on something
that might break in unexpected ways. That's all.
Post by Eric Blake
Post by Jef Driesen
When using an AS_IF based test, that's the case too. So that's why I
thought the m4_ifset test was not the right tool.
Yeah, m4_ifset hides the entire AC_DEFINE from view of any other tool,
like autoheader, that scans for m4 calls. If you want the template to
if m4_ifset([dc_version_suffix], [:], [false]); then
AC_DEFINE([USE_REVISION], [1], [Use the revision number.])
fi
which then makes the AC_DEFINE() unconditionally expanded at m4 time (so
autoheader will list the template), but the shell decision on whether to
do anything is now minimized.
I already implemented the direct m4_ifset call. No need to add extra complexity
if not absolutely necessary :-)

Anyway, thanks for your time and feedback! It helped me a lot to understand what
is going on.

Jef
Jef Driesen
2013-01-02 15:02:52 UTC
Permalink
Post by Eric Blake
Post by Jef Driesen
Post by Eric Blake
[adding autoconf, as this question technically is independent of automake]
What I want to accomplish is as follows. I have a dc_version() function
in my library which returns the version number. The main part of the
version number is generated directly from configure.ac (with AC_SUBST
and a version.h.in file). But I also generate a revision.h file at build
time containing the git SHA1. So far no problem. But now I'm trying to
append this git revision info for non-release builds (e.g.
dc_version_suffix not empty).
You may be interested in seeing how GNU Coreutils approaches this. It
uses a tool git-version-gen from gnulib, as well as some hooks into
configure.ac and Makefile.am, so that if you are building from
coreutils.git, then the git version is injected as a suffix into the
generated version string via a file version.[ch], and if you are
building from a tarball, then the information is hard-coded and there is
no suffix. By sticking the version information in a separate .c file,
it becomes merely a matter of linking to the new .o file (rather than
recompiling the world) when the version number changes.
I already have something like this in place.
Post by Eric Blake
Post by Jef Driesen
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Within a single project, you should know whether you are using config.h;
being conditional only matters for libraries like libtool that are
designed to work even without autoconf. That is, these days, most
people _don't_ need #ifdef HAVE_CONFIG_H, but can blindly assume that it
is in use.
I also support building my project with msvc, and in that case there is no
autoconf...
Post by Eric Blake
Post by Jef Driesen
So I wanted to have this USE_REVISION macro somehow end up in the
config.h header, such that the above code would work.
The m4_ifset based test does that, but if the dc_version_suffix is
empty, the USE_REVISION macro is not present in the config.h file at
all. Usually when you define any sort of tests (e.g. AC_CHECK_*), then
the corresponding macros always ends up in the config.h file, but
/* Use the revision number. */
/* #undef USE_REVISION */
Ah, so you want the template to be visible to autoheader, even when the
template is not in use from a tarball.
It's not a must, but because that appeared to be the normal behavior, I thought
I might be doing this the wrong way, and I just don't want to rely on something
that might break in unexpected ways. That's all.
Post by Eric Blake
Post by Jef Driesen
When using an AS_IF based test, that's the case too. So that's why I
thought the m4_ifset test was not the right tool.
Yeah, m4_ifset hides the entire AC_DEFINE from view of any other tool,
like autoheader, that scans for m4 calls. If you want the template to
if m4_ifset([dc_version_suffix], [:], [false]); then
AC_DEFINE([USE_REVISION], [1], [Use the revision number.])
fi
which then makes the AC_DEFINE() unconditionally expanded at m4 time (so
autoheader will list the template), but the shell decision on whether to
do anything is now minimized.
I already implemented the direct m4_ifset call. No need to add extra complexity
if not absolutely necessary :-)

Anyway, thanks for your time and feedback! It helped me a lot to understand what
is going on.

Jef
Jef Driesen
2013-01-02 15:03:13 UTC
Permalink
Post by Eric Blake
Post by Jef Driesen
Post by Eric Blake
[adding autoconf, as this question technically is independent of automake]
What I want to accomplish is as follows. I have a dc_version() function
in my library which returns the version number. The main part of the
version number is generated directly from configure.ac (with AC_SUBST
and a version.h.in file). But I also generate a revision.h file at build
time containing the git SHA1. So far no problem. But now I'm trying to
append this git revision info for non-release builds (e.g.
dc_version_suffix not empty).
You may be interested in seeing how GNU Coreutils approaches this. It
uses a tool git-version-gen from gnulib, as well as some hooks into
configure.ac and Makefile.am, so that if you are building from
coreutils.git, then the git version is injected as a suffix into the
generated version string via a file version.[ch], and if you are
building from a tarball, then the information is hard-coded and there is
no suffix. By sticking the version information in a separate .c file,
it becomes merely a matter of linking to the new .o file (rather than
recompiling the world) when the version number changes.
I already have something like this in place.
Post by Eric Blake
Post by Jef Driesen
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Within a single project, you should know whether you are using config.h;
being conditional only matters for libraries like libtool that are
designed to work even without autoconf. That is, these days, most
people _don't_ need #ifdef HAVE_CONFIG_H, but can blindly assume that it
is in use.
I also support building my project with msvc, and in that case there is no
autoconf...
Post by Eric Blake
Post by Jef Driesen
So I wanted to have this USE_REVISION macro somehow end up in the
config.h header, such that the above code would work.
The m4_ifset based test does that, but if the dc_version_suffix is
empty, the USE_REVISION macro is not present in the config.h file at
all. Usually when you define any sort of tests (e.g. AC_CHECK_*), then
the corresponding macros always ends up in the config.h file, but
/* Use the revision number. */
/* #undef USE_REVISION */
Ah, so you want the template to be visible to autoheader, even when the
template is not in use from a tarball.
It's not a must, but because that appeared to be the normal behavior, I thought
I might be doing this the wrong way, and I just don't want to rely on something
that might break in unexpected ways. That's all.
Post by Eric Blake
Post by Jef Driesen
When using an AS_IF based test, that's the case too. So that's why I
thought the m4_ifset test was not the right tool.
Yeah, m4_ifset hides the entire AC_DEFINE from view of any other tool,
like autoheader, that scans for m4 calls. If you want the template to
if m4_ifset([dc_version_suffix], [:], [false]); then
AC_DEFINE([USE_REVISION], [1], [Use the revision number.])
fi
which then makes the AC_DEFINE() unconditionally expanded at m4 time (so
autoheader will list the template), but the shell decision on whether to
do anything is now minimized.
I already implemented the direct m4_ifset call. No need to add extra complexity
if not absolutely necessary :-)

Anyway, thanks for your time and feedback! It helped me a lot to understand what
is going on.

Jef

Loading...