Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Install custom files

2 views
Skip to first unread message

Simon Ruderich

unread,
Apr 1, 2011, 1:15:45 PM4/1/11
to module...@perl.org
Hi,

I'm trying to install custom files to a specific location which
should be relative to the given prefix/install_base/.. In this
case into share/locale. So e.g. if --prefix=/usr/local then it
should install into /usr/local/share/locale/.

I'm using Module::Build 0.340201 on Debian Squeeze.

I tried the following ($class has a method process_locale_files()
which creates the files in blib/locale, that part works just
fine):

my $build = $class->new(
...
);
$build->add_build_element('locale');
$build->install_base_relpaths(locale => 'locale');
$build->create_build_script;

But no files get installed. After some testing it looks like
$build->install_base_relpaths() doesn't work at all -
$build->install_base_relpaths(lib => 'whatever') does nothing for
me, my .pm files are still installed in the same place.

I could use $build->install_path(locale => '...') but that
requires an absolute path. At the moment I'm using the following
hack to get the real installation path (I'm not sure if that's
even correct all the time):

sub install_base_path {
my $self = shift;

if (defined $self->install_base) {
return $self->install_base;
} elsif (defined $self->prefix) {
return $self->prefix;
} else {
return $self->original_prefix->{$self->installdirs};
}
}

It seems to work, but doesn't look like a good solution. Is there
a variable which returns the absolute installation prefix? I
couldn't find any in the documentation.

Btw. the real reason why I need this is to install .po/.mo files
in share/locale. Is there a simple way to do that? I attached my
current solution (including the hack above). If there's a better
way to handle that, please tell me.

Regards,
Simon
--
+ privacy is necessary
+ using gnupg http://gnupg.org
+ public key id: 0x92FEFDB7E44C32F9

Build.PL

Leon Timmermans

unread,
Apr 1, 2011, 3:19:22 PM4/1/11
to Simon Ruderich, module...@perl.org
On Fri, Apr 1, 2011 at 9:15 PM, Leon Timmermans <faw...@gmail.com> wrote:
>  $build->install_sets($_, 'locale', catdir($build->original_prefix($_)), 'share', 'locale')) for qw/core vendor site/;

Oops, that would be a parenthesis too many:

$build->install_sets($_, 'locale', catdir($build->original_prefix($_),
'share', 'locale')) for qw/core vendor site/;

Leon Timmermans

unread,
Apr 1, 2011, 3:15:53 PM4/1/11
to Simon Ruderich, module...@perl.org
On Fri, Apr 1, 2011 at 7:15 PM, Simon Ruderich <si...@ruderich.org> wrote:
> I'm trying to install custom files to a specific location which
> should be relative to the given prefix/install_base/.. In this
> case into share/locale. So e.g. if --prefix=/usr/local then it
> should install into /usr/local/share/locale/.

How do you call your Build/Build.PL exactly? Do you call your example
with --install_base?

> I'm using Module::Build 0.340201 on Debian Squeeze.

You might want to upgrade to a more recent version of Module::Build.
«apt-get install libmodule-build-perl» should upgrade it to 0.3607.
CPAN will upgrade it to 0.38. It might solve your problems.

>    $build->add_build_element('locale');
>    $build->install_base_relpaths(locale => 'locale');

The general solution looks something like this:

use File::Spec 'catdir';

$build->add_build_element('locale');
$build->install_base_relpaths(locale => catdir('share', 'locale'));
$build->prefix_relpaths($_, locale => catdir('share', 'locale')) for


qw/core vendor site/;
$build->install_sets($_, 'locale',
catdir($build->original_prefix($_)), 'share', 'locale')) for qw/core
vendor site/;

Yeah, you need all of that for all options to work as you expect them
to. Also, you then have to figure out a way for your program to know
where to find the files, but that's a different discussion.

A much simpler solution in your case would be to use the sharedir
functionality of Module::Build (available since 0.36). It doesn't
sound like you need something sharedir can't provide.

> It seems to work, but doesn't look like a good solution. Is there
> a variable which returns the absolute installation prefix? I
> couldn't find any in the documentation.

No, that's not how it works on the inside: an absolute installation
prefix is only well-defined in a limited set of circumstances (when
using --prefix and --install_base).

Leon

Simon Ruderich

unread,
Apr 1, 2011, 3:15:19 PM4/1/11
to module...@perl.org
On Fri, Apr 01, 2011 at 07:15:45PM +0200, Simon Ruderich wrote:
> sub install_base_path {
> my $self = shift;
>
> if (defined $self->install_base) {
> return $self->install_base;
> } elsif (defined $self->prefix) {
> return $self->prefix;
> } else {
> return $self->original_prefix->{$self->installdirs};
> }
> }

Hm, found the first issue - it only works if the user specifies
the prefix/install_base when calling perl Build.PL, not when
calling ./Build. But I've no idea how to fix this. Any ideas?

