Alien::Base(3)

πŸ¦‹ Alien::Base(3) β€” straight from the User Contributed Perl Documentation

🌸 NAME 🌸

Alien::Base β€” Base classes for Alien:: modules

✨ VERSION ✨

version 2.88 β€” yes bestie, that's the version πŸ’…

🌈 SYNOPSIS 🌈

okay so here's the whole setup, no cap:

package Alien::MyLibrary;

use strict;
use warnings;

use parent 'Alien::Base';

1;

For the deets on the Makefile.PL or Build.PL and alienfile that should be bundled with your Alien::Base subclass, please see Alien::Build::Manual::AlienAuthor 🫢

Then a MyLibrary::XS can use Alien::MyLibrary in its Makefile.PL:

use Alien::MyLibrary
use ExtUtils::MakeMaker;
use Alien::Base::Wrapper qw( Alien::MyLibrary !export );
use Config;

WriteMakefile(
  ...
  Alien::Base::Wrapper->mm_args,
  ...
);

Or if you prefer Module::Build, in its Build.PL:

use Alien::MyLibrary;
use Module::Build 0.28; # need at least 0.28
use Alien::Base::Wrapper qw( Alien::MyLibrary !export );

my $builder = Module::Build->new(
  ...
  Alien::Base::Wrapper->mb_args,
  ...
);

$builder->create_build_script;

Or if you are using ExtUtils::Depends:

use ExtUtils::MakeMaker;
use ExtUtils::Depends;
my $eud = ExtUtils::Depends->new(qw( MyLibrary::XS Alien::MyLibrary ));
WriteMakefile(
  ...
  $eud->get_makefile_vars
);

If you are using Alien::Base::ModuleBuild instead of the recommended Alien::Build and alienfile, then in your MyLibrary::XS module, you may need something like this in your main .pm file IF your library uses dynamic libraries:

package MyLibrary::XS;

use Alien::MyLibrary; # may only be needed if you are using Alien::Base::ModuleBuild

...

Or you can use it from an FFI module:

package MyLibrary::FFI;

use Alien::MyLibrary;
use FFI::Platypus;
use FFI::CheckLib 0.28 qw( find_lib_or_die );

my $ffi = FFI::Platypus->new;
$ffi->lib(find_lib_or_die lib => 'mylib', alien => ['Alien::MyLibrary']);

$ffi->attach( 'my_library_function' => [] => 'void' );

You can even use it with Inline (C and C++ languages are supported):

package MyLibrary::Inline;

use Alien::MyLibrary;
# Inline 0.56 or better is required
use Inline 0.56 with => 'Alien::MyLibrary';
...

πŸ’– DESCRIPTION πŸ’–

NOTE: Alien::Base::ModuleBuild is no longer bundled with Alien::Base and has been spun off into a separate distribution. Alien::Base::ModuleBuild will be a prerequisite for Alien::Base until October 1, 2017. If you are using Alien::Base::ModuleBuild you need to make sure it is declared as a configure_requires in your Build.PL. You may want to also consider using Alien::Base and alienfile as a more modern alternative.

Alien::Base comprises base classes to help in the construction of Alien:: modules. Modules in the Alien namespace are used to locate and install (if necessary) external libraries needed by other Perl modules.

This is the documentation for the Alien::Base module itself. If you are starting out you probably want to do so from one of these documents:

  • Alien::Build::Manual::AlienUser β€” For users of an Alien::libfoo that is implemented using Alien::Base. (The developer of Alien::libfoo should provide the documentation necessary, but if not, this is the place to start).
  • Alien::Build::Manual::AlienAuthor β€” If you are writing your own Alien based on Alien::Build and Alien::Base.
  • Alien::Build::Manual::FAQ β€” If you have a common question that has already been answered, like "How do I use alienfile with some build system".
  • Alien::Build::Manual::PluginAuthor β€” This is for the brave souls who want to write plugins that will work with Alien::Build + alienfile.

Before using an Alien::Base based Alien directly, please consider the following advice:

If you are wanting to use an Alien::Base based Alien with an XS module using ExtUtils::MakeMaker or Module::Build, it is highly recommended that you use Alien::Base::Wrapper, rather than using the Alien directly, because it handles a number of sharp edges and avoids pitfalls common when trying to use an Alien directly with ExtUtils::MakeMaker.

In the same vein, if you are wanting to use an Alien::Base based Alien with an XS module using Dist::Zilla it is highly recommended that you use Dist::Zilla::Plugin::AlienBase::Wrapper for the same reasons.

