Discussion:
AC_SUBST'ing foodir correctly?
Wouter Verhelst
2016-05-24 15:12:41 UTC
Permalink
Hi,

I'm adding a systemd unit to my package. To that end, I'm checking if
there is a pkg-config .pc file for systemd which sets a variable
"systemdsystemunitdir", and am trying to install the systemd unit in
that location.

I'm currently doing this:

AC_MSG_CHECKING([for systemd unit file locations])
AC_ARG_ENABLE(
systemd,
AS_HELP_STRING([--disable-systemd],[Do not install systemd support files (or use --enable-systemd to fail build when not available)]),
[
if test "x$enableval" = "xyes"; then
ENABLE_SYSTEMD=yes
else
ENABLE_SYSTEMD=no
fi
],[]
)

if test "x$ENABLE_SYSTEMD" != "xno"; then
PKG_CHECK_VAR([SYSTEMDUNIT],[systemd],systemdsystemunitdir],[AC_SUBST([systemdunitdir], [$SYSTEMDUNIT])])
fi

and then in my Makefile.am:

if SYSTEMD
systemdunit_DATA = ***@.service
endif

(if you need the full files, they're in the git repository at
git.debian.org/users/wouter/nbd.git)

However, now my "make distcheck" fails, because the "make install"
target disregards DESTDIR and tries to install files in the actual
systemd unit directory, rather than the staging one. Clearly this means
I'm doing something wrong, but I'm not sure what the proper way for
doing this would be.

Help?
--
< ron> I mean, the main *practical* problem with C++, is there's like a dozen
people in the world who think they really understand all of its rules,
and pretty much all of them are just lying to themselves too.
-- #debian-devel, OFTC, 2016-02-12
Nick Bowler
2016-05-24 16:06:52 UTC
Permalink
Post by Wouter Verhelst
I'm adding a systemd unit to my package. To that end, I'm checking if
there is a pkg-config .pc file for systemd which sets a variable
"systemdsystemunitdir", and am trying to install the systemd unit in
that location.
[snip configure script computes systemdunitdir from pkg-config]
Post by Wouter Verhelst
if SYSTEMD
endif
(if you need the full files, they're in the git repository at
git.debian.org/users/wouter/nbd.git)
However, now my "make distcheck" fails, because the "make install"
target disregards DESTDIR and tries to install files in the actual
systemd unit directory, rather than the staging one. Clearly this means
I'm doing something wrong, but I'm not sure what the proper way for
doing this would be.
I suspect it is not the DESTDIR check which is failing -- the problem
is that your installation directory ignores prefix. The package must
install all files into ${prefix}-relative locations by default.

Basically, distcheck is telling you that unprivileged installs will
fail because they try to install to /usr somewhere.

Here are some basic options, in increasing order of complexity:

- Don't install the unit files (user can copy them manually).

- Don't autodetect at all: just default to some ${prefix}-relative
installation directory and allow the user to change it manually.
E.g., make systemdunitdir=/path/to/wherever.

- Munge the autodetected path into something relative to ${prefix}.

See "Installing to Hard-Coded Locations"[1] in the Automake manual for
some more information on this topic.

[1] https://www.gnu.org/software/automake/manual/automake.html#Hard_002dCoded-Install-Paths

Cheers,
Nick
Mathieu Lirzin
2016-05-24 16:11:47 UTC
Permalink
Hi,
Post by Wouter Verhelst
I'm adding a systemd unit to my package. To that end, I'm checking if
there is a pkg-config .pc file for systemd which sets a variable
"systemdsystemunitdir", and am trying to install the systemd unit in
that location.
AC_MSG_CHECKING([for systemd unit file locations])
AC_ARG_ENABLE(
systemd,
AS_HELP_STRING([--disable-systemd],[Do not install systemd support files (or use --enable-systemd to fail build when not available)]),
[
if test "x$enableval" = "xyes"; then
ENABLE_SYSTEMD=yes
else
ENABLE_SYSTEMD=no
fi
],[]
)
if test "x$ENABLE_SYSTEMD" != "xno"; then
PKG_CHECK_VAR([SYSTEMDUNIT],[systemd],systemdsystemunitdir],[AC_SUBST([systemdunitdir], [$SYSTEMDUNIT])])
fi
if SYSTEMD
endif
(if you need the full files, they're in the git repository at
git.debian.org/users/wouter/nbd.git)
This URL doesn't work for me.
Post by Wouter Verhelst
However, now my "make distcheck" fails, because the "make install"
target disregards DESTDIR and tries to install files in the actual
systemd unit directory, rather than the staging one. Clearly this means
I'm doing something wrong, but I'm not sure what the proper way for
doing this would be.
‘systemdsystemunitdir’ seems not affected by DESTDIR because IIUC
PKG_CHECK_VAR set it to something like "/lib/systemd/system" instead of
"${libdir}/systemd/system".

I suppose it would work better to define it manually like
this:

if SYSTEMD
systemdunitdir = $(libdir)/systemd/system
systemdunit_DATA = ***@.service
endif

