Alien-Base-ModuleBuild
view release on metacpan or search on metacpan
lib/Alien/Base/ModuleBuild/FAQ.pod view on Meta::CPAN
Alien::Base::ModuleBuild->new(
...
alien_bin_requires => {
'Alien::gmake' => 0.11, # needed for %{gmake} helper
},
alien_build_commands => [
"%{gmake}",
],
alien_install_commands => [
"%{gmake} install",
],
...
)->create_build_script;
=head2 When debugging my package build, I get different results!
If you get results from running the commands in your shell different to what happens when your C<Alien::>
distribution attempts to build, it may be because your environment is different than the one that your
distribution is using. For example, if you use L<Alien::CMake> or L<Alien::gmake> to build with specific tools
that are provided by your operating system, L<Alien::Base::ModuleBuild> will adjust the path before executing
build and install commands.
In the alien build directory (usually C<_alien>) you will find environment files that you can source
into your shell (C<env.csh> for tcsh and C<env.sh> for bourne based shells), which should provide the
identical environment used by the build process in order to troubleshoot the build manually.
% source _alien/env.sh
=head2 Can/Should I write a tool oriented Alien module using C<Alien::Base> that provides executables instead of a library?
Certainly. The original intent was to provide libraries, but tools are also quite doable using the
C<Alien::Base> tool set. A simple minded example of this which is fairly easy to replicate is L<Alien::m4>.
In general, this means specifying a subclass in your C<Build.PL> and bundling it in your distribution C<inc> directory.
C<Build.PL>:
...
use lib 'inc';
use My::ModuleBuild;
My::ModuleBuild->new(
...
)->create_build_script;
C<inc/My/ModuleBuild.pm>:
package My::ModuleBuild;
use strict;
use warnings;
use parent 'Alien::Base::ModuleBuild';
use Capture::Tiny qw( capture );
sub alien_check_installed_version
{
# see Alien::Base::ModuleBuild#alien_check_installed_version for details
my($self) = @_;
my($stdout, $stderr) = capture { system 'mytool', '--version' };
# return empty list if the tool is unavailable on the system,
# or unacceptable.
return if $! || ...;
# parse from stdout or stderr
my $version = ...;
return $version;
}
sub alien_check_built_version
{
# see Alien::Base::ModuleBuild#alien_check_built_version for details
# return empty list if the tool version cannot be found, or if it
# is unacceptable. Note that this will cause a failure, so "unknown"
# may be reasonable if the tool version cannot be determined.
return if ...;
# determine from the tool itself, or the current directory.
my $version = ...;
return $version;
}
1;
As usual your C<Alien::MyTool> class will simply be a subclass of L<Alien::Base>.
If you tool is installed in a C<bin> directory, you are done, the default C<bin_dir>
implementation should work for you. Otherwise you may need to provide an alternate
implementation:
package Alien::MyTool;
use strict;
use warnings;
use parent 'Alien::Base';
sub bin_dir
{
# see Alien::Base#bin_dir for details
# You only need to override the default implementation if your tool
# does not install into the standard "bin" directory.
my($class) = @_;
# normally for system installs the tool should already be in your
# PATH, so return an empty list.
return if $class->install_type eq 'system';
# install_type = share
my $dist_dir = $class->dist_dir;
return ("$dist_dir/some/bin", "$dist_dir/some/other/bin");
}
1;
Now once your tool based Alien is installed you can use the C<bin_dir> method to
update the C<PATH> as necessary:
use Alien::MyTool;
use Env qw( @PATH );
unshift @PATH, Alien::MyTool->bin_dir;
system 'mytool';
=head2 How do I use C<Alien::Base> from C<Dist::Zilla>
( run in 0.476 second using v1.01-cache-2.11-cpan-fa01517f264 )