automake
[Top][All Lists]
Advanced

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

Re: Calculating Perl module installation directory


From: Stefano Lattarini
Subject: Re: Calculating Perl module installation directory
Date: Wed, 7 Dec 2011 17:54:59 +0100
User-agent: KMail/1.13.7 (Linux/2.6.30-2-686; KDE/4.6.5; i686; ; )

On Wednesday 07 December 2011, Adam Spiers wrote:
> On Tue, Dec 6, 2011 at 7:16 PM, Stefano Lattarini
>
> [SNIP]
>
> > Warning: the ${var#pattern} substitution is unfortunately unportable to
> > Bourne shells that lack full POSIX compliance, such as Solaris 10 /bin/sh
> > (and I guess many other vendor /bin/sh).  While almost all systems have
> > a (mostly-)POSIX-compliant shell installed somewhere (for example, on
> > Solaris 10 there is /usr/xpg4/bin/sh), and while autoconf-generated
> > configure scripts usually take care of re-executing themelves with a
> > such a better shell when /bin/sh is not POSIX, you can't be sure that
> > this will always happen.  If you still want to use POSIX shell constructs
> > not portable to traditional Bourne shells in your configure script, you
> > might want to ask on the autoconf list whether and how it is possible to
> > force configure to re-execute itslef with a POSIX-complant shell, or give
> > a clear error message when no one is found.
> 
> Hrmph :-)  How about this as a workaround?
> 
>   pmdir_relative_path=$( echo "${installsitelib}" | sed -e 
> "s!^$siteprefix/!!" )
>
Alas, command substitutions with $(...) are as well unportable to
old-style Bourne shells (like Solaris 10 /bin/sh).  You'll have to
use backticks instead: `...`

Apart from that, what you do should be mostly OK, assuming that:
 1. "${installsitelib}" does not contain backslashes nor starts with a `-'
    (and I assume these are fair assumptions), otherwise echo might get
    confused; and
 2. `$siteprefix' does not contain regular expression characters that
    might mess up the sed invocation (this too could be safely assumed
     I guess; even the case in which $siteprefix conains literal dots
    `.' should be safe).

But then it occurs to me that, since your configure script assumes the
presence of perl, you could simplify all of this by accessing and
munging the values of $installsitelib and $siteprefix from perl itself,
using the `Config' built-in module; these values are indeed accessible:

 $ perl -e 'use Config; print $Config{siteprefix} . "\n"'
 /usr/local
 $ perl -e 'use Config; print $Config{installsitelib} . "\n"'
 /usr/local/share/perl/5.12.4

Details about how to do so are left as an excercise to the reader :-)