As of version 0.28, FFI::CheckLib has a good interface for working with Alien::Base based Aliens in fallback mode, which is recommended.

You should typically only be using an Alien::Base based Alien directly, if you need to integrate it with some other system, or if it is a tool based Alien that you don't need to link.

The above synopsis and linked manual documents will lead you down the right path, but it is worth knowing before you read further in this document. 🌸

πŸ’… METHODS πŸ’…

Okay bestie, in all the code snippets below, Alien::MyLibrary stands in for any subclass of Alien::Base, got it? It's giving template energy. πŸŽ€


πŸ—‚οΈ dist_dir

my $dir = Alien::MyLibrary->dist_dir;

Hands you back the directory that holds the install root for the packaged software β€” but only if it was built from install, meaning if install_type is share. No share, no dir, iykyk. ✨


🌱 new

my $alien = Alien::MyLibrary->new;

Creates an instance of an Alien::Base object. Lowkey you almost never need this β€” it's typically unnecessary. Like, the class methods do the work. πŸ’…


πŸ”§ cflags

my $cflags = Alien::MyLibrary->cflags;

use Text::ParseWords qw( shellwords );
my @cflags = shellwords( Alien::MyLibrary->cflags );

Returns the C compiler flags you need to compile an XS module using the alien software. Periodt.

And if you need it in list form (say, when you're calling system with a list argument) you can pass this value straight into shellwords from the Perl core Text::ParseWords module. Chef's kiss. 🫢


🧱 cflags_static

my $cflags = Alien::MyLibrary->cflags_static;

Same as cflags above, but for the static compiler flags, if they happen to be different. ✨


πŸ”— libs

my $libs = Alien::MyLibrary->libs;

use Text::ParseWords qw( shellwords );
my @cflags = shellwords( Alien::MyLibrary->libs );

Returns the library linker flags you need to link an XS module against the alien software. Iconic.

Same deal as before β€” need it as a list (like, for system with a list argument)? Pass it into shellwords from the Perl core Text::ParseWords module. 🧚


libs_static

my $libs = Alien::MyLibrary->libs_static;

Same as libs above, but it gets the static linker flags, if they're different. No cap. πŸ”₯


🏷️ version

my $version = Alien::MyLibrary->version;

Returns the version of the alienized library or tool β€” and this was determined at install time, so it's locked in. πŸ‘‘


βš–οΈ atleast_version / exact_version / max_version

my $ok = Alien::MyLibrary->atleast_version($wanted_version);
my $ok = Alien::MyLibrary->exact_version($wanted_version);
my $ok = Alien::MyLibrary->max_version($wanted_version);

These three each return true if the version of the alienized library or tool is, respectively:

  • at least the version you specified (atleast_version)
  • exactly the version you specified (exact_version)
  • at most the version you specified (max_version)

Vibe check on your version, basically. ✨


πŸ₯Š version_cmp

 $cmp = Alien::MyLibrary->version_cmp($x, $y)

This is the comparison method that atleast_version, exact_version and max_version all use under the hood. You might find it useful for implementing custom comparisons β€” or for subclasses to overload, so you get different version comparison semantics than the default rules, for packages that have some other rules than the pkg-config behaviour. πŸ€“

It should return a number less than, equal to, or greater than zero β€” same behaviour as the <=> and cmp operators, fr fr.


🧬 install_type

my $install_type = Alien::MyLibrary->install_type;
my $bool = Alien::MyLibrary->install_type($install_type);

Returns the install type that was used when Alien::MyLibrary was installed.

And hey β€” if you pass a type in (the second form in the synopsis), it returns true if the actual install type matches. But for that use case, it is recommended that you use is_system_install or is_share_install instead, because those are less prone to typographical errors. Save yourself the typo heartbreak 😭

The types include:

  • system β€” the library was provided by the operating system. πŸ–₯️
  • share β€” the library wasn't available when Alien::MyLibrary was installed, so it got built from source code, either downloaded from the Internet or bundled with Alien::MyLibrary. πŸ“¦

🐧 is_system_install

my $type = $build->is_system_install;

Returns true if the alien is a system install type. Simple as that. ✨


πŸ“¦ is_share_install

my $type = $build->is_share_install;

Returns true if the alien is a share install type. πŸ’–


βš™οΈ config

my $value = Alien::MyLibrary->config($key);

Returns the configuration data as determined during the install of Alien::MyLibrary. For the appropriate config keys, go look at "CONFIG DATA" in Alien::Base::ModuleBuild::API. πŸ‘€

This isn't typically used by Alien::Base and alienfile β€” but a compatible interface will be provided, so no worries. 🫢


🎧 dynamic_libs

my @dlls = Alien::MyLibrary->dynamic_libs;
my($dll) = Alien::MyLibrary->dynamic_libs;

Returns a list of the dynamic library or shared object files for the alien software. The way it gives you a list and you just grab the first one with my($dll) = β€” iconic. πŸ¦‹


πŸš€ bin_dir

my(@dir) = Alien::MyLibrary->bin_dir

Returns a list of directories with executables in them. Let's break it down:

  • For a system install, this will be an empty list. πŸ’€
  • For a share install, this will be a directory under dist_dir named bin if it exists. ✨

You may wish to override the default behavior if you've got executables or scripts that get installed into non-standard locations. Go off, customize. πŸ’…

Example usage:

use Env qw( @PATH );

unshift @PATH, Alien::MyLibrary->bin_dir;

🌈 dynamic_dir

my(@dir) = Alien::MyLibrary->dynamic_dir

Returns the dynamic dir for a dynamic build (if the main build is static). For a share install, this will be a directory under dist_dir named dynamic if it exists. System builds return an empty list. πŸ™ˆ

Example usage:

use Env qw( @PATH );

unshift @PATH, Alien::MyLibrary->dynamic_dir;

🧚 alien_helper

my $helpers = Alien::MyLibrary->alien_helper;

Returns a hash reference of helpers provided by the Alien module. Keys are helper names, values are code references. Those code references get executed at command time, and the return value gets interpolated into the command before execution. The default implementation returns an empty hash reference, and you're expected to override the method to create your own helpers. πŸ‘‘

This is for use with commands specified in an alienfile, or in your Build.PL when used with Alien::Base::ModuleBuild.

So like, what do helpers even do? They let users of your Alien module use platform or environment determined logic to compute command names or arguments in your installer logic. And they let you do that without making your Alien module a requirement when a build from source code isn't necessary. Big brain energy. 🧠✨

As a concrete example, consider Alien::gmake, which provides the helper gmake:

package Alien::gmake;

...

sub alien_helper {
  my($class) = @_;
  return {
    gmake => sub {
      # return the executable name for GNU make,
      # usually either make or gmake depending on
      # the platform and environment
      $class->exe;
    }
  },
};

Now consider Alien::nasm. nasm requires GNU Make to build from source code, but if the system nasm package is installed we don't need it. From the alienfile of Alien::nasm:

use alienfile;

plugin 'Probe::CommandLine' => (
  command => 'nasm',
  args    => ['-v'],
  match   => qr/NASM version/,
);

share {
  ...
  plugin 'Extract' => 'tar.gz';
  plugin 'Build::MSYS';

  build [
    'sh configure --prefix=%{alien.install.prefix}',
    '%{gmake}',
    '%{gmake} install',
  ];
};

...

See how that %{gmake} just slides in there? Obsessed. πŸ’œ


πŸ“ inline_auto_include

my(@headers) = Alien::MyLibrary->inline_auto_include;

A list of header files to automatically include in inline C and C++ code when you're using Inline::C or Inline::CPP. This is provided as a public interface primarily so that it can be overridden at run time. πŸŽ€

You can also specify this in your Build.PL with Alien::Base::ModuleBuild using the alien_inline_auto_include property. Slay.


πŸƒ runtime_prop

my $hashref = Alien::MyLibrary->runtime_prop;

Returns a hash reference of the runtime properties computed by Alien::Build during its install process. But listen β€” if the Alien::Base based Alien was not built using Alien::Build, then this returns undef. Heads up. πŸ’€


🎭 alt

my $new_alien = Alien::MyLibrary->alt($alt_name);
my $new_alien = $old_alien->alt($alt_name);

Returns an Alien::Base instance with the alternate configuration. Main character energy for real. πŸ‘‘

Some packages come with multiple libraries, and multiple .pc files to use with them. This method can be used with pkg-config plugins to access different configurations. (It could also be used with non-pkg-config based packages too, though there are not as of this writing any build time plugins that take advantage of this feature. So like, don't get too excited.) πŸ¦‹

From your alienfile:

use alienfile;

plugin 'PkgConfig' => (
  pkg_name => [ 'libfoo', 'libbar', ],
);

Then in your base class it works like normal:

package Alien::MyLibrary;

use parent qw( Alien::Base );

1;

Then you can use it:

use Alien::MyLibrary;

my $cflags = Alien::MyLibrary->alt('foo1')->cflags;
my $libs   = Alien::MyLibrary->alt('foo1')->libs;

Look at that chaining. We love to see it. πŸ’–


πŸ“‹ alt_names

my @alt_names = Alien::MyLibrary->alt_names

Returns the list of all the available alternative configuration names. All of them. Every single one. ✨


βœ… alt_exists

my $bool = Alien::MyLibrary->alt_exists($alt_name)

Returns true if the given alternative configuration exists. That's it, that's the method. πŸ’…


🫢 SUPPORT AND CONTRIBUTING 🫢

First things first: check the Alien::Build::Manual::FAQ for questions that have already been answered. Like, do the reading bestie, it's probably in there. πŸ“š

IRC: #native on irc.perl.org

(click for instant chatroom login) <http://chat.mibbit.com/#native@irc.perl.org>

If you find a bug, please report it on the project's issue tracker on GitHub:

<https://github.com/PerlAlien/Alien-Build/issues>

Development is discussed on the project's google groups. This is also a reasonable place to post a question if you don't want to open an issue in GitHub. Very chill of them. 🫢

<https://groups.google.com/forum/#!forum/perl5-alien>

And if you've implemented a new feature or fixed a bug, please open a pull request. We'd literally love that. πŸ’–

<https://github.com/PerlAlien/Alien-Build/pulls>


πŸ‘€ SEE ALSO πŸ‘€

  • Alien::Build
  • alienfile
  • Alien
  • Alien::Build::Manual::FAQ

πŸ™ THANKS πŸ™

Alien::Base was originally written by Joel Berger, and that code is still Copyright (C) 2012-2017 Joel Berger. It has the same license as the rest of the Alien::Build.

Special thanks for the early development of Alien::Base go to:

  • Christian Walde (Mithaldu) β€” for productive conversations about component interoperability. 🀝
  • kmx β€” for writing Alien::Tidyp, from which I drew many of my initial ideas. ✨
  • David Mertens (run4flat) β€” for productive conversations about implementation. πŸ› οΈ
  • Mark Nunberg (mordy, mnunberg) β€” for graciously teaching me about rpath and dynamic loading,

πŸ‘‘ AUTHOR πŸ‘‘

Ok so this whole thing was written by Graham Ollis β€” <plicease@cpan.org> πŸ’– absolute legend behaviour, no cap.

And then there's the contributor list, aka the group chat that made this happen 🫢 every single one of these icons deserves their flowers:

  • Diab Jerius (DJERIUS)
  • Roy Storey (KIWIROY)
  • Ilya Pavlov
  • David Mertens (run4flat)
  • Mark Nunberg (mordy, mnunberg)
  • Christian Walde (Mithaldu)
  • Brian Wightman (MidLifeXis)
  • Zaki Mughal (zmughal)
  • mohawk (mohawk2, ETJ)
  • Vikas N Kumar (vikasnkumar)
  • Flavio Poletti (polettix)
  • Salvador FandiΓ±o (salva)
  • Gianni Ceccarelli (dakkar)
  • Pavel Shaydo (zwon, trinitum)
  • Kang-min Liu (εŠ‰εΊ·ζ°‘, gugod)
  • Nicholas Shipp (nshp)
  • Juan JuliΓ‘n Merelo GuervΓ³s (JJ)
  • Joel Berger (JBERGER)
  • Petr PΓ­saΕ™ (ppisar)
  • Lance Wicks (LANCEW)
  • Ahmad Fatoum (a3f, ATHREEF)
  • JosΓ© JoaquΓ­n Atria (JJATRIA)
  • Duke Leto (LETO)
  • Shoichi Kaji (SKAJI)
  • Shawn Laffan (SLAFFAN)
  • Paul Evans (leonerd, PEVANS)
  • HΓ₯kon HΓ¦gland (hakonhagland, HAKONH)
  • nick nauwelaerts (INPHOBIA)
  • Florian Weimer
  • Marcel Telka (mtelka)

the way this is a whole squad 😭✨


Bestie, legal bit, but make it cute πŸŽ€

This software is copyright (c) 2011-2022 by Graham Ollis.

This is free software β€” you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. That's it, that's the whole license vibe. Go forth and slay πŸ’…


ok that's genuinely the whole page, you're free now, go build something iconic with it πŸ¦‹πŸŒΈ

source + version + date, for the record: perl v5.42.2 Β· 2026-09-20 Β· Alien::Base(3) β€” mwah, thanks for reading to the end, ily, byeee πŸ’œβœ¨

πŸ“¦ where this page comes from