1use strict;
2use warnings;
3use 5.012;
4
5package MY::orderedhash;
6require Tie::Hash;
7our @ISA = qw(Tie::ExtraHash);
8sub tie      { CORE::tie my %a, $_[0], $_[1]; \%a }
9sub TIEHASH  { bless [{%{$_[1]}}], $_[0] }
10sub FIRSTKEY { $_[0][1] = [ sort keys %{$_[0][0]} ]; shift @{ $_[0][1] } }
11sub NEXTKEY  { shift @{ $_[0][1] } }
12
13package MY;
14use strict;
15use warnings;
16use lib '.';
17use Cwd;
18use Config;
19use DynaLoader;
20use Prima::sys::Gencls;
21use ExtUtils::MakeMaker;
22use File::Find;
23use File::Path;
24use File::Basename;
25use File::Copy;
26
27use vars qw(
28	$ARGV_STR
29	$COUTOFLAG
30	$COUTEXEFLAG
31	$CLIBPATHFLAG
32	$CLINKPREFIX
33	$LDLIBFLAG
34	$LDOUTFLAG
35	$TMPDIR
36	$NULLDEV
37	$SCRIPT_EXT
38	$LD_LIB_EXT
39	$LIB_EXT
40	$LIB_PREFIX
41	$LDFLAGS
42	$LDDLFLAGS
43	@LIBS
44	@INCPATH
45	@LIBPATH
46	%DEFINES
47	%PREREQ
48	%PASSIVE_CODECS
49	@ACTIVE_CODECS
50	$DL_LOAD_FLAGS
51	$DISTNAME
52	$CWD
53	$SHQUOTE
54	$DEFFILE
55	$OPTIMIZE
56	$OPENMP
57	%ALL_PM_INSTALL
58	%ALL_MAN_INSTALL
59	%MODVERSIONS
60	$PKGCONFIG
61);
62
63use vars qw(
64	%cmd_options
65	%passthru_options
66	$Win32
67	$Win64
68	$unix
69	$cygwin
70	$mingw
71	$platform
72	$flavor
73	$path_sep
74	%alldeps
75	@pm_files
76	@prima_files
77	@pod_files
78	@c_files
79	@h_files
80	@o_files
81	@exe_files
82	@cls_files
83	@target_clean
84	%cache_find_files
85	$binary_prereq
86	$compiler_type
87	$compiler_version
88	@Prima_exports
89	$win32_use_dlltool
90	$cygwin_fake_Slib
91	$force_cccdl
92	$use_pkgconfig
93	$macos_broken_setup
94	$macos_x11_path
95);
96
97sub printlog($)
98{
99	print $_[0];
100	print MAKELOG $_[0];
101}
102
103my $END;
104END {
105	printlog $END if defined $END;
106};
107
108my ($offset_makefile_log, $captured_makefile_log);
109my $see_makefile_log = "(see also makefile.log for details)";
110
111sub see_makefile_log
112{
113	my $ret = "$see_makefile_log\n";
114	$ret .= "\n--------------------------------------------\n$captured_makefile_log\n"
115		if defined $captured_makefile_log;
116	return $ret;
117}
118
119sub usage
120{
121	print <<HELP;
122
123$0 - configuration script for Prima
124
125syntax:
126    perl Makefile.PL [options]
127
128options:
129    X11BASE           - path where X11 includes and libraries are installed
130    WITH_XFT          - compile with/without Xft (default 1), X only
131    WITH_FRIBIDI      - compile with/without fribidi (default 1)
132    WITH_HARFBUZZ     - compile with/without harfbuzz (default 1), X only
133    WITH_ICONV        - compile with/without iconv (default 1), X only
134    WITH_GTK2         - compile with/without GTK2 (default 1), X only
135    WITH_GTK3         - compile with/without GTK3 (default 0), X only
136    WITH_OPENMP       - compile with/without openmp (default 1)
137    WITH_COCOA        - compile with/without Cocoa (default 1), MacOSX only
138    CYGWIN_WINAPI     - Winapi build in cygwin environment
139    DEBUG             - build with debug information
140    VERBOSE           - don't redirect commands to makefile.log
141    EXTRA_LDFLAGS     - add extra ld line (i.e. -lgcc )
142    EXTRA_CCFLAGS     - add extra cc line (i.e. -I/usr/local/include )
143
144HELP
145	exit;
146}
147
148usage if grep /^(-h|--help)$/, @ARGV;
149if ( defined($ARGV[0]) and $ARGV[0] =~ /^--(.*)$/) {
150	my $sub = MY-> can("command_$1");
151	die "invalid command $ARGV[0]\n" unless $sub;
152	shift @ARGV;
153	$sub->(@ARGV);
154	exit;
155}
156
157unlink "showlog";
158rename "makefile.log", "makefile.log.old";
159open MAKELOG, ">", "makepl.log";
160
161setup_argv();
162setup_variables();
163setup_environment();
164setup_compiler();
165setup_exports();
166setup_defines();
167setup_dl_loadflags();
168setup_pkgconfig();
169setup_fribidi() if $cmd_options{WITH_FRIBIDI};
170setup_X11() if $unix;
171setup_xlibs() if $unix;
172setup_codecs();
173setup_macosx() if $cmd_options{WITH_COCOA} || $macos_x11_path;
174create_codecs_c();
175create_config_h();
176create_config_pm();
177create_par_list();
178setup_files();
179
180sub setup_argv
181{
182	$ARGV_STR = join(' ', @ARGV);
183
184	%cmd_options = (
185		X11BASE       => undef,
186		WITH_XFT      => 1,
187		WITH_HARFBUZZ => 1,
188		WITH_FRIBIDI   => 1,
189		WITH_ICONV    => 1,
190		WITH_GTK2     => 1,
191		WITH_GTK3     => 0,
192		WITH_OPENMP   => 1,
193		WITH_COCOA    => ($^O eq 'darwin'),
194		CYGWIN_WINAPI => 0,
195		DEBUG         => 0,
196		EXTRA_CCFLAGS => '',
197		EXTRA_LDFLAGS => '',
198		VERBOSE       => 0,
199
200		# service vars
201		AUTOMATED_RUN => 0,
202		DL_LOAD_FLAGS => undef,
203	);
204
205	%passthru_options = (
206		DEFINE        => '',
207		LIBS          => '',
208		INC           => '',
209		LD            => $Config{ld},
210		LDDLFLAGS     => $Config{lddlflags},
211	);
212
213	@ARGV = grep {
214		my ( $k, $v) = split( '=', $_, 2 );
215		exists($cmd_options{$k}) ? ($cmd_options{$k} = $v, 0) : 1;
216	} @ARGV;
217
218	for ( @ARGV ) {
219		my ( $k, $v) = split( '=', $_, 2 );
220		next unless exists $passthru_options{$k};
221		$passthru_options{$k} = $v;
222	}
223}
224
225sub setup_variables
226{
227	$DL_LOAD_FLAGS = 0;
228	if ( $^O =~ /mswin32/i) {
229		$Win32 = 1;
230		$platform = 'win32';
231	} elsif ( $^O =~ /cygwin/i) {
232		if ( $cmd_options{CYGWIN_WINAPI}) {
233			$Win32 = 1;
234			$platform = 'win32';
235		} else {
236			$unix = 1;
237			$platform = 'unix';
238		}
239		$cygwin = 1;
240	} else {
241		$platform = 'unix';
242		$unix = 1;
243		$DL_LOAD_FLAGS = -1; # check later
244	}
245
246	$DL_LOAD_FLAGS = $cmd_options{DL_LOAD_FLAGS} if defined $cmd_options{DL_LOAD_FLAGS};
247}
248
249sub extmap
250{
251	my $newext = shift;
252	return map { my $x = $_; $x =~ s/\.\w+$/$newext/; $x } @_;
253}
254
255sub ffind
256{
257	my ( $mask, $fdir ) = @_;
258	$fdir = '.' unless defined $fdir;
259	my @ret;
260	File::Find::finddepth( sub {
261		return unless -f and m/$mask/;
262		return if /\.swp$/;
263		my $dir = $File::Find::dir;
264		$dir =~ s/^\.[\\\/]?//;
265		return if $dir =~ /^blib/;
266		my $f = length($dir) ? "$dir/$_" : $_;
267		push @ret, $f;
268	}, $fdir);
269	return @ret;
270}
271
272sub setup_files
273{
274	@prima_files   = ('Prima.pm', ffind( qr/./, 'Prima' ));
275	@pod_files  = ffind( qr/./, 'pod' );
276	@pm_files  = ffind( qr/\.pm$/ );
277	@c_files    = (
278		<src/*.c>,
279		(grep { not $PASSIVE_CODECS{$_} } <img/*.c>),
280		(grep { !m/xft.c/ || $cmd_options{WITH_XFT} } <$platform/*.c>),
281	);
282	@cls_files  = ( <src/*.cls> );
283	@h_files    = (
284		<include/*.h>,
285		<include/generic/*.h>,
286		<include/$platform/*.h>,
287		map { s[src/][]; "include/generic/$_" } extmap( '.h', @cls_files),
288	);
289	@o_files  = extmap( $Config{_o}, @c_files );
290
291	@exe_files = (
292		<utils/*.pl>,
293		<Prima/VB/*.pl>
294	);
295
296	@target_clean = (
297		"include/generic/*",
298		"src/*$Config{_o}",
299		"img/*$Config{_o}",
300		"$platform/*$Config{_o}",
301	);
302
303	# I still like to have my scripts as .pl, but installed without
304	# extension. Hack, hack, hack. See also corresponding part in the postamble
305	if ($unix or $cygwin) {
306		@exe_files = extmap('', @exe_files);
307		push @target_clean, @exe_files;
308	}
309
310	%ALL_PM_INSTALL = (
311		# PM
312		( map { $_ => '$(INST_LIBDIR)/'. $_ } @prima_files ),
313		# INC
314		( map {
315			my $k = $_;
316			$k =~ s/^include\///;
317			( $_ => '$(INST_LIBDIR)/Prima/CORE/' . $k )
318		} @h_files ),
319		# POD
320		( map {
321			my $k = $_;
322			$k =~ s/^pod\///;
323			$_ => '$(INST_LIBDIR)/' . $k
324		} @pod_files ),
325		# examples
326		( map { $_ => '$(INST_LIBDIR)/Prima/' . $_ } <examples/*> ),
327	);
328	%ALL_MAN_INSTALL = (
329		map {
330			my $target = $_;
331			$target =~ s/\//::/g;
332			$target =~ s/\.\w+$//;
333			$_ => '$(INST_MAN3DIR)/'. $target . '.$(MAN3EXT)'
334		}
335		(@pm_files, grep { /pod$/ } @pod_files)
336	);
337}
338
339sub gcc { $compiler_type eq 'gcc' }
340
341sub setup_environment
342{
343	if ( $Config{ccname} =~ /\bgcc/ ) {
344		$compiler_type = 'gcc';
345	} else {
346		$compiler_type = $Config{ccname};
347	}
348
349	if ( $Win32 and not $cygwin ) {
350		$SCRIPT_EXT = '.bat';
351		$SHQUOTE    = '"';
352		if (gcc) {
353			$win32_use_dlltool = $Config{dlltool} || 'dlltool';
354			$mingw = 1;
355		}
356	} else {
357		$SCRIPT_EXT = '';
358		$SHQUOTE    = "'";
359	}
360
361	$OPTIMIZE = $Config{optimize};
362
363	if ( $compiler_type eq 'cl') {
364		$COUTOFLAG    = '-Fo';
365		$COUTEXEFLAG  = '-Fe';
366		$CLIBPATHFLAG = '/LIBPATH:';
367		$CLINKPREFIX  = '/link';
368		$CLINKPREFIX .= " $1" if $Config{libs} =~ /(bufferoverflowU.lib)/i;
369		$LDLIBFLAG    = '';
370		$LDOUTFLAG    = '/OUT:';
371		$LD_LIB_EXT   = '.lib';
372		$OPTIMIZE     = '-Zi' if $cmd_options{DEBUG};
373		$OPENMP       = '/openmp';
374		# link flag is /DEBUG, but we don't care because ActiveState has it on by default anyway
375	}
376	else {
377		$COUTOFLAG    = '-o ';
378		$COUTEXEFLAG  = '-o ';
379		$CLIBPATHFLAG = '-L';
380		$CLINKPREFIX  = '';
381		$LDLIBFLAG    = '-l';
382		$LDOUTFLAG    = '-o ';
383		$LD_LIB_EXT   = '';
384		$OPTIMIZE     = '-g' if $cmd_options{DEBUG};
385		$OPENMP       = '-fopenmp';
386		$OPTIMIZE    .= ' -Wall' if gcc;
387		if ($cmd_options{DEBUG}) {
388			$passthru_options{LDDLFLAGS} .= ' -g';
389			$passthru_options{LDDLFLAGS} =~ s/(^| )\-s\b//;
390		}
391	}
392
393	$DEFFILE    = 'Prima.def';
394	$LIB_EXT    = ($cygwin ? '.dll' : '') . $Config{ _a};
395	$LIB_PREFIX = ($cygwin || $mingw) ? 'lib' : '';
396	$LDFLAGS    = '';
397
398	open F, 'Prima.pm' or die "Cannot open Prima.pm:$!\n";
399	my ($ver1, $ver2);
400	while (<F>) {
401		next unless m/\$VERSION[^\.\d]*(\d+)\.([_\d]+)/;
402		$ver1 = $1, $ver2 = $2, last;
403	}
404	close F;
405	die "Cannot find VERSION string in Prima.pm\n" unless defined $ver1;
406	printlog "Version: $ver1.$ver2\n";
407
408	my $PATCHLEVEL = defined($Config{PATCHLEVEL}) ? $Config{PATCHLEVEL} : $Config{PERL_PATCHLEVEL};
409	my $SUBVERSION = defined($Config{SUBVERSION}) ? $Config{SUBVERSION} : $Config{PERL_SUBVERSION};
410	my $REVISION   = defined($Config{REVISION})   ? $Config{REVISION}   : $Config{PERL_REVISION};
411
412	%DEFINES = (
413		PRIMA_VERSION    => $ver1,
414		PRIMA_SUBVERSION => $ver2,
415		PERL_PATCHLEVEL  => $PATCHLEVEL,
416		PERL_SUBVERSION  => $SUBVERSION,
417		PRIMA_CORE       => 1,
418		PERL_POLLUTE     => 1,
419	);
420
421	if ( $platform eq 'win32') {
422		$DEFINES{PRIMA_PLATFORM_WINDOWS} = 1;
423	} else {
424		$DEFINES{PRIMA_PLATFORM_X11} = 1;
425	}
426
427	$TMPDIR  = $ENV{ TMPDIR} || $ENV{ TEMPDIR} || ( $Win32 ? ( $ENV{ TEMP} || "$ENV{SystemDrive}\\TEMP") : "/tmp");
428	$NULLDEV = 'makefile.log';
429
430	printlog "Flavor: ";
431	$flavor = $^O;
432	if ( $Win32 and not $cygwin ) {
433		if ( $Config{myuname} =~ /strawberry\-?perl/i) {
434			$flavor = 'strawberry';
435		} elsif ( `perl -V` =~ /activeperl/i) {
436			$flavor = 'activestate';
437		}
438		$flavor .= ( $Config{ptrsize} == 8 ) ? '64' : '32';
439	} elsif ( $cygwin ) {
440		$flavor .= ( $Config{ptrsize} == 8 ) ? '64' : '32';
441		$flavor .= '.' . ( $cmd_options{CYGWIN_WINAPI} ? 'win32' : 'x11' );
442	} else {
443		my $arch = `uname -m`;
444		chomp $arch;
445		$flavor .= ".$arch";
446	}
447	$flavor =~ s/\s/_/g;
448	printlog "$flavor\n";
449
450	$flavor =~ s/strawberry/sb/;
451	$flavor =~ s/activestate/as/;
452
453	$DISTNAME = "Prima-$ver1.$ver2-$flavor-$REVISION.$PATCHLEVEL.$SUBVERSION";
454	printlog "Build: $DISTNAME\n";
455
456	$cygwin_fake_Slib = 'SlibPrima' . ( $Config{lib_ext} || '.a' );
457	$PKGCONFIG = 'pkg-config';
458}
459
460sub qtilde
461{
462	my $path = shift;
463	return $path unless $path =~ s/^~//;
464	die "** path '~$path' begins with '~' but no HOME is set\n" unless exists $ENV{HOME};
465	return $ENV{HOME} . $path;
466}
467
468sub _find_file
469{
470	my ( $fname, $dir) = @_;
471	my ( $pathname, $found);
472	$pathname = "$dir/$fname";
473	return $pathname if $pathname !~ /\.\./ && -e $pathname;
474	opendir D, $dir or die "Cannot open dir $dir: $!";
475	my @entries =
476		map { "$dir/$_"}
477		grep { !/^blib/ }
478		grep { /^[^.]/ && -d "$dir/$_"}
479		readdir D;
480	closedir D;
481	foreach my $entry ( @entries) {
482		$pathname = _find_file( $fname, $entry);
483		next unless defined $pathname;
484		return $pathname;
485	}
486	return undef;
487}
488
489sub find_file
490{
491	my ( $fname) = @_;
492	$fname =~ s/\\/\//g;
493	return $cache_find_files{$fname} if exists $cache_find_files{$fname};
494	return $cache_find_files{$fname} = _find_file( $fname, '.');
495}
496
497sub canon_name
498{
499	my ( $fname) = @_;
500	my $qdirsep = quotemeta('/');
501	$fname =~ s{[^$qdirsep]+$qdirsep\.\.(?:$qdirsep|\Z)}{}
502		while $fname =~ /(?:$qdirsep|\A)\.\.(?:$qdirsep|\Z)/;
503	$fname =~ s{(?:(?<=$qdirsep)|(?<=\A))\.(?=$qdirsep|\Z)$qdirsep?}{}g;
504	return $fname;
505}
506
507sub find_cdeps
508{
509	my ( $cfile, $deps, $included) = @_;
510
511	$deps ||= {};
512	$included ||= {};
513
514	return () if exists $deps->{ $cfile};
515	$deps->{ $cfile} = [];
516	return @{ $alldeps{ $cfile}} if exists $alldeps{ $cfile};
517	$alldeps{ $cfile} = [];
518	return () unless -f $cfile;
519
520	local *CF;
521	open CF, "<$cfile" or die "Cannot open $cfile: $!";
522	while ( <CF>) {
523		chomp;
524		next unless /^\s*\#\s*include\s+"([^\"]+)"/;
525		my $incfile = $1;
526		my $i = find_file( $incfile);
527		$incfile = defined($i) ? $i : "include/generic/$incfile";
528		$incfile = canon_name( $incfile);
529		unless ( exists $included->{ $incfile}) {
530			push @{ $alldeps{ $cfile}}, $incfile;
531			push @{ $deps->{ $cfile}}, $incfile;
532			$included->{ $incfile} = 1;
533		}
534		my @subdeps = find_cdeps( $incfile, $deps, $included);
535		push @{ $deps->{ $cfile}}, @subdeps;
536		push @{ $alldeps{ $cfile}}, @subdeps;
537	}
538	close CF;
539	return @{ $deps->{ $cfile}};
540}
541
542sub cc_command_line
543{
544	my ( $srcf, $objf, $exef, $compile_only, $dl) = @_;
545	my $ccflags = $Config{ccflags};
546	$ccflags =~ s/\b\-W(all|error|\d)w*//i;
547	my $cc = "$Config{cc} $ccflags";
548	$cc .= " $cmd_options{EXTRA_CCFLAGS}"  if length $cmd_options{EXTRA_CCFLAGS};
549	$cc .= " $passthru_options{DEFINE}" if length $passthru_options{DEFINE};
550	$cc .= " $Config{cccdlflags}" if $dl || $force_cccdl;
551	$cc .= " $Config{ccdlflags}" if $dl && !$compile_only;
552	$cc .= " -c " if $compile_only;
553	$cc .= ' ' . join(' ', map { "-I$_" } @INCPATH);
554	$cc .= " $passthru_options{INC}" if length $passthru_options{INC};
555	$cc .= $compile_only ? " $COUTOFLAG$objf" : " $COUTEXEFLAG$exef";
556	$cc .= " $COUTOFLAG$objf" if $compiler_type eq 'cl' && !$compile_only;
557	$cc .= ' ' . join(' ', map { "$CLIBPATHFLAG$_"} @LIBPATH) unless $compile_only || ( $compiler_type eq 'cl');
558	$cc .= " $srcf";
559	return $cc if $compile_only;
560	$cc .= " $passthru_options{LDDLFLAGS}" if gcc;
561	$cc .= " $CLINKPREFIX";
562	$cc .= " $LDFLAGS";
563	$cc .= ' ' . join(' ', map { "\"$CLIBPATHFLAG\\\"$_\\\"\"" } @LIBPATH) if $compiler_type eq 'cl';
564	$cc .= ' ' . join(' ', map { "$LDLIBFLAG$_$LD_LIB_EXT"} @LIBS);
565	$cc .= " $passthru_options{LIBS}" if length $passthru_options{LIBS};
566	$cc .= " $cmd_options{EXTRA_LDFLAGS}" if length $cmd_options{EXTRA_LDFLAGS};
567	return $cc;
568}
569
570sub ld_command_line
571{
572	my ( $dstf) = shift;
573	my $ld = "$passthru_options{LD} $passthru_options{LDDLFLAGS}";
574	$ld .= " $LDFLAGS";
575	$ld .= " $cmd_options{EXTRA_LDFLAGS}" if length $cmd_options{EXTRA_LDFLAGS};
576	$ld .= " $LDOUTFLAG$dstf @_";
577	$ld .= ' ' . join(' ', map { "$LDLIBFLAG$_$LD_LIB_EXT"} @LIBS);
578	return $ld;
579}
580
581sub null_output
582{
583	open OLDSTDOUT, ">&STDOUT" or die "STDOUT dup failed: $!";
584	open OLDSTDERR, ">&STDERR" or die "STDERR dup failed: $!";
585#	$NULLDEV = ( $Win32) ? "CON" : "/dev/tty";
586#	$NULLDEV = ( $Win32) ? "NUL" : "/dev/null";
587	if ( $^O !~ /linux/) {
588		close STDOUT;
589		close STDERR;
590	}
591	open STDOUT, ">>$NULLDEV" or die "STDOUT redirect failed: $!";
592	open STDERR, ">&STDOUT" or die "STDERR redirect failed: $!";
593
594	if ( -f $NULLDEV ) {
595		$offset_makefile_log = -s $NULLDEV;
596		undef $captured_makefile_log;
597	}
598}
599
600sub restore_output
601{
602	if ( $^O !~ /linux/) {
603		close STDOUT;
604		close STDERR;
605	}
606	open STDOUT, ">&OLDSTDOUT" or die "STDOUT restoration failed: $!";
607	open STDERR, ">&OLDSTDERR" or die "STDERR restoration failed: $!";
608	close OLDSTDOUT;
609	close OLDSTDERR;
610
611	if ( -f $NULLDEV ) {
612		if ( open MAKEFILELOG, '<', $NULLDEV) {
613			binmode MAKEFILELOG;
614			seek MAKEFILELOG, $offset_makefile_log, 0;
615			local $/;
616			$captured_makefile_log = <MAKEFILELOG>;
617			print "\n", $captured_makefile_log if $cmd_options{VERBOSE};
618			close MAKEFILELOG;
619		}
620	}
621}
622
623sub tempfile
624{
625	my $mask = shift;
626	my $name;
627	my $n = 0;
628	do {
629		$name = sprintf $mask, $n++;
630	} while ( -e $name);
631	return $name;
632}
633
634sub compile
635{
636	my ( $text, $compile_only, @extra) = @_;
637	my $tmpsrc = tempfile( "$TMPDIR/pmts%04d.c");
638	my $tmpo = tempfile( "$TMPDIR/pmts%04d$Config{_o}");
639	my $tmpexe = tempfile( "$TMPDIR/pmts%04d$Config{_exe}");
640	my @tmpextras = ( $tmpsrc, $tmpsrc);
641	$tmpextras[0] =~ s/\.[^\.+]$/.ilk/;
642	$tmpextras[1] =~ s/\.[^\.+]$/.pdb/;
643	unlink @tmpextras; # leftovers are toxic to msvc
644
645	open TMPSRC, ">$tmpsrc" or die "Creation of temporary file $tmpsrc failed";
646	print TMPSRC $text;
647	close TMPSRC;
648
649	null_output;
650	my $cc = cc_command_line( $tmpsrc, $tmpo, $tmpexe, $compile_only || 0);
651	$cc .= ' ' . join(' ', @extra) if @extra;
652	print STDERR "$cc\n";
653	my $rc = system($cc);
654	restore_output;
655	unlink $tmpsrc;
656	unlink $tmpo if -w $tmpo;
657	unlink $tmpexe if -w $tmpexe;
658	unlink $_ for @tmpextras;
659	return( $rc == 0);
660}
661
662sub compile_and_run
663{
664	my ( $text) = @_;
665	my $tmpsrc = tempfile( "$TMPDIR/pmts%04d.c");
666	my $tmpo = tempfile( "$TMPDIR/pmts%04d$Config{_o}");
667	my $tmpexe = tempfile( "$TMPDIR/pmts%04d$Config{_exe}");
668	my @tmpextras = ( $tmpsrc, $tmpsrc);
669	$tmpextras[0] =~ s/\.[^\.+]$/.ilk/;
670	$tmpextras[1] =~ s/\.[^\.+]$/.pdb/;
671	unlink @tmpextras; # leftovers are toxic to msvc
672
673	open TMPSRC, ">$tmpsrc" or die "Creation of temporary file $tmpsrc failed";
674	print TMPSRC $text;
675	close TMPSRC;
676
677	null_output;
678	my $cc = cc_command_line( $tmpsrc, $tmpo, $tmpexe, 0);
679	$cc =~ s/\s\-+(s(hared)?|mdll)\b//g if gcc;
680	print STDERR "$cc\n";
681	my $rc = system($cc);
682	print "$tmpexe\n";
683	restore_output;
684	unlink $tmpsrc;
685	unlink $tmpo if -w $tmpo;
686	my $ret = '';
687	if ( -x $tmpexe ) {
688		$ret = `$tmpexe`;
689		chomp $ret;
690	}
691	unlink $tmpexe if -w $tmpexe;
692	unlink $_ for @tmpextras;
693	return $ret;
694}
695
696sub have_header
697{
698	my $header = shift;
699	(my $defname = "HAVE_" . uc $header) =~ s/\W/_/g;
700	return $DEFINES{$defname} if exists $DEFINES{$defname};
701	my @pre_headers = map { "#include <$_>\n" } @_;
702	printlog "Checking for presence of $header... ";
703	my $present = compile( <<EOF, 1);
704@pre_headers
705#include <$header>
706EOF
707	$DEFINES{ $defname} = undef;
708	$DEFINES{ $defname} = 1 if $present;
709	printlog ($present ? "yes" : "no");
710	printlog "\n";
711	return $present;
712}
713
714sub find_header
715{
716	my $header = shift;
717	my $options = ref($_[0]) eq 'HASH' ? shift : {};
718	my ( $incpath, $present);
719	foreach $incpath ( @_) {
720		local @INCPATH = @INCPATH;
721		push @INCPATH, $incpath if $incpath;
722		my $code = $options->{Code} || <<EOF;
723#include <$header>
724EOF
725		$present = compile( $code, 1);
726		return $incpath if $present;
727	}
728	return undef;
729}
730
731sub find_lib
732{
733	my ( $lib, $inc) = ( shift, shift );
734	my ( $libpath, $present);
735
736	local @LIBS = @LIBS;
737	push @LIBS, $lib;
738	foreach $libpath ( @_) {
739		local @LIBPATH = (@LIBPATH, $libpath) if $libpath;
740		$present = compile( <<EOF);
741$inc
742
743int
744main()
745{
746   return 0;
747}
748EOF
749		return $libpath if $present;
750	}
751	return undef;
752}
753
754sub have_func
755{
756	my ( $funcname, @headers) = @_;
757	die "have_func() without any header is deprecated " unless @headers;
758	my $defname = "HAVE_" . uc $funcname;
759	my @srchead = map { "#include <$_>\n"} @headers;
760	$defname =~ s/\W/_/g;
761	printlog "Checking for function $funcname... ";
762	my $rc = compile( <<EOF);
763@srchead
764
765int
766main()
767{
768    void * ixi = $funcname;
769    return 0;
770}
771EOF
772	if ( $rc) {
773		$DEFINES{ $defname} = 1;
774		printlog "yes\n";
775	} else {
776		$DEFINES{ $defname} = undef;
777		printlog "no\n";
778	}
779	return $rc;
780}
781
782sub have_define
783{
784	my ( $defname) = @_;
785	my $cwd = cwd;
786	chdir $TMPDIR;
787	my $tmpsrc = tempfile( "pmts%04d.c");
788	my $tmpo = $tmpsrc;
789	$tmpo =~ s/\.c$/\.$Config{_o}/;
790	open TMPSRC, ">$tmpsrc" or die "Creation of temporary file $tmpsrc failed";
791	print TMPSRC <<EOF;
792int
793main()
794{
795#if defined( $defname)
796return 0;
797#else
7980error No
799#endif
800}
801EOF
802	close TMPSRC;
803	null_output;
804	my $ccrc = system( "$Config{cc} -c $tmpsrc");
805	restore_output;
806	unlink $tmpsrc, $tmpo;
807	chdir $cwd;
808	return $ccrc == 0;
809}
810
811sub have_type
812{
813	my ( $type, @headers) = @_;
814	(my $defname = "HAVE_" . uc $type) =~ s/\W/_/g;
815	return 1 if $DEFINES{$defname};
816	printlog "Checking for presence of type $type... ";
817	my @srchead = map { "#include <$_>\n"} @headers;
818	my $rc = compile( <<EOF);
819@srchead
820
821int
822main()
823{
824	${ type} foo;
825	return 0;
826}
827EOF
828	if ( $rc) {
829		$DEFINES{ $defname} = 1;
830		printlog "yes\n";
831	}
832	else {
833		$DEFINES{ $defname} = undef;
834		printlog "no\n";
835	}
836	return $rc;
837}
838
839sub have_types_in
840{
841	my ($hdr, @types) = @_;
842	return unless have_header( $hdr);
843	my $found = 1;
844	for my $type (@types) {
845		$found = $found && have_type($type, $hdr);
846		last unless $found;
847	}
848	return $found;
849}
850
851sub have_funcs_in
852{
853	my ($hdr, @funcs) = @_;
854	return unless have_header( $hdr);
855	my $found = 1;
856	for my $func (@funcs) {
857		$found = $found && have_func( $func, $hdr);
858		last unless $found;
859	}
860	return $found;
861}
862
863
864sub find_inline
865{
866	printlog "Checking for inline... ";
867	for ( qw( inline __inline inline__ __inline__
868				INLINE __INLINE INLINE__ __INLINE__)) {
869		my $i = $_;
870		my $rc = compile( <<EOF);
871
872$_ void a( void) {};
873
874int
875main()
876{
877	return 0;
878}
879EOF
880		if ( $rc) {
881			$DEFINES{__INLINE__} = $i;
882			printlog "$i\n";
883			return;
884		}
885	}
886	printlog "none found\n";
887	$DEFINES{__INLINE__} = '';
888}
889
890sub find_glibc
891{
892	printlog "Checking for glibc... ";
893	my $rc = compile_and_run( <<'GLIBC');
894#include <stdio.h>
895int
896main()
897{
898#ifdef __GLIBC__
899	printf("1\n");
900#else
901	printf("0\n");
902#endif
903	return 0;
904}
905GLIBC
906	printlog ($rc ? "yes\n" : "no\n");
907	$DEFINES{HAS_GLIBC} = 1 if $rc;
908}
909
910sub setup_compiler
911{
912	printlog "Compiler: $compiler_type\n";
913
914	printlog "Checking if can compile... ";
915	compile('int a;', 1) or die "no " . see_makefile_log;
916	printlog "yes\n";
917
918	my $text = <<EOF;
919int
920main()
921{
922   return 0;
923}
924EOF
925
926	printlog "Checking if can link... ";
927	unless ( compile($text, 0)) {
928		printlog "no, let's try with '$Config{cccdlflags}'... ";
929		$force_cccdl = 1;
930		compile( $text, 0) or die "no " . see_makefile_log;
931	}
932	printlog "yes\n";
933
934	if ( $cmd_options{WITH_OPENMP} ) {
935		printlog "Checking if can compile with OpenMP... ";
936	my $text = <<'EOF';
937#include <omp.h>
938#include <stdio.h>
939int
940main()
941{
942   int i, x = omp_get_thread_num();
943#pragma omp parallel for
944   for ( i = 0; i < x; i++) x++;
945   printf("1\n");
946   return 0;
947}
948EOF
949		my $savecc = $cmd_options{EXTRA_CCFLAGS};
950		my $saveld = $passthru_options{LDDLFLAGS};
951		$cmd_options{EXTRA_CCFLAGS} .= " $OPENMP";
952		$passthru_options{LDDLFLAGS} .= " $OPENMP";
953		my @savelibs = @LIBS;
954#		push @LIBS, 'gomp' if $compiler_type eq 'gcc';
955		if ( compile_and_run($text)) {
956		YES_OPENMP:
957			$DEFINES{HAVE_OPENMP} = 1;
958			printlog "yes\n";
959		} else {
960			if ( $captured_makefile_log =~ /recompile with (\-fpic)/i) {
961				printlog "no, trying with $1 ...";
962				$cmd_options{EXTRA_CCFLAGS} .= " $1";
963				$OPENMP .= " $1";
964				goto YES_OPENMP if compile($text);
965			}
966
967			@LIBS = @savelibs;
968			$cmd_options{WITH_OPENMP} = 0;
969			$cmd_options{EXTRA_CCFLAGS} = $savecc;
970			$passthru_options{LDDLFLAGS} = $saveld;
971			printlog "no\n";
972		}
973	}
974
975	if ( $compiler_type eq 'cl' ) {
976		printlog "Checking MSVC version... ";
977		$compiler_version = compile_and_run(<<'MSCVER');
978#include <stdio.h>
979int main() {
980	printf("%d\n", _MSC_VER);
981	return 0;
982}
983MSCVER
984		printlog "$compiler_version\n";
985
986		# kill annoying warnings
987		if ( $compiler_version < 1400) {
988			$OPTIMIZE .= " -D_CRT_SECURE_NO_DEPRECATE";
989		}
990		if ( $compiler_version >= 1600 ) {
991			$OPTIMIZE .= " -D_CRT_SECURE_NO_WARNINGS";
992			$OPTIMIZE .= " /wd4244"; #  '=' : conversion from 'Bool' to 'char', possible loss of data
993			$OPTIMIZE .= " /wd4267"; #  '=' : conversion from 'size_t' to 'int', possible loss of data
994			$OPTIMIZE .= " /wd4018"; #  '<' : signed/unsigned mismatch";
995		}
996	}
997
998	if ($Win32) {
999		printlog "Checking windows subsystem...";
1000		$Win64 = have_define('_WIN64');
1001		printlog ($Win64 ? " 64" : " 32");
1002		printlog " bits\n";
1003		$DISTNAME =~ s/(mswin|sb|as)32/${1}64/i if $Win64;
1004	}
1005
1006	@INCPATH = (
1007		'include',
1008		'include/generic',
1009	);
1010
1011	push @LIBS, qw(usp10 gdi32 gdiplus mpr winspool comdlg32 msimg32 ole32 uuid) if $Win32; # add more when appropriate
1012	push @LIBPATH, '/usr/lib/w32api' if $cygwin;
1013	if ($^O eq 'solaris') {
1014		push @LIBPATH, '/opt/csw/lib';
1015	}
1016}
1017
1018sub setup_defines
1019{
1020	have_header( "io.h");
1021	have_header( "unistd.h");
1022	have_header( "strings.h");
1023
1024	my @int_types = qw(int8_t int16_t int32_t int64_t);
1025	my @uint_types = qw(uint8_t uint16_t uint32_t uint64_t);
1026	my @u_int_types = qw(u_int8_t u_int16_t u_int32_t u_int64_t);
1027	my @size_types = qw(ssize_t);
1028	have_types_in( "sys/types.h", @int_types)
1029		|| have_types_in( "sys/bitypes.h", @int_types)
1030		|| have_types_in( "sys/inttypes.h", @int_types)
1031		|| have_types_in( "stdint.h", @int_types);
1032	have_types_in( "sys/types.h", @uint_types)
1033		|| have_types_in( "sys/bitypes.h", @uint_types)
1034		|| have_types_in( "sys/inttypes.h", @uint_types)
1035		|| have_types_in( "stdint.h", @uint_types);
1036	have_types_in( "sys/types.h", @u_int_types)
1037		|| have_types_in( "sys/bitypes.h", @u_int_types)
1038		|| have_types_in( "sys/inttypes.h", @u_int_types)
1039		|| have_types_in( "stdint.h", @u_int_types);
1040	have_types_in( "sys/types.h", @size_types)
1041		|| have_types_in( "io.h", @size_types)
1042		|| have_types_in( "unistd.h", @size_types);
1043
1044	if ( $unix) {
1045		have_header( "sys/ipc.h", "sys/types.h");
1046		have_header( "sys/shm.h", "sys/types.h");
1047	}
1048
1049	if ( !have_funcs_in( 'strings.h', 'strcasecmp')) {
1050	   have_funcs_in( 'string.h', 'stricmp');
1051	}
1052	if ( !have_funcs_in( 'strings.h', 'strncasecmp')) {
1053	   have_funcs_in( 'string.h', 'strnicmp');
1054	}
1055	have_funcs_in( 'strings.h', 'strcasestr');
1056	have_funcs_in( 'stdio.h', 'snprintf');
1057	have_funcs_in( 'stdio.h', '_snprintf');
1058	have_funcs_in( 'stdlib.h', 'reallocf');
1059	have_funcs_in( 'strings.h', 'bzero');
1060	have_funcs_in( 'string.h', 'memmem');
1061	have_funcs_in( 'unistd.h', 'eaccess');
1062	if ( $Win32) {
1063		have_type( "BOOLEAN", "windows.h");
1064	}
1065	find_inline();
1066	find_glibc;
1067}
1068
1069sub setup_dl_loadflags
1070{
1071	return if $DL_LOAD_FLAGS >= 0;
1072
1073	printlog "Determining dl_load_flags... ";
1074
1075	local @INCPATH = ( qtilde($Config{archlib}) . "/CORE");
1076
1077	my $c1  = tempfile( "$TMPDIR/pmts%04d.c");
1078	$c1 =~ m/pmts([^\.]*).c$/;
1079	my ( $n1, $n2) = ( $1, sprintf("%04d", 1 + $1));
1080
1081	my $o1  = "$TMPDIR/pmts$n1$Config{_o}";
1082	my $o2  = "$TMPDIR/pmts$n2$Config{_o}";
1083	my $dl1 = "$TMPDIR/pmts$n1.$Config{dlext}";
1084	my $dl2 = "$TMPDIR/pmts$n2.$Config{dlext}";
1085	my @ex = map { "$TMPDIR/pmts$_"} map { ("$n1$_", "$n2$_") } ('.ilk', '.pdb');
1086
1087	open TMPSRC, ">$c1" or die "Creation of temporary file $c1 failed";
1088	print TMPSRC <<D;
1089#include <EXTERN.h>
1090#include <perl.h>
1091#include <XSUB.h>
1092
1093int test( void ) { return 1; }
1094
1095XS(boot_pmts$n1) {
1096   dXSARGS;
1097   XSRETURN(1);
1098}
1099D
1100	close TMPSRC;
1101
1102	my $c2  = tempfile( "$TMPDIR/pmts%04d.c");
1103	open TMPSRC, ">$c2" or die "Creation of temporary file $c2 failed";
1104	print TMPSRC <<D;
1105#include <EXTERN.h>
1106#include <perl.h>
1107#include <XSUB.h>
1108
1109extern int test ( void );
1110
1111XS(boot_pmts$n2) {
1112   dXSARGS;
1113   test();
1114   XSRETURN(1);
1115}
1116D
1117	close TMPSRC;
1118
1119	my $cc1 = cc_command_line( $c1, $o1, $dl1, 1, 1);
1120	my $cc2 = cc_command_line( $c2, $o2, $dl2, 1, 1);
1121	my $ld1 = ld_command_line( $dl1, $o1);
1122	my $ld2 = ld_command_line( $dl2, $o2);
1123	my $dlpl = "$^X -e '" . (join ' ', split("\n", <<DN)) . "'";
1124require DynaLoader;
1125unshift \@INC, q($TMPDIR);
1126
1127package pmts$n1;
1128\@ISA = q(DynaLoader);
1129sub dl_load_flags{0x00}
1130bootstrap pmts$n1 0;
1131
1132package pmts$n2;
1133\@ISA = q(DynaLoader);
1134bootstrap pmts$n2 0;
1135DN
1136
1137	null_output;
1138	print STDERR "$cc1\n";
1139	goto FAIL if system($cc1);
1140	print STDERR "$ld1\n";
1141	goto FAIL if system($ld1);
1142	print STDERR "$cc2\n";
1143	goto FAIL if system($cc2);
1144	print STDERR "$ld2\n";
1145	goto FAIL if system($ld2);
1146	print STDERR "$dlpl\n";
1147	my $ok_0 = system( $dlpl );
1148	$dlpl =~ s/0x00/0x01/;
1149	print STDERR "$dlpl\n";
1150	my $ok_1 = system( $dlpl );
1151
1152	if ( $ok_0 != 0 && $ok_1 == 0) {
1153		$DL_LOAD_FLAGS = 1;
1154	} elsif ( $ok_0 == 0 && $ok_1 == 0) {
1155		$DL_LOAD_FLAGS = 0;
1156	}
1157FAIL:
1158	unlink ( $c1, $c2, $o1, $o2, $dl1, $dl2, @ex );
1159	restore_output;
1160	if ( $DL_LOAD_FLAGS < 0 ) {
1161		printlog <<DLERR;
1162unknown
1163** warning: set DL_LOAD_FLAGS=1 if your system requires RTLD_GLOBAL
1164DLERR
1165		$DL_LOAD_FLAGS = 0;
1166	} else {
1167		printlog sprintf("0x%02x\n", $DL_LOAD_FLAGS);
1168	}
1169}
1170
1171sub setup_pkgconfig
1172{
1173	printlog "Checking for pkg-config... ";
1174	my $v = `pkg-config --version`;
1175	if ( $Win32 && $? ) {
1176		$v = `pkg-config.bat --version`;
1177		$PKGCONFIG = 'pkg-config.bat';
1178	}
1179	chomp $v;
1180	unless ($v =~ /^[\d\.]+$/) {
1181		printlog "no\n";
1182		return;
1183	}
1184
1185	# is your cygwin's pkg-config shading over old strawberry?
1186	if ( $Win32 && $flavor =~ /^sb/ && $DEFINES{PERL_PATCHLEVEL} < 20) {
1187		$v = `$PKGCONFIG --real-version 2>&1`;
1188		if ( $? ) {
1189			printlog "no, it's cygwin's\n";
1190			$END .= <<MIXED;
1191
1192** Warning: it seems that your setup has old perl and cygwin mixed.
1193
1194This is a bad idea, and no guarantees are made that Prima will build.
1195Please take cygwin away from your PATH or upgrade your perl to 5.20 at least.
1196MIXED
1197			return;
1198		}
1199	}
1200
1201	# it is mac's broken XQuartz setup?
1202	my $xquartz_pkgconfig_path = '/opt/X11/lib/pkgconfig';
1203	if ( $^O eq 'darwin' && !exists $ENV{PKG_CONFIG_PATH} && -d $xquartz_pkgconfig_path) {
1204		printlog "trying PKG_CONFIG_PATH=$xquartz_pkgconfig_path... ";
1205		my $add_path;
1206		null_output;
1207		if ( system "$PKGCONFIG --exists x11" ) {
1208			local $ENV{PKG_CONFIG_PATH} = $xquartz_pkgconfig_path;
1209			$add_path = 1 unless system "$PKGCONFIG --exists x11";
1210		}
1211		restore_output;
1212		if ($add_path) {
1213			$ENV{PKG_CONFIG_PATH} = "/usr/local/lib/pkgconfig:$xquartz_pkgconfig_path";
1214			$macos_broken_setup = 1;
1215		}
1216	}
1217
1218	$use_pkgconfig = 1;
1219	printlog "yes\n";
1220}
1221
1222sub pkgconfig
1223{
1224	my $package = shift;
1225
1226	printlog "Checking for $package using pkg-config...";
1227	null_output;
1228
1229	if ( system "$PKGCONFIG --exists $package" ) {
1230		restore_output;
1231		printlog "no\n";
1232		return 0;
1233	}
1234	restore_output;
1235
1236	my $modversion  = `$PKGCONFIG --modversion $package`;
1237	chomp $modversion;
1238	$MODVERSIONS{$package} = $modversion;
1239	printlog "$modversion\n";
1240
1241	my %h;
1242
1243	%h = map { $_ => 1 } @INCPATH;
1244	my $inc  = `$PKGCONFIG --cflags-only-I $package`;
1245	if ( $? != 0 ) { # package has error?
1246		printlog "misconfigured\n";
1247		return 0;
1248	}
1249	chomp $inc;
1250	$inc =~ s/\-I//g;
1251	for ( split " ", $inc ) {
1252		push @INCPATH, $_ unless $h{$_};
1253	}
1254
1255	%h = map { $_ => 1 } @LIBS;
1256	my $libs    = `$PKGCONFIG --libs-only-l $package`;
1257	if ( $? != 0 ) {
1258		   printlog "misconfigured\n";
1259		   return 0;
1260	}
1261	chomp $libs;
1262	$libs =~ s/\-l//g;
1263	for ( split " ", $libs ) {
1264		push @LIBS, $_ unless $h{$_};
1265	}
1266
1267	%h = map { $_ => 1 } @LIBPATH;
1268	my $libpath    = `$PKGCONFIG --libs-only-L $package`;
1269	if ( $? != 0 ) {
1270		   printlog "misconfigured\n";
1271		   return 0;
1272	}
1273	chomp $libpath;
1274	$libpath =~ s/\-[LR]//g;
1275	for ( split " ", $libpath ) {
1276		push @LIBPATH, $_ unless $h{$_};
1277	}
1278
1279	return 1;
1280}
1281
1282sub setup_X11
1283{
1284	if ($use_pkgconfig) {
1285		my $n_libpath = @LIBPATH;
1286		unless (pkgconfig('x11')) {
1287			warn
1288				"Prima needs package with x11 development file for compilation! ".
1289				"Please install it with your system installer tool.\n";
1290			exit(0);
1291		}
1292		pkgconfig('xext');
1293		if ( $macos_broken_setup ) {
1294			# stuff /opt/X11 or whatever comes with XQuartz at the end of the list
1295			# to use libs that come with homebrew instead. If we won't do that,
1296			# strange coredumps ensue
1297			$macos_x11_path = [ @LIBPATH[$n_libpath .. $#LIBPATH] ]
1298				if $n_libpath < @LIBPATH;
1299		}
1300		return;
1301	}
1302
1303	# find X11 include files
1304	printlog "Checking for X11 headers...";
1305	push @INCPATH, "$cmd_options{X11BASE}/include"
1306		if defined($cmd_options{X11BASE}) and -d "$cmd_options{X11BASE}/include";
1307	for ( 'local/', 'freeware/', 'gnu/', 'opt/') {
1308		push @INCPATH, "/usr/${_}include" if -d "/usr/${_}include";
1309	}
1310	my $incpath = find_header( "X11/Xlib.h",
1311		"/usr/X11R6/include",
1312		"/usr/X11/include",
1313		"/usr/X/include",
1314		"/usr/openwin/include",
1315		"/opt/X11/include"
1316	);
1317
1318	unless ( defined $incpath) {
1319		printlog "no\n";
1320		warn
1321			"Prima needs X11 headers for compilation! ".
1322			"Set X11BASE='/path/to/X' or INCPATH+='/path/to/X/include' ".
1323			"if you have a non-standard path to X. $see_makefile_log\n";
1324		exit(0);
1325	}
1326
1327	printlog "yes";
1328	if ( -d $incpath) {
1329		printlog ", in $incpath";
1330		push @INCPATH, $incpath;
1331	}
1332	printlog "\n";
1333
1334	# find X11 libraries
1335	my @libpath = ( "X11", '',
1336		(defined($cmd_options{X11BASE}) ? "$cmd_options{X11BASE}/lib" : ()),
1337		"/usr/X11R6/lib",
1338		"/usr/X11/lib",
1339		"/usr/X/lib",
1340		"/usr/openwin/lib",
1341		"/opt/X11/lib",
1342        	"/usr/local/lib"
1343	);
1344	# using /usr/X11R6/lib64 ?
1345	unshift @libpath, map { s/lib$/lib64/; $_ } grep { /lib$/ } @libpath
1346		if $Config{intsize} == 8;
1347
1348	printlog "Checking for library X11... ";
1349	my $libpath = find_lib( @libpath);
1350	unless ( defined $libpath) {
1351		printlog "no\n";
1352	NO_X:
1353		warn
1354			"Prima needs X11 libraries for compilation! ".
1355			"Set X11BASE='/path/to/X' ".
1356			"if you have a non-standard path to X. $see_makefile_log\n";
1357		exit(0);
1358	}
1359
1360	printlog "yes";
1361	if ( -d $libpath) {
1362		printlog ", in $libpath";
1363		push @LIBPATH, $libpath;
1364	}
1365	printlog "\n";
1366
1367	push @LIBS, 'X11';
1368	if (defined find_lib( "Xext", '', '')) {
1369		printlog "Xext library found.\n";
1370		push @LIBS, "Xext";
1371	}
1372}
1373
1374sub setup_xft
1375{
1376	my $HAVE_XFT = 0;
1377	my $NEED_XFT = 4;
1378	my @pre_xft_libs    = @LIBS;
1379	my @pre_xft_libpath = @LIBPATH;
1380	my @pre_xft_incpath = @INCPATH;
1381
1382	if ( $use_pkgconfig ) {
1383		my $has_xft = pkgconfig('xft') ? 1 : 0;
1384		my @post_xft_libpath = @LIBPATH;
1385		my @packages = map { pkgconfig($_) ? 1 : () } (qw(freetype2 fontconfig xrender));
1386		if ((@packages + $has_xft) != $NEED_XFT ) {
1387			$cmd_options{WITH_XFT} = 0;
1388			@LIBS    = @pre_xft_libs;
1389			@LIBPATH = @pre_xft_libpath;
1390			@INCPATH = @pre_xft_incpath;
1391		} else {
1392			$DEFINES{$_} = 1 for qw(
1393				HAVE_FREETYPE_FREETYPE_H
1394				HAVE_FONTCONFIG_FONTCONFIG_H
1395				HAVE_X11_EXTENSIONS_XRENDER_H
1396				HAVE_X11_XFT_XFT_H
1397			);
1398			if (
1399				$macos_broken_setup &&
1400				$macos_x11_path &&
1401				$cmd_options{WITH_HARFBUZZ} &&
1402				@pre_xft_libpath == @post_xft_libpath
1403			) {
1404				$cmd_options{WITH_HARFBUZZ} = 0;
1405				$END .= <<BROKEN_PATH_SETUP;
1406
1407** Warning: harfbuzz have been disabled.
1408
1409This happened because broken setup was detected where both harfbuzz and libXft
1410depend on freetype2, but one on /opt/X11 and another in /usr/local.
1411This _WILL_ result in coredumps.
1412
1413To resolve the issue install libXft that uses the recent freetype2, with
1414
1415    brew install dk/x11/libxft
1416
1417BROKEN_PATH_SETUP
1418			}
1419		}
1420		return;
1421	}
1422
1423	my @ft_incpaths = ( "",
1424		( defined($cmd_options{X11BASE}) ? "$cmd_options{X11BASE}/include/freetype2" : ()),
1425		"/usr/include/freetype2",
1426		"/usr/X11R6/include/freetype2",
1427		"/usr/X11/include/freetype2",
1428		"/usr/X/include/freetype2",
1429		"/usr/openwin/include/freetype2",
1430		"/opt/X11/include/freetype2",
1431		"/usr/local/include/freetype2",
1432		"/usr/gnu/include/freetype2",
1433		"/usr/freeware/include/freetype2",
1434		"/usr/opt/include/freetype2"
1435	);
1436	my $have_ft2build_h = defined find_header( "ft2build.h", @ft_incpaths );
1437
1438	printlog "Checking for presence of freetype/freetype.h... ";
1439	my $incpath;
1440	if ($have_ft2build_h) {
1441		$incpath = find_header(
1442			"freetype/freetype.h", {
1443				Code => <<EOF,
1444#include "ft2build.h"
1445#include FT_FREETYPE_H
1446EOF
1447			},
1448			@ft_incpaths,
1449		);
1450	} else {
1451		$incpath = find_header( "freetype/freetype.h", @ft_incpaths);
1452	}
1453	if (defined $incpath) {
1454		printlog "yes";
1455		printlog ", in $incpath" if $incpath;
1456		printlog "\n";
1457		push @INCPATH, $incpath if $incpath;
1458		printlog "Checking for presence of libfreetype... ";
1459		if ( defined find_lib( 'freetype', '', '')) {
1460			push @LIBS, 'freetype';
1461			$HAVE_XFT++;
1462			printlog "yes\n";
1463			$DEFINES{HAVE_FREETYPE_FREETYPE_H} = 1;
1464		} else {
1465			printlog "no\n";
1466			$DEFINES{HAVE_FREETYPE_FREETYPE_H} = undef;
1467		}
1468	} else {
1469		printlog "no\n";
1470	}
1471
1472	if ( have_header( "fontconfig/fontconfig.h")) {
1473		printlog "Checking for presence of libfontconfig... ";
1474		if ( defined find_lib( 'fontconfig', '', '')) {
1475			push @LIBS, 'fontconfig';
1476			$HAVE_XFT++;
1477			printlog "yes\n";
1478		} else {
1479			$DEFINES{HAVE_FONTCONFIG_FONTCONFIG_H} = undef;
1480			printlog "no\n";
1481		}
1482	}
1483
1484	if ( have_header( "X11/extensions/Xrender.h", "X11/X.h",
1485			"X11/Xlib.h", "X11/extensions/Xext.h")) {
1486		printlog "Checking for presence of libXrender... ";
1487		if ( defined find_lib( 'Xrender', '', '')) {
1488			push @LIBS, 'Xrender';
1489			$HAVE_XFT++;
1490			printlog "yes\n";
1491		} else {
1492			$DEFINES{HAVE_X11_EXTENSIONS_XRENDER_H} = undef;
1493			printlog "no\n";
1494		}
1495	}
1496
1497	if ( have_header( "X11/Xft/Xft.h", "X11/X.h", "X11/Xlib.h",
1498			"X11/extensions/Xext.h", "X11/extensions/Xrender.h")) {
1499		printlog "Checking for presence of libXft... ";
1500		if ( defined find_lib( 'Xft', '', '')) {
1501			printlog "yes\n";
1502			push @LIBS, 'Xft';
1503			$HAVE_XFT++;
1504		} else {
1505			printlog "no\n";
1506			$DEFINES{HAVE_X11_XFT_XFT_H} = undef;
1507		}
1508	}
1509
1510	$cmd_options{WITH_XFT} = 0 unless $HAVE_XFT == $NEED_XFT;
1511	@LIBS = @pre_xft_libs unless $cmd_options{WITH_XFT};
1512}
1513
1514sub setup_iconv
1515{
1516	if ( have_header( "iconv.h")) {
1517		printlog "Checking for presence of libiconv... ";
1518		my $ok = compile( "#include <iconv.h>\nint main() { iconv_close(0); return 0; }\n");
1519		if ( $ok ) {
1520			printlog "no, but works as part of libc\n";
1521		} else {
1522			if ( defined find_lib( 'iconv', '', '')) {
1523				push @LIBS, 'iconv';
1524				printlog "yes\n";
1525			} else {
1526				$DEFINES{HAVE_ICONV_H} = undef;
1527				$cmd_options{WITH_ICONV} = 0;
1528				printlog "no\n";
1529			}
1530		}
1531	} else {
1532		$cmd_options{WITH_ICONV} = 0;
1533	}
1534}
1535
1536sub setup_fribidi
1537{
1538	$cmd_options{WITH_FRIBIDI} = 0;
1539	unless ( $use_pkgconfig ) {
1540		printlog "Checking for presence of fribidi... no, can only check with pkg-config installed\n";
1541		goto WARN;
1542	}
1543	goto WARN unless pkgconfig('fribidi');
1544	$DEFINES{WITH_FRIBIDI} = 1;
1545	$cmd_options{WITH_FRIBIDI} = 1;
1546	return;
1547
1548WARN:
1549	$END .= <<BIDI;
1550
1551** Warning: fribidi is needed for bidirectional text.
1552Prima compiled without fribidi will not be able
1553to handle right-to-left text, f.ex. Arabic or Hebrew.
1554Consider fixing your installation.
1555
1556BIDI
1557}
1558
1559sub setup_harfbuzz
1560{
1561	$cmd_options{WITH_HARFBUZZ} = 0;
1562
1563	if ( !$cmd_options{WITH_XFT}) {
1564		printlog "harfbuzz deselected as it requires Xft\n";
1565		return;
1566	}
1567
1568	unless ( $use_pkgconfig ) {
1569		printlog "Checking for presence of harfbuzz... no, can only check with pkg-config installed\n";
1570		return;
1571	}
1572	return unless pkgconfig('harfbuzz');
1573	$DEFINES{WITH_HARFBUZZ} = 1;
1574	$cmd_options{WITH_HARFBUZZ} = 1;
1575}
1576
1577sub setup_gtk
1578{
1579	my $use_gtk3 = $cmd_options{WITH_GTK3};
1580	my $use_gtk2 = $cmd_options{WITH_GTK2};
1581	$cmd_options{WITH_GTK3} = 0;
1582	$cmd_options{WITH_GTK2} = 0;
1583
1584	unless ( $use_pkgconfig ) {
1585		printlog "Checking for presence of gtk... no, can only check with pkg-config installed\n";
1586		return;
1587	}
1588
1589	if ( $use_gtk3 && pkgconfig('gtk+-3.0')) {
1590		my $version = `$PKGCONFIG --modversion gtk+-3.0`;
1591		printlog "Checking if can compile and link with gtk3... ";
1592		my $minversion = 9;
1593		unless ( $version =~ m/^3\.(\d+)/ && $1 > $minversion ) {
1594			printlog "no, need at least v3.$minversion.0\n";
1595			return;
1596		}
1597		$use_gtk2 = 0;
1598	}
1599	if ( $use_gtk2 && pkgconfig('gtk+-2.0')) {
1600		my $version = `$PKGCONFIG --modversion gtk+-2.0`;
1601		printlog "Checking if can compile and link with gtk2... ";
1602		my $minversion = 7;
1603		unless ( $version =~ m/^2\.(\d+)/ && $1 > $minversion ) {
1604			printlog "no, need at least v2.$minversion.0\n";
1605			return;
1606		}
1607		$use_gtk3 = 0;
1608	}
1609	# now, try to compile with GTK. I've got lots of CPAN build failures
1610	# because GTK wasn't willing to compile or god knows what.
1611	unless (compile( "#include <gtk/gtk.h>\nint main() { return 0; }\n")) {
1612		printlog "no\n";
1613		$END .= <<WARNING;
1614
1615** Warning: not compiling with GTK2. Fonts and colors will look
1616differently from Gnome environment. You might want to install
1617'libgtk+-3.0-dev' or 'libgtk+-2.0-dev' package.
1618
1619WARNING
1620		return;
1621	}
1622	if ( $^O eq 'darwin') {
1623		printlog "without X11... ";
1624		$DEFINES{WITH_GTK_NONX11} = 1 unless compile( "#include <gdk/gdkx.h>\nint main() { return 0; }\n");
1625	}
1626	printlog "yes\n";
1627	$DEFINES{WITH_GTK} = $use_gtk3 ? 3 : 2;
1628	$cmd_options{$use_gtk3 ? 'WITH_GTK3' : 'WITH_GTK2'} = 1;
1629}
1630
1631sub setup_x11_extension
1632{
1633	my $name = shift;
1634
1635	my $define = 'HAVE_X11_EXTENSIONS_' . uc($name) . '_H';
1636	if ( $use_pkgconfig ) {
1637		$DEFINES{$define} = pkgconfig($name) ? 1 : undef;
1638		return;
1639	}
1640
1641	my $libname = ucfirst $name;
1642	if ( have_header( "X11/extensions/$libname.h")) {
1643		printlog "Checking for presence of lib$libname... ";
1644		if ( defined find_lib( $libname, '', '')) {
1645			push @LIBS, $libname;
1646			printlog "yes\n";
1647		} else {
1648			$DEFINES{$define} = undef;
1649			printlog "no\n";
1650		}
1651	}
1652}
1653
1654sub setup_xlibs
1655{
1656	have_header( "X11/extensions/shape.h", "X11/X.h", "X11/Xlib.h", "X11/Xutil.h");
1657	have_header( "X11/extensions/XShm.h", "X11/X.h", "X11/Xlib.h", "X11/Xutil.h");
1658
1659	setup_xft() if $cmd_options{WITH_XFT};
1660	setup_harfbuzz() if $cmd_options{WITH_HARFBUZZ};
1661	$END .= <<NO_HARFBUZZ unless $DEFINES{WITH_HARFBUZZ};
1662
1663** Warning: Prima compiled without harfbuzz will not be able
1664to render proper ligatured text, f.ex. Arabic, Hindi, Tibetan etc etc.
1665Consider fixing your installation.
1666
1667NO_HARFBUZZ
1668	$cmd_options{WITH_ICONV} = 0 unless $cmd_options{WITH_XFT}; # iconv is used for xft only
1669	setup_iconv() if $cmd_options{WITH_ICONV};
1670	setup_gtk() if $cmd_options{WITH_GTK2} || $cmd_options{WITH_GTK3};
1671	setup_x11_extension($_) for qw(xrandr xcomposite);
1672
1673	if ( $use_pkgconfig ) {
1674		$DEFINES{HAVE_X11_XCURSOR_XCURSOR_H} = 1 if pkgconfig('xcursor');
1675	} elsif ( have_header( "X11/Xcursor/Xcursor.h", "X11/Xlib.h")) {
1676		printlog "Checking for presence of libXcursor... ";
1677		if ( defined find_lib( 'Xcursor', '', '')) {
1678			printlog "yes\n";
1679			push @LIBS, 'Xcursor';
1680		} else {
1681			printlog "no\n";
1682			$DEFINES{HAVE_X11_XCURSOR_XCURSOR_H} = undef;
1683		}
1684	}
1685
1686	printlog "Using Xft library\n" if $cmd_options{WITH_XFT};
1687	printlog "Using fribidi library\n" if $cmd_options{WITH_FRIBIDI};
1688	printlog "Using harfbuzz library\n" if $cmd_options{WITH_HARFBUZZ};
1689	printlog "Using iconv library\n" if $cmd_options{WITH_ICONV};
1690	printlog "Using gtk2 library\n" if $cmd_options{WITH_GTK2};
1691	printlog "Using gtk3 library\n" if $cmd_options{WITH_GTK3};
1692	printlog "Using Xrandr library\n" if $DEFINES{HAVE_X11_EXTENSIONS_XRANDR_H};
1693}
1694
1695sub setup_macosx
1696{
1697	if ( $macos_x11_path ) {
1698		my %remove = map { $_ => 1 } @{ $macos_x11_path // [] };
1699		@LIBPATH = grep { !exists $remove{$_} } @LIBPATH;
1700		push @LIBPATH, @{ $macos_x11_path // [] };
1701	}
1702
1703	return unless $cmd_options{WITH_COCOA};
1704	printlog "Can compile with Cocoa...";
1705	my $old_ldflags = $LDFLAGS;
1706
1707	$LDFLAGS .= ' -framework Cocoa';
1708	my $ok = compile(<<TEXT);
1709#import <ApplicationServices/ApplicationServices.h>
1710int main() {
1711	printf("%x\\n", (void*)CGColorSpaceCreateDeviceRGB());
1712	return 0;
1713}
1714TEXT
1715	unless ($ok) {
1716		printlog "no\n";
1717		$LDFLAGS = $old_ldflags;
1718		return;
1719	}
1720
1721	printlog "yes\n";
1722	$DEFINES{WITH_COCOA} = 1;
1723}
1724
1725sub generate_win32_def
1726{
1727	open PRIMADEF, ">$DEFFILE" or die "Cannot create $DEFFILE: $!";
1728	print PRIMADEF <<EOF;
1729LIBRARY Prima
1730EXPORTS
1731EOF
1732	if ( $compiler_type eq 'bcc32') {
1733		print PRIMADEF map { "\t_$_\n\t$_=_$_\n"} @Prima_exports;
1734	}
1735	else {
1736		print PRIMADEF map { "\t$_\n\t_$_ = $_\n"} @Prima_exports;
1737	}
1738	close PRIMADEF;
1739}
1740
1741sub suck_symbols
1742{
1743	my $fn = shift;
1744	open F, $fn or die "Cannot open $fn:$!\n";
1745	local $/;
1746	my $x = <F>;
1747	close F;
1748	return ( $x =~ m/\bextern\s+\w+(?:\s*\*\s*)?\s+(\w+)\s*\(.*?;/gs );
1749}
1750
1751sub setup_exports
1752{
1753	@Prima_exports = qw(
1754boot_Prima build_dynamic_vmt build_static_vmt call_perl call_perl_indirect
1755clean_perl_call_method clean_perl_call_pv create_mate create_object
1756ctx_remap_def cv_call_perl duplicate_string eval gimme_the_mate
1757gimme_the_vmt kind_of prima_kill_zombies notify_perl Object_create Object_destroy parse_hv
1758plist_create plist_destroy prima_mallocz pop_hv_for_REDEFINED protect_object
1759push_hv push_hv_for_REDEFINED query_method sv_call_perl sv_query_method
1760unprotect_object perl_error exception_remember exception_block exception_check_raise
1761exception_charged
1762);
1763	push @Prima_exports, grep { /^(apc|list|prima)/ } suck_symbols('include/apricot.h');
1764	push @Prima_exports, suck_symbols('include/img.h');
1765	push @Prima_exports, suck_symbols('include/img_conv.h');
1766	generate_win32_def() if $Win32;
1767}
1768
1769sub setup_codecs
1770{
1771	# see if Prima::codecs:: is installed
1772	my ( $prereq, $have_binary_prereq);
1773	$prereq = 'win32' if $Win32 and not $cygwin;
1774	$prereq = 'win64' if $Win64 and not $cygwin;
1775	if ( $prereq) {
1776		printlog "Checking for Prima::codecs::$prereq... ";
1777		eval "use Prima::codecs::$prereq;";
1778		unless ( $@) {
1779			printlog "yes\n";
1780			$have_binary_prereq++;
1781			my $f = $INC{"Prima/codecs/$prereq.pm"};
1782			$f =~ s/.pm$//;
1783			push @LIBPATH, "$f/lib";
1784			push @INCPATH, "$f/include";
1785
1786		} else {
1787			printlog "no\n";
1788		}
1789	}
1790
1791	# finding image codecs
1792	my %libs = map { $_ => 1 } @LIBS;
1793	my @codecs;
1794	my @builtin_codecs;
1795	while ( <img/codec_*.c>) {
1796		if ( m/codec_(bmp|X11)/) {
1797			push @builtin_codecs, $1;
1798		} else {
1799			push @codecs, $_;
1800		}
1801	}
1802
1803	my @codec_libpath = $Config{installsitearch};
1804	my @warn_codecs;
1805	my $webp_version;
1806	CODEC: for my $cx ( @codecs) {
1807		my @inc;
1808		my $foundlib;
1809		$cx =~ m/codec_(.*)\.c$/i;
1810		my ( $fn, $lib, $codec) = ( $cx, $1, $1);
1811
1812		# First check if pkg-config can help us here. Not necessarily it can, not all
1813		# graphic libs have .pc files. But if it can, it helps greatly with dll hell.
1814		if ( $use_pkgconfig ) {
1815			my $found;
1816			if ( $codec eq 'webp') {
1817				if (pkgconfig('libwebp') && pkgconfig('libwebpdemux') && pkgconfig('libwebpmux')) {
1818					$found = 1;
1819					$webp_version = $1 * 0x10000 + $2 * 0x100 + $3
1820						if $MODVERSIONS{libwebp} =~ /^(\d+).(\d+).(\d+)/;
1821				}
1822			} elsif ( $codec eq 'png') {
1823				$found = 1 if pkgconfig('libpng');
1824			} elsif ( $codec eq 'tiff') {
1825				$found = 1 if pkgconfig('libtiff-5') || pkgconfig('libtiff-4');
1826			} elsif ( $codec eq 'Xpm') {
1827				$found = 1 if pkgconfig('xpm');
1828			} # gif and jpeg -- I've never seen yet these libs shipped with .pc file, so don't check them so far
1829
1830			if ( $found ) {
1831				push( @ACTIVE_CODECS, $codec);
1832				next;
1833			}
1834		}
1835
1836		next unless open F, $fn;
1837		while(<F>) {
1838			push @inc, $_ if m/^\s*#include\s*\</;
1839		}
1840		close F;
1841
1842		# do we have a versioned inc/lib from dependency hell?
1843		my $version = '';
1844		if (
1845			( $codec ne 'X11' ) &&
1846			( my @versioned = grep { /$codec\d+$/ } @INCPATH )
1847		) {
1848			$versioned[0] =~ /$codec(\d+)$/;
1849			$version = $1;
1850			$lib .= $1;
1851		}
1852
1853	AGAIN:
1854		printlog "Checking for $codec$version library... ";
1855		if (
1856			$libs{$lib} ||
1857			defined ( $foundlib = find_lib( $lib, join('', @inc), '', @codec_libpath))
1858		) {
1859			if ( defined $foundlib and length $foundlib) {
1860				push @LIBPATH, $foundlib;
1861				@codec_libpath = ();
1862			}
1863			push( @ACTIVE_CODECS, $codec);
1864
1865			printlog "yes";
1866			if ($codec eq 'webp') {
1867				my @addlib;
1868				for my $lib2 ('webpdemux', 'webmux') {
1869					if ( defined find_lib($lib2,join('', @inc), '', @codec_libpath)) {
1870						push @addlib, $lib2 unless $libs{$lib2};
1871					} else {
1872						printlog ", but $lib2 not found, skipping\n";
1873						@addlib = ();
1874						pop @ACTIVE_CODECS;
1875						$PASSIVE_CODECS{$fn} = 1;
1876						pop @LIBPATH if defined $foundlib and length $foundlib;
1877						next CODEC;
1878					}
1879				}
1880				unshift( @LIBS, @addlib );
1881			}
1882			# In gcc, order of libs matters. libXpm requires libgdi32, and
1883			# has to be mentioned _after_ it to work.
1884			unshift( @LIBS, $lib) unless $libs{$lib};
1885			printlog ", in $foundlib" if defined($foundlib) and length($foundlib);
1886			printlog "\n";
1887		} elsif ( $codec eq 'X11') {
1888			$DEFINES{EMULATE_X11_CODEC} = 1;
1889			push( @ACTIVE_CODECS, $codec);
1890			printlog "no, using built-in\n";
1891		} elsif ( length $version) {
1892			$lib = $codec;
1893			$version = '';
1894			printlog "no\n";
1895			goto AGAIN;
1896		} else {
1897			$PASSIVE_CODECS{$fn} = 1;
1898			push @warn_codecs, $codec;
1899			printlog "no\n";
1900		}
1901	}
1902
1903
1904	# check supported versions
1905	if ( grep {/webp/} @ACTIVE_CODECS) {
1906		$webp_version //= compile_and_run(<<'VER');
1907#include <stdio.h>
1908#include <webp/decode.h>
1909int main() {
1910	printf("%d\n", WebPGetDecoderVersion());
1911	return 0;
1912}
1913VER
1914		if (( $webp_version // 0) < 1537 ) { # 0.6.1
1915			printlog "** Warning: webp version ".
1916				((defined($webp_version) ?
1917					"is too low, 0.6.1 at least is needed" :
1918					"cannot be determined")).
1919				", skipping\n";
1920			@ACTIVE_CODECS = grep { !/webp/ } @ACTIVE_CODECS;
1921			$PASSIVE_CODECS{'img/codec_webp.c'} = 1;
1922		}
1923	}
1924
1925	unless ( @ACTIVE_CODECS) {
1926		$binary_prereq = $prereq;
1927		$PREREQ{"Prima::codecs::$prereq"} = 0;
1928		$END .= <<NOCODECS;
1929
1930** No image codecs found.
1931
1932Note that in this configuration Prima will not be
1933able to work with graphic files. Please follow the
1934instructions in README file.
1935
1936NOCODECS
1937		$END .= <<BROKEN_CODECS if $have_binary_prereq;
1938
1939** Prima::codecs::$binary_prereq is found in
1940$Config{installsitearch}, but is broken. Please reinstall it.
1941
1942BROKEN_CODECS
1943		$END .= <<NOCODECS_BIN if $binary_prereq;
1944
1945If you are under CPAN shell and are asked to install
1946Prima::codecs::$binary_prereq dependency, do so. Otherwise,
1947install it manually.
1948
1949NOCODECS_BIN
1950
1951		$END .= <<NOCODECS_CYGWIN if $cygwin;
1952
1953Install these libraries and re-run Makefile.PL
1954
1955NOCODECS_CYGWIN
1956	} elsif ( @warn_codecs) {
1957		$END .= <<NOCODECS;
1958
1959** Warning: the following image libraries weren't found:
1960
1961@warn_codecs
1962
1963Note that in this configuration Prima will not be
1964able to work with the corresponding image formats.
1965Please follow the instructions in README file.
1966
1967NOCODECS
1968	}
1969	push @ACTIVE_CODECS, @builtin_codecs;
1970}
1971
1972sub create_codecs_c
1973{
1974	printlog "Creating img/codecs.c\n";
1975	open F, "> img/codecs.c" or die "cannot open img/codecs.c:$!\n";
1976
1977	my $def1 = join("\n", map { "extern void apc_img_codec_$_(void);"} @ACTIVE_CODECS);
1978	my $def2 = join("\n", map { "\tapc_img_codec_$_();"} @ACTIVE_CODECS);
1979
1980	print F <<CONTENT;
1981/*
1982  This file was automatically generated.
1983  Do not edit, you'll loose your changes anyway.
1984*/
1985
1986#include "img.h"
1987
1988#ifdef __cplusplus
1989extern "C" {
1990#endif
1991
1992$def1
1993
1994void
1995prima_cleanup_image_subsystem(void)
1996{
1997	apc_img_done();
1998}
1999
2000void
2001prima_init_image_subsystem(void)
2002{
2003	apc_img_init();
2004$def2
2005}
2006
2007#ifdef __cplusplus
2008}
2009#endif
2010
2011CONTENT
2012
2013	close F;
2014}
2015
2016sub create_config_h
2017{
2018	my $config_dir = "include/generic";
2019	my $config_h = "$config_dir/config.h";
2020	printlog "Creating $config_h\n";
2021	unless ( -d "$config_dir") {
2022		mkdir $config_dir, 0777;
2023	}
2024	open CONFIG, ">$config_h" or die "Creation of $config_h failed: $!";
2025	print CONFIG <<EOF;
2026#ifndef __GENERIC_CONFIG_H__
2027#define __GENERIC_CONFIG_H__
2028EOF
2029	foreach my $define ( sort keys %DEFINES) {
2030		print CONFIG "#undef $define\n";
2031		print CONFIG "#define $define $DEFINES{ $define}\n" if defined $DEFINES{ $define};
2032	}
2033	print CONFIG <<EOF;
2034#endif
2035EOF
2036	close CONFIG;
2037}
2038
2039sub _quote
2040{
2041	my $name = shift;
2042	$name =~ s/'/\\'/g;
2043	return \ "'$name'";
2044}
2045
2046sub _quotepath { _quote(@_) }
2047
2048sub create_config_pm
2049{
2050	my $cwd = cwd;
2051	my $ifs = '/';
2052
2053	# includes
2054	my @ip = @INCPATH;
2055	$ip[0] = "$cwd${ifs}include";
2056	$ip[1] = "$cwd${ifs}include${ifs}generic";
2057	my $ipp = join(',', map {"\'$_\'"} @ip);
2058	my $inc    = join(' ', map { "-I$_" } @ip);
2059	$ip[0] = '$(lib)' . "/Prima/CORE";
2060	$ip[1] = '$(lib)' . "/Prima/CORE/generic";
2061	my $ippi = join(',', map {"\'$_\'"} @ip);
2062	my $inci = join(' ', map { "-I$_" } @ip);
2063
2064	# libs
2065	my @libpath = @LIBPATH;
2066	my @libs    = @LIBS;
2067	unless ( $unix or gcc) {
2068		push @libpath, "$cwd/auto/Prima";
2069		push @libs, "Prima$LD_LIB_EXT";
2070	}
2071	my $libpath = join( ',', map {"'$_'"} @libpath);
2072	unless ( $unix or gcc) {
2073		$libpath[-1] = '$(lib)/auto/Prima';
2074	}
2075	my $libpathi = join( ',', map {"'$_'"} @libpath);
2076	my $ldlibs  = join( ',', map {"'$_'"} @libs);
2077
2078	my ($libs, $libsi) = ('','');
2079	if ( $cygwin) {
2080		$libs  = "-L$cwd/blib/arch/auto/Prima -lPrima";
2081		$libsi = '-L$(lib)/auto/Prima -lPrima';
2082	} elsif ( $Win32) {
2083		$libs  = "$cwd/blib/arch/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT";
2084		$libsi = '$(lib)' . "/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT";
2085	}
2086
2087	my $cc_openmp = $cmd_options{WITH_OPENMP} ? $OPENMP : '';
2088
2089	open F, "> Prima/Config.pm" or die "cannot open Prima/Config.pm:$!\n";
2090	print F <<CONFIG;
2091# This file was automatically generated.
2092# Do not edit, you'll loose your changes anyway.
2093package Prima::Config;
2094use strict;
2095use warnings;
2096use vars qw(%Config %Config_inst);
2097
2098%Config_inst = (
2099	incpaths              => [ $ippi ],
2100	gencls                => '\$(bin)${ifs}prima-gencls$SCRIPT_EXT',
2101	tmlink                => '\$(bin)${ifs}prima-tmlink$SCRIPT_EXT',
2102	libname               => '\$(lib)${ifs}auto${ifs}Prima${ifs}${LIB_PREFIX}Prima$LIB_EXT',
2103	dlname                => '\$(lib)${ifs}auto${ifs}Prima${ifs}Prima.$Config{dlext}',
2104	ldpaths               => [$libpathi],
2105
2106	inc                   => '$inci',
2107	libs                  => '$libsi',
2108);
2109
2110%Config = (
2111	ifs                   => '\\$ifs',
2112	quote                 => '\\$SHQUOTE',
2113	platform              => '$platform',
2114	incpaths              => [ $ipp ],
2115	gencls                => ${_quotepath("$cwd/blib/script/prima-gencls$SCRIPT_EXT")},
2116	tmlink                => ${_quotepath("$cwd/blib/script/prima-tmlink$SCRIPT_EXT")},
2117	scriptext             => ${_quote($SCRIPT_EXT)},
2118	genclsoptions         => '--tml --h --inc',
2119	cobjflag              => ${_quote($COUTOFLAG)},
2120	coutexecflag          => ${_quote($COUTEXEFLAG)},
2121	clinkprefix           => ${_quote($CLINKPREFIX)},
2122	clibpathflag          => ${_quote($CLIBPATHFLAG)},
2123	cdefs                 => [],
2124	libext                => ${_quote($LIB_EXT)},
2125	libprefix             => ${_quote($LIB_PREFIX)},
2126	libname               => ${_quotepath("$cwd/blib/arch/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT")},
2127	dlname                => ${_quotepath("$cwd/blib/arch/auto/Prima/Prima.$Config{dlext}")},
2128	ldoutflag             => ${_quote($LDOUTFLAG)},
2129	ldlibflag             => ${_quote($LDLIBFLAG)},
2130	ldlibpathflag         => ${_quote($CLIBPATHFLAG)},
2131	ldpaths               => [$libpath],
2132	ldlibs                => [$ldlibs],
2133	ldlibext              => ${_quote($LD_LIB_EXT)},
2134	inline                => ${_quote($DEFINES{__INLINE__})},
2135	dl_load_flags         => $DL_LOAD_FLAGS,
2136	optimize              => '$OPTIMIZE',
2137	openmp                => '$cc_openmp',
2138
2139	inc                   => '$inc',
2140	define                => '',
2141	libs                  => '$libs',
2142);
2143
21441;
2145CONFIG
2146	close F;
2147}
2148
2149sub create_par_list
2150{
2151	open F, ">", "utils/par.txt" or die "Cannot open utils/par.txt:$!";
2152	find( sub {
2153		return unless -f;
2154		return if /\.p[lm]$/i || /^(VB|prima-cfgmaint)$/;
2155		my $d = $File::Find::dir;
2156		return if $d =~ /examples/;
2157		print F "$d/$_\n";
2158	}, 'Prima');
2159	close F;
2160}
2161
2162# executed from inside makefiles
2163
2164sub command_postinstall
2165{
2166	my %opt = map { split /=/, $_, 2 } @_;
2167
2168	if ( $opt{slib} ) {
2169		my $f = "$opt{dest}/auto/Prima/$opt{slib}";
2170		open F, ">", $f or warn "** warning: Cannot write to a fake lib '$f': Prima extensions won't build\n";
2171		close F;
2172	}
2173
2174	my $fn_cfg = "$opt{dest}/Prima/Config.pm";
2175	print "Updating config $fn_cfg\n";
2176	open F, $fn_cfg or die "cannot open $fn_cfg:$!\n";
2177	open FF, "> $fn_cfg.tmp" or die "cannot open $fn_cfg.tmp:$!\n";
2178	my ( $c_state, $ci_state) = (0,0);
2179	my (%ci, %vars);
2180
2181	%vars = %opt;
2182	if ( $^O =~ /mswin32/i) {
2183		s/\//\\/g for values %vars;
2184	}
2185
2186	print FF <<HEADER;
2187# This file was automatically generated.
2188package Prima::Config;
2189use vars qw(\%Config);
2190
2191my \$bin = q($opt{bin});
2192
2193# Determine lib based on the location of this module
2194use File::Basename qw(dirname);
2195use File::Spec;
2196my \$lib = File::Spec->catfile(dirname(__FILE__), '..');
2197
2198%Config = (
2199HEADER
2200	while ( <F>) {
2201		if ( $ci_state == 0) {
2202			if ( m/\%Config_inst = \(/) {
2203				$ci_state = 1;
2204			}
2205		} elsif ( $ci_state == 1) {
2206			if ( m/^\);/) {
2207				$ci_state = 0;
2208			} elsif ( m/^\s*(\S+)\s*/ ) {
2209				my $k = $1;
2210				s/\$\((\w+)\)/\$$1/g;
2211				s/'/"/g;
2212				s{\\}{\\\\}g;
2213				$ci{$k} = $_;
2214			}
2215		}
2216		if ( $c_state == 0) {
2217			if ( m/\%Config = \(/) {
2218				$c_state = 1;
2219			}
2220		} elsif ( $c_state == 1) {
2221			if ( m/^\);/) {
2222				$c_state = 0;
2223			} else {
2224				if ( m/^\s*(\S+)\s*/ && exists $ci{$1}) {
2225					print FF $ci{$1};
2226				} else {
2227					print FF $_;
2228				}
2229			}
2230		}
2231	}
2232print FF <<FOOTER;
2233);
2234
22351;
2236FOOTER
2237	close FF;
2238	close F;
2239	unlink $fn_cfg;
2240	rename "$fn_cfg.tmp", $fn_cfg;
2241}
2242
2243sub command_dl
2244{
2245	$DL_LOAD_FLAGS = shift;
2246	my $f = "blib/lib/Prima.pm";
2247
2248	open F, $f or die "cannot open $f:$!\n";
2249	local $/;
2250	my $ct = <F>;
2251	close F;
2252
2253	$ct =~ m/dl_load_flags\s*\{\s*0x0(\d)/;
2254	return if $1 eq $DL_LOAD_FLAGS;
2255
2256	print "Setting dl_load_flags=$DL_LOAD_FLAGS in $f\n";
2257	$ct =~ s/(dl_load_flags\s*\{\s*)0x00/${1}0x0$DL_LOAD_FLAGS/;
2258	# open_rw(\*F, $f);
2259	open F, "> $f.tmp" or die "Cannot open $f.tmp:$!";
2260	print F $ct;
2261	close F;
2262	unlink $f;
2263	rename "$f.tmp", $f;
2264}
2265
2266sub command_bindist
2267{
2268	$CWD = cwd();
2269	$DISTNAME = shift;
2270
2271	sub clean_dist
2272	{
2273		my @dirs;
2274		return unless -d $DISTNAME;
2275		print "Cleaning...\n";
2276		finddepth( sub {
2277			my $f = "$File::Find::dir/$_";
2278			-d($f) ? push(@dirs, $f) : unlink($f);
2279		}, "$CWD/$DISTNAME");
2280		rmdir $_ for sort {length($b) <=> length($a)} @dirs;
2281		rmdir $DISTNAME;
2282	}
2283
2284	sub cleanup
2285	{
2286		clean_dist;
2287		warn("$_[0]:$!\n") if defined $_[0];
2288		exit(0);
2289	}
2290
2291	clean_dist;
2292	my @dirs;
2293	my @files;
2294	finddepth( sub {
2295		return if $_ eq '.' ||
2296			($_ eq 'Makefile' && $File::Find::dir eq $CWD) ||
2297			m/^\./;
2298		return if /\.(pdb|ncb|opt|dsp|dsw)$/i; # MSVC
2299		my $f = "$File::Find::dir/$_";
2300		return if $f =~ /include.generic|\.git|\.swp|\.log|blib|dll.base|dll.exp|Prima.bs|Prima.def/;
2301		return if $f =~ /\.(c|cls|h)$/i;
2302		return if $f =~ /$CWD.(img|include|win32|unix|Makefile.old)/i;
2303		if ( -d $f) {
2304			$f =~ s/^$CWD/$DISTNAME/;
2305			push @dirs, $f;
2306		} else {
2307			return if $f =~ m/$Config{_o}$/;
2308			push @files, $f;
2309		}
2310	}, $CWD);
2311
2312	print "Creating directories...\n";
2313	push @dirs, "$DISTNAME/auto/Prima";
2314	for ( @dirs) {
2315		next if -d $_;
2316		cleanup( "Can't mkdir $_") unless mkpath $_;
2317	}
2318
2319	print "Copying files...\n";
2320	for ( @files) {
2321		my $f = $_;
2322		$f =~ s/^$CWD/$DISTNAME/;
2323		cleanup("Error copying $_ to $_") unless copy $_, $f;
2324	}
2325	for (<blib/arch/auto/Prima/*>) {
2326		next if m/(\.exists|Prima\.bs|Prima\.pdb)$/;
2327		my $f = $_;
2328		$f =~ s[^blib/arch][$DISTNAME];
2329		cleanup("Error copying $_ to $_") unless copy $_, $f;
2330	}
2331	if ($^O eq 'cygwin') {
2332		system "strip $DISTNAME/auto/Prima/Prima.$Config{dlext}" ; # it's 27 MB!
2333		$cygwin_fake_Slib = 'SlibPrima' . ( $Config{lib_ext} || '.a' );
2334		open F, '>', "$DISTNAME/auto/Prima/$cygwin_fake_Slib";
2335		close F;
2336	}
2337
2338	my $zipname = "$DISTNAME.zip";
2339	unlink $zipname;
2340	unlink "$DISTNAME/$zipname";
2341	system "zip -r $zipname $DISTNAME";
2342
2343	clean_dist;
2344}
2345
2346sub command_cpbin
2347{
2348	my ($from, $to) = @_;
2349	local $/;
2350	open FROM, '<', $from or die "Cannot open $from:$!\n";
2351	open TO, '>',   $to or die "Cannot open $to:$!\n";
2352	print TO "#!$Config{perlpath} -w\n";
2353	print TO <FROM>;
2354	close TO;
2355	close FROM;
2356	chmod 0755, $to;
2357}
2358
2359# EU::MM overridden stuff
2360
2361sub c_o
2362{
2363	my $t = shift-> SUPER::c_o(@_);
2364	my $re1 = '\.c\$\(OBJ_EXT\)\s*:\n\t.*';
2365	my $ending = '$*$(OBJ_EXT)';
2366	unless ( $t =~ /$re1\Q$ending\E/ ) {
2367		$t =~ s/($re1)/$1 $COUTOFLAG$ending/;
2368	}
2369	return $t;
2370}
2371
2372sub special_targets
2373{
2374	my $self = shift;
2375	my $t = $self->SUPER::special_targets(@_);
2376	$t .= <<RERUN if $binary_prereq and not $cmd_options{AUTOMATED_RUN};
2377all ::
2378\t\@echo Rebuilding Makefile...
2379\t\@\$(RM_F) Makefile
2380\t\@$^X Makefile.PL $ARGV_STR AUTOMATED_RUN=1
2381\t\@$Config{make}
2382
2383RERUN
2384	return $t;
2385}
2386
2387sub postamble
2388{
2389	my $self = shift;
2390	my $t = $self->SUPER::postamble(@_);
2391
2392	my @alltml;
2393	my @alltmldeps;
2394
2395	my $showlog = '';
2396
2397	# that's because CPAN doesn't save Makefile.PL output, and I want it for tests
2398	if ( $ENV{AUTOMATED_TESTING} ) {
2399		$showlog = 'showlog';
2400		$t .= <<SHOWMORE;
2401
2402showlog:
2403\t\$(NOECHO) $^X -e ${SHQUOTE}open F,q(makepl.log);print <F>${SHQUOTE}
2404\t\$(NOECHO) \$(TOUCH) showlog
2405
2406SHOWMORE
2407	}
2408
2409    	printlog "Finding .cls dependencies...\n";
2410
2411	for my $clsfile ( @cls_files) {
2412		my ( $base ) = $clsfile =~ m/^src\/(.*?).cls$/;
2413		my $ancestors = join(' ', map { "include/generic/$_.h src/$_.cls" } gencls( $clsfile, depend => 1, incpath => ['src']));
2414	  	$t .= <<H;
2415
2416include/generic/$base.h: \$(FIRST_MAKEFILE) $showlog src/$base.cls $ancestors
2417\t$^X -I. utils/prima-gencls.pl --inc --h -Isrc --tml $clsfile include/generic
2418
2419H
2420		push @alltml, "include/generic/$base.tml";
2421		push @alltmldeps, "include/generic/$base.h";
2422		$showlog = '';
2423	}
2424
2425	$t .= <<H;
2426include/generic/thunks.tinc: \$(FIRST_MAKEFILE) @alltmldeps
2427\t$^X utils/prima-tmlink.pl -Iinclude/generic -oinclude/generic/thunks.tinc @alltml
2428
2429H
2430
2431	my %dirs;
2432	for my $cfile ( @c_files ) {
2433        	my ( $dir ) = ( $cfile =~ /^(\w+)\// );
2434        	$dir = 'root directory' unless $dir;
2435		printlog "Finding .c dependencies in $dir...\n" unless $dirs{$dir}++;
2436
2437		my ( $base ) = $cfile =~ m/^(.*?).c$/;
2438		my @deps = find_cdeps( $cfile );
2439		$t .= <<H
2440
2441$base$Config{_o}: \$(FIRST_MAKEFILE) $cfile @deps
2442
2443H
2444	}
2445
2446	my ( $pm_deinstall, $pm_deinstall_dir, %pm_deinstall_dir) = ('');
2447	my @rm;
2448	for ( values %ALL_PM_INSTALL ) {
2449		my $f = $_;
2450		$f =~ s/INST_LIBDIR/DESTINSTALLSITEARCH/;
2451		push @rm, $f;
2452		$f =~ s/[-\w\.]*$//;
2453		$pm_deinstall_dir{$f} = 1;
2454	}
2455	$pm_deinstall_dir{'$(DESTINSTALLSITEARCH)/Prima/sys'}  = 1;
2456	$pm_deinstall_dir{'$(DESTINSTALLSITEARCH)/auto/Prima'} = 1;
2457	for ( values %ALL_MAN_INSTALL ) {
2458		my $f = $_;
2459		$f =~ s/INST_MAN3DIR/DESTINSTALLSITEMAN3DIR/;
2460		push @rm, $f;
2461	}
2462	push @rm,
2463		'$(DESTINSTALLSITEMAN3DIR)/prima-gencls.$(MAN3EXT)',
2464		'$(DESTINSTALLSITEMAN1DIR)/VB.$(MAN1EXT)',
2465		'$(DESTINSTALLSITEMAN1DIR)/prima-cfgmaint.$(MAN1EXT)',
2466		'$(DESTINSTALLSITEARCH)/auto/Prima/' . $LIB_PREFIX . '$(BASEEXT)$(LIB_EXT)',
2467		'$(DESTINSTALLSITEARCH)/auto/Prima/$(DLBASE).$(DLEXT)',
2468		'$(DESTINSTALLSITEARCH)/auto/Prima/$(BASEEXT).bs',
2469		'$(DESTINSTALLSITEARCH)/auto/Prima/Prima.exp',
2470		'$(DESTINSTALLSITEARCH)/auto/Prima/Prima.pdb',
2471		;
2472	while (@rm) {
2473		my @part = splice(@rm, 0, 20);
2474		$pm_deinstall .= "\t\$(ABSPERL) -e ${SHQUOTE}unlink \@ARGV${SHQUOTE} @part\n";
2475	}
2476	chomp $pm_deinstall;
2477	$pm_deinstall_dir =
2478		"\t\$(ABSPERL) -e ${SHQUOTE}rmdir for \@ARGV${SHQUOTE} ".
2479		join( ' ', sort { length $b <=> length $a } keys %pm_deinstall_dir)
2480		;
2481	$t .= <<H;
2482
2483bindist: all
2484\t$^X $0 --bindist $DISTNAME
2485
2486devclean:
2487\t\$(RM_F) src/*$Config{_o} img/*$Config{_o} $platform/*$Config{_o}
2488
2489deinstall:
2490$pm_deinstall
2491$pm_deinstall_dir
2492
2493H
2494
2495	if ($unix or $cygwin) {
2496		$t .= <<H for @exe_files; # .pl -> .
2497$_: $_.pl
2498\t$^X $0 --cpbin $_.pl $_
2499
2500H
2501	}
2502
2503	return $t;
2504}
2505
2506sub dynamic_lib
2507{
2508	my $self = shift;
2509	my $t = $self->SUPER::dynamic_lib(@_);
2510	if ( $win32_use_dlltool ) {
2511		my $lib  = "blib/arch/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT";
2512		my $line = "\t$win32_use_dlltool -l $lib -d Prima.def -D PRIMA.$Config{dlext} \$\@\n";
2513		$END .= <<BAD_MAKEFILE unless $t =~ s/(^\$\(INST_DYNAMIC\)\s*\:.*?\n(?:\t.*?\n)*)/$1$line/m;
2514
2515** Warning: expected format of Makefile generated by ExtUtils::MakeMaker is
2516changed, so making of library Prima.a will not be performed correctly.
2517Prima will run OK, but modules dependent on it may not build.
2518Please notify the author by sending a report with Makefile and
2519noting that ExtUtils\:\:MakeMaker version $ExtUtils::MakeMaker::VERSION was used.
2520
2521BAD_MAKEFILE
2522
2523	}
2524	return $t;
2525}
2526
2527# generate Prima.def ourselves - too many symbols, EU::MM dies with "command line too long"
2528sub dlsyms { '' }
2529
2530sub install
2531{
2532	my $self = shift;
2533	my $t = $self->SUPER::install(@_);
2534	my $n = $t =~ s[
2535		(pure_\w+_install.*?)                       # 1
2536		(INST_ARCHLIB\)"?\s+"?)\$\(DEST(\w+)\)(.*?)     # 2,3,4
2537		(INST_BIN\)"?\s+"?)\$\(DEST(\w+)\)(.*?)         # 5,6,7
2538		(.*?)                                       # 8
2539		\n\n
2540	][
2541		"$1".
2542		"$2\$(DEST$3)$4".
2543		"$5\$(DEST$6)$7$8".
2544		"\n\t\$(NOECHO) \$(ABSPERL) $0 --postinstall ".
2545			"dest=\$(DEST$3) bin=\$($6) slib=$cygwin_fake_Slib\n\n"
2546	]xgse;
2547
2548	$END .= <<BAD_MAKEFILE if $n != 3;
2549
2550** Warning: expected format of Makefile generated by ExtUtils::MakeMaker
2551is changed, so post-installation steps may not be performed correctly.
2552Prima will run OK, but modules dependent on it may not build.
2553Please notify the author by sending a report with Makefile and
2554noting that ExtUtils\:\:MakeMaker version $ExtUtils::MakeMaker::VERSION was used.
2555
2556BAD_MAKEFILE
2557
2558	return $t;
2559}
2560
2561sub linkext { shift->SUPER::linkext .  "\t\$(NOECHO) \$(ABSPERL) $0 --dl $DL_LOAD_FLAGS\n\n" }
2562
2563WriteMakefile(
2564	NAME              => 'Prima',
2565	VERSION_FROM      => 'Prima.pm',
2566	ABSTRACT_FROM     => 'Prima.pm',
2567	AUTHOR            => 'Dmitry Karasik <dmitry@karasik.eu.org>',
2568	PM                => MY::orderedhash->tie(\%ALL_PM_INSTALL),
2569	OPTIMIZE          => $OPTIMIZE,
2570	LDDLFLAGS         => $passthru_options{LDDLFLAGS},
2571	PREREQ_PM         => \%PREREQ,
2572	OBJECT            => "@o_files",
2573	INC               =>
2574		join(' ', map { "-I$_" } @INCPATH ).
2575		' ' . $cmd_options{EXTRA_CCFLAGS},
2576	LIBS              => [
2577		$cmd_options{EXTRA_LDFLAGS} . ' ' .
2578		$LDFLAGS . ' ' .
2579		':nosearch ' .
2580		join(' ', map { "-L$_" } @LIBPATH) . ' ' .
2581		join(' ', map { "-l$_" } @LIBS),
2582	],
2583	LICENSE           => 'FREEBSD',
2584	EXE_FILES         => \@exe_files,
2585	PL_FILES          => {},
2586	MAN3PODS          => MY::orderedhash->tie(\%ALL_MAN_INSTALL),
2587	META_MERGE        => {
2588		resources => {
2589			homepage   => 'http://www.prima.eu.org/',
2590			repository => 'http://github.com/dk/Prima',
2591		},
2592		no_index  => {
2593			directory  => [qw(include t img unix win32)],
2594			file       => [qw(Makefile.PL ms_install.pl)],
2595		},
2596	},
2597        test => {TESTS => 't/*/*.t'},
2598	clean             => { FILES => "@target_clean" },
2599	MIN_PERL_VERSION  => 5.012,
2600);
2601
2602