FAQ
I've been receiving bug reports that 5.8.0's MakeMaker broke this style:

perl Makefile.PL PREFIX=foo
make test
make install PREFIX=bar

ie. configure and build the module in one prefix, but actually install it in
another. This is commonly used for packaging like dpkgs and RPMs.

perl Makefile.PL PREFIX=/where/it/will/ultimately/be/installed
make test
make install PREFIX=/directory/where/im/building/the/package

It broke because the make variables no longer retain the $(PREFIX). So
5.6.1's MakeMaker you might have:

PREFIX=foo
INSTALLPRIVLIB = $(PREFIX)/lib/perl/5.6.1
INSTALLSITELIB = $(PREFIX)/lib/perl/5.6.1

which means "make install PREFIX=something/else" will still work. 5.8.0's
MakeMaker fully expanded the directories:

PREFIX=foo
INSTALLPRIVLIB = foo/lib/perl/5.6.1
INSTALLSITELIB = foo/lib/perl/5.6.1

It made a lot of the internals easier and it wasn't realized that "make
install PREFIX=something/else" was important.


The simple fix might be to just put $(PREFIX) back into the INSTALL*
variables. But it gets complicated because there are really *four*
prefixes, not one. 5.8.0's MakeMaker tries to honor all of them properly
and it makes things complicated.

Here's a quick tour of the prefixes:

Core libraries:
Stuff that comes with the core or CPAN distributions of core modules.
Anything with INSTALLDIRS => 'perl' in the Makefile.PL. If you download
Test::Harness from CPAN it goes in here. This is PREFIX inside MakeMaker
and $Config{prefix} in Config. Hereafter I'll refer to it as PERLPREFIX to
disambiguate it from the user prefix.

CPAN ('site') libraries:
The default prefix for MakeMaker, so most anything you install from CPAN
will go here. SITEPREFIX in the Makefile and $Config{siteprefix}.

Vendor libraries:
Anything installed from your "vendor". For example, Redhat, Debian,
Solaris, Apple, etc... If you install the libcgi-pm-perl Debian package it
will go here. VENDORPREFIX in the Makefile and $Config{vendorprefix}.
While the concept of vendor libraries has been in Perl for a while,
MakeMaker was only recently adapted to support it. Some vendors have had
their own patched versions for a while (Debian is one).

User specified prefix:
This is the prefix specified by "perl Makefile.PL PREFIX=~" or "make install
PREFIX=~". If set will override all the other prefixes. It is currently
represented in the Makefile by PREFIX which confuses things.


The problem: What happens when your core prefix and your site prefix are
different? [1]

Consider the following. Let's say you run "perl Makefile.PL".
Your $Config{prefix} is /usr and $Config{siteprefix} is /opt. So the
Makefile might have:

PREFIX = # no user prefix given
PERLPREFIX = /usr
SITEPREFIX = /opt

and your INSTALL* variables should look something like this:

# where core libraries will go.
INSTALLPRIVLIB = $(PERLPREFIX)/lib/perl/5.8.0

# where site libraries will go.
INSTALLSITELIB = $(SITEPREFIX)/lib/perl/5.8.0

and you run "make install" and everything goes in the right place. That
works fine. But that's the easy part.

What if you had said "make install PREFIX=somewhere/else". The INSTALL*
variables aren't using $(PREFIX) so it won't work.

What about "make install SITEPREFIX=somewhere/else". That will change where
CPAN modules go, but what if you were installing Test::Harness? You have to
change the PERLPREFIX, too. And that's no good. Users shouldn't have to
know if what they're installing is a core or site module.


Somehow the SITEPREFIX and PERLPREFIX have to be PREFIX if and only if
PREFIX was set. Using an imaginary Perl/make fusion syntax I might say:

SITEPREFIX = $(PREFIX) ? $(PREFIX) : /opt
PERLPREFIX = $(PREFIX) ? $(PREFIX) : /usr

And then all these combinations work:

perl Makefile.PL # PREFIX not set, SITE/PERLPREFIX use defaults
make install # ditto

perl Makefile.PL PREFIX=~ # PREFIX set, SITE/PERLPREIFX use PREFIX
make install # ditto

perl Makefile.PL # PREFIX not set, SITE/PERLPREFIX use defaults
make install PREFIX=~ # PREFIX set, SITE/PERLPREFIX use PREFIX

perl Makefile.PL PREFIX=~ # PREFIX set, SITE/PERLPREFIX use PREFIX
make install PREFIX=foo # PREFIX reset, SITE/PERLPREFIX use new PREFIX

and this even works:

perl Makefile.PL PREFIX=~ # PREFIX set, SITE/PERLREFIX use PREFIX
make install SITEPREFIX=foo # PREFIX set, SITEPREFIX set.
# PERLPREFIX uses PREFIX. SITEPREFIX
# overriden by command line arg.