Simon Ruderich

unread,
Apr 4, 2011, 9:55:24 AM4/4/11
to module...@perl.org
On Fri, Apr 01, 2011 at 09:15:53PM +0200, Leon Timmermans wrote:

> On Fri, Apr 1, 2011 at 7:15 PM, Simon Ruderich wrote:
>> I'm trying to install custom files to a specific location which
>> should be relative to the given prefix/install_base/.. In this
>> case into share/locale. So e.g. if --prefix=/usr/local then it
>> should install into /usr/local/share/locale/.
>
> How do you call your Build/Build.PL exactly? Do you call your example
> with --install_base?

Hi Leon,

Thanks for your quick response.

Yes, I tried --install_base and --prefix, both have the same
problem. It looks like --destdir also doesn't work with ./Build,
just with perl Build.PL. I'm not sure if this is expected or a
bug.

>> I'm using Module::Build 0.340201 on Debian Squeeze.

> You might want to upgrade to a more recent version of Module::Build.
> «apt-get install libmodule-build-perl» should upgrade it to 0.3607.
> CPAN will upgrade it to 0.38. It might solve your problems.

Retried with 0.38, same problem.

>> $build->add_build_element('locale');
>> $build->install_base_relpaths(locale => 'locale');
>
> The general solution looks something like this:
>
> use File::Spec 'catdir';
> …
> $build->add_build_element('locale');
> $build->install_base_relpaths(locale => catdir('share', 'locale'));
> $build->prefix_relpaths($_, locale => catdir('share', 'locale')) for
> qw/core vendor site/;
> $build->install_sets($_, 'locale',
> catdir($build->original_prefix($_)), 'share', 'locale')) for qw/core
> vendor site/;

Hm, looks really complicated for such a simple task :-/

But it works fine, thanks for your help.

> Yeah, you need all of that for all options to work as you expect them
> to. Also, you then have to figure out a way for your program to know
> where to find the files, but that's a different discussion.

Yeah, at the moment I rewrite the files to point to the right
place. My current solution feels really like a hack:

# Fix some paths so custom installation paths work.
sub ACTION_build {
my $self = shift;

$self->SUPER::ACTION_build;

$self->sed('blib/script/pabook',
'LIBDIR', $self->install_destination('lib'));
$self->sed('blib/lib/Pabook/Util.pm',
'LOCALEDIR', $self->install_destination('locale'));
}
sub sed {
my $self = shift;
my ($file, $search, $replacement) = @_;

$replacement =~ s/\//\\\//g;
$self->do_system('perl', '-pi', '-e',
"s/$search/$replacement/g", $file);
}

Is there a simple way for text replacements like this in
Module::Build (or maybe a better way to do it)? One known problem
with my solution is that a --prefix/--install_base change doesn't
case an update to the file, so it points to the wrong path.

> A much simpler solution in your case would be to use the sharedir
> functionality of Module::Build (available since 0.36). It doesn't
> sound like you need something sharedir can't provide.

I had a look at it, but I want a path like /usr/share/locale, and
it gives me something like /usr/share/perl/5.10.1/auto/<package-name>.

But the solution you gave me above works fine.

>> It seems to work, but doesn't look like a good solution. Is there
>> a variable which returns the absolute installation prefix? I
>> couldn't find any in the documentation.
>
> No, that's not how it works on the inside: an absolute installation
> prefix is only well-defined in a limited set of circumstances (when
> using --prefix and --install_base).

I see the problem now - I'm only used to --prefix so I didn't
think of that.

> Leon

Simon Ruderich

unread,
Apr 4, 2011, 10:08:27 AM4/4/11
to module...@perl.org
On Mon, Apr 04, 2011 at 03:55:24PM +0200, Simon Ruderich wrote:
>>> I'm using Module::Build 0.340201 on Debian Squeeze.
>
>> You might want to upgrade to a more recent version of Module::Build.
>> «apt-get install libmodule-build-perl» should upgrade it to 0.3607.
>> CPAN will upgrade it to 0.38. It might solve your problems.
>
> Retried with 0.38, same problem.

Sorry, wrong version. I retried it with 0.36.

>> The general solution looks something like this:
>>
>> use File::Spec 'catdir';
>> …
>> $build->add_build_element('locale');
>> $build->install_base_relpaths(locale => catdir('share', 'locale'));
>> $build->prefix_relpaths($_, locale => catdir('share', 'locale')) for
>> qw/core vendor site/;
>> $build->install_sets($_, 'locale',
>> catdir($build->original_prefix($_)), 'share', 'locale')) for qw/core
>> vendor site/;

It would be great if this could get added to the cookbook.

Leon Timmermans

