JezK
Edit File: Alien::Build::Manual::PluginAuthor.3pm
.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Alien::Build::Manual::PluginAuthor 3pm" .TH Alien::Build::Manual::PluginAuthor 3pm "2020-01-27" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Alien::Build::Manual::PluginAuthor \- Alien::Build plugin author documentation .SH "VERSION" .IX Header "VERSION" version 1.96 .SH "SYNOPSIS" .IX Header "SYNOPSIS" your plugin: .PP .Vb 1 \& package Alien::Build::Plugin::Build::MyPlugin; \& \& use strict; \& use warnings; \& use Alien::Build::Plugin; \& \& has arg1 => \*(Aqdefault_for arg1\*(Aq; \& has arg2 => sub { [ \*(Aqdefault\*(Aq, \*(Aqfor\*(Aq, \*(Aqarg2\*(Aq ] }; \& \& sub init \& { \& my($self, $meta) = @_; \& ... \& } \& \& 1; .Ve .PP and then from alienfile: .PP .Vb 5 \& use alienfile; \& plugin \*(AqBuild::MyPlugin\*(Aq => ( \& arg1 => \*(Aqoverride for arg1\*(Aq, \& arg2 => [ \*(Aqsomething\*(Aq, \*(Aqelse\*(Aq ], \& ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This document explains how to write Alien::Build plugins using the Alien::Build::Plugin base class. Plugins use Alien::Build::Plugin, which sets the appropriate base class, and provides you with the \f(CW\*(C`has\*(C'\fR property builder. \f(CW\*(C`has\*(C'\fR takes two arguments, the name of the property and the default value. (As with Moose and Moo, you should use a code reference to specify default values for non-string defaults). .PP The only method that you need to implement is \f(CW\*(C`init\*(C'\fR. From this method you can add hooks to change the behavior of the alienfile recipe. .PP .Vb 10 \& sub init \& { \& my($self, $meta) = @_; \& $meta\->register_hook( \& probe => sub { \& my($build) = @_; \& if( ... ) \& { \& return \*(Aqsystem\*(Aq; \& } \& else \& { \& return \*(Aqshare\*(Aq; \& } \& }, \& ); \& } .Ve .PP Hooks get the Alien::Build instance as their first argument, and depending on the hook may get additional arguments. .PP You can also modify hooks using \f(CW\*(C`before_hook\*(C'\fR, \f(CW\*(C`around_hook\*(C'\fR and \f(CW\*(C`after_hook\*(C'\fR: .PP .Vb 3 \& sub init \& { \& my($self, $meta) = @_; \& \& $meta\->before_hook( \& build => sub { \& my($build) = @_; \& $build\->log(\*(Aqthis runs before the build\*(Aq); \& }, \& ); \& \& $meta\->after_hook( \& build => sub { \& my($build) = @_; \& $build\->log(\*(Aqthis runs after the build\*(Aq); \& }, \& ); \& \& $meta\->around_hook( \& build => sub { \& my $orig = shift; \& \& # around hooks are useful for setting environment variables \& local $ENV{CPPFLAGS} = \*(Aq\-I/foo/include\*(Aq; \& \& $orig\->(@_); \& }, \& ); \& } .Ve .PP You can and should write tests for your plugin. The best way to do this is using Test::Alien::Build, which allows you to write an inline alienfile in your test. .PP .Vb 2 \& use Test::V0; \& use Test::Alien::Build; \& \& my $build = alienfile_ok q{ \& use alienfile; \& plugin \*(AqBuild::MyPlugin\*(Aq => ( \& arg1 => \*(Aqoverride for arg1\*(Aq, \& arg2 => [ \*(Aqsomething\*(Aq, \*(Aqelse\*(Aq ], \& ); \& ... \& }; \& \& # you can interrogate $build, it is an instance of L<Alien::Build>. \& \& my $alien = alien_build_ok; \& \& # you can interrogate $alien, it is an instance of L<Alien::Base>. .Ve .SH "HOOKS" .IX Header "HOOKS" .SS "probe hook" .IX Subsection "probe hook" .Vb 5 \& $meta\->register_hook( probe => sub { \& my($build) = @_; \& return \*(Aqsystem\*(Aq if ...; # system install \& return \*(Aqshare\*(Aq; # otherwise \& }); \& \& $meta\->register_hook( probe => [ $command ] ); .Ve .PP This hook should return the string \f(CW\*(C`system\*(C'\fR if the operating system provides the library or tool. It should return \f(CW\*(C`share\*(C'\fR otherwise. .PP You can also use a command that returns true when the tool or library is available. For example for use with \f(CW\*(C`pkg\-config\*(C'\fR: .PP .Vb 2 \& $meta\->register_hook( probe => \& [ \*(Aq%{pkgconf} \-\-exists libfoo\*(Aq ] ); .Ve .PP Or if you needed a minimum version: .PP .Vb 2 \& $meta\->register_hook( probe => \& [ \*(Aq%{pkgconf} \-\-atleast\-version=1.00 libfoo\*(Aq ] ); .Ve .PP Note that this hook \s-1SHOULD NOT\s0 gather system properties, such as cflags, libs, versions, etc, because the probe hook will be skipped in the event the environment variable \f(CW\*(C`ALIEN_INSTALL_TYPE\*(C'\fR is set. The detection of these properties should instead be done by the \&\f(CW\*(C`gather_system\*(C'\fR hook, below. .SS "gather_system hook" .IX Subsection "gather_system hook" .Vb 6 \& $meta\->register_hook( gather_system => sub { \& my($build) = @_; \& $build\->runtime_prop\->{cflags} = ...; \& $build\->runtime_prop\->{libs} = ...; \& $build\->runtime_prop\->{version} = ...; \& }); .Ve .PP This hook is called for a system install to determine the properties necessary for using the library or tool. These properties should be stored in the \f(CW\*(C`runtime_prop\*(C'\fR hash as shown above. Typical properties that are needed for libraries are cflags and libs. If at all possible you should also try to determine the version of the library or tool. .SS "download hook" .IX Subsection "download hook" .Vb 4 \& $meta\->register_hook( download => sub { \& my($build) = @_; \& ... \& }); .Ve .PP This hook is used to download from the internet the source. Either as an archive (like tar, zip, etc), or as a directory of files (git clone, etc). When the hook is called, the current working directory will be a new empty directory, so you can save the download to the current directory. If you store a single file in the directory, Alien::Build will assume that it is an archive, which will be processed by the extract hook below. If you store multiple files, Alien::Build will assume the current directory is the source root. If no files are stored at all, an exception with an appropriate diagnostic will be thrown. .PP \&\fBNote\fR: If you register this hook, then the fetch, decode and prefer hooks will \s-1NOT\s0 be called. .SS "fetch hook" .IX Subsection "fetch hook" .Vb 1 \& package Alien::Build::Plugin::MyPlugin; \& \& use strict; \& use warnings; \& use Alien::Build::Plugin; \& use Carp (); \& \& has \*(Aq+url\*(Aq => sub { Carp::croak "url is required property" }; \& \& sub init \& { \& my($self, $meta) = @_; \& \& $meta\->register_hook( fetch => sub { \& my($build, $url) = @_; \& ... \& } \& } \& \& 1; .Ve .PP Used to fetch a resource. The first time it will be called without an argument, so the configuration used to find the resource should be specified by the plugin's properties. On subsequent calls the first argument will be a \s-1URL.\s0 .PP Normally the first fetch will be to either a file or a directory listing. If it is a file then the content should be returned as a hash reference with the following keys: .PP .Vb 7 \& # content of file stored in Perl \& return { \& type => \*(Aqfile\*(Aq, \& filename => $filename, \& content => $content, \& version => $version, # optional, if known \& }; \& \& # content of file stored in the filesystem \& return { \& type => \*(Aqfile\*(Aq, \& filename => $filename, \& path => $path, # full file system path to file \& version => $version, # optional, if known \& tmp => $tmp, # optional \& }; .Ve .PP \&\f(CW$tmp\fR if set will indicate if the file is temporary or not, and can be used by Alien::Build to save a copy in some cases. The default is true, so Alien::Build assumes the file or directory is temporary if you don't tell it otherwise. .PP If the \s-1URL\s0 points to a directory listing you should return it as either a hash reference containing a list of files: .PP .Vb 12 \& return { \& type => \*(Aqlist\*(Aq, \& list => [ \& # filename: each filename should be just the \& # filename portion, no path or url. \& # url: each url should be the complete url \& # needed to fetch the file. \& # version: OPTIONAL, may be provided by some fetch or prefer \& { filename => $filename1, url => $url1, version => $version1 }, \& { filename => $filename2, url => $url2, version => $version2 }, \& ] \& }; .Ve .PP or if the listing is in \s-1HTML\s0 format as a hash reference containing the \&\s-1HTML\s0 information: .PP .Vb 6 \& return { \& type => \*(Aqhtml\*(Aq, \& charset => $charset, # optional \& base => $base, # the base URL: used for computing relative URLs \& content => $content, # the HTML content \& }; .Ve .PP or a directory listing (usually produced by ftp servers) as a hash reference: .PP .Vb 5 \& return { \& type => \*(Aqdir_listing\*(Aq, \& base => $base, \& content => $content, \& }; .Ve .SS "decode hook" .IX Subsection "decode hook" .Vb 3 \& sub init \& { \& my($self, $meta) = @_; \& \& $meta\->register_hook( decode => sub { \& my($build, $res) = @_; \& ... \& } \& } .Ve .PP This hook takes a response hash reference from the \f(CW\*(C`fetch\*(C'\fR hook above with a type of \f(CW\*(C`html\*(C'\fR or \f(CW\*(C`dir_listing\*(C'\fR and converts it into a response hash reference of type \f(CW\*(C`list\*(C'\fR. In short it takes an \s-1HTML\s0 or \s-1FTP\s0 file listing response from a fetch hook and converts it into a list of filenames and links that can be used by the prefer hook to choose the correct file to download. See \f(CW\*(C`fetch\*(C'\fR for the specification of the input and response hash references. .SS "prefer hook" .IX Subsection "prefer hook" .Vb 3 \& sub init \& { \& my($self, $meta) = @_; \& \& $meta\->register_hook( prefer => sub { \& my($build, $res) = @_; \& return { \& type => \*(Aqlist\*(Aq, \& list => [sort @{ $res\->{list} }], \& }; \& } \& } .Ve .PP This hook sorts candidates from a listing generated from either the \f(CW\*(C`fetch\*(C'\fR or \f(CW\*(C`decode\*(C'\fR hooks. It should return a new list hash reference with the candidates sorted from best to worst. It may also remove candidates that are totally unacceptable. .SS "extract hook" .IX Subsection "extract hook" .Vb 4 \& $meta\->register_hook( extract => sub { \& my($build, $archive) = @_; \& ... \& }); .Ve .SS "patch hook" .IX Subsection "patch hook" .Vb 4 \& $meta\->register_hook( patch => sub { \& my($build) = @_; \& ... \& }); .Ve .PP This hook is completely optional. If registered, it will be triggered after extraction and before build. It allows you to apply any patches or make any modifications to the source if they are necessary. .SS "patch_ffi hook" .IX Subsection "patch_ffi hook" .Vb 4 \& $meta\->register_hook( patch_ffi => sub { \& my($build) = @_; \& ... \& }); .Ve .PP This hook is exactly like the \f(CW\*(C`patch\*(C'\fR hook, except it fires only on an \&\s-1FFI\s0 build. .SS "build hook" .IX Subsection "build hook" .Vb 4 \& $meta\->register_hook( build => sub { \& my($build) = @_; \& ... \& }); .Ve .PP This does the main build of the alienized project and installs it into the staging area. The current directory is the build root. You need to run whatever tools are necessary for the project, and install them into \f(CW\*(C`%{.install.prefix}\*(C'\fR. .SS "build_ffi hook" .IX Subsection "build_ffi hook" .Vb 4 \& $meta\->register_hook( build_ffi => sub { \& my($build) = @_; \& ... \& }); .Ve .PP This is the same as \f(CW\*(C`build\*(C'\fR, except it fires only on a \s-1FFI\s0 build. .SS "gather_share hook" .IX Subsection "gather_share hook" .Vb 4 \& $meta\->register_hook( gather_share => sub { \& my($build) = @_; \& ... \& }); .Ve .PP This is the same as \f(CW\*(C`gather_system\*(C'\fR, except it fires after a \f(CW\*(C`share\*(C'\fR install. .SS "gather_ffi hook" .IX Subsection "gather_ffi hook" .Vb 4 \& $meta\->register_hook( gather_ffi => sub { \& my($build) = @_; \& ... \& }); .Ve .PP This is the same as \f(CW\*(C`gather_share\*(C'\fR, except it fires after a \f(CW\*(C`share\*(C'\fR \s-1FFI\s0 install. .SS "override hook" .IX Subsection "override hook" .Vb 3 \& $meta\->register_hook( override => sub { \& my($build) = @_; \& }); .Ve .PP This allows you to alter the override logic. It should return one of \&\f(CW\*(C`share\*(C'\fR, \f(CW\*(C`system\*(C'\fR, \f(CW\*(C`default\*(C'\fR or \f(CW\*(Aq\*(Aq\fR. The default implementation is just this: .PP .Vb 1 \& return $ENV{ALIEN_INSTALL_TYPE} || \*(Aq\*(Aq; .Ve .SS "clean_install" .IX Subsection "clean_install" .Vb 3 \& $meta\->register_hook( clean_install => sub { \& my($build) = @_; \& }); .Ve .PP This hook allows you to remove files from the final install location before the files are installed by the installer layer (examples: Alien::Build::MM, Alien::Build::MB or App::af). This hook is never called by default, and must be enabled via the interface to the installer layer. .PP This hook \s-1SHOULD NOT\s0 remove the \f(CW\*(C`_alien\*(C'\fR directory or its content from the install location. .PP The default implementation removes all the files \s-1EXCEPT\s0 the \f(CW\*(C`_alien\*(C'\fR directory and its content. .SH "AUTHOR" .IX Header "AUTHOR" Author: Graham Ollis <plicease@cpan.org> .PP Contributors: .PP Diab Jerius (\s-1DJERIUS\s0) .PP Roy Storey (\s-1KIWIROY\s0) .PP Ilya Pavlov .PP David Mertens (run4flat) .PP Mark Nunberg (mordy, mnunberg) .PP Christian Walde (Mithaldu) .PP Brian Wightman (MidLifeXis) .PP Zaki Mughal (zmughal) .PP mohawk (mohawk2, \s-1ETJ\s0) .PP Vikas N Kumar (vikasnkumar) .PP Flavio Poletti (polettix) .PP Salvador Fandiño (salva) .PP Gianni Ceccarelli (dakkar) .PP Pavel Shaydo (zwon, trinitum) .PP Kang-min Liu (劉康民, gugod) .PP Nicholas Shipp (nshp) .PP Juan Julián Merelo Guervós (\s-1JJ\s0) .PP Joel Berger (\s-1JBERGER\s0) .PP Petr Pisar (ppisar) .PP Lance Wicks (\s-1LANCEW\s0) .PP Ahmad Fatoum (a3f, \s-1ATHREEF\s0) .PP José Joaquín Atria (\s-1JJATRIA\s0) .PP Duke Leto (\s-1LETO\s0) .PP Shoichi Kaji (\s-1SKAJI\s0) .PP Shawn Laffan (\s-1SLAFFAN\s0) .PP Paul Evans (leonerd, \s-1PEVANS\s0) .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2011\-2020 by Graham Ollis. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.