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