1Alien::Base::ModuleBuilUds:e:rFACQo(n3tprmi)buted Perl DAolciuemne:n:tBaatsieo:n:ModuleBuild::FAQ(3pm)
2
3
4

NAME

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

VERSION

10       version 1.17
11

SYNOPSIS

13        perldoc Alien::Base::FAQ
14

DESCRIPTION

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

SEE ALSO

552       •   Alien::Base
553
554       •   Alien::Base::ModuleBuild
555
556       •   Alien::Base::ModuleBuild::API
557

AUTHOR

559       Original author: Joel A Berger <joel.a.berger@gmail.com>
560
561       Current maintainer: Graham Ollis <plicease@cpan.org>
562
563       Contributors:
564
565       David Mertens (run4flat)
566
567       Mark Nunberg (mordy, mnunberg)
568
569       Christian Walde (Mithaldu)
570
571       Brian Wightman (MidLifeXis)
572
573       Graham Ollis (plicease)
574
575       Zaki Mughal (zmughal)
576
577       mohawk2
578
579       Vikas N Kumar (vikasnkumar)
580
581       Flavio Poletti (polettix)
582
583       Salvador Fandiño (salva)
584
585       Gianni Ceccarelli (dakkar)
586
587       Pavel Shaydo (zwon, trinitum)
588
589       Kang-min Liu (劉康民, gugod)
590
591       Nicholas Shipp (nshp)
592
593       Petr Písař (ppisar)
594
595       Alberto Simões (ambs)
596
598       This software is copyright (c) 2012-2022 by Joel A Berger.
599
600       This is free software; you can redistribute it and/or modify it under
601       the same terms as the Perl 5 programming language system itself.
602
603
604
605perl v5.38.0                      2023-07-20Alien::Base::ModuleBuild::FAQ(3pm)
Impressum