Manpages - Alien_Build_Manual_FAQ.3pm
Table of Contents
- NAME
- VERSION
- SYNOPSIS
- DESCRIPTION
- QUESTIONS
- What is Alien, Alien::Base and Alien::Build?
- How do I build a package that uses build system
- How do I probe for a package that uses pkg-config?
- How do I specify a minimum or exact version requirement for packages
- How do I probe for a package that uses multiple .pc files?
- How to create an Alien module for packages that do not support
- Can/Should I write a tool oriented Alien module?
- How do I test my package once it is built (before it is installed)?
- How do I patch packages that need alterations?
- The flags that a plugin produces are wrong!
- “cannot open shared object file” trying to load XS
- 599 Internal Exception errors downloading packages from the internet
- Network fetch is turned off
- I would really prefer you not download stuff off the internet
- For testing I would like to test both system and share installs!
- How do I use Alien::Build from Dist::Zilla?
- Cannot find either a share directory or a ConfigData module
- I have a question not listed here!
- SEE ALSO
- AUTHOR
- COPYRIGHT AND LICENSE
NAME
Alien::Build::Manual::FAQ - Frequently Asked Questions about Alien::Build
VERSION
version 2.44
SYNOPSIS
perldoc Alien::Build::Manual::FAQ
DESCRIPTION
This document serves to answer the most frequently asked questions made by developers creating Alien modules using Alien::Build.
QUESTIONS
What is Alien, Alien::Base and Alien::Build?
Alien in a Perl namespace for defining dependencies in CPAN for libraries and tools which are not native to CPAN. For a manifesto style description of the Why, and How see Alien. Alien::Base is a base class for the Alien runtime. Alien::Build is a tool for probing the operating system for existing libraries and tools, and downloading, building and installing packages. alienfile is a recipe format for describing how to probe, download, build and install a package.
How do I build a package that uses build system
autoconf
Use the autoconf plugin (Alien::Build::Plugin::Build::Autoconf). If your
package provides a pkg-config .pc
file, then you can also use the
PkgConfig plugin (Alien::Build::Plugin::PkgConfig::Negotiate).
use alienfile plugin PkgConfig => libfoo; share { start_url => http://example.org/dist; plugin Download => ( version => qr/libfoo-([0-9\.])\.tar\.gz$/, ); plugin Extract => tar.gz; plugin Build::Autoconf; };
If you need to provide custom flags to configure, you can do that too:
share { plugin Build::Autoconf; build [ %{configure} –disable-shared –enable-foo, %{make}, %{make} install, ]; };
If your package requires GNU Make, use %{gmake}
instead of %{make}
.
autoconf-like
If you see an error like this:
Unknown option “–with-pic”.
It is because the autoconf plugin uses the --with-pic
option by
default, since it makes sense most of the time, and autoconf usually
ignores options that it does not recognize. Some autoconf style build
systems fail when they see an option that they do not recognize. You can
turn this behavior off for these packages:
plugin Build::Autoconf => ( with_pic => 0, );
Another thing about the autoconf plugin is that it uses DESTDIR
to do
a double staged install. If you see an error like nothing was installed
into destdir, that means that your package does not support DESTDIR
.
You should instead use the MSYS plugin and use a command sequence to do
the build like this:
share { plugin Build::MSYS; build [ # explicitly running configure with “sh” will make sure that # it works on windows as well as UNIX. sh configure –prefix=%{.install.prefix} –disable-shared, %{make}, %{make} install, ]; };
CMake
There is an alien Alien::cmake3 that provides cmake
3.x or better (It
is preferred to the older Alien::CMake). Though it is recommended that
you use the cmake
(Alien::Build::Plugin::Build::CMake) plugin instead
of using Alien::cmake3.
use alienfile; share { plugin Build::CMake; build [ # this is the default build step, if you do not specify one. [ %{cmake}, @{ meta->prop->{plugin_build_cmake}->{args} }, # … put extra cmake args here … . ], %{make}, %{make} install, ]; };
vanilla Makefiles
Alien::Build provides a helper (%{make}
) for the make
that is used
by Perl and ExtUtils::MakeMaker (EUMM). Unfortunately the make
supported by Perl and EUMM on Windows (nmake
and dmake
) are not
widely supported by most open source projects. (Thankfully recent perls
and EUMM support GNU Make on windows now).
You can use the make
plugin (Alien::Build::Plugin::Build::Make) to
tell the Alien::Build system which make the project that you are
alienizing requires.
plugin Build::Make => umake; # umake makes %{make} either GNU Make or BSD Make on Unix and GNU Make on Windows. build { build [ # You can use the Perl config compiler and cflags using the %{perl.config…} helper [ %{make}, CC=%{perl.config.cc}, CFLAGS=%{perl.config.cccdlflags} %{perl.config.optimize} ], [ %{make}, install, PREFIX=%{.install.prefix} ], ], };
Some open source projects require GNU Make, and you can specify that, and Alien::gmake will be pulled in on platforms that do not already have it.
plugin Build::Make => gmake; …
How do I probe for a package that uses pkg-config?
Use the pkg-config
plugin
(Alien::Build::Plugin::PkgConfig::Negotiate):
use alienfile; plugin PkgConfig => ( pkg_name => libfoo, );
It will probe for a system version of the library. It will also add the
appropriate version
cflags
and libs
properties on either a
system
or share
install.
How do I specify a minimum or exact version requirement for packages
that use pkg-config?
The various pkg-config plugins all support atleast_version,
exact_version and maximum_version fields, which have the same meaning as
the pkg-config
command line interface:
use alienfile; plugin PkgConfig, pkg_name => foo, atleast_version => 1.2.3;
or
use alienfile; plugin PkgConfig, pkg_name => foo, exact_version => 1.2.3;
How do I probe for a package that uses multiple .pc files?
Each of the PkgConfig
plugins will take an array reference instead of
a string:
use alienfile; plugin PkgConfig => ( pkg_name => [ foo, bar, baz ] );
The first pkg_name
given will be used by default once your alien is
installed. To get the configuration for foo
and bar
you can use the
Alien::Base alt method:
use Alien::libfoo; $cflags = Alien::libfoo->cflags; # compiler flags for foo $cflags = Alien::libfoo->alt(bar)->cflags ; # compiler flags for bar $cflags = Alien::libfoo->alt(baz)->cflags ; # compiler flags for baz
How to create an Alien module for packages that do not support
pkg-config? Packages that provide a configuration script
Many packages provide a command that you can use to get the appropriate version, compiler and linker flags. For those packages you can just use the commands in your alienfile. Something like this:
use alienfile; probe [ foo-config –version ]; share { … build [ %{make} PREFIX=%{.runtime.prefix}, %{make} install PREFIX=%{.runtime.prefix}, ]; }; gather [ [ foo-config, –version, \%{.runtime.version} ], [ foo-config, –cflags, \%{.runtime.cflags} ], [ foo-config, –libs, \%{.runtime.libs} ], ];
Packages that require a compile test
Some packages just expect you do know that -lfoo
will work. For those
you can use the cbuilder
plugin
(Alien::Build::Plugin::Probe::CBuilder).
use alienfile; plugin Probe::CBuilder => ( cflags => -I/opt/libfoo/include, libs => -L/opt/libfoo/lib -lfoo, ); share { … gather sub { my($build) = @_; my $prefix = $build->runtime_prop->{prefix}; $build->runtime_prop->{cflags} = “-I$prefix/include ”; $build->runtime_prop->{libs} = “-L$prefix/lib -lfoo ”; }; }
This plugin will build a small program with these flags and test that it works. (There are also options to provide a program that can make simple tests to ensure the library works). If the probe works, it will set the compiler and linker flags. (There are also options for extracting the version from the test program). If you do a share install you will need to set the compiler and linker flags yourself in the gather step, if you aren’t using a build plugin that will do that for you.
Can/Should I write a tool oriented Alien module?
Certainly. The original intent was to provide libraries, but tools are also quite doable using the Alien::Build toolset. A good example of how to do this is Alien::nasm. You will want to use the ’Probe::CommandLine’:
use alienfile; plugin Probe::CommandLine => ( command => gzip, );
How do I test my package once it is built (before it is installed)?
Use Test::Alien. It has extensive documentation, and integrates nicely with Alien::Base.
How do I patch packages that need alterations?
If you have a diff file you can use patch:
use alienfile; probe sub { share }; # replace with appropriate probe share { … patch [ %{patch} -p1 < %{.install.patch}/mypatch.diff ]; build [ … ] ; } …
You can also patch using Perl if that is easier:
use alienfile; probe sub { share }; share { … patch sub { my($build) = @_; # make changes to source prior to build }; build [ … ]; };
The flags that a plugin produces are wrong!
Sometimes, the compiler or linker flags that the PkgConfig plugin comes
up with are not quite right. (Frequently this is actually because a
package maintainer is providing a broken .pc
file). (Other plugins may
also have problems). You could replace the plugin’s gather
step but a
better way is to provide a subroutine callback to be called after the
gather stage is complete. You can do this with the alienfile after
directive:
use alienfile; plugin PkgConfig > libfoo; share { ... after gather =>
sub { my($build) = @_; $build->runtime_prop->{libs} .
“ -lbar”; #
libfoo also requires libbar $build->runtime_prop->{libs_static} .= “
-lbar -lbaz”; # libfoo also requires libbaz under static linkage }; };
Sometimes you only need to do this on certain platforms. You can adjust
the logic based on $^O
appropriately.
use alienfile; plugin PkgConfig > libfoo; share { ... after gather =>
sub { my($build) = @_; if($^O eq MSWin32) { $build->runtime_prop->{libs}
.
“ -lpsapi”; } }; };
“cannot open shared object file” trying to load XS
The error looks something like this:
t/acme_alien_dontpanic2.t ……. 1/? # Failed test xs # at t/acme_alien_dontpanic2.t line 13. # XSLoader failed # Cant load home/cip.cpanm/work/1581635869.456/Acme-Alien-DontPanic2-2.0401/_alien/tmp/test-alien-lyiQNX/auto/Test/Alien/XS/Mod0/Mod0.so for module Test::Alien::XS::Mod0: libdontpanic.so.0: cannot open shared object file: No such file or directory at /opt/perl/5.30.1/lib/5.30.1/x86_64-linux/DynaLoader.pm line 193. # at /home/cip/perl5/lib/perl5/Test/Alien.pm line 414. # Compilation failed in require at /home/cip/perl5/lib/perl5/Test/Alien.pm line 414. # BEGIN failed–compilation aborted at /home/cip/perl5/lib/perl5/Test/Alien.pm line 414. t/acme_alien_dontpanic2.t ……. Dubious, test returned 1 (wstat 256, 0x100) Failed 1/6 subtests t/acme_alien_dontpanic2_ _ffi.t .. ok
This error happened at test time for the Alien, but depending on your environment and Alien it might happen later and the actual diagnostic wording might vary.
This is usually because your XS or Alien tries to use dynamic libraries instead of static ones. Please consult the section about dynamic vs. static libraries in Alien::Build::Manual::AlienAuthor. The TL;DR is that Alien::Build::Plugin::Gather::IsolateDynamic might help. If you are the Alien author and the package you are alienizing doesn’t have a static option you can use Alien::Role::Dino, but please note the extended set of caveats!
599 Internal Exception errors downloading packages from the internet
Alien::Build::Plugin::Fetch::HTTPTiny> 599 Internal Exception fetching http://dist.libuv.org/dist/v1.15.0 Alien::Build::Plugin::Fetch::HTTPTiny> exception: IO::Socket::SSL 1.42 must be installed for https support Alien::Build::Plugin::Fetch::HTTPTiny> exception: Net::SSLeay 1.49 must be installed for https support Alien::Build::Plugin::Fetch::HTTPTiny> An attempt at a SSL URL https was made, but your :Tiny does not appear to be able to use https. Alien::Build::Plugin::Fetch::HTTPTiny> Please see: https://metacpan.org/pod/Alien::Build::Manual::FAQ#599-Internal-Exception-errors-downloading-packages-from-the-internet error fetching http://dist.libuv.org/dist/v1.15.0: 599 Internal Exception at Users/ollisg.perlbrew/libs/perl-5.26.0@test1/lib/perl5/Alien/Build/Plugin/Fetch/HTTPTiny.pm line 68.
(Older versions of Alien::Build produced a less verbose more confusing version of this diagnostic).
TL;DR, instead of this:
share { start_url => http://example.org/dist; … };
do this:
share { start_url => https://example.org/dist; };
If the website is going to redirect to a secure URL anyway.
The 599 Internal Exception indicates an internal exception from
:Tiny and is not a real HTTP status code or error. This could mean
a number of different problems, but most frequently indicates that a SSL
request was made without the required modules (Net::SSLeay and
IO::Socket::SSL). Normally the Alien::Build::Plugin::Download::Negotiate
and Alien::Build::Plugin::Fetch::HTTPTiny will make sure that the
appropriate modules are added to your prerequisites for you if you
specify a https
URL. Some websites allow an initial request from
http
but then redirect to https
. If you can it is better to specify
https
, if you cannot, then you can instead use the ssl
property on
either of those two plugins.
Network fetch is turned off
If you get an error like this:
Alien::Build> install type share requested or detected, but network fetch is turned off Alien::Build> see see https://metacpan.org/pod/Alien::Build::Manual::FAQ#Network-fetch-is-turned-off
This is because your environment is setup not to install aliens that
require the network. You can turn network fetch back on by setting
ALIEN_INSTALL_NETWORK
to true, or by unsetting it. This environment
variable is designed for environments that don’t ever want to install
aliens that require downloading source packages over the internet.
I would really prefer you not download stuff off the internet
The idea of Alien is to download missing packages and build them automatically to make installing easier. Some people may not like this, or may even have security requirements that they not download random package over the internet (caveat, downloading random stuff off of CPAN may not be any safer, so make sure you audit all of the open source software that you use appropriately). Another reason you may not want to download from the internet is if you are packaging up an alien for an operating system vendor, which will always want to use the system version of a library. In that situation you don’t want Alien::Build to go off and download something from the internet because the probe failed for some reason.
This is easy to take care of, simply set ALIEN_INSTALL_TYPE
to
system
and a build from source code will never be attempted. On
systems that do not provide system versions of the library or tool you
will get an error, allowing you to install the library, and retry the
alien install. You can also set the environment variable on just some
aliens.
% export ALIEN_INSTALL_TYPE=system # for everyone % env ALIEN_INSTALL_TYPE=system cpanm -v Alien::libfoo
For testing I would like to test both system and share installs!
You can use the ALIEN_INSTALL_TYPE
environment variable. It will force
either a share
or system
install depending on how it is set. For
travis you can do something like this:
env: matrix: - ALIEN_INSTALL_TYPE=share - ALIEN_INSTALL_TYPE=system
How do I use Alien::Build from Dist::Zilla?
For creating Alien::Base and Alien::Build based dist from Dist::Zilla you can use the dzil plugin Dist::Zilla::Plugin::AlienBuild.
Cannot find either a share directory or a ConfigData module
If you see an error like this:
Cannot find either a share directory or a ConfigData module for Alien::libfoo. (Alien::libfoo loaded from lib/Alien/libfoo.pm) Please see https://metacpan.org/pod/distribution/Alien-Build/lib/Alien/Build/Manual/FAQ.pod#Cannot-find-either-a-share-directory-or-a-ConfigData-module Cant locate Alien/libfoo/ConfigData.pm in @INC (you may need to install the Alien::libfoo::ConfigData module) (@INC contains: …)
it means you are trying to use an Alien that hasn’t been properly installed. An Alien::Base based Alien needs to have either the share directory build during the install process or for older legacy Alien::Base::ModuleBuild based Aliens, a ConfigData module generated by Module::Build.
This usually happens if you try to use an Alien module from the lib
directory as part of the Alien’s distribution. You need to build the
alien and use blib/lib
instead of lib
or install the alien and use
the installed path.
It is also possible that your Alien installer is not set up correctly.
Make sure your Makefile.PL
is using Alien::Build::MM correctly.
I have a question not listed here!
There are a number of forums available to people working on Alien, Alien::Base and Alien::Build modules:
- “#native” on irc.perl.org
- This is intended for native interfaces in general so is a good place for questions about Alien generally or Alien::Base and Alien::Build specifically.
- mailing list
- The
perl5-alien
google group is intended for Alien issues generally, including Alien::Base and Alien::Build. https://groups.google.com/forum/#!forum/perl5-alien - Open a support ticket
- If you have an issue with Alien::Build itself, then please open a support ticket on the project’s GitHub issue tracker. https://github.com/PerlAlien/Alien-Build/issues
SEE ALSO
Alien::Build, Alien::Build::MM, Alien::Build::Plugin, alienfile
AUTHOR
Author: Graham Ollis <plicease@cpan.org>
Contributors:
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)
COPYRIGHT AND LICENSE
This software is copyright (c) 2011-2020 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.