unfortunately, there's no portable way to do if/else logic in make that I
know of. [2] So I proposed the problem to the Portland Perl Mongers and 'lo
and behold they had a solution:

PERLPREFIX = $(PERLRUN) -e 'q{$(PREFIX)} ? q{$$(PREFIX)} : "/usr"'
SITEPREFIX = $(PERLRUN) -e 'q{$(PREFIX)} ? q($$(PREFIX)} : "/opt"'

I think that'll work. Thoughts?


[1] I'm ignoring the vendor prefix just to make things simpler.

[2] Potential challengers: remember we're covering Gnu make, Perl make, Sun
make, Borland make, nmake, dmake, mmk/mms (ie. VMS Module Management System)
and MPW's build tool (ie. MacOS Classic).


--

Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
How can you get very far,
If you don't know Who You Are?
How can you do what you ought,
If you don't know What You've Got?

Search Discussions

  • Michael G Schwern at Nov 26, 2002 at 11:18 am

    On Mon, Nov 25, 2002 at 10:14:07PM -0800, Michael G Schwern wrote:
    PERLPREFIX = $(PERLRUN) -e 'q{$(PREFIX)} ? q{$$(PREFIX)} : "/usr"'
    SITEPREFIX = $(PERLRUN) -e 'q{$(PREFIX)} ? q($$(PREFIX)} : "/opt"'

    I think that'll work. Thoughts?
    Of course it was all too easy. I'm wrong.

    Values on the RHS of a macro assigment aren't run through the shell, of
    course. So the above just creates a macro containing a perl oneliner, not
    the results of that one liner.

    If it can be guaranteed that the *PREFIX macros, and any macro with
    $(*PREFIX) in it, is always used on the shell line, this works.

    PERLPREFIX = `$(PERLRUN) -e 'q{$(PREFIX)} ? q{$(PREFIX)} : "/usr"'`
    SITEPREFIX = `$(PERLRUN) -e 'q{$(PREFIX)} ? q($(PREFIX)} : "/opt"'`

    but that situation is only true on Unix, and its precarious at best. And it
    means that little Perl program is run over and over and over again as the
    Makefile runs, crushingly slow on Windows. Besides, I have no idea what the
    portable shell equivalent to `` is.

    I need some way to define a macro using the results of a shell command, as I
    had originally assumed.

    Otherwise, I need a portable version of this:

    if PREFIX
    PERLPREFIX = $(PREFIX)
    SITEPREFIX = $(PREFIX)
    else
    PERLPREFIX = /usr
    SITEPREFIX = /top
    endif

    Gnu make can do something like that, but I doubt most other make variants
    can.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    It's Airplane Glue sniffing time!
  • Abigail at Nov 26, 2002 at 12:45 pm

    On Tue, Nov 26, 2002 at 03:17:05AM -0800, Michael G Schwern wrote:
    On Mon, Nov 25, 2002 at 10:14:07PM -0800, Michael G Schwern wrote:
    PERLPREFIX = $(PERLRUN) -e 'q{$(PREFIX)} ? q{$$(PREFIX)} : "/usr"'
    SITEPREFIX = $(PERLRUN) -e 'q{$(PREFIX)} ? q($$(PREFIX)} : "/opt"'

    I think that'll work. Thoughts?
    Of course it was all too easy. I'm wrong.

    Values on the RHS of a macro assigment aren't run through the shell, of
    course. So the above just creates a macro containing a perl oneliner, not
    the results of that one liner.

    If it can be guaranteed that the *PREFIX macros, and any macro with
    $(*PREFIX) in it, is always used on the shell line, this works.

    PERLPREFIX = `$(PERLRUN) -e 'q{$(PREFIX)} ? q{$(PREFIX)} : "/usr"'`
    SITEPREFIX = `$(PERLRUN) -e 'q{$(PREFIX)} ? q($(PREFIX)} : "/opt"'`

    but that situation is only true on Unix, and its precarious at best. And it
    means that little Perl program is run over and over and over again as the
    Makefile runs, crushingly slow on Windows. Besides, I have no idea what the
    portable shell equivalent to `` is.

    I need some way to define a macro using the results of a shell command, as I
    had originally assumed.

    Otherwise, I need a portable version of this:

    if PREFIX
    PERLPREFIX = $(PREFIX)
    SITEPREFIX = $(PREFIX)
    else
    PERLPREFIX = /usr
    SITEPREFIX = /top
    endif

    Gnu make can do something like that, but I doubt most other make variants
    can.

    PERLPREFIX=${PREFIX:-/usr}
    SITEPREFIX=${PREFIX:-/top}


    I've used that long before I heard about bash.
    It's also part of the POSIX 1003.1-2001 standard.



    Abigail
  • Michael G Schwern at Nov 26, 2002 at 9:53 pm

    On Tue, Nov 26, 2002 at 01:48:03PM +0100, Abigail wrote:
    PERLPREFIX=${PREFIX:-/usr}
    SITEPREFIX=${PREFIX:-/top}


    I've used that long before I heard about bash.
    It's also part of the POSIX 1003.1-2001 standard.
    Perl make understands it, but I can't get that to work in GNU make. POSIX
    or not, that kills it. :(

    GNU make claims to conform to "section 6.2 of IEEE Standard 1003.2-1992
    (POSIX.2)", not 2001. Is it in the 1992 standard? Not that it'll make much
    difference, but at least we can glare disapprovingly at the GNU folks.

    $ cat Makefile
    PREFIX=foo
    SITEPREFIX=${PREFIX:-/usr}

    prefixes:
    @echo PREFIX = $(PREFIX)
    @echo SITEPREFIX = $(SITEPREFIX)

    $ pmake prefixes
    Reading /usr/local/share/perl/5.6.1/Make.pm
    Reading /home/schwern/tmp/Makefile
    PREFIX = foo
    SITEPREFIX = /usr

    $ make -v
    GNU Make version 3.79.1, by Richard Stallman and Roland McGrath.
    Built for powerpc-unknown-linux-gnu
    <snip>

    $ make prefixes
    PREFIX = foo
    SITEPREFIX =


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    You see, in this world there's two kinds of people. Those with loaded
    guns, and those who dig. Dig.
    -- Blondie, "The Good, The Bad And The Ugly"
  • Paul Smith at Nov 26, 2002 at 10:13 pm
    %% Michael G Schwern writes:

    mgs> On Tue, Nov 26, 2002 at 01:48:03PM +0100, Abigail wrote:
    PERLPREFIX=${PREFIX:-/usr}
    SITEPREFIX=${PREFIX:-/top}
    I've used that long before I heard about bash.
    It's also part of the POSIX 1003.1-2001 standard.
    This is wrong. I'm not exactly sure what you're trying to say here, but
    there is no make I know of that accepts exactly that syntax. That's
    _shell_ syntax. Maybe that's what you meant by part of the
    standard... it's certainly syntax that's valid in POSIX shell, and also
    in almost all pre-POSIX Bourne shells, but it's not make syntax of any
    flavor.

    You mean:

    PERLPREFIX = $${PREFIX:-/usr}
    SITEPREFIX = $${PREFIX:-/top}
    ^
    (note the escaped dollar). You want the _shell_ to expand this
    variable, not make.

    mgs> Perl make understands it, but I can't get that to work in GNU
    mgs> make. POSIX or not, that kills it. :(

    That's because it's an invalid syntax...

    mgs> GNU make claims to conform to "section 6.2 of IEEE Standard
    mgs> 1003.2-1992 (POSIX.2)", not 2001. Is it in the 1992 standard?
    mgs> Not that it'll make much difference, but at least we can glare
    mgs> disapprovingly at the GNU folks.

    We'll glare disapprovingly right back atcha! :-P :)

    --
    -------------------------------------------------------------------------------
    Paul D. Smith <pausmith@nortelnetworks.com> HASMAT--HA Software Mthds & Tools
    "Please remain calm...I may be mad, but I am a professional." --Mad Scientist
    -------------------------------------------------------------------------------
    These are my opinions---Nortel Networks takes no responsibility for them.
  • Paul D. Smith at Nov 26, 2002 at 10:22 pm
    Sorry, I sent that wearing the wrong hat :(.

    --
    -------------------------------------------------------------------------------
    Paul D. Smith <psmith@gnu.org> Find some GNU make tips at:
    http://www.gnu.org http://make.paulandlesley.org
    "Please remain calm...I may be mad, but I am a professional." --Mad Scientist
  • Slaven Rezic at Nov 26, 2002 at 10:19 pm

    Michael G Schwern writes:
    On Tue, Nov 26, 2002 at 01:48:03PM +0100, Abigail wrote:
    PERLPREFIX=${PREFIX:-/usr}
    SITEPREFIX=${PREFIX:-/top}


    I've used that long before I heard about bash.
    It's also part of the POSIX 1003.1-2001 standard.
    Perl make understands it, but I can't get that to work in GNU make. POSIX
    or not, that kills it. :(
    It works neither with pmake (the make shipped with FreeBSD).
    GNU make claims to conform to "section 6.2 of IEEE Standard 1003.2-1992
    (POSIX.2)", not 2001. Is it in the 1992 standard? Not that it'll make much
    difference, but at least we can glare disapprovingly at the GNU folks.
    --
    Slaven Rezic - slaven.rezic@berlin.de

    tkrevdiff - graphical display of diffs between revisions (RCS or CVS)
    http://ptktools.sourceforge.net/#tkrevdiff

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupperl5-porters @
categoriesperl
postedNov 26, '02 at 10:12a
activeNov 26, '02 at 10:22p
posts7
users5
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase