1Alien::Base::ModuleBuilUds:e:rFACQo(n3t)ributed Perl DocAulmieennt:a:tBiaosne::ModuleBuild::FAQ(3)
2
3
4

NAME

6       Alien::Base::ModuleBuild::FAQ - Frequently Asked Questions about
7       Alien::Base::ModuleBuild
8

SYNOPSIS

10        perldoc Alien::Base::FAQ
11

DESCRIPTION

13       NOTE: Please consider for new development of Aliens that you use
14       Alien::Build and alienfile instead.  Like Alien::Base::ModuleBUild they
15       work with Alien::Base.  Unlike Alien::Base::Module::Build they are more
16       easily customized and handle a number of corner cases better.  For a
17       good place to start, please see Alien::Build::Manual::API.  Although
18       the Alien-Base / Alien-Build team will continue to maintain this
19       module, (we will continue to fix bugs where appropriate), we aren't
20       adding any new features to this module.
21
22       This document serves to answer the most frequently asked questions made
23       by Alien::Base authors.
24
25   What is Alien and Alien::Base?
26       Alien is a Perl namespace for defining dependencies in CPAN for
27       libraries and tools which are not "native" to CPAN.  For a manifesto
28       style description of the Why, and How see Alien.  Alien::Base is a base
29       class and framework for creating Alien distributions.  The idea is to
30       address as many of the common challenges to developing Alien modules in
31       the base class to simplify the process.
32
33   How do I specify a minimum or exact version requirement for packages that
34       use pkg-config?
35       The "alien_version_check" attribute to Alien::Base::ModuleBuild will be
36       executed to determine if the library is provided by the operating
37       system.  The default for this is "%{pkg_config} --modversion %n" which
38       simply checks to see if any version of that package is available, and
39       prints the version number.  You can use the "--atleast-version",
40       "--exact-version" options to require a specific range of versions, but
41       these flags do not work with the "--modversion" flag, so be sure to
42       invoke separately.
43
44        use Alien::Base::ModuleBuild;
45        Alien::Base::ModuleBuild->new(
46          dist_name           => 'Alien::Foo',
47          alien_name          => 'foo',
48          configure_requires  => { 'Alien::Base::ModuleBuild' => '0.022' }, # required for %{pkg_config}
49          alien_version_check => '%{pkg_config} --atleast-version 1.2.3 %n && %{pkg_config} --modversion %n',
50          ...
51        )->create_build_script;
52
53       It is better to use the built in "%{pkg_config}" helper as it will use
54       the system provided pkg-config if it is available and fallback on the
55       pure perl PkgConfig if not.
56
57       You can also use "--exact-version" to specify an exact version.
58
59   How to create an Alien module for packages that do not support pkg-config?
60       Although Alien::Base and Alien::Base::ModuleBuild assume packages come
61       with a "pkg-config" ".pc" file to determine compiler and linker flags
62       by default, you can implement an Alien module for packages that do use
63       "pkg-config" by following these tasks:
64
65       subclass Alien::Base::ModuleBuild and implement
66       "alien_check_installed_version"
67           Create a subclass of Alien::Base::ModuleBuild and put it in the
68           "inc" directory of your distribution so that it can be used during
69           install but won't be installed.
70
71            # inc/My/ModuleBuild.pm
72            package My::ModuleBuild;
73
74            use parent 'Alien::Base::ModuleBuild';
75
76            sub alien_check_installed_version {
77              my($class) = @_;
78
79              # determine if your library is already provided by the system
80              my $version = ...;
81
82              # return false if the library is NOT provided by the system
83              return unless defined $version;
84
85              # otherwise return the version detected
86              # (if you cannot determine the version it
87              #  is usually sufficient to return a true value)
88              return $version;
89            }
90
91           There are number of methods you can use to determine if the system
92           provides your library.  From Perl methods include Devel::CheckLib,
93           ExtUtils::CBuilder, ExtUtls::CChecker, Config::AutoConf,
94           FFI::CheckLib among others.  It is also frequently possible to
95           determine if a library is installed using a "-config" suffixed
96           program.  For example "libxml2" comes with xml2-config which
97           provides the existence, compiler and linker flags it needs.  In my
98           experience, however, most packages that provide a "-config"
99           suffixed program also provide a "pkg-config" interface as well.
100
101       implement "alien_check_built_version" in your Alien::Base::ModuleBuild
102       subclass
103           You should also implement "alien_check_build_version" which will be
104           executed from the package build root once the package is
105           successfully built.
106
107            # inc/My/ModuleBuild.pm
108            package My::ModuleBuild;
109
110            ...
111
112            sub alien_check_built_version {
113              my($self) = @_;
114
115              my $version = ...
116
117              # (Again, if you cannot determine the version,
118              #  it is usually sufficent to return a true value)
119              return $version;
120            }
121
122       set "alien_provides_cflags" and "alien_provides_libs" in "Build.PL".
123           Add something like this to your "Build.PL":
124
125            # Build.PL
126            use lib 'inc';
127            use My::ModuleBuild;
128
129            My::ModuleBuild->new(
130              ...
131              alien_provides_cflags => '-I/usr/include/foo',
132              alien_provides_libs   => '-L/usr/lib/foo -lfoo',
133              ...
134            );
135
136           Note that it is frequently sufficient to provide
137           "alien_provides_libs" and the appropriate "-l" flag.  These flags
138           will be used in the event that the system package can be found.  It
139           is a good idea to verify that these flags do indeed work in
140           "alien_check_installed_version" above.
141
142       For a fully implemented example, see Alien::Libbz2.
143
144   How do I test my package once it is built (before it is installed)?
145       There are many ways to test Alien modules before (or after) they are
146       installed, but instead of rolling your own, consider using Test::Alien
147       which is light on dependencies and will test your module very closely
148       to the way that it will actaully be used.  That is to say by building a
149       mini XS or FFI extension and using it.  It even has tests for tool
150       oriented Alien distributions (like Alien::gmake and Alien::patch).
151       Here is a short example, there are many others included with the
152       Test::Alien documentation:
153
154        use Test2::V0;
155        use Test::Alien 0.05;
156        use Alien::Editline;
157
158        alien_ok 'Alien::Editline';
159        my $xs = do { local $/; <DATA> };
160        xs_ok $xs, with_subtest {
161          my($module) = @_;
162          ok $module->version;
163        };
164
165        done_testing;
166
167        __DATA__
168
169        #include "EXTERN.h"
170        #include "perl.h"
171        #include "XSUB.h"
172        #include <editline/readline.h>
173
174        /* having a string parameter that we ignore
175           allows us to call this as a class method */
176        const char *
177        version(const char *class)
178        {
179          return rl_library_version;
180        }
181
182        MODULE = TA_MODULE PACKAGE = TA_MODULE
183
184        const char *version(class);
185            const char *class;
186
187   How do I patch packages that need minor (or major) alterations?
188       One approach is to create a unified diff for patches that you want to
189       apply and simply run patch on them.  The Alien::patch and the
190       "%{patch}" helper can be used like this:
191
192        # Build.PL
193        use Alien::Base::ModuleBuild;
194
195        Alien::Base::ModuleBuild->new(
196          ...
197          alien_bin_requires => {
198            'Alien::patch' => 0.06, # needed for %{patch} helper
199          },
200          alien_build_commands => [
201            '%{patch} -p1 < ../../patch/mypackage.patch',
202            ...
203          ],
204          ...
205        )->create_build_script;
206
207       Create a folder in your distribution root called "patch" and place the
208       "mypackage.patch" file in there.  Since the "patch" command will be
209       executed in the package root instead of the distribution root, you need
210       to use a relative path prefixed by "../..".  Here we use Alien::patch
211       to provide patch even in environments where it is not provided.
212
213       A more powerful approach to patching is to write a perl subroutine to
214       modify the source after it has been extracted.  One way to do this is
215       to create a module in your distribution's inc directory that does the
216       patching (modules in inc can be used during build/test but won't be
217       installed):
218
219        # inc/My/AlienPatch.pm
220        package My::AlienPatch;
221
222        # add this sub to the main namespace
223        # so we don't need to quote or escape
224        # anything below
225        sub main::alien_patch {
226          # is executed in the package root,
227          # make what ever changes you need to
228          # to the source here.
229        }
230
231        1;
232
233        # Build.PL
234        use Alien::Base::ModuleBuild;
235
236        Alien::Base::ModuleBuild->new(
237          ...
238          alien_build_commands => [
239            # %x will be replaced by path for calling Perl
240            # from the command line
241            "%x -I../../inc -MMy::AlienPatch -e alien_patch",
242            ...
243          ],
244          ...
245        )->create_build_script;
246
247   How do I build a package that uses build system?
248       autoconf
249
250       By default Alien::Base::ModuleBuild assumes a package with an autoconf
251       style "configure" script.  The default is
252
253        # Build.PL
254        use Alien::Base::ModuleBuild;
255        Alien::Base::ModuleBuild->new(
256          ...
257          alien_build_commands => [
258            '%c --prefix=%s',
259            'make',
260          ],
261          alien_install_commands => [
262            'make install',
263          ],
264          ...
265        )->create_build_script;
266
267       There are a couple of short cuts here, %c indicates the platform
268       independent method for executing the "configure" script, plus any
269       normal autoconf flags that are appropriate for Perl Alien libraries.
270       The %c also tells Alien::Base::ModuleBuild to use Alien::MSYS on
271       Windows platforms and to add that as a dependency.  The %s is a
272       placeholder for the location to which the package will be installed.
273       This is normally in a share directory specific to your distribution.
274
275       autoconf-like
276
277       If you see an error like this:
278
279        Unknown option "--with-pic".
280
281       It may be because your package provides a "configure" script that
282       provides an autoconf-style interface, but is not actually autoconf.
283       Alien::Base::ModuleBuild is aggressive in using the "--with-pic" option
284       because when supported by autoconf it produces position independent
285       code (important for reliably building XS extensions), and when not
286       supported autoconf simply ignores the option. Unfortunately some
287       autoconf-style "configure" scripts consider it an error when they see
288       options that they do not recognize.  You can tell
289       Alien::Base::ModuleBuild to not use the "--with-pic" option via the
290       "alien_autoconf_with_pic" property:
291
292        # Build.PL
293        use Alien::Base::ModuleBuild;
294        Alien::Base::ModuleBuild->new(
295          ...
296          alien_autoconf_with_pic => 0,
297          ...
298        )->create_build_script;
299
300       CMAKE
301
302       You probably cannot count on CMake being available on most platforms.
303       Fortunately, there is an alien distribution Alien::CMake which will
304       either use the CMake provided by the operating system, or download and
305       install it for you.  You can use this from your "Build.PL" with the
306       "alien_bin_requires" property:
307
308        # Build.PL
309        use Alien::Base::ModuleBuild;
310        use Config;
311        Alien::Base::ModuleBuild->new(
312          ...
313          alien_bin_requires => {
314            'Alien::CMake' => 0.07,
315          },
316          alien_build_commands => [
317            # acutal required arguments may vary
318            "cmake -G 'Unix Makefiles' -DCMAKE_MAKE_PROGRAM=$Config{make} -DCMAKE_INSTALL_PREFIX:PATH=%s",
319            "$Config{make}",
320          ],
321          alien_install_commands => [
322            "$Config{make} install",
323          ],
324          ...
325        )->create_build_script;
326
327       vanilla Makefiles?
328
329       If you want to use the same "make" as Perl, you can use Config:
330
331        # Build.PL
332        use Alien::Base::ModuleBuild;
333        use Config;
334        Alien::Base::ModuleBuild->new(
335          ...
336          alien_build_commands => [
337            "$Config{make}",
338          ],
339          alien_install_commands => [
340            "$Config{make} install",
341          ],
342          ...
343        )->create_build_script;
344
345       Gnu Makefiles?
346
347       Some packages require GNU Make's unique syntax.  Perl's Config provides
348       an entry for "gmake", but it is frequently wrong.  Do not depend on it.
349       Instead you can ues Alien::gmake to provide a real GNU Make (either
350       from the operating system, or built from source):
351
352        # Build.PL
353        use Alien::Base::ModuleBuild;
354
355        Alien::Base::ModuleBuild->new(
356          ...
357          alien_bin_requires => {
358            'Alien::gmake' => 0.11, # needed for %{gmake} helper
359          },
360          alien_build_commands => [
361            "%{gmake}",
362          ],
363          alien_install_commands => [
364            "%{gmake} install",
365          ],
366          ...
367        )->create_build_script;
368
369   When debugging my package build, I get different results!
370       If you get results from running the commands in your shell different to
371       what happens when your "Alien::" distribution attempts to build, it may
372       be because your environment is different than the one that your
373       distribution is using.  For example, if you use Alien::CMake or
374       Alien::gmake to build with specific tools that are provided by your
375       operating system, Alien::Build::ModuleBuild will adjust the path before
376       executing build and install commands.
377
378       In the alien build directory (usually "_alien") you will find
379       environment files that you can source into your shell ("env.csh" for
380       tcsh and "env.sh" for bourne based shells), which should provide the
381       identical environment used by the build process in order to
382       troubleshoot the build manually.
383
384        % source _alien/env.sh
385
386   Can/Should I write a tool oriented Alien module using "Alien::Base" that
387       provides executables instead of a library?
388       Certainly.  The original intent was to provide libraries, but tools are
389       also quite doable using the "Alien::Base" toolset.  A simple minded
390       example of this which is fairly easy to replicate is Alien::m4.
391
392       In general, this means specifying a subclass in your "Build.PL" and
393       bundling it in your distribution "inc" directory.
394
395       "Build.PL":
396
397        ...
398        use lib 'inc';
399        use My::ModuleBuild;
400
401        My::ModuleBuild->new(
402          ...
403        )->create_build_script;
404
405       "inc/My/ModuleBuild.pm":
406
407        package My::ModuleBuild;
408
409        use strict;
410        use warnings;
411        use parent 'Alien::Base::ModuleBuild';
412        use Capture::Tiny qw( capture );
413
414        sub alien_check_installed_version
415        {
416          # see Alien::Base::ModuleBuild#alien_check_installed_version for details
417
418          my($self) = @_;
419          my($stdout, $stderr) = capture { system 'mytool', '--version' };
420
421          # return empty list if the tool is unavailable on the system,
422          # or unacceptable.
423          return if $! || ...;
424
425          # parse from stdout or stderr
426          my $version = ...;
427          return $version;
428        }
429
430        sub alien_check_built_version
431        {
432          # see Alien::Base::ModuleBuild#alien_check_built_version for details
433
434          # return empty list if the tool version cannot be found, or if it
435          # is unacceptable.  Note that this will cause a failure, so "unknown"
436          # may be reasonable if the tool version cannot be determined.
437          return if ...;
438
439          # determine from the tool itself, or the current directory.
440          my $version = ...;
441          return $version;
442        }
443
444        1;
445
446       As usual your "Alien::MyTool" class will simply be a subclass of
447       Alien::Base.  If you tool is installed in a "bin" directory, you are
448       done, the default "bin_dir" implementation should work for you.
449       Otherwise you may need to provide an alternate implementation:
450
451        package Alien::MyTool;
452
453        use strict;
454        use warnings;
455        use parent 'Alien::Base';
456
457        sub bin_dir
458        {
459          # see Alien::Base#bin_dir for details
460          # You only need to override the default implementation if your tool
461          # does not install into the standard "bin" directory.
462
463          my($class) = @_;
464
465          # normally for system installs the tool should already be in your
466          # PATH, so return an empty list.
467          return if $class->install_type eq 'system';
468
469          # install_type = share
470          my $dist_dir = $class->dist_dir;
471          return ("$dist_dir/some/bin", "$dist_dir/some/other/bin");
472        }
473
474        1;
475
476       Now once your tool based Alien is installed you can use the "bin_dir"
477       method to update the "PATH" as necessary:
478
479        use Alien::MyTool;
480        use Env qw( @PATH );
481
482        unshift @PATH, Alien::MyTool->bin_dir;
483        system 'mytool';
484
485   How do I use "Alien::Base" from "Dist::Zilla"
486       For creating Alien::Base based dists from Dist::Zilla you can use the
487       plugin Dist::Zilla::Plugin::Alien.
488
489   How do I check the built version if my library doesn't provide a ".pc"
490       file.
491       The default implementation of "alien_check_built_version" uses several
492       heuristics, but leans heavily on "pkg-config" style ".pc" files, so if
493       your library or tool does not provide a ".pc", the version may not be
494       detected and your build may fail.
495
496       A lot of libraries are bundled as tarballs with the version in the
497       directory name that they are extracted into, and the current directory
498       when "alien_check_built_version" is called is the build root, so you
499       can use "File::chdir" as an easy way to determine the version number:
500
501        package My::ModuleBuild;
502
503        use strict;
504        use warnings;
505        use parent 'Alien::Base::ModuleBuild';
506        use File::chdir; # provides @CWD
507
508        sub alien_check_built_version
509        {
510          my $dir_name = $CWD[-1];
511
512          if($dir_name =~ /^libfoo-([0-9\.]+)$/) {
513            return $1;
514          } else {
515            # Note that this will trigger a build failure
516            return;
517          }
518        }
519
520        1;
521
522       Using File::chdir and @CWD is a common idiom in Alien::Base, because
523       File::chdir is already a dependency of Alien::Base.  For packages that
524       do not provide a version number in the extracted directory, you may
525       require some creativity.
526
527   I have question not listed here!
528       There are a number of forums available to people working on Alien and
529       Alien::Base modules:
530
531       "#native" on irc.perl.org
532           This is intended for native interfaces in general and so is a good
533           place for questions about Alien generally or Alien::Base
534           specifically.
535
536       mailing list
537           The "perl5-alien" google group is intended for Alien issues
538           generally, including Alien::Base.
539
540           <https://groups.google.com/forum/#!forum/perl5-alien>
541
542       Open a support ticket
543           If you have an issue with Alien::Base itself, then please open a
544           support ticket on the project's GitHub issue tracker.
545
546           <https://github.com/Perl5-Alien/Alien-Base-ModuleBuild/issues>
547

SEE ALSO

549       ·   Alien::Base
550
551       ·   Alien::Base::ModuleBuild
552
553       ·   Alien::Base::ModuleBuild::API
554

AUTHOR

556       Original author: Joel Berger, <joel.a.berger@gmail.com>
557
558       Current maintainer: Graham Ollis <plicease@cpan.org> and the
559       Alien::Base team
560
562       Copyright (C) 2012-2017 by Joel Berger
563
564       This library is free software; you can redistribute it and/or modify it
565       under the same terms as Perl itself.
566
567
568
569perl v5.28.1                      2019-02-02  Alien::Base::ModuleBuild::FAQ(3)
Impressum