and keep only the feature test in configure.ac followed with the
Automake conditional.
--
Mathieu Lirzin
Wouter Verhelst
2016-05-26 14:31:07 UTC
Permalink
Post by Mathieu Lirzin
Post by Wouter Verhelst
(if you need the full files, they're in the git repository at
git.debian.org/users/wouter/nbd.git)
This URL doesn't work for me.
Sorry, that should've been http://anonscm.debian.org/cgit/users/wouter/nbd.git/
(I typed it from memory, incorrectly as always :)
Post by Mathieu Lirzin
Post by Wouter Verhelst
However, now my "make distcheck" fails, because the "make install"
target disregards DESTDIR and tries to install files in the actual
systemd unit directory, rather than the staging one. Clearly this means
I'm doing something wrong, but I'm not sure what the proper way for
doing this would be.
‘systemdsystemunitdir’ seems not affected by DESTDIR because IIUC
PKG_CHECK_VAR set it to something like "/lib/systemd/system" instead of
"${libdir}/systemd/system".
I suppose it would work better to define it manually like
if SYSTEMD
systemdunitdir = $(libdir)/systemd/system
endif
Well. That would work, yes, but it wouldn't work *better*. The whole
point is that I do not want to hardcode such things, so that if a user
installs systemd units in </usr/local/brokenstuff/systemd> and the
pkg-config files are where they need to be, everything works as expected.

I was under the impression that automake looks at DESTDIR for every
foodir it looks at, but apparently that's not the case then? That seems
broken; after all, I don't think a staging directory should depend on
whether or not something was part of a given prefix. Is there any
explanation available somewhere on why this behaviour occurs? Would a
patch that changes this behaviour be acceptable?
--
< ron> I mean, the main *practical* problem with C++, is there's like a dozen
people in the world who think they really understand all of its rules,
and pretty much all of them are just lying to themselves too.
-- #debian-devel, OFTC, 2016-02-12
Mathieu Lirzin
2016-05-30 14:48:57 UTC
Permalink
Post by Wouter Verhelst
Post by Mathieu Lirzin
‘systemdsystemunitdir’ seems not affected by DESTDIR because IIUC
PKG_CHECK_VAR set it to something like "/lib/systemd/system" instead of
"${libdir}/systemd/system".
I suppose it would work better to define it manually like
if SYSTEMD
systemdunitdir = $(libdir)/systemd/system
endif
Well. That would work, yes, but it wouldn't work *better*. The whole
point is that I do not want to hardcode such things, so that if a user
installs systemd units in </usr/local/brokenstuff/systemd> and the
pkg-config files are where they need to be, everything works as expected.
You are right, that would be better. My understanding is that
pkg-config files are supposed to define variables in terms of 'prefix'
as described in pkg-config(1)

--8<---------------cut here---------------start------------->8---
prefix=/home/hp/unst # this defines a variable
exec_prefix=${prefix} # defining another variable in terms of the first
libdir=${exec_prefix}/lib
includedir=${prefix}/include
--8<---------------cut here---------------end--------------->8---

but “systemd.pc” isn't doing that.
Post by Wouter Verhelst
I was under the impression that automake looks at DESTDIR for every
foodir it looks at, but apparently that's not the case then? That seems
broken; after all, I don't think a staging directory should depend on
whether or not something was part of a given prefix. Is there any
explanation available somewhere on why this behaviour occurs? Would a
patch that changes this behaviour be acceptable?
Every default installation directories are expected to be subdirectories
of the 'prefix' variable. This is verified by ‘make distcheck’ and
specified in GNU coding standards:

https://www.gnu.org/prep/standards/html_node/Directory-Variables.html#Directory-Variables

So it is unlikely that a patch is going to be accepted in Automake.
However I guess the default pkg-config file could be fixed in Systemd.

Thanks,
--
Mathieu Lirzin
Wouter Verhelst
2016-06-23 13:18:51 UTC
Permalink
Hi Mathieu,

Sorry for the late reply -- been busy, you know how it goes.
Post by Mathieu Lirzin
Post by Wouter Verhelst
Post by Mathieu Lirzin
‘systemdsystemunitdir’ seems not affected by DESTDIR because IIUC
PKG_CHECK_VAR set it to something like "/lib/systemd/system" instead of
"${libdir}/systemd/system".
I suppose it would work better to define it manually like
if SYSTEMD
systemdunitdir = $(libdir)/systemd/system
endif
Well. That would work, yes, but it wouldn't work *better*. The whole
point is that I do not want to hardcode such things, so that if a user
installs systemd units in </usr/local/brokenstuff/systemd> and the
pkg-config files are where they need to be, everything works as expected.
You are right, that would be better. My understanding is that
pkg-config files are supposed to define variables in terms of 'prefix'
as described in pkg-config(1)
--8<---------------cut here---------------start------------->8---
prefix=/home/hp/unst # this defines a variable
exec_prefix=${prefix} # defining another variable in terms of the first
libdir=${exec_prefix}/lib
includedir=${prefix}/include
--8<---------------cut here---------------end--------------->8---
but “systemd.pc” isn't doing that.
I'm not convinced that is the right way to fix this. Yes, perhaps the
systemd .pc file could export $prefix-prefixed variables. However, that
doesn't help -- it's *systemd*'s prefix it would be prefixing with, not
nbd's prefix. If someone installed systemd with --prefix=/opt, and then
installed nbd with --prefix=/usr, then in your suggestion, nbd would be
installing the systemd unit files into /usr/lib/systemd, where they
should really have been installed into /opt/lib/systemd.

It's not limited to that kind of stuff, either -- it would also break
if someone were to configure systemd with an explicit --libdir=, where
the .pc file is generated with AC_CONFIG_FILES.

Please remember that I'm installing a file for systemd to use, not a
file for nbd to use (in this particular case it's a systemd
configuration file, but it could equally well have been a plugin, or an
extension, or whatever).
Post by Mathieu Lirzin
Post by Wouter Verhelst
I was under the impression that automake looks at DESTDIR for every
foodir it looks at, but apparently that's not the case then? That seems
broken; after all, I don't think a staging directory should depend on
whether or not something was part of a given prefix. Is there any
explanation available somewhere on why this behaviour occurs? Would a
patch that changes this behaviour be acceptable?
Every default installation directories are expected to be subdirectories
of the 'prefix' variable. This is verified by ‘make distcheck’ and
https://www.gnu.org/prep/standards/html_node/Directory-Variables.html#Directory-Variables
So it is unlikely that a patch is going to be accepted in Automake.
Not even for the --foreign mode of automake?
Post by Mathieu Lirzin
However I guess the default pkg-config file could be fixed in Systemd.
That would mean the nbd build will break for everyone who did a
non-default build of systemd... not a very attractive proposal.
--
< ron> I mean, the main *practical* problem with C++, is there's like a dozen
people in the world who think they really understand all of its rules,
and pretty much all of them are just lying to themselves too.
-- #debian-devel, OFTC, 2016-02-12
Mike Miller
2016-06-27 21:35:53 UTC
Permalink
Post by Wouter Verhelst
Please remember that I'm installing a file for systemd to use, not a
file for nbd to use (in this particular case it's a systemd
configuration file, but it could equally well have been a plugin, or an
extension, or whatever).
I have run across this dilemma several times in my use of automake. Yes,
this is a recurring tension between automake's $(prefix)-rooted design
philosophy and the practical need to install a file in another project's
configuration directory or namespace.
Post by Wouter Verhelst
Post by Mathieu Lirzin
Post by Wouter Verhelst
I was under the impression that automake looks at DESTDIR for every
foodir it looks at, but apparently that's not the case then? That seems
broken; after all, I don't think a staging directory should depend on
whether or not something was part of a given prefix. Is there any
explanation available somewhere on why this behaviour occurs? Would a
patch that changes this behaviour be acceptable?
I think the point is that automake by design expects both that every
file will be installed under $(prefix) by default *and* that $(DESTDIR)
will be respected if defined.

You can of course choose to break either one or both of those
assumptions, but then other features of automake may break, such as the
'distcheck' target.
Post by Wouter Verhelst
Post by Mathieu Lirzin
Every default installation directories are expected to be subdirectories
of the 'prefix' variable. This is verified by ‘make distcheck’ and
https://www.gnu.org/prep/standards/html_node/Directory-Variables.html#Directory-Variables
So it is unlikely that a patch is going to be accepted in Automake.
Not even for the --foreign mode of automake?
I can't speak for the automake maintainers, but to me this seems like a
different class of incompatibility than what --foreign covers.
Post by Wouter Verhelst
Post by Mathieu Lirzin
However I guess the default pkg-config file could be fixed in Systemd.
That would mean the nbd build will break for everyone who did a
non-default build of systemd... not a very attractive proposal.
IMHO the best way to address this is to configure your project
differently for 'distcheck' from a typical system install. We already do
this for every autotools-based project that uses $(sysconfdir).

One way would be to defer the "correct" definition of $(systemdunitdir)
until the sysadmin installs it or the deb or rpm package is built. Your
default build could define it to be rooted anywhere under $(prefix), and
it would be up to the caller of 'make install' to override as needed.
This is pretty simple, but also easy to forget.

Another way would be to default $(systemdunitdir) as you have it, and
require that 'make distcheck' is called with a command-line override
based on $(prefix) so that it passes. Also simple, but the only one who
needs to remember it is the maintainer running 'distcheck'.

If automake supported something like a $(AM_DISTCHECK_MAKEFLAGS)
variable, that might make the latter option a little easier.

A third option might be to either reuse your --enable-systemd option or
add a different AC_ARG_ENABLE option to select whether the value of
$(systemdunitdir) is rooted in $(prefix) or comes straight from
systemd.pc. Specifically, something like

./configure --disable-systemd ## not installed
./configure --enable-systemd=system ## installed in /lib/systemd
./configure --enable-systemd=rooted ## installed in $(libdir)/systemd
./configure --enable-systemd ## choose your favorite default

One advantage of using a configure option over a makefile variable
override is that there *is* a $(AM_DISTCHECK_CONFIGURE_FLAGS), so you
can encode exactly how 'make distcheck' differs from a default build, if
that's what you want.

HTH,
--
mike
Loading...