i_img_info() (C API) no longer tries to handle a NULL image object pointer.
[imager.git] / Makefile.PL
1 #!perl -w
2 use strict;
3 use ExtUtils::MakeMaker;
4 use Cwd;
5 use Config;
6 use File::Spec;
7 use Getopt::Long;
8 use ExtUtils::Manifest qw(maniread);
9 use ExtUtils::Liblist;
10 use vars qw(%formats $VERBOSE $INCPATH $LIBPATH $NOLOG $DEBUG_MALLOC $MANUAL $CFLAGS $LFLAGS $DFLAGS);
11 use lib 'inc', 'lib';
12 use Imager::Probe;
13
14 # EU::MM runs Makefile.PL all in the same process, so sub-modules will
15 # see this
16 our $BUILDING_IMAGER = 1;
17
18 # used to display a summary after we've probed the world
19 our %IMAGER_LIBS;
20
21 #
22 # IM_INCPATH      colon seperated list of paths to extra include paths
23 # IM_LIBPATH      colon seperated list of paths to extra library paths
24 #
25 # IM_VERBOSE      turns on verbose mode for the library finding and such
26 # IM_MANUAL       to manually select which libraries are used and which not
27 # IM_ENABLE       to programmatically select which libraries are used
28 #                 and which are not
29 # IM_NOLOG        if true logging will not be compiled into the module
30 # IM_DEBUG_MALLOC if true malloc debbuging will be compiled into the module
31 #                 do not use IM_DEBUG_MALLOC in production - this slows
32 #                 everything down by alot
33 # IM_CFLAGS       Extra flags to pass to the compiler
34 # IM_LFLAGS       Extra flags to pass to the linker
35 # IM_DFLAGS       Extra flags to pass to the preprocessor
36
37 my $KEEP_FILES = $ENV{IMAGER_KEEP_FILES};
38
39 # make sure --verbose will dump environment settings
40 if (grep $_ =~ /^--?v(?:erbose)?$/, @ARGV) {
41   $VERBOSE = 1;
42 }
43
44 # modules/features bundled with Imager that can be enabled/disabled
45 # withs --enable/--disable
46 my @bundled = qw(FT1 FT2 GIF JPEG PNG T1 TIFF W32);
47
48 # extra modules bundled with Imager not available on CPAN
49 my @extras = qw(CountColor DynTest ICO SGI Mandelbrot Flines);
50
51 # alternate names for modules
52 my %bundled_names = qw(win32 w32 tt ft1);
53
54 getenv();     # get environment variables
55
56 my $lext=$Config{'so'};   # Get extensions of libraries
57 my $aext=$Config{'_a'};
58
59 my $help; # display help if set
60 my @enable; # list of drivers to enable
61 my @disable; # or list of drivers to disable
62 my @incpaths; # places to look for headers
63 my @libpaths; # places to look for libraries
64 my $coverage; # build for coverage testing
65 my $assert; # build with assertions
66 my $trace_context; # trace context management to stderr
67 GetOptions("help" => \$help,
68            "enable=s" => \@enable,
69            "disable=s" => \@disable,
70            "incpath=s", \@incpaths,
71            "libpath=s" => \@libpaths,
72            "verbose|v" => \$VERBOSE,
73            "nolog" => \$NOLOG,
74            'coverage' => \$coverage,
75            "assert|a" => \$assert,
76            "tracecontext" => \$trace_context);
77
78 setenv();
79
80 if ($ENV{AUTOMATED_TESTING}) {
81   $assert = 1;
82 }
83
84 if ($VERBOSE) { 
85   print "Verbose mode\n"; 
86   require Data::Dumper; 
87   import Data::Dumper qw(Dumper);
88 }
89
90 if ($help) {
91   usage();
92 }
93
94 my @defines;
95
96 if ($NOLOG)   { print "Logging not compiled into module\n"; }
97 else { 
98   push @defines, [ IMAGER_LOG => 1, "Logging system" ];
99 }
100
101 if ($assert) {
102   push @defines, [ IM_ASSERT => 1, "im_assert() are effective" ];
103 }
104
105 if ($DEBUG_MALLOC) {
106   push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
107   print "Malloc debugging enabled\n";
108 }
109
110 if (@enable && @disable) {
111   print STDERR "Only --enable or --disable can be used, not both, try --help\n";
112   exit 1;
113 }
114
115 my %definc;
116 my %deflib;
117 my @incs; # all the places to look for headers
118 my @libs; # all the places to look for libraries
119
120 init();       # initialize global data
121 pathcheck();  # Check if directories exist
122
123 my @enabled_bundled;
124 if (exists $ENV{IM_ENABLE}) {
125   push @enable, split ' ', $ENV{IM_ENABLE};
126 }
127 if (@enable) {
128   my %en = map { lc $_ => 1 } map_bundled(@enable);
129   @enabled_bundled = grep $en{lc $_}, @bundled;
130 }
131 elsif (@disable) {
132   my %dis = map { lc $_ => 1 } map_bundled(@disable);
133   @enabled_bundled = grep !$dis{lc $_}, @bundled;
134 }
135 else {
136   @enabled_bundled = @bundled;
137 }
138
139 # Pick what libraries are used
140 if ($MANUAL) {
141   manual();
142 } else {
143   automatic();
144 }
145
146 my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
147               log.o gaussian.o conv.o pnm.o raw.o feat.o combine.o
148               filters.o dynaload.o stackmach.o datatypes.o
149               regmach.o trans2.o quant.o error.o convert.o
150               map.o tags.o palimg.o maskimg.o img8.o img16.o rotate.o
151               bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
152               imext.o scale.o rubthru.o render.o paste.o compose.o flip.o
153               perlio.o imexif.o);
154
155 my $lib_define = '';
156 my $lib_inc = '';
157 my $lib_libs = '';
158 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
159   my $frm = $formats{$frmkey};
160   if ($frm->{enabled}) {
161     push @defines, [ $frm->{def}, 1, "$frmkey available" ];
162     push @objs, $frm->{objfiles};
163     $lib_define .= " $frm->{DEFINE}" if $frm->{DEFINE};
164     $lib_inc    .= " $frm->{INC}"    if $frm->{INC};
165     $lib_libs   .= " $frm->{LIBS}"   if $frm->{LIBS};
166   }
167 }
168
169 my $OSLIBS = '';
170 my $OSDEF  = "-DOS_$^O";
171
172 if ($^O eq 'hpux')                { $OSLIBS .= ' -ldld'; }
173 if (defined $Config{'d_dlsymun'}) { $OSDEF  .= ' -DDLSYMUN'; }
174
175 if ($Config{useithreads}) {
176   if ($Config{i_pthread}) {
177     print "POSIX threads\n";
178     push @objs, "mutexpthr.o";
179   }
180   elsif ($^O eq 'MSWin32') {
181     print "Win32 threads\n";
182     push @objs, "mutexwin.o";
183   }
184   else {
185     print "Unsupported threading model\n";
186     push @objs, "mutexnull.o";
187     if ($ENV{AUTOMATED_TESTING}) {
188       die "OS unsupported: no threading support code for this platform\n";
189     }
190   }
191 }
192 else {
193   print "No threads\n";
194   push @objs, "mutexnull.o";
195 }
196
197 my @typemaps = qw(typemap.local typemap);
198 if ($] < 5.008) {
199     unshift @typemaps, "typemap.oldperl";
200 }
201
202 if ($trace_context) {
203   $CFLAGS .= " -DIMAGER_TRACE_CONTEXT";
204 }
205
206 my $tests = 't/*.t t/*/*.t';
207 if (-d "xt" && scalar(() = glob("xt/*.t"))) {
208   $tests .= " xt/*.t";
209 }
210
211 my %opts=
212   (
213    NAME         => 'Imager',
214    VERSION_FROM => 'Imager.pm',
215    LIBS         => "$LFLAGS -lm $lib_libs $OSLIBS",
216    DEFINE       => "$OSDEF $lib_define $CFLAGS",
217    INC          => "$lib_inc $DFLAGS",
218    OBJECT       => join(' ', @objs),
219    DIR          => [ sort grep -d, @enabled_bundled, @extras ],
220    clean          => { FILES=>'testout rubthru.c scale.c conv.c  filters.c gaussian.c render.c rubthru.c' },
221    PM             => gen_PM(),
222    PREREQ_PM      =>
223    { 
224     'Test::More' => 0.99,
225     'Scalar::Util' => 1.00,
226     'XSLoader'    => 0,
227    },
228    TYPEMAPS       => \@typemaps,
229    test =>        { TESTS => $tests },
230   );
231
232 if ($coverage) {
233     if ($Config{gccversion}) {
234         push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
235         $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
236     }
237     else {
238         die "Don't know the coverage C flags for your compiler\n";
239     }
240 }
241
242 if (eval { ExtUtils::MakeMaker->VERSION('6.06'); 1 }) {
243   $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
244   $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
245 }
246
247 if (eval { ExtUtils::MakeMaker->VERSION('6.46'); 1 }) {
248   $opts{LICENSE} = "perl_5";
249   $opts{META_MERGE} =
250     {
251      'meta-spec' =>
252      {
253       version => "2",
254       url => "https://metacpan.org/pod/CPAN::Meta::Spec",
255      },
256      prereqs =>
257      {
258       runtime =>
259       {
260        recommends =>
261        {
262         "Parse::RecDescent" => 0
263        },
264        requires =>
265        {
266         'Scalar::Util' => "1.00",
267         XSLoader => 0,
268        },
269       },
270       build =>
271       {
272        requires =>
273        {
274         XSLoader => 0,
275        },
276       },
277       test =>
278       {
279        requires =>
280        {
281         'Test::More' => "0.99",
282        },
283       },
284      },
285      dynamic_config => 0,
286      no_index =>
287      {
288       directory =>
289       [
290        "PNG",
291        "GIF",
292        "TIFF",
293        "JPEG",
294        "W32",
295        "FT2",
296        "T1",
297       ],
298      },
299      resources =>
300      {
301       homepage => "http://imager.perl.org/",
302       repository =>
303       {
304        url => "git://git.imager.perl.org/imager.git",
305        web => "http://git.imager.perl.org/imager.git",
306        type => "git",
307       },
308       bugtracker =>
309       {
310        web => "https://rt.cpan.org/Dist/Display.html?Name=Imager",
311        mailto => 'bug-Imager@rt.cpan.org',
312       },
313      },
314     };
315 }
316
317 make_imconfig(\@defines);
318
319 if ($VERBOSE) { print Dumper(\%opts); }
320 mkdir('testout',0777); # since we cannot include it in the archive.
321
322 -d "probe" and rmdir "probe";
323
324 WriteMakefile(%opts);
325
326 my @good;
327 my @bad;
328 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
329   if ($IMAGER_LIBS{$name}) {
330     push @good, $name;
331   }
332   else {
333     push @bad, $name;
334   }
335 }
336
337 print "\n";
338 print "Libraries found:\n" if @good;
339 print "  $_\n" for @good;
340 print "Libraries *not* found:\n" if @bad;
341 print "  $_\n" for @bad;
342
343 exit;
344
345
346 sub MY::postamble {
347     my $self = shift;
348     my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
349     my $mani = maniread;
350
351     my @ims = grep /\.im$/, keys %$mani;
352 '
353 dyntest.$(MYEXTLIB) : dynfilt/Makefile
354         cd dynfilt && $(MAKE) $(PASTHRU)
355
356 lib/Imager/Regops.pm : regmach.h regops.perl
357         $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
358
359 imconfig.h : Makefile.PL
360         $(ECHO) "imconfig.h out-of-date with respect to $?"
361         $(PERLRUN) Makefile.PL
362         $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
363 '.qq!
364 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
365         $perl apidocs.perl lib/Imager/APIRef.pod
366
367 !.join('', map _im_rule($perl, $_), @ims)
368
369 }
370
371 sub _im_rule {
372   my ($perl, $im) = @_;
373
374   (my $c = $im) =~ s/\.im$/.c/;
375   return <<MAKE;
376
377 $c: $im lib/Imager/Preprocess.pm
378         $perl -Ilib -MImager::Preprocess -epreprocess $im $c
379
380 MAKE
381
382 }
383
384 # manual configuration of helper libraries
385
386 sub manual {
387   print <<EOF;
388
389       Please answer the following questions about
390       which formats are avaliable on your computer
391
392       Warning: if you use manual configuration you are responsible for
393       configuring extra include/library directories as necessary using
394       INC and LIBS command-line assignments.
395
396 press <return> to continue
397 EOF
398
399   <STDIN>; # eat one return
400
401   for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
402   SWX:
403     if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
404     print "Enable $frm support: ";
405     my $gz = <STDIN>;
406     chomp($gz);
407     if ($gz =~ m/^(y|yes|n|no)/i) {
408       if ($gz =~ /y/i) {
409         $formats{$frm}{enabled} = 1;
410         $IMAGER_LIBS{$frm} = 1;
411       }
412     } else { goto SWX; }
413   }
414 }
415
416
417 # automatic configuration of helper libraries
418
419 sub automatic {
420   print "Automatic probing:\n" if $VERBOSE;
421
422   if (grep $_ eq "FT1", @enabled_bundled) {
423     my %probe =
424       (
425        name => "FT1",
426        inccheck => sub { -e File::Spec->catfile($_[0], "ftnameid.h") },
427        libbase => "ttf",
428        testcode => _ft1_test_code(),
429        testcodeheaders => [ "freetype.h", "stdio.h" ],
430        incpaths => \@incpaths,
431        libpaths => \@libpaths,
432        alternatives =>
433        [
434         {
435          incsuffix => "freetype",
436         }
437        ],
438        verbose => $VERBOSE,
439       );
440     my $probe_res = Imager::Probe->probe(\%probe);
441     $IMAGER_LIBS{FT1} = defined $probe_res;
442     if ($probe_res) {
443       $formats{FT1}{enabled} = 1;
444       @{$formats{FT1}}{qw/DEFINE INC LIBS/} =
445         @$probe_res{qw/DEFINE INC LIBS/};
446     }
447   }
448 }
449
450 sub pathcheck {
451   if ($VERBOSE) {
452     print "pathcheck\n";
453     print "  Include paths:\n";
454     for (@incs) { print $_,"\n"; }
455   }
456   @incs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
457
458   if ($VERBOSE) {
459     print "\nLibrary paths:\n";
460     for (@libs) { print $_,"\n"; }
461   }
462   @libs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
463   print "\ndone.\n";
464 }
465
466
467 # Format data initialization
468
469 # format definition is:
470 # defines needed
471 # default include path
472 # files needed for include (boolean perl code)
473 # default lib path
474 # libs needed
475 # files needed for link (boolean perl code)
476 # object files needed for the format
477
478
479 sub init {
480
481   my @definc = qw(/usr/include);
482   @definc{@definc}=(1) x @definc;
483   @incs=
484     (
485      split(/\Q$Config{path_sep}/, $INCPATH),
486      map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths 
487     );
488   if ($Config{locincpth}) {
489     push @incs, grep -d, split ' ', $Config{locincpth};
490   }
491   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
492     push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
493   }
494   if ($Config{incpath}) {
495     push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
496   }
497   push @incs, grep -d,
498       qw(/sw/include 
499          /usr/include/freetype2
500          /usr/local/include/freetype2
501          /usr/local/include/freetype1/freetype
502          /usr/include /usr/local/include /usr/include/freetype
503          /usr/local/include/freetype);
504   if ($Config{ccflags}) {
505     my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
506     push @incs, @hidden;
507     @definc{@hidden} = (1) x @hidden;
508   }
509
510   @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
511     map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
512   if ($Config{loclibpth}) {
513     push @libs, grep -d, split ' ', $Config{loclibpth};
514   }
515   
516   push @libs, grep -d, qw(/sw/lib),  split(/ /, $Config{'libpth'});
517   push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
518   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
519     push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
520   }
521   if ($^O eq 'cygwin') {
522     push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
523     push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
524   }
525   if ($Config{ldflags}) {
526     # some builds of perl put -Ldir into ldflags without putting it in
527     # loclibpth, let's extract them
528     my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
529       split ' ', $Config{ldflags};
530     push @libs, @hidden;
531     # don't mark them as seen - EU::MM will remove any libraries
532     # it can't find and it doesn't look for -L in ldflags
533     #@deflib{@hidden} = @hidden;
534   }
535   push @libs, grep -d, qw(/usr/local/lib);
536
537   $formats{FT1}=
538     {
539      order=>'31',
540      def=>'HAVE_LIBTT',
541      objfiles=>'fontft1.o',
542      LIBS => "-lttf",
543      docs=>q{
544 Freetype 1.x supports Truetype fonts and is obsoleted by Freetype 2.x.
545
546 It's probably insecure.
547 }
548                        };
549   # Make fix indent
550   for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/  /mg; }
551 }
552
553
554
555 sub gen {
556   my $V = $ENV{$_[0]};
557   print "  $_[0]: '$V'\n"
558       if $VERBOSE && defined $V;
559   defined($V) ? $V : "";
560 }
561
562
563 # Get information from environment variables
564
565 sub getenv {
566
567   $VERBOSE ||= gen("IM_VERBOSE");
568
569   print "Environment config:\n" if $VERBOSE;
570
571   ($INCPATH,
572    $LIBPATH,
573    $NOLOG,
574    $DEBUG_MALLOC,
575    $MANUAL,
576    $CFLAGS,
577    $LFLAGS,
578    $DFLAGS) = map { gen $_ } qw(IM_INCPATH
579                                 IM_LIBPATH
580                                 IM_NOLOG
581                                 IM_DEBUG_MALLOC
582                                 IM_MANUAL
583                                 IM_CFLAGS
584                                 IM_LFLAGS
585                                 IM_DFLAGS);
586 }
587
588 # populate the environment so that sub-modules get the same info
589 sub setenv {
590   $ENV{IM_VERBOSE} = 1 if $VERBOSE;
591   $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
592   $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
593 }
594
595 sub make_imconfig {
596   my ($defines) = @_;
597
598   open CONFIG, "> imconfig.h"
599     or die "Cannot create imconfig.h: $!\n";
600   print CONFIG <<EOS;
601 /* This file is automatically generated by Makefile.PL.
602    Don't edit this file, since any changes will be lost */
603
604 #ifndef IMAGER_IMCONFIG_H
605 #define IMAGER_IMCONFIG_H
606 EOS
607   for my $define (@$defines) {
608     if ($define->[2]) {
609       print CONFIG "\n/*\n  $define->[2]\n*/\n\n";
610     }
611     print CONFIG "#define $define->[0] $define->[1]\n";
612   }
613   if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
614     print CONFIG <<EOS;
615 /*
616
617 Compiler supports the GCC __attribute__((format...)) syntax.
618
619 */
620
621 #define IMAGER_FORMAT_ATTR 1
622
623 EOS
624   }
625
626   if ($Config{d_snprintf}) {
627     print CONFIG <<EOS;
628 /* We can use snprintf() */
629 #define IMAGER_SNPRINTF 1
630
631 EOS
632   }
633
634   if ($Config{d_vsnprintf}) {
635     print CONFIG <<EOS;
636 /* We can use vsnprintf() */
637 #define IMAGER_VSNPRINTF 1
638
639 EOS
640   }
641
642   print CONFIG <<EOS;
643 /*
644  Type and format code for formatted output as with printf.
645
646  This is intended for formatting i_img_dim values.
647 */
648 typedef $Config{ivtype} i_dim_format_t;
649 #define i_DF $Config{ivdformat}
650 EOS
651
652   print CONFIG "\n#endif\n";
653   close CONFIG;
654 }
655
656 sub usage {
657   print STDERR <<EOS;
658 Usage: $0 [--enable feature1,feature2,...] [other options]
659        $0 [--disable feature1,feature2,...]  [other options]
660        $0 --help
661 Possible feature names are:
662   T1-fonts
663 Other options:
664   --verbose | -v
665     Verbose library probing (or set IM_VERBOSE in the environment)
666   --nolog
667     Disable logging (or set IM_NOLOG in the environment)
668   --incpath dir
669     Add to the include search path
670   --libpath dir
671     Add to the library search path
672   --coverage
673     Build for coverage testing.
674   --assert
675     Build with assertions active.
676 EOS
677   exit 1;
678
679 }
680
681 # generate the PM MM argument
682 # I'd prefer to modify the public version, but there doesn't seem to be 
683 # a public API to do that
684 sub gen_PM {
685   my %pm;
686   my $instbase = '$(INST_LIBDIR)';
687
688   # first the basics, .pm and .pod files
689   $pm{"Imager.pm"} = "$instbase/Imager.pm";
690
691   my $mani = maniread();
692
693   for my $filename (keys %$mani) {
694     if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
695       (my $work = $filename) =~ s/^lib//;
696       $pm{$filename} = $instbase . $work;
697     }
698   }
699
700   # need the typemap
701   $pm{typemap} = $instbase . '/Imager/typemap';
702
703   # and the core headers
704   for my $filename (keys %$mani) {
705     if ($filename =~ /^\w+\.h$/) {
706       $pm{$filename} = $instbase . '/Imager/include/' . $filename;
707     }
708   }
709
710   # and the generated header
711   $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
712
713   \%pm;
714 }
715
716 my $home;
717 sub _tilde_expand {
718   my ($path) = @_;
719
720   if ($path =~ m!^~[/\\]!) {
721     defined $home or $home = $ENV{HOME};
722     if (!defined $home && $^O eq 'MSWin32'
723        && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
724       $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
725     }
726     unless (defined $home) {
727       $home = eval { (getpwuid($<))[7] };
728     }
729     defined $home or die "You supplied $path, but I can't find your home directory\n";
730     $path =~ s/^~//;
731     $path = File::Spec->catdir($home, $path);
732   }
733
734   $path;
735 }
736
737 sub _ft1_test_code {
738   return <<'CODE';
739 TT_Engine engine;
740 TT_Error error;
741
742 error = TT_Init_FreeType(&engine);
743 if (error) {
744    printf("FT1: Could not initialize engine\n");
745    exit(1);
746 }
747
748 return 0;
749 CODE
750 }
751
752 sub map_bundled {
753   my (@names) = @_;
754
755   @names = map { split /,/ } @names;
756
757   my @outnames;
758   for my $name (@names) {
759     push @outnames, $name;
760     push @outnames, $bundled_names{$name}
761       if $bundled_names{$name};
762   }
763
764   @outnames;
765 }
766
767 1;