unread,
Apr 4, 2011, 11:12:00 AM4/4/11
to Simon Ruderich, module...@perl.org
On Mon, Apr 4, 2011 at 3:55 PM, Simon Ruderich <si...@ruderich.org> wrote:
> Yes, I tried --install_base and --prefix, both have the same
> problem. It looks like --destdir also doesn't work with ./Build,
> just with perl Build.PL. I'm not sure if this is expected or a
> bug.

What *exactly* did you try to do? «./Build --install_base foo» or
«./Build install --install_base foo»? Or both?

> Hm, looks really complicated for such a simple task :-/

I agree. I think adding a helper function for this may be a good idea.

> Yeah, at the moment I rewrite the files to point to the right
> place. My current solution feels really like a hack:

It has the issue that the install_destination may not be known at
build time. The stages are rather independent. In theory it may even
be installed to multiple locations.

> Is there a simple way for text replacements like this in
> Module::Build (or maybe a better way to do it)? One known problem
> with my solution is that a --prefix/--install_base change doesn't
> case an update to the file, so it points to the wrong path.

No there isn't (nor should there be IMO, it has enough cruft as it is).

> I had a look at it, but I want a path like /usr/share/locale, and
> it gives me something like /usr/share/perl/5.10.1/auto/<package-name>.

Fair enough.

Leon

Simon Ruderich

unread,
Apr 4, 2011, 3:38:14 PM4/4/11
to module...@perl.org
On Mon, Apr 04, 2011 at 05:12:00PM +0200, Leon Timmermans wrote:
> What *exactly* did you try to do? «./Build --install_base foo» or
> «./Build install --install_base foo»? Or both?

Sorry. I tried the following.

Works fine:

perl Build.PL --install_base ~/test
./Build
./Build install

Works, but doesn't correctly replace the paths with my hacky
solution. Exactly the problem you mentioned below.

perl Build.PL
./Build
./Build install --install_base ~/test

Doesn't work:

perl Build.PL
./Build --install_base ~/test
./Build install

I thought ./Build --install_base ~/test would store the path
somewhere.

>> Hm, looks really complicated for such a simple task :-/
>
> I agree. I think adding a helper function for this may be a good idea.

That would be perfect.

>> Yeah, at the moment I rewrite the files to point to the right
>> place. My current solution feels really like a hack:
>
> It has the issue that the install_destination may not be known at
> build time. The stages are rather independent. In theory it may even
> be installed to multiple locations.

Good point. But how can I handle the problem? Is there no
solution which works in all cases?

>> Is there a simple way for text replacements like this in
>> Module::Build (or maybe a better way to do it)? One known problem
>> with my solution is that a --prefix/--install_base change doesn't
>> case an update to the file, so it points to the wrong path.
>
> No there isn't (nor should there be IMO, it has enough cruft as it is).

Ok.

Leon Timmermans

unread,
Apr 5, 2011, 6:44:28 AM4/5/11
to Simon Ruderich, module...@perl.org
On Mon, Apr 4, 2011 at 9:38 PM, Simon Ruderich <si...@ruderich.org> wrote:
> Sorry. I tried the following.
>
> Works fine:
>
>    perl Build.PL --install_base ~/test
>    ./Build
>    ./Build install
>
> Works, but doesn't correctly replace the paths with my hacky
> solution. Exactly the problem you mentioned below.
>
>    perl Build.PL
>    ./Build
>    ./Build install --install_base ~/test
>
> Doesn't work:
>
>    perl Build.PL
>    ./Build --install_base ~/test
>    ./Build install

Yeah, that's exactly what I would expect.

> Good point. But how can I handle the problem? Is there no
> solution which works in all cases?

The obvious solution would be to move it from build time to (pre-)install time.

Leon

Simon Ruderich

unread,
May 15, 2011, 10:54:40 AM5/15/11
to module...@perl.org
On Tue, Apr 05, 2011 at 12:44:28PM +0200, Leon Timmermans wrote:
>> Good point. But how can I handle the problem? Is there no
>> solution which works in all cases?
>
> The obvious solution would be to move it from build time to
> (pre-)install time.

Sorry for the late reply, I completely forgot the mail.

How can I do this? Once I perform the substitution (like LIBDIR
-> /usr/share/...) I can't perform it again for the next prefix.
Is there a simple way to handle this?

Leon Timmermans

unread,
May 15, 2011, 5:40:19 PM5/15/11
to Simon Ruderich, module...@perl.org
On Sun, May 15, 2011 at 4:54 PM, Simon Ruderich <si...@ruderich.org> wrote:
> Sorry for the late reply, I completely forgot the mail.
>
> How can I do this? Once I perform the substitution (like LIBDIR
> -> /usr/share/...) I can't perform it again for the next prefix.
> Is there a simple way to handle this?

Why insist on substitution? I think the easiest solution would be to
add a configuration file in blib/lib/auto or some such that has these
locations in them.

Leon

0 new messages