1Alien::Build::Manual::AUlsieernACuotnhtorri(b3u)ted PerlAlDioecnu:m:eBnutialtdi:o:nManual::AlienAuthor(3)
2
3
4

NAME

6       Alien::Build::Manual::AlienAuthor - Alien author documentation
7

VERSION

9       version 2.47
10

SYNOPSIS

12        perldoc Alien::Build::Manual::AlienAuthor
13

DESCRIPTION

15       Note: Please read the entire document before you get started in writing
16       your own alienfile.  The section on dynamic vs. static libraries will
17       likely save you a lot of grief if you read it now!
18
19       This document is intended to teach Alien authors how to build their own
20       Alien distribution using Alien::Build and Alien::Base.  Such an Alien
21       distribution consists of three essential parts:
22
23       An alienfile
24           This is a recipe for how to 1) detect an already installed version
25           of the library or tool you are alienizing 2) download and build the
26           library or tool that you are alienizing and 3) gather the
27           configuration settings necessary for the use of that library or
28           tool.
29
30       An installer "Makefile.PL" or "Build.PL" or a "dist.ini" if you are
31       using Dist::Zilla
32           This is a thin layer between your alienfile recipe, and the Perl
33           installer (either ExtUtils::MakeMaker or Module::Build.
34
35       A Perl class (.pm file) that inherits from Alien::Base
36           For most Aliens this does not need to be customized at all, since
37           Alien::Base usually does what you need.
38
39       For example if you were alienizing a library called libfoo, you might
40       have these files:
41
42        Alien-Libfoo-1.00/Makefile.PL
43        Alien-Libfoo-1.00/alienfile
44        Alien-Libfoo-1.00/lib/Alien/Libfoo.pm
45
46       This document will focus mainly on instructing you how to construct an
47       alienfile, but we will also briefly cover making a simple "Makefile.PL"
48       or "dist.ini" to go along with it.  We will also touch on when you
49       might want to extend your subclass to add non-standard functionality.
50
51   Using commands
52       Most software libraries and tools will come with instructions for how
53       to install them in the form of commands that you are intended to type
54       into a shell manually.  The easiest way to automate those instructions
55       is to just put the commands in your alienfile.  For example, lets
56       suppose that libfoo is built using autoconf and provides a "pkg-config"
57       ".pc" file.
58
59       We will also later discuss plugins.  For common build systems like
60       autoconf or CMake, it is usually better to use the appropriate plugin
61       because they will handle corner cases better than a simple set of
62       commands.  We're going to take a look at commands first because it's
63       easier to understand the different phases with commands.
64
65       (Aside, autoconf is a series of tools and macros used to configure
66       (usually) a C or C++ library or tool by generating any number of
67       Makefiles.  It is the C equivalent to ExtUtils::MakeMaker, if you will.
68       Basically, if your library or tool instructions start with
69       './configure' it is most likely an autoconf based library or tool).
70
71       (Aside2, "pkg-config" is a standard-ish way to provide the compiler and
72       linker flags needed for compiling and linking against the library.  If
73       your tool installs a ".pc" file, usually in "$PREFIX/lib/pkgconfig"
74       then, your tool uses "pkg-config").
75
76       Here is the alienfile that you might have:
77
78        use alienfile;
79
80        probe [ 'pkg-config --exists libfoo' ];
81
82        share {
83
84          start_url 'http://www.libfoo.org/src/libfoo-1.00.tar.gz';
85
86          download [ 'wget %{.meta.start_url}' ];
87
88          extract [ 'tar zxf %{.install.download}' ];
89
90          build [
91            [ './configure --prefix=%{.install.prefix} --disable-shared' ],
92            [ '%{make}' ],
93            [ '%{make} install' ],
94          ];
95
96        };
97
98        gather [
99          [ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
100          [ 'pkg-config --cflags     libfoo', \'%{.runtime.cflags}'  ],
101          [ 'pkg-config --libs       libfoo', \'%{.runtime.libs}'    ],
102        ];
103
104       There is a lot going on here, so lets decode it a little bit.  An
105       alienfile is just some Perl with some alien specific sugar.  The first
106       line
107
108        use alienfile;
109
110       imports the sugar into the alienfile.  It also is a flag for the reader
111       to see that this is an alienfile and not some other kind of Perl
112       script.
113
114       The second line is the probe directive:
115
116        probe [ 'pkg-config --exists libfoo' ];
117
118       is used to see if the library is already installed on the target
119       system.  If "pkg-config" is in the path, and if libfoo is installed,
120       this should exit with a success (0) and tell Alien::Build to use the
121       system library.  If either "pkg-config" in the PATH, or if libfoo is
122       not installed, then it will exist with non-success (!= 0) and tells
123       Alien::Build to download and build from source.
124
125       You can provide as many probe directives as you want.  This is useful
126       if there are different ways to probe for the system.  Alien::Build will
127       stop on the first successfully found system library found.  Say our
128       library libfoo comes with a ".pc" file for use with "pkg-config" and
129       also provides a "foo-config" program to find the same values.  You
130       could then specify this in your alienfile
131
132        probe [ 'pkg-config --exists libfoo' ];
133        probe [ 'foo-config --version' ];
134
135       Other directives can be specified multiple times if there are different
136       methods that can be tried for the various steps.
137
138       Sometimes it is easier to probe for a library from Perl rather than
139       with a command.  For that you can use a code reference.  For example,
140       another way to call "pkg-config" would be from Perl:
141
142        probe sub {
143          my($build) = @_;  # $build is the Alien::Build instance.
144          system 'pkg-config --exists libfoo';
145          $? == 0 ? 'system' : 'share';
146        };
147
148       The Perl code should return 'system' if the library is installed, and
149       'share' if not.  (Other directives should return a true value on
150       success, and a false value).  You can also throw an exception with
151       "die" to indicate a failure.
152
153       The next part of the alienfile is the "share" block, which is used to
154       group the directives which are used to download and install the library
155       or tool in the event that it is not already installed.
156
157        share {
158          start_url 'http://www.libfoo.org/src/libfoo-1.00.tar.gz';
159          download [ 'wget %{.meta.start_url}' ];
160          extract [ 'tar zxf %{.install.download}' ];
161          build [
162            [ './configure --prefix=%{.install.prefix} --disable-shared' ],
163            [ '%{make}' ],
164            [ '%{make} install' ],
165          ];
166        };
167
168       The start_url specifies where to find the package that you are
169       alienizing.  It should be either a tarball (or zip file, or what have
170       you) or an HTML index.  The download directive as you might imagine
171       specifies how to download  the library or tool.  The extract directive
172       specifies how to extract the archive once it is downloaded.  In the
173       extract step, you can use the variable "%{.install.download}" as a
174       placeholder for the archive that was downloaded in the download step.
175       This is also accessible if you use a code reference from the
176       Alien::Build instance:
177
178        share {
179          ...
180          requires 'Archive::Extract';
181          extract sub {
182            my($build) = @_;
183            my $tarball = $build->install_prop->{download};
184            my $ae = Archive::Extract->new( archive => $tarball );
185            $ae->extract;
186            1;
187          }
188          ...
189        };
190
191       The build directive specifies how to build the library or tool once it
192       has been downloaded and extracted.  Note the special variable
193       "%{.install.prefix}" is the location where the library should be
194       installed.  "%{make}" is a helper which will be replaced by the
195       appropriate "make", which may be called something different on some
196       platforms (on Windows for example, it frequently may be called "nmake"
197       or "dmake").
198
199       The final part of the alienfile has a gather directive which specifies
200       how to get the details on how to compile and link against the library.
201       For this, once again we use the "pkg-config" command:
202
203        gather [
204          [ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
205          [ 'pkg-config --cflags     libfoo', \'%{.runtime.cflags}'  ],
206          [ 'pkg-config --libs       libfoo', \'%{.runtime.libs}'    ],
207        ];
208
209       The scalar reference as the final item in the command list tells
210       Alien::Build that the output from the command should be stored in the
211       given variable.  The runtime variables are the ones that will be
212       available to "Alien::Libfoo" once it is installed.  (Install
213       properties, which are the ones that we have seen up till now are thrown
214       away once the Alien distribution is installed.
215
216       You can also provide a "sys" block for directives that should be used
217       when a system install is detected.  Normally you only need to do this
218       if the gather step is different between share and system installs.  For
219       example, the above is equivalent to:
220
221        build {
222          ...
223          gather [
224            [ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
225            [ 'pkg-config --cflags     libfoo', \'%{.runtime.cflags}'  ],
226            [ 'pkg-config --libs       libfoo', \'%{.runtime.libs}'    ],
227          ];
228        };
229
230        sys {
231          gather [
232            [ 'pkg-config --modversion libfoo', \'%{.runtime.version}' ],
233            [ 'pkg-config --cflags     libfoo', \'%{.runtime.cflags}'  ],
234            [ 'pkg-config --libs       libfoo', \'%{.runtime.libs}'    ],
235          ];
236        };
237
238       (Aside3, the reason it is called "sys" and not "system" is so that it
239       does not conflict with the built in "system" function)!
240
241   Using plugins
242       The first example is a good way of showing the full manual path that
243       you can choose, but there is a lot of repetition, if you are doing many
244       Aliens that use autoconf and "pkg-config" (which are quite common.
245       alienfile allows you to use plugins.  See Alien::Build::Plugin for a
246       list of some of the plugin categories.
247
248       For now, I will just show you how to write the alienfile for libfoo
249       above using Alien::Build::Plugin::Build::Autoconf,
250       Alien::Build::Plugin::PkgConfig::Negotiate,
251       Alien::Build::Plugin::Download::Negotiate, and
252       Alien::Build::Plugin::Extract::Negotiate
253
254        use alienfile;
255
256        plugin 'PkgConfig' => (
257          pkg_name => 'libfoo',
258        );
259
260        share {
261          start_url 'http://www.libfoo.org/src';
262          plugin 'Download' => (
263            filter => qr/^libfoo-[0-9\.]+\.tar\.gz$/,
264            version => qr/^libfoo-([0-9\.]+)\.tar\.gz$/,
265          );
266          plugin 'Extract' => 'tar.gz';
267          plugin 'Build::Autoconf';
268          build [
269            '%{configure} --disable-shared',
270            '%{make}',
271            '%{make} install',
272          ];
273        };
274
275       The first plugin that we use is the "pkg-config" negotiation plugin.  A
276       negotiation plugin is one which doesn't do the actual work but selects
277       the best one from a set of plugins depending on your platform and
278       environment.  (In the case of
279       Alien::Build::Plugin::PkgConfig::Negotiate, it may choose to use
280       command line tools, a pure Perl implementation (PkgConfig), or
281       libpkgconf, depending on what is available).  When using negotiation
282       plugins you may omit the "::Negotiate" suffix.  So as you can see using
283       the plugin here is an advantage because it is more reliable than just
284       specifying a command which may not be installed!
285
286       Next we use the download negotiation plugin.  This is also better than
287       the version above, because again, "wget" my not be installed on the
288       target system.  Also you can specify a URL which will be scanned for
289       links, and use the most recent version.
290
291       We use the Extract negotiation plugin to use either command line tools,
292       or Perl libraries to extract from the archive once it is downloaded.
293
294       Finally we use the Autoconf plugin
295       (Alien::Build::Plugin::Build::Autoconf).  This is a lot more
296       sophisticated and reliable than in the previous example, for a number
297       of reasons.  This version will even work on Windows assuming the
298       library or tool you are alienizing supports that platform!
299
300       Strictly speaking the build directive is not necessary, because the
301       autoconf plugin provides a default which is reasonable.  The only
302       reason that you would want to include it is if you need to provide
303       additional flags to the configure step.
304
305        share {
306          ...
307          build [
308            '%{configure} --enable-bar --enable-baz --disable-shared',
309            '%{make}',
310            '%{make} install',
311          ];
312        };
313
314   Multiple .pc files
315       Some packages come with multiple libraries paired with multiple ".pc"
316       files.  In this case you want to provide the
317       Alien::Build::Plugin::PkgConfig::Negotiate with an array reference of
318       package names.
319
320        plugin 'PkgConfig' => (
321          pkg_name => [ 'foo', 'bar', 'baz' ],
322        );
323
324       All packages must be found in order for the "system" install to
325       succeed.  Once installed the first "pkg_name" will be used by default
326       (in this example "foo"), and you can retrieve any other "pkg_name"
327       using the Alien::Base alt method.
328
329   A note about dynamic vs. static libraries
330       If you are using your Alien to build an XS module, it is important that
331       you use static libraries if possible.  If you have a package that
332       refuses to build a static library, then you can use Alien::Role::Dino.
333
334       Actually let me back up a minute.  For a "share" install it is best to
335       use static libraries to build your XS extension.  This is because if
336       your Alien is ever upgraded to a new version it can break your existing
337       XS modules.  For a "system" install shared libraries are usually best
338       because you can often get security patches without having to re-build
339       anything in perl land.
340
341       If you looked closely at the "Using commands" and "Using plugins"
342       sections above, you may notice that we went out of our way where
343       possible to tell Autotools to build only static libraries using the
344       "--disable-shared" command.  The Autoconf plugin also does this by
345       default.
346
347       Sometimes though you will have a package that builds both, or maybe you
348       want both static and dynamic libraries to work with XS and FFI.  For
349       that case, there is the Alien::Build::Plugin::Gather::IsolateDynamic
350       plugin.
351
352        use alienfile;
353        ...
354        plugin 'Gather::IsolateDynamic';
355
356       What it does, is that it moves the dynamic libraries (usually .so on
357       Unix and .DLL on Windows) to a place where they can be found by FFI,
358       and where they won't be used by the compiler for building XS.  It
359       usually doesn't do any harm to include this plugin, so if you are just
360       starting out you might want to add it anyway.  Arguably it should have
361       been the default behavior from the beginning.
362
363       If you have already published an Alien that does not isolate its
364       dynamic libraries, then you might get some fails from old upgraded
365       aliens because the share directory isn't cleaned up by default (this is
366       perhaps a design bug in the way that share directories work, but it is
367       a long standing characteristic).  One work around for this is to use
368       the "clean_install" property on Alien::Build::MM, which will clean out
369       the share directory on upgrade, and possibly save you a lot of grief.
370
371   Verifying and debugging your alienfile
372       You could feed your alienfile directly into Alien::Build, or
373       Alien::Build::MM, but it is sometimes useful to test your alienfile
374       using the "af" command (it does not come with Alien::Build, you need to
375       install App::af).  By default "af" will use the "alienfile" in the
376       current directory (just as "make" uses the "Makefile" in the current
377       directory; just like "make" you can use the "-f" option to specify a
378       different alienfile).
379
380       You can test your alienfile in dry run mode:
381
382        % af install --dry-run
383        Alien::Build::Plugin::Core::Legacy> adding legacy hash to config
384        Alien::Build::Plugin::Core::Gather> mkdir -p /tmp/I2YXRyxb0r/_alien
385        ---
386        cflags: ''
387        cflags_static: ''
388        install_type: system
389        legacy:
390          finished_installing: 1
391          install_type: system
392          name: libfoo
393          original_prefix: /tmp/7RtAusykNN
394          version: 1.2.3
395        libs: '-lfoo '
396        libs_static: '-lfoo '
397        prefix: /tmp/7RtAusykNN
398        version: 1.2.3
399
400       You can use the "--type" option to force a share install (download and
401       build from source):
402
403        % af install --type=share --dry-run
404        Alien::Build::Plugin::Core::Download> decoding html
405        Alien::Build::Plugin::Core::Download> candidate *https://www.libfoo.org/download/libfoo-1.2.4.tar.gz
406        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.3.tar.gz
407        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.2.tar.gz
408        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.1.tar.gz
409        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.0.tar.gz
410        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.9.tar.gz
411        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.8.tar.gz
412        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.7.tar.gz
413        Alien::Build::Plugin::Core::Download> candidate  ...
414        Alien::Build::Plugin::Core::Download> setting version based on archive to 1.2.4
415        Alien::Build::Plugin::Core::Download> downloaded libfoo-1.2.4.tar.gz
416        Alien::Build::CommandSequence> + ./configure --prefix=/tmp/P22WEXj80r --with-pic --disable-shared
417        ... snip ...
418        Alien::Build::Plugin::Core::Gather> mkdir -p /tmp/WsoLAQ889w/_alien
419        ---
420        cflags: ''
421        cflags_static: ''
422        install_type: share
423        legacy:
424          finished_installing: 1
425          install_type: share
426          original_prefix: /tmp/P22WEXj80r
427          version: 1.2.4
428        libs: '-L/tmp/P22WEXj80r/lib -lfoo '
429        libs_static: '-L/tmp/P22WEXj80r/lib -lfoo '
430        prefix: /tmp/P22WEXj80r
431        version: 1.2.4
432
433       You can also use the "--before" and "--after" options to take a peek at
434       what the build environment looks like at different stages as well,
435       which can sometimes be useful:
436
437        % af install --dry-run --type=share --before build bash
438        Alien::Build::Plugin::Core::Download> decoding html
439        Alien::Build::Plugin::Core::Download> candidate *https://www.libfoo.org/download/libfoo-1.2.4.tar.gz
440        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.3.tar.gz
441        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.2.tar.gz
442        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.1.tar.gz
443        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.0.tar.gz
444        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.9.tar.gz
445        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.8.tar.gz
446        Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.7.tar.gz
447        Alien::Build::Plugin::Core::Download> candidate  ...
448        Alien::Build::Plugin::Core::Download> setting version based on archive to 1.2.4
449        Alien::Build::Plugin::Core::Download> downloaded libfoo-1.2.4.tar.gz
450        App::af::install>  [ before build ] + bash
451        /tmp/fbVPu4LRTs/build_5AVn/libfoo-1.2.4$ ls
452        CHANGES Makefile autoconf.ac lib
453        /tmp/fbVPu4LRTs/build_5AVn/libfoo-1.2.4$
454
455       There are a lot of other useful things that you can do with the "af"
456       command.  See af for details.
457
458   Integrating with MakeMaker
459       Once you have a working alienfile you can write your "Makefile.PL".
460
461        use ExtUtils::MakeMaker;
462        use Alien::Build::MM;
463
464        my $abmm = Alien::Build::MM->new;
465
466        WriteMakefile($abmm->mm_args(
467          ABSTRACT           => 'Discover or download and install libfoo',
468          DISTNAME           => 'Alien-Libfoo',
469          NAME               => 'Alien::Libfoo',
470          VERSION_FROM       => 'lib/Alien/Libfoo.pm',
471          CONFIGURE_REQUIRES => {
472            'Alien::Build::MM' => 0,
473          },
474          BUILD_REQUIRES => {
475            'Alien::Build::MM' => 0,
476          },
477          PREREQ_PM => {
478            'Alien::Base' => 0,
479          },
480          # If you are going to write the recommended
481          # tests you will will want these:
482          TEST_REQUIRES => {
483            'Test::Alien' => 0,
484            'Test2::V0'   => 0,
485          },
486        ));
487
488        sub MY::postamble {
489          $abmm->mm_postamble;
490        }
491
492       The "lib/Alien/Libfoo.pm" that goes along with it is very simple:
493
494        package Alien::Libfoo;
495
496        use strict;
497        use warnings;
498        use parent qw( Alien::Base );
499
500        1;
501
502       You are done and can install it normally:
503
504        % perl Makefile.PL
505        % make
506        % make test
507        % make install
508
509   Integrating with Module::Build
510       Please don't!  Okay if you have to there is Alien::Build::MB.
511
512   Non standard configuration
513       Alien::Base support most of the things that your Alien will need, like
514       compiler flags (cflags), linker flags (libs) and binary directory
515       (bin_dir).  Your library or tool may have other configuration items
516       which are not supported by default.  You can store the values in the
517       alienfile into the runtime properties:
518
519        gather [
520          # standard:
521          [ 'foo-config --version libfoo', \'%{.runtime.version}' ],
522          [ 'foo-config --cflags  libfoo', \'%{.runtime.cflags}'  ],
523          [ 'foo-config --libs    libfoo', \'%{.runtime.libs}'    ],
524          # non-standard
525          [ 'foo-config --bar-baz libfoo', \'%{.runtime.bar_baz}' ],
526        ];
527
528       then you can expose them in your Alien::Base subclass:
529
530        package Alien::Libfoo;
531
532        use strict;
533        use warnings;
534        use parent qw( Alien::Base );
535
536        sub bar_baz {
537          my($self) = @_;
538          $self->runtime_prop->{bar_baz},
539        };
540
541        1;
542
543   Testing
544       (optional, but highly recommended)
545
546       You should write a test using Test::Alien to make sure that your alien
547       will work with any XS modules that are going to use it:
548
549        use Test2::V0;
550        use Test::Alien;
551        use Alien::Libfoo;
552
553        alien_ok 'Alien::Libfoo';
554
555        xs_ok do { local $/; <DATA> }, with_subtest {
556          is Foo::something(), 1, 'Foo::something() returns 1';
557        };
558
559        done_testing;
560
561        __DATA__
562        #include "EXTERN.h"
563        #include "perl.h"
564        #include "XSUB.h"
565        #include <foo.h>
566
567        MODULE = Foo PACKAGE = Foo
568
569        int something()
570
571       You can also use Test::Alien to test tools instead of libraries:
572
573        use Test2::V0;
574        use Test::Alien;
575        use Alien::Libfoo;
576
577        alien_ok 'Alien::Libfoo';
578        run_ok(['foo', '--version'])
579          ->exit_is(0);
580
581        done_testing;
582
583       You can also write tests specifically for FFI::Platypus, if your alien
584       is going to be used to write FFI bindings.  (the test below is the FFI
585       equivalent to the XS example above).
586
587        use Test2::V0;
588        use Test::Alien;
589        use Alien::Libfoo;
590
591        alien_ok 'Alien::Libfoo';
592        ffi_ok { symbols => [ 'something' ] }, with_subtest {
593          # $ffi is an instance of FFI::Platypus with the lib
594          # set appropriately.
595          my($ffi) = @_;
596          my $something = $ffi->function( something => [] => 'int' );
597          is $something->call(), 1, 'Foo::something() returns 1';
598        };
599
600       If you do use "ffi_ok" you want to make sure that your alien reliably
601       produces dynamic libraries.  If it isn't consistent (if for example
602       some platforms tend not to provide or build dynamic libraries), you can
603       check that "dynamic_libs" doesn't return an empty list.
604
605        ...
606        alien_ok 'Alien::Libfoo';
607        SKIP: {
608          skip "This test requires a dynamic library"
609            unless Alien::Libfoo->dynamic_libs;
610          ffi_ok { symbols [ 'something' ] }, with_subtest {
611            ...
612          };
613        }
614
615       More details on testing Alien modules can be found in the Test::Alien
616       documentation.
617
618       You can also run the tests that come with the package that you are
619       alienizing, by using a "test" block in your alienfile.  Keep in mind
620       that some packages use testing tools or have other prerequisites that
621       will not be available on your users machines when they attempt to
622       install your alien.  So you do not want to blindly add a test block
623       without checking what the prereqs are.  For Autoconf style packages you
624       typically test a package using the "make check" command:
625
626        use alienfile;
627
628        plugin 'PkgConfig' => 'libfoo';
629
630        share {
631          ... # standard build steps.
632          test [ '%{make} check' ];
633        };
634
635   Dist::Zilla
636       (optional, mildly recommended)
637
638       You can also use the Alien::Build Dist::Zilla plugin
639       Dist::Zilla::Plugin::AlienBuild:
640
641        name    = Alien-Libfoo
642        author  = E. Xavier Ample <example@cpan.org>
643        license = Perl_5
644        copyright_holder = E. Xavier Ample <example@cpan.org>
645        copyright_year   = 2017
646        version = 0.01
647
648        [@Basic]
649        [AlienBuild]
650
651       The plugin takes care of a lot of details like making sure that the
652       correct minimum versions of Alien::Build and Alien::Base are used.  See
653       the plugin documentation for additional details.
654
655   Using your Alien
656       Once you have installed you can use your Alien.  See
657       Alien::Build::Manual::AlienUser for guidance on that.
658

AUTHOR

660       Author: Graham Ollis <plicease@cpan.org>
661
662       Contributors:
663
664       Diab Jerius (DJERIUS)
665
666       Roy Storey (KIWIROY)
667
668       Ilya Pavlov
669
670       David Mertens (run4flat)
671
672       Mark Nunberg (mordy, mnunberg)
673
674       Christian Walde (Mithaldu)
675
676       Brian Wightman (MidLifeXis)
677
678       Zaki Mughal (zmughal)
679
680       mohawk (mohawk2, ETJ)
681
682       Vikas N Kumar (vikasnkumar)
683
684       Flavio Poletti (polettix)
685
686       Salvador Fandiño (salva)
687
688       Gianni Ceccarelli (dakkar)
689
690       Pavel Shaydo (zwon, trinitum)
691
692       Kang-min Liu (劉康民, gugod)
693
694       Nicholas Shipp (nshp)
695
696       Juan Julián Merelo Guervós (JJ)
697
698       Joel Berger (JBERGER)
699
700       Petr Písař (ppisar)
701
702       Lance Wicks (LANCEW)
703
704       Ahmad Fatoum (a3f, ATHREEF)
705
706       José Joaquín Atria (JJATRIA)
707
708       Duke Leto (LETO)
709
710       Shoichi Kaji (SKAJI)
711
712       Shawn Laffan (SLAFFAN)
713
714       Paul Evans (leonerd, PEVANS)
715
716       Håkon Hægland (hakonhagland, HAKONH)
717
718       nick nauwelaerts (INPHOBIA)
719
721       This software is copyright (c) 2011-2020 by Graham Ollis.
722
723       This is free software; you can redistribute it and/or modify it under
724       the same terms as the Perl 5 programming language system itself.
725
726
727
728perl v5.34.0                      2022-03-0A7lien::Build::Manual::AlienAuthor(3)
Impressum