This document is intended for a user of an Alien::Base based Alien module's user. Although specifically
geared for Alien::Base subclasses, it may have some useful hints for Alien in general.
Full working examples of how to use an Alien module are also bundled with Alien::Build in the
distribution's "example/user" directory. Those examples use Alien::xz, which uses alienfile +
Alien::Build + Alien::Base.
The following documentation will assume you are trying to use an Alien called "Alien::Foo" which provides
the library "libfoo" and the command line tool "foo". Many Aliens will only provide one or the other.
The best interface to use for using Alien::Base based aliens is Alien::Base::Wrapper. This allows you to
combine multiple aliens together and handles a number of corner obscure corner cases that using Aliens
directly does not. Also as of 0.64, Alien::Base::Wrapper comes bundled with Alien::Build and Alien::Base
anyway, so it is not an extra dependency.
What follows are the main use cases.
ExtUtils::MakeMaker
use ExtUtils::MakeMaker;
use Alien::Base::Wrapper ();
WriteMakefile(
Alien::Base::Wrapper->new('Alien::Foo')->mm_args2(
NAME => 'FOO::XS',
...
),
);
Alien::Base::Wrapper will take a hash of "WriteMakefile" arguments and insert the appropriate compiler
and linker flags for you. This is recommended over doing this yourself as the exact incantation to get
EUMM to work is tricky to get right.
The "mm_args2" method will also set your "CONFIGURE_REQUIRES" for Alien::Base::Wrapper,
ExtUtils::MakeMaker and any aliens that you specify.
Module::Build
use Module::Build;
use Alien::Base::Wrapper qw( Alien::Foo !export );
use Alien::Foo;
my $build = Module::Build->new(
...
configure_requires => {
'Alien::Base::Wrapper' => '0',
'Alien::Foo' => '0',
...
},
Alien::Base::Wrapper->mb_args,
...
);
$build->create_build_script;
For Module::Build you can also use Alien::Base::Wrapper, but you will have to specify the
"configure_requires" yourself.
Inline::C/Inline::CPP
use Inline 0.56 with => 'Alien::Foo';
Inline::C and Inline::CPP can be configured to use an Alien::Base based Alien with the "with" keyword.
ExtUtils::Depends
use ExtUtils::MakeMaker;
use ExtUtils::Depends;
my $pkg = ExtUtils::Depends->new("Alien::Foo");
WriteMakefile(
...
$pkg->get_makefile_vars,
...
);
ExtUtils::Depends works similar to Alien::Base::Wrapper, but uses the Inline interface under the covers.
Dist::Zilla
[@Filter]
-bundle = @Basic
-remove = MakeMaker
[Prereqs / ConfigureRequires]
Alien::Foo = 0
[MakeMaker::Awesome]
header = use Alien::Base::Wrapper qw( Alien::Foo !export );
WriteMakefile_arg = Alien::Base::Wrapper->mm_args
FFI::Platypus
Requires "Alien::Foo" always:
use FFI::Platypus;
use Alien::Foo;
my $ffi = FFI::Platypus->new(
lib => [ Alien::Foo->dynamic_libs ],
);
Use "Alien::Foo" in fallback mode:
use FFI::Platypus;
use FFI::CheckLib 0.28 qw( find_lib_or_die );
use Alien::Foo;
my $ffi = FFI::Platypus->new(
lib => [ find_lib_or_die lib => 'foo', alien => ['Alien::Foo'] ],
);
If you are going to always require an Alien you can just call "dynamic_libs" and pass it into
FFI::Platypus' lib method. You should consider using FFI::CheckLib to use the Alien in fallback mode
instead. This way you only need to install the Alien if the system doesn't provide it.
For fallback mode to work correctly you need to be using FFI::CheckLib 0.28 or better.
Inline::C
use Inline with => 'Alien::Foo';
use Inline C => <<~'END';
#include <foo.h>
const char *my_foo_wrapper()
{
foo();
}
END
sub exported_foo()
{
my_foo_wrapper();
}
tool
use Alien::Foo;
use Env qw( @PATH );
unshift @PATH, Alien::Foo->bin_dir;
system 'foo', '--bar', '--baz';
Some Aliens provide tools instead of or in addition to a library. You need to add them to the "PATH"
environment variable though. (Unless the tool is already provided by the system, in which case it is
already in the path and the "bin_dir" method will return an empty list).