> It seems to work fine.  I am also providing installation via
> Module::Build, so crippled systems could use that instead, I guess.
>
> >> AC_CONFIG_COMMANDS_POST([eval echo "Perl modules will be installed to 
> >> $PMDIR"])
> >> AC_SUBST([PMDIR])
> >>
> >> except that now the default value in the help text is wrong, and I
> >> don't know how to fix it.
> >>
> >> Is this a reasonable approach, and if so, how can I dynamically
> >> generate the correct default value in the help text?
> >
> > Maybe something like (untested!):
> >
> >  eval "`$PERL -V:installsitelib -V:siteprefix`"
> >  pmdir_relative_path=${installsitelib#$siteprefix/}
> 
> Yeah, I had only just realised that you can embed normal shell-code
> inside configure.ac - doh :-)
> 
> >  AC_ARG_ENABLE(
> 
> I think you meant AC_ARG_WITH ;-)
> 
Oops, sorry.  Copy & paste typo.

> >    [pmdir],
> >    [AS_HELP_STRING(
> >      [--with-pmdir=DIR],
> >      [Perl modules are in DIR [[LIBDIR/$pmdir_relative_path]]])],
> >    [PMDIR=${withval}],
> >    [PMDIR='${prefix}'/$pmdir_relative_path])
> >
> > (note that I've also used the autoconf's AS_HELP_STRING macro here, that
> > should ensure a better formatting of the help message).
> 
> Awesome! ... but $pmdir_relative_path doesn't get expanded inside the
> help string.  The docs for AS_HELP_STRING say that the
>
This sounds strange... can you copy and past the output from the help
screen?

>      second argument of `AS_HELP_STRING' is treated as a whitespace
>      separated list of text to be reformatted, and is not subject to
>      macro expansion.  Since it is not expanded, it should not be
>      double quoted.
>
This means that you should drop the outmost pair of square brackets from
`[[LIBDIR/$pmdir_relative_path]]' the, to avoid getting spurious `[' and
`]' in the output.  But this has nothing to do with the fact that
$pmdir_relative_path is not expanded (it is not an m4 macro).

> However, even without using AS_HELP_STRING, I cannot figure out how to
> expand shell variables inside AC_ARG_WITH :-(  Any ideas?
>
There should be no problem with such an expansion ... can you give
us more information about the details of the failure, or even post
the entire generated configure script (compressed please)?  It might
be a mistake of mine, but I can't tell without more details.

> There was another problem.  prefix defaults to /usr/local, but if
> $PERL -V:siteprefix is not /usr/local (e.g. openSUSE Perl has
> siteprefix as /usr) then   will be a path not included in @INC by
> default.
>
Yeah; and making the configure script print a warning about this might
be worthwhile.  But you then should take care of ensuring that this
message gets printed only if PMDIR truly is not in the default @INC
of the user's perl.  (Update: I see you already do something similar
in your configure.ac; good).

> In this case the installation only works if the user set
> PERL5LIB, or did
> 
>   eval `perl -V:siteprefix`
>   ./configure --prefix=$siteprefix
> 
> My first inclination was to add:
> 
>   AC_PREFIX_DEFAULT($siteprefix)
>
Evil!  This would mean that, if I'd do a simple:

  ./configure && make && sudo make install

your package would install itself in /usr on my system.  I would
definitely not like that, and probably many users agree with me.

> but it turns out that this gets expanded near the top of ./configure,
> which is much earlier than where siteprefix gets set.  I found an evil
> hack which works around this:
> 
>   ac_default_prefix=$siteprefix
> 
> but ac_default_prefix is not documented and presumably not part of the
> public API.
>
Yes, this all seems rather brittle and a source of potential problems.
I'd advise you not to follow this road.

Maybe you can recognize a special argument for `--with-pmdir' [1]
that will cause configure to bypass the munging of $installsitelib,
and just define PMDIR to this unmodified value.  This is something
that should be documented in the INSTALL and README file of course;
and probably added to the configure help screen as well.

[1] --with-pmdir= ... "aks-perl"? "perl-style"? "distro-default"?
    I suck at choosing names :-) 

> Here are the latest versions ...
> 
>   https://github.com/aspiers/stow/blob/pmdir-default/configure.ac
>   https://github.com/aspiers/stow/blob/pmdir-default/Makefile.am
>
Thanks for the reference.  A couple of random remarks:

> AC_PATH_PROGS([PERL], [perl] [perl5], [false])
> if test "x$PERL" = xfalse
> then
>  AC_MSG_WARN([WARNING: Perl not found; you must edit line 1 of 'stow'])
> fi
>
IMO you should just abort the configure process if perl cannot be found.
This is especially true since later in the script you use a call to perl
to determine the default directory where to install *.pm files -- so that
you might end up installing to sem-random directories if a perl command
isn't available!

> # N.B. ${var#pattern} will not work with some shells, such as
> # Solaris 10's /bin/sh :-(
> #
> # 
> http://thread.gmane.org/gmane.comp.sysutils.automake.general/13203/focus=13204
> #
For issues like this, you might want to reference the autoconf
manual as well, which describes in detail many quirks, limitations
and portability problems of various UNIX tools (and especially of
the shell).  For example, about this isue, it says:

  ${#var}
  ${var%word}
  ${var%%word}
  ${var#word}
  ${var##word}

  Posix requires support for these usages, but they do not work with many
  traditional shells, e.g., Solaris 10 /bin/sh.  Also, pdksh 5.2.14
  mishandles some word forms. For example if ‘$1’ is ‘a/b’ and ‘$2’ is
  ‘a’, then ‘${1#$2}’ should yield ‘/b’, but with pdksh it yields the
  empty string. 

It's a very recommended reading!
<http://www.gnu.org/software/autoconf/manual/autoconf.html#Portable-Shell>

> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> !! WARNING!
> !!
> !! Perl modules will be installed to $PMDIR.
> !! Unless you override the value of prefix at make-time,
> !! this will expand to
> !!
> !!   $pmdir
> !!
> !! which is not in $PERL's built-in @INC.
> !!
> !! This means you will have to set PERL5LIB appropriately
> !! before running Stow, e.g.
> !!
> !!   export PERL5LIB=$pmdir
> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
>
This is suboptimal, and I also find it very user unfriendly.  IMHO you
should add to your scripts a BEGIN block where the value of @INC is
extended with the value of $PMDIR determined at configure time.  This
is what automake (itself a perl program) does to ensure it can find its
private libraries after installation.

Regards,
  Stefano



reply via email to

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