I apologize in advance for my lack of experience with m4sh.
I have a configure.ac
file containing the following lines:
AC_INIT([libhelloworld], [2.5])
...
AC_OUTPUT([
Makefile
src/helloworld-${PACKAGE_VERSION}.pc
src/Makefile
])
The reason behind the argument of AC_OUTPUT()
is that I would like to avoid to copy and paste the new version of my program in multiple places on every update. Therefore I decided to exploit the PACKAGE_VERSION
macro, automatically defined when invoking AC_INIT()
at the beginning of configure.ac
.
The line src/helloworld-${PACKAGE_VERSION}.pc
then correctly expands into src/helloworld-2.5.pc
and everything seems to be working fine. However I have a couple of questions.
${PACKAGE_VERSION}
as a shell variable, but PACKAGE_VERSION
itself is a m4 macro. Can I trust that this will always work? Will it always be defined as such when AC_OUTPUT()
is invoked?PACKAGE_VERSION
within configure.ac
? For example, if instead of configure.ac
I were inside Makefile.am
I would not use the curly brackets, but the command evaluation syntax instead, as in $(PACKAGE_VERSION)
. What is the proper correct way of doing what I want within configure.ac
?The documentation for AC_INIT
states that PACKAGE_VERSION
is an "output variable", meaning when you call AC_INIT
, something like this gets executed:
AC_SUBST([PACKAGE_VERSION], [2.5])
This allows the configuration of input files such as Makefile.in
(generated from Makefile.am
) to rely on @PACKAGE_VERSION@
inside those files being replaced by 2.5
.
There's nothing wrong with your approach if it works, but you might consider using AS_VAR_SET([hello_version], [AC_PACKAGE_VERSION])
to set the hello_version
shell variable and src/helloworld-${hello_version}.pc
in Autoconf input. This way, even if Autoconf no longer exposes a PACKAGE_VERSION
shell variable in some future release, your code won't break because you'll be relying upon your own hello_version
variable.
As an aside, it's a bit irregular to use helloworld-2.5.pc
when the helloworld
version is 1.0 or greater (i.e. the API is stable). It's common to see helloworld.pc
, except then there's the problem of what happens when you release 3.0 and replace the installed 2.x version of helloworld.pc
with the 3.0 version: assuming you're using semantic versioning, 3.0 is incompatible with 2.x, and any code relying on something like pkg-config --libs helloworld
will break.
You might then consider using helloworld-2.pc
instead and when you release 3.0, you'd instead have helloworld-3.pc
to avoid users of your library linking the incorrect/incompatible library (and also allowing users the option of moving to the new version at their own pace); one can also apply this idea in Automake for a version-specific header directory:
## SOURCE PATH => INSTALL PATH
## include/hello.h => $(includedir)/helloworld-2/hello.h
helloincludedir = @includedir@/helloworld-@hello_major@
helloinclude_HEADERS = include/hello.h
Autoconf also allows you to specify an output file's inputs, so an output file src/helloworld-${hello_major}.pc
in the build directory could be generated from src/helloworld.pc.in
in the source directory without you needing to update the src/helloworld.pc.in
filename when moving from 2.x to 3.0; this could also be used with AC_INIT
if you're OK with macros, allowing you to control the version info in one central location:
m4_define([hello_version_major], [2]) dnl
m4_define([hello_version_minor], [5]) dnl
m4_define([hello_version], [hello_version_major[.]hello_version_minor]) dnl
AC_PREREQ([2.69])
AC_INIT([libhelloworld], [hello_version])
AS_VAR_SET([hello_major], [hello_version_major])
AS_VAR_SET([hello_minor], [hello_version_minor])
# For automake and configuration of pkg-config file
AC_SUBST([hello_major])
AC_SUBST([hello_minor])
AC_SUBST([hello_version])
...
AC_CONFIG_FILES([
Makefile
src/Makefile
src/helloworld-]hello_version_major[.pc:src/helloworld.pc.in
])
AC_OUTPUT
I realize it looks surprisingly more complicated than one might expect, but that's Autoconf for you. Note that I had to use some odd quoting in AC_CONFIG_FILES
to make use of the macro. Using
src/helloworld-${hello_major}.pc:src/helloworld.pc.in
instead of the macro resulted in a crippled config.status
file being generated in Autoconf 2.69 (try config.status
with no arguments, then config.status src/helloworld-2.pc
to see the issue); I haven't tested any other versions. I've reported the bug, but the macro works until the next release.