perldoc Alien::Build::Manual::FAQ
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 know 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'; ...
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.
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';
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}', '%{amek} 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.
use alienfile; plugin 'Probe::CommandLine' => ( command => 'gzip', );
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 [ ... ]; };
use alienfile; plugin 'PlgConfig' => '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 'PlgConfig' => 'libfoo'; share { ... after 'gather' => sub { my($build) = @_; if($^O eq 'MSWin32') { $build->runtime_prop->{libs} .= " -lpsapi"; } }; };
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 HTTP::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 HTTP::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.
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.
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
env: matrix: - ALIEN_INSTALL_TYPE=share - ALIEN_INSTALL_TYPE=system
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 Can't 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.
Contributors:
Diab Jerius (DJERIUS)
Roy Storey
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 Pisar (ppisar)
Lance Wicks (LANCEW)
Ahmad Fatoum (a3f, ATHREEF)
José Joaquín Atria (JJATRIA)
Duke Leto (LETO)
Shoichi Kaji (SKAJI)
Shawn Laffan (SLAFFAN)
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.