#! /usr/bin/perl -w # # Copyright (c) 1997-2002 The Protein Laboratory, University of Copenhagen # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $Id: Makefile.PL,v 1.221 2008/11/08 23:19:02 dk Exp $ # BEGIN { unshift @INC, '.'; }; my $END; END { print $END if defined $END; }; require 5.00502; use strict; use Config; my %Config = %Config::Config; # original %Config is read-only use File::Find; use File::Basename; use File::Path; use File::Copy; use Cwd; use DynaLoader; use Prima::Gencls; use ExtUtils::Packlist; use vars qw( %make_trans @ovvars @path_expand_ovvars $dir_sep $path_sep @no_compat ); use vars @ovvars = qw( $CC $CFLAGS $CCFLAGS $CCCDLFLAGS $CDLFLAGS $C_FLAGS $CDEBUGFLAGS $CDLFLAGS $COUTOFLAG $COUTEXEFLAG $CINCPATHFLAG $CDEFFLAG $COMPONLYFLAG $CLIBPATHFLAG $CLINKPREFIX $LD $LDFLAGS $LD_FLAGS $LDOUTFLAG $LDLIBPATHFLAG $LDLIBFLAG $LIB $LIBOFLAG $OBJ_EXT $LIB_EXT $LIB_PREFIX $EXE_EXT $DL_EXT $SCRIPT_EXT @INCPATH @LIBPATH $LIBS $INC $PLATFORM $COMPILER $PREFIX $X11BASE $INSTALLSCRIPT $INSTALLSITEARCH $INSTALL_BASE $INSTALL_LIB $INSTALL_DL $INSTALL_EXAMPLES $INSTALL_MAN3 $INSTALL_MAN1 $TMPDIR $NULLDEV $MAKE $RM $SHQUOTE $MAKETYPE $DEFFILE $DISTNAME $DL_LOAD_FLAGS $DEBUG $WITH_XFT $WITH_ICONV $WITH_GTK2 $AUTOMATED_RUN $CYGWIN_X11 ); use vars @path_expand_ovvars = qw( @INCPATH @LIBPATH $INC $LIBS $COMPILER $PREFIX $X11BASE $INSTALLSCRIPT $INSTALLSITEARCH $INSTALL_BASE $INSTALL_LIB $INSTALL_DL $INSTALL_EXAMPLES $INSTALL_MAN3 $INSTALL_MAN1 $TMPDIR $MAKE $RM $DEFFILE ); @no_compat = qw( SITELIBEXP INSTALLDIRS PERLPREFIX SITEPREFIX VENDORPREFIX INST_ARCHLIB INSTALLARCHLIB INSTALLVENDORARCH INST_LIB INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB INST_BIN INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN INST_SCRIPT INSTALLSITESCRIPT INSTALLVENDORSCRIPT INST_MAN1DIR INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR INST_MAN3DIR INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR ); use vars qw( $CWD $Win32 $cygwin $NeedX11 $OS2 $OS2DLLF $useGC %cc_specs @LIBS %DEFINES %PASSIVE_CODECS @ACTIVE_CODECS %USER_VARS %USER_VARS_ADDONS %USER_VARS_LINKS %USER_DEFINES %USER_DEFINES_ADDONS %overrideable $ARGV_STR @alltml @alltmldeps @allclean @allrealclean @allojects %alldeps @allinstall @allbins @alldirs @allman @headers @footers @Makefile_deps $PrimaLib $PrimaTarget @Prima_exports $extralibs @executables $install_manuals $packlist %cache_find_files $binary_prereq $win32_use_dlltool ); my $see_makefile_log = "(see also makefile.log for details)"; sub print_config { foreach my $var ( sort keys %Config) { print "$var='", $Config{ $var} || '', "'\n"; } } sub qd { my ( $path_str) = @_; $path_str =~ s[/][$dir_sep]g; return $path_str; } sub quoted_split { my @neww = (); my $text = shift; while ($text =~ m< "((?:[^\"\\]*\\.[^\"\\]*)*)"\s* | (\S+)\s* | \s+ >gx) { if ( defined $1) { push @neww, $1; } elsif ( defined $2) { push @neww, $2; } } return @neww; } sub fatal { open ERRLOG, ">". qd "$CWD/makefile.log"; print ERRLOG @_; close ERRLOG; die @_; } sub quotemake { return join '', map { $make_trans{ $MAKETYPE}->[ ord]} split //, $_[ 0]; } sub tempfile { my $mask = shift; my $name; my $n = 0; do { $name = sprintf $mask, $n++; } while ( -e $name); return $name; } sub cc_command_line { my ( $srcf, $objf, $exef, $compile_only, $dl) = @_; my @cc = ( $CC, split(' ', $CFLAGS), split(' ', $CCFLAGS)); push @cc, split ' ', $CCCDLFLAGS if $dl; push @cc, split ' ', $CDLFLAGS if $dl && !$compile_only; push @cc, $COMPONLYFLAG if $compile_only; push @cc, map( { "$CINCPATHFLAG$_"} @INCPATH); # for ( keys %DEFINES) { # next unless $DEFINES{$_}; # push @cc, "$CDEFFLAG$_=$DEFINES{$_}"; # } push @cc, "${ CDEFFLAG}HAVE_CONFIG_H=1"; push @cc, ( $compile_only ? "$COUTOFLAG$objf" : "$COUTEXEFLAG$exef"); push @cc, "$COUTOFLAG$objf" if $COMPILER =~ /^(msvc|bcc32)$/ && !$compile_only; push @cc, map { "$CLIBPATHFLAG$_"} @LIBPATH unless $compile_only || ( $COMPILER eq 'msvc'); push @cc, $srcf; return @cc if $compile_only; push @cc, $CLINKPREFIX; push @cc, map { "\"$CLIBPATHFLAG\\\"$_\\\"\"" } @LIBPATH if $COMPILER eq 'msvc'; push @cc, map { "$LDLIBFLAG$_"} @LIBS; return @cc; } sub ld_command_line { my ( $dstf) = shift; my @ld = ( $LD, split( ' ', $LDFLAGS)); if ( $COMPILER eq 'bcc32') { push @ld, '-L"' . join( ';', @LIBPATH) . '" c0d32.obj '; push @ld, @_; push @ld, ",", $dstf, ", ,", @LIBS, ",", "win32\\Prima.def,"; } else { push @ld, map { m/\s/ ? "$SHQUOTE$LDLIBPATHFLAG$_$SHQUOTE" : "$LDLIBPATHFLAG$_" } @LIBPATH; push @ld, map { "-Wl,-R$_" } @LIBPATH if $^O =~ /netbsd/; push @ld, "$LDOUTFLAG$dstf", @_; push @ld, map { "$LDLIBFLAG$_"} @LIBS; push @ld, "os2\\Prima.def" if $OS2; if ( $Win32) { push @ld, "/def:win32\\Prima.def" if $COMPILER eq 'msvc'; push @ld, "win32/Prima.def" if $COMPILER eq 'gcc'; } } return @ld; } sub null_output { open OLDSTDOUT, ">&STDOUT" or die "STDOUT dup failed: $!"; open OLDSTDERR, ">&STDERR" or die "STDERR dup failed: $!"; # $NULLDEV = ( $Win32 || $OS2) ? "CON" : "/dev/tty"; # $NULLDEV = ( $Win32 || $OS2) ? "NUL" : "/dev/null"; if ( $^O !~ /linux/) { close STDOUT; close STDERR; } open STDOUT, ">>$NULLDEV" or fatal "STDOUT redirect failed: $!"; open STDERR, ">&STDOUT" or fatal "STDERR redirect failed: $!"; } sub restore_output { if ( $^O !~ /linux/) { close STDOUT; close STDERR; } open STDOUT, ">&OLDSTDOUT" or fatal "STDOUT restoration failed: $!"; open STDERR, ">&OLDSTDERR" or fatal "STDERR restoration failed: $!"; close OLDSTDOUT; close OLDSTDERR; } sub compile { my ( $text, $compile_only, @extra) = @_; my $tmpsrc = qd( tempfile( "$TMPDIR/pmts%04d.c")); my $tmpo = qd( tempfile( "$TMPDIR/pmts%04d$OBJ_EXT")); my $tmpexe = qd( tempfile( "$TMPDIR/pmts%04d$EXE_EXT")); my @tmpextras = ( $tmpsrc, $tmpsrc); $tmpextras[0] =~ s/\.[^\.+]$/.ilk/; $tmpextras[1] =~ s/\.[^\.+]$/.pdb/; open TMPSRC, ">$tmpsrc" or die "Creation of temporary file $tmpsrc failed $see_makefile_log"; print TMPSRC $text; close TMPSRC; null_output; my @cc = grep !/^-W(all|error|\d)/i, cc_command_line( $tmpsrc, $tmpo, $tmpexe, $compile_only || 0); push @cc, @extra; print STDERR "@cc\n"; my $rc = system("@cc"); restore_output; unlink $tmpsrc; unlink $tmpo if -w $tmpo; unlink $tmpexe if -w $tmpexe; unlink $_ for @tmpextras; return( $rc == 0); } sub have_header { my $header = shift; (my $defname = "HAVE_" . uc $header) =~ s/\W/_/g; return $DEFINES{$defname} if exists $DEFINES{$defname}; my @pre_headers = map { "#include <$_>\n" } @_; print "Checking for presence of $header... "; my $present = compile( < EOF $DEFINES{ $defname} = undef; $DEFINES{ $defname} = 1 if $present; print( $present ? "yes" : "no", "\n"); return $present; } sub find_header { my $header = shift; my $options = ref($_[0]) eq 'HASH' ? shift : {}; my ( $incpath, $present); foreach $incpath ( @_) { local @INCPATH = @INCPATH; push @INCPATH, $incpath if $incpath; my $code = $options->{Code} || < EOF $present = compile( $code, 1); return $incpath if $present; } return undef; } sub find_lib { my ( $lib, $inc) = ( shift, shift ); my ( $libpath, $present); if ( $OS2 && !length $inc) { # link386 is broken - warns, not dies if no library found if ( -f $lib) { $lib =~ s/(\\|\/[^\\|\/]*)$//g; return $lib; } for ( @LIBPATH) { return $_ if -f "$_/$lib"; return $_ if -f "$_/$lib.lib"; return $_ if -f "$_/$lib.a"; } return undef; } local @LIBS = @LIBS; push @LIBS, $lib; foreach $libpath ( @_) { local @LIBPATH = (@LIBPATH, $libpath) if $libpath; $present = compile( <\n"} @headers; $defname =~ s/\W/_/g; print "Checking for function $funcname... "; my $rc = compile( <$tmpsrc" or die "Creation of temporary file $tmpsrc failed $see_makefile_log"; print TMPSRC <\n"} @headers; my $rc = compile( <{ src}}) { eval "\$$varname = sprintf \"$USER_VARS_LINKS{ $varname}->{ format}\", \$$USER_VARS_LINKS{ $varname}->{ src}"; } else { eval "\$$varname = join( '', \@_)"; } die $@ if $@; if ( defined $USER_VARS_ADDONS{ $varname}) { eval "\$$varname .= join( '', \@{ \$USER_VARS_ADDONS{ \$varname}})"; } die $@ if $@; } elsif ( $overrideable{ $varname} eq '@') { if ( defined $USER_VARS{ $varname}) { eval "\@$varname = \@{\$USER_VARS{ \$varname}}"; } else { eval "\@$varname = \@_"; } die $@ if $@; if ( defined $USER_VARS_ADDONS{ $varname}) { eval "push \@$varname, \@{ \$USER_VARS_ADDONS{ \$varname}}"; } die $@ if $@; } else { die "Unsupported type of variable"; } } sub env_true { my ( $var) = @_; return( $ENV{ $var} && $ENV{ $var} =~ /^1|yes|on|true$/i); } sub suck_symbols { my $fn = shift; open F, $fn or die "Cannot open $fn:$!\n"; local $/; my $x = ; close F; return ( $x =~ m/\bextern\s+\w+(?:\s*\*\s*)?\s+(\w+)\s*\(.*?;/gs ); } sub setup_variables { setvar( 'CYGWIN_X11', 0); $Win32 = 0 if $CYGWIN_X11; my $platform; $NeedX11 = 0; if ( $Win32) { $platform = 'win32'; } elsif ( $OS2) { $platform = 'os2'; } else { $platform = 'unix'; $NeedX11 = 1; } setvar( 'PLATFORM', $platform); %cc_specs = ( cc => { warnflags => "", cflags => "", coutoflag => '-o ', coutexeflag => '-o ', cdebugflags => '-g -O', clinkprefix => '', clibpathflag => '-L', ldflags => '', ldoutflag => '-o ', ldlibpathflag => '-L', ldlibflag => '-l', ldlibext => '', lddebugflags => '-g', name => "CC", lib => '', liboflag => '', }, gcc => { warnflags => "", cflags => "", coutoflag => '-o ', coutexeflag => '-o ', cdebugflags => '-g -O -Wall', clinkprefix => '', clibpathflag => '-L', ldflags => '', ldoutflag => '-o ', ldlibpathflag => '-L', ldlibflag => '-l', ldlibext => '', lddebugflags => '-g', name => "GNU", lib => '', liboflag => '', }, hpcc => { warnflags => "", #"+w1", cflags => "-Ae", coutoflag => '-o ', coutexeflag => '-o ', cdebugflags => '-g +O2 +Onolimit', clinkprefix => '', clibpathflag => '-L', ldflags => '', ldoutflag => '-o ', ldlibpathflag => '-L', ldlibflag => '-l', ldlibext => '', lddebugflags => '-g', name => "HP-UX C-ANSI-C", lib => '', liboflag => '', }, irixcc => { warnflags => "-fullwarn", cflags => "-diag_error 1035 -woff 1011,1042,1048,1140,1164,1174,1209,1506,1515,1552", coutoflag => '-o', coutexeflag => '-o', cdebugflags => '-g -O0', clinkprefix => '', clibpathflag => '-L', ldflags => '', ldoutflag => '-o', ldlibpathflag => '-L', ldlibflag => '-l', ldlibext => '', lddebugflags => '-g', name => "IRIX Native", lib => '', liboflag => '', }, emx => { warnflags => "-Wall", cflags => "", coutoflag => '-o', coutexeflag => '-o', cdebugflags => '-g -O', clinkprefix => '', clibpathflag => '-L', ldflags => '', ldoutflag => '-o', ldlibpathflag => '-L', ldlibflag => '-l', ldlibext => '', lddebugflags => '-g', lib => 'emxomf', liboflag => '-o', name => "EMX", }, msvc => { warnflags => "-W3 -WX", cflags => "-nologo", coutoflag => '-Fo', coutexeflag => '-Fe', clinkprefix => '/link', clibpathflag => '/LIBPATH:', cdebugflags => '-Zi', ldflags => '', ldoutflag => '/OUT:', ldlibpathflag => '/LIBPATH:', ldlibflag => '', ldlibext => '.lib', lddebugflags => '/DEBUG', name => "Microsoft Visual C++", lib => 'lib', liboflag => '-out:', }, bcc32 => { warnflags => "-w0", # Borland is the only compiler which doesn't allow of geting rid of warnings. cflags => "-tWM", coutoflag => '-o', coutexeflag => '-e', clinkprefix => '', clibpathflag => '-L', cdebugflags => '-v -y', ldflags => '', ldoutflag => '', ldlibpathflag => '-L', ldlibflag => '', ldlibext => '', lddebugflags => '-v', lib => '', liboflag => '', name => "Borland C++", }, ); setvar( 'TMPDIR', $ENV{ TMPDIR} || $ENV{ TEMPDIR} || ( $Win32 ? ( $ENV{ TEMP} || "$ENV{ SystemDrive}\\TEMP") : "/tmp")); setvar( 'NULLDEV', "$CWD/makefile.log"); setvar( 'DL_LOAD_FLAGS', ( $Win32 || $OS2) ? 0 : -1); setvar( 'SHQUOTE', $Win32 ? '"' : "'"); setvar( 'CC', $Config{ cc}); print "Determining compiler type... "; # setting preliminary $COMPILER so have_define() can run if ( $Win32) { $COMPILER = ( $CC =~ /cl(\.exe)?$/i ) ? 'msvc' : $CC; } else { $COMPILER = $CC; } if ( defined $USER_VARS{ COMPILER}) { $COMPILER = $USER_VARS{ COMPILER}; die "Compiler type $COMPILER is unknown" unless defined $cc_specs{ $COMPILER}; } elsif ( $^O =~ /irix/ && $CC =~ /^(\S*\/)?cc\b/) { # this code should be put first, as cc call does not treat #error as error, # and have_define() is therefore always true $COMPILER = 'irixcc'; } elsif ( $^O eq "hpux" && $CC =~ /^(\S*\/)?cc\b/) { # this code should be put first, as cc call does not treat #error as error, # and have_define() is therefore always true $COMPILER = 'hpcc'; } elsif ( have_define( "__EMX__")) { $COMPILER = 'emx'; } elsif ( have_define( "__GNUC__")) { $COMPILER = 'gcc'; } elsif ( have_define( "__BORLANDC__")) { $COMPILER = 'bcc32'; } elsif ( have_define( "_MSC_VER")) { $COMPILER = 'msvc'; } elsif ( $CC =~ /^(\S*\/)?cc\b/ ) { $COMPILER = 'cc'; } else { print "($CC is unknown, assuming COMPILER=cc) "; $COMPILER = 'cc'; } print "$cc_specs{ $COMPILER}->{ name}\n"; $win32_use_dlltool = $Win32 && ( $COMPILER eq 'gcc') && !$cygwin; # 5.8.0 hack $Config{PATCHLEVEL} = $Config{PERL_PATCHLEVEL} if !defined $Config{PATCHLEVEL} || !length $Config{PATCHLEVEL}; $Config{SUBVERSION} = $Config{PERL_SUBVERSION} if !defined $Config{SUBVERSION} || !length $Config{SUBVERSION}; # Checking some Config.pm - were empty for ActiveState 626 $Config{PATCHLEVEL} = $Config{patchlevel} if !defined $Config{PATCHLEVEL} || !length $Config{PATCHLEVEL}; $Config{SUBVERSION} = $Config{subversion} if !defined $Config{SUBVERSION} || !length $Config{SUBVERSION}; $Config{ld} = (($COMPILER eq 'msvc') ? 'link' : 'ld'), print("** warning: malformed Config.pm\n") unless length $Config{ld}; my $ccflags = $Config{ ccflags}; my $warnflags = $cc_specs{ $COMPILER}->{ warnflags}; # my $ldflags = $COMPILER eq 'emx' ? "" : "$Config{ ldflags} "; my $ldflags = ""; my $lddlflags = $Config{ lddlflags}; setvar( 'DEBUG', defined($ENV{ PRIMA_DEVEL}) ? $ENV{ PRIMA_DEVEL} : 0); if ( $COMPILER eq 'msvc' && (( $ccflags =~ /TP/) || ($ccflags =~ /O\d/))) { # M$VC++ protection $warnflags =~ s/W3/W1/; # lower warning level $ccflags =~ s/\-W3/\-W1/; # lower warning level $warnflags =~ s/(-|\/)WX//; # and dismiss 'warnings as errors'; ( for its stupidity in the c++ case) $ldflags =~ s/(-|\/)nodefaultlib//g; $lddlflags =~ s/(-|\/)nodefaultlib//g; $ccflags =~ s/(-|\/)O\d//g if $DEBUG; # remove optimization } setvar( 'C_FLAGS', "$ccflags $warnflags $cc_specs{ $COMPILER}->{ cflags} " . ( $Config{ optimize} || '') . " "); setvar( 'CFLAGS', "$ccflags $warnflags $cc_specs{ $COMPILER}->{ cflags}" . ( $DEBUG ? " $cc_specs{ $COMPILER}->{ cdebugflags}" : " " . ( $Config{ optimize} || '')) . " "); setvar( 'CCFLAGS', ''); if ( $COMPILER eq 'gcc' && $Config{ cccdlflags} =~ /-K\S/) { # remove known proprietary compiler junk flags $Config{ cccdlflags} =~ s/-K\S*//; } setvar( 'CCCDLFLAGS', $Config{ cccdlflags}); setvar( 'CDLFLAGS', $Config{ ccdlflags}); setvar( 'COUTOFLAG', $cc_specs{ $COMPILER}->{ coutoflag}); setvar( 'COUTEXEFLAG', $cc_specs{ $COMPILER}->{ coutexeflag}); setvar( 'CINCPATHFLAG', '-I'); setvar( 'CDEFFLAG', '-D'); setvar( 'COMPONLYFLAG', '-c'); setvar( 'CLINKPREFIX', $cc_specs{ $COMPILER}->{ clinkprefix}); setvar( 'CLIBPATHFLAG', $cc_specs{ $COMPILER}->{ clibpathflag}); setvar( 'LD', $Config{ ld}); setvar( 'LD_FLAGS', "$ldflags $lddlflags $cc_specs{ $COMPILER}->{ ldflags} "); setvar( 'LDFLAGS', "$ldflags $lddlflags $cc_specs{ $COMPILER}->{ ldflags}" . ( $DEBUG ? " $cc_specs{ $COMPILER}->{ lddebugflags}" : "") . " "); setvar( 'LDOUTFLAG', $cc_specs{ $COMPILER}->{ ldoutflag}); setvar( 'LDLIBPATHFLAG', $cc_specs{ $COMPILER}->{ ldlibpathflag}); setvar( 'LDLIBFLAG', $cc_specs{ $COMPILER}->{ ldlibflag}); setvar( 'OBJ_EXT', $Config{ _o}); setvar( 'LIB_EXT', ( $cygwin ? '.dll' : '') . $Config{ _a}); setvar( 'LIB_PREFIX', $cygwin ? 'lib' : ''); setvar( 'EXE_EXT', $Config{ _exe}); setvar( 'LIB', $cc_specs{ $COMPILER}->{ lib}); setvar( 'LIBOFLAG', $cc_specs{ $COMPILER}->{ liboflag}); setvar( 'SCRIPT_EXT', (( $Win32 && !$cygwin) ? '.bat' : ( $OS2 ? '.cmd' : ''))); setvar( 'DL_EXT', "." . $Config{ dlext}); setvar( 'INC', ''); # compat mode INC setvar( 'INCPATH', ( "include", qd( "include/generic"), $Config{installarchlib} . qd( "/CORE"), ( map { s/-I//; $_ } split ' ', $INC) )); my @libpaths = quoted_split( $Config{ libpth}); push( @libpaths, '/usr/local/lib') if $platform eq 'unix'; # or perl makefile.pl LIBPATH+=/usr/local/lib setvar( 'LIBPATH', @libpaths); my @libs = map { s/^$LDLIBFLAG//; $_} quoted_split($Config{ libs}); # compat mode LIBS setvar( 'LIBS', ''); for ( split ' ', $LIBS) { if ( /^-l(.*)/) { push @libs, $1; } elsif ( /^-L(.*)/) { push @LIBPATH, $1; } else { $LDFLAGS .= " $_"; } } # push ( @libs, 'pmprintf') if $OS2 && defined $ENV{PRIMA_PMPRINTF}; if ( $useGC) { push @libs, 'leak'; } if ( $COMPILER eq 'gcc') { push @libs, 'gcc'; } my @flibs; if ( $Win32 && $COMPILER eq 'gcc') { $Config{libperl} =~ s/^lib(.*)\.a$/$1/i; push @libs, qw(gdi32 mpr winspool comdlg32); # add more when appropriate } if ( $CYGWIN_X11) { $Config{libperl} =~ s/^lib(.*)\.a$/$1/i; } open F, 'Prima.pm' or die "Cannot open Prima.pm:$!\n"; my ($ver1, $ver2); while () { next unless m/\$VERSION[^\.\d]*(\d+)\.(\d+)/; $ver1 = $1, $ver2 = $2, last; } close F; die "Cannot find VERSION string in Prima.pm\n" unless defined $ver1; print "Version: $ver1.$ver2\n"; setvar( 'DISTNAME', "Prima-$ver1.$ver2"); # here starts lot of execs... setup_compiler(); for my $lib (@libs) { print "Checking for library $lib... "; my $path = find_lib($lib, '', ''); if ( defined $path) { push @flibs, $lib; print "yes"; print ", in $path" if length($path); print "\n"; } else { print "no\n"; $END .= "*** Warning (probably harmless): `$lib' library not found\n"; } } @LIBS = @flibs; %DEFINES = ( PRIMA_VERSION => $ver1, PRIMA_SUBVERSION => $ver2, PERL_PATCHLEVEL => $Config{ PATCHLEVEL}, PERL_SUBVERSION => $Config{ SUBVERSION}, PRIMA_CORE => 1, PERL_POLLUTE => 1, PRIMA_DEBUG => $DEBUG, ); $DEFINES{PRIMA_PLATFORM} = $OS2 ? 1 : ( $Win32 ? 2 : 3); if ( env_true( 'PRIMA_PARANOID_MALLOC')) { $DEFINES{ PARANOID_MALLOC} = 1; } if ( $useGC) { $DEFINES{ USE_GC} = 1; } while ( $CFLAGS =~ s/-D(\w+)(?:=(\S+))?\s*//) { my ( $defname, $defvalue) = ( $1, $2 || 1); $DEFINES{ $defname} = $defvalue; } while ( $CCFLAGS =~ s/-D(\w+)(?:=(\S+))?\s*//) { my ( $defname, $defvalue) = ( $1, $2 || 1); $DEFINES{ $defname} = $defvalue; } if ( $COMPILER eq 'msvc') { $DEFINES{_CRT_SECURE_NO_DEPRECATE} = 1; # to be invoked on command line $CFLAGS .= " -D_CRT_SECURE_NO_DEPRECATE"; } # find common denominator with installsitearch and installscript my @a = split( '\\\\|\/', $Config{installscript}); my @b = split( '\\\\|\/', $Config{installsitearch}); my $i = 0; while ( defined $a[$i] && defined $b[$i]) { last if $a[$i] ne $b[$i]; $i++; } my $prefix = qd(($i ? join( '/', @a[0..$i-1]) : '')); $USER_VARS{PREFIX} ||= $USER_VARS{INSTALL_BASE} if exists $USER_VARS{INSTALL_BASE}; setvar( 'PREFIX', $prefix); setvar( 'INSTALLSCRIPT', $PREFIX . qd( '/' . join( '/', @a[$i .. $#a]))); setvar( 'INSTALLSITEARCH', $PREFIX . qd( '/' . join( '/', @b[$i .. $#b]))); setvar( 'INSTALL_LIB', $INSTALLSITEARCH . qd( "/Prima")); setvar( 'INSTALL_DL', $INSTALLSITEARCH . qd( "/auto/Prima")); setvar( 'INSTALL_EXAMPLES', $INSTALLSITEARCH . qd( "/Prima/examples")); if ( exists $USER_VARS{PREFIX}) { setvar( 'INSTALL_MAN1', $INSTALLSITEARCH . qd( "/man/man1")); setvar( 'INSTALL_MAN3', $INSTALLSITEARCH . qd( "/man/man3")); } else { setvar( 'INSTALL_MAN1', $Config{installman1dir}); setvar( 'INSTALL_MAN3', $Config{installman3dir}); } setvar( 'X11BASE'); setvar( 'MAKETYPE', lc ( $MAKE = $Config{ make})); # Note that Borland's make utility also named 'make'. But its # usage is deprecated, thus we can ignore it. # # In Linux GNU make also has name 'make'. But Makefile been # generated by this script is compatible with it. If it named # 'gmake' then we force $MAKETYPE to contain 'make'. $MAKETYPE = 'make' if $MAKETYPE =~ /^gmake|pmake$/; die "Unknown make utility" unless $MAKETYPE =~ /^make|nmake|dmake$/; setvar( 'RM', $Config{ rm}); $OS2DLLF = 'Prima'; $OS2DLLF = &DynaLoader::mod2fname([$OS2DLLF]) if $OS2 && defined &DynaLoader::mod2fname; $PrimaLib = qd( "auto/Prima/${LIB_PREFIX}Prima$LIB_EXT"); $PrimaTarget = qd( "auto/Prima/$OS2DLLF$DL_EXT"); $extralibs = ''; $extralibs = qd("auto/Prima/Prima.lib") if $OS2; setvar( 'DEFFILE', $Win32 ? qd( "win32/Prima.def") : ( $OS2 ? qd( "os2/Prima.def") : '')); setvar( 'AUTOMATED_RUN', 0); @executables = qw( Prima/VB/VB.pl Prima/VB/cfgmaint.pl ); my $unix = (!$Win32 && !$OS2); setvar('WITH_ICONV', $unix); setvar('WITH_XFT', $unix); setvar('WITH_GTK2', $unix); $install_manuals = $cygwin || (!$Win32 && !$OS2); $install_manuals = 0 if !length( $INSTALL_MAN1) || !length($INSTALL_MAN3); $binary_prereq = ''; @Prima_exports = qw( boot_Prima build_dynamic_vmt build_static_vmt call_perl call_perl_indirect clean_perl_call_method clean_perl_call_pv create_mate create_object ctx_remap_def cv_call_perl debug_write duplicate_string eval gimme_the_mate gimme_the_vmt kind_of kill_zombies notify_perl Object_create Object_destroy parse_hv plist_create plist_destroy prima_mallocz pop_hv_for_REDEFINED protect_object push_hv push_hv_for_REDEFINED query_method sv_call_perl sv_query_method unprotect_object perl_error ); push @Prima_exports, grep { /^(apc|list|prima)/ } suck_symbols('include/apricot.h'); push @Prima_exports, suck_symbols('include/img.h'); push @Prima_exports, suck_symbols('include/img_conv.h'); my %g = map { $_ => 1 } @Prima_exports; delete @g{qw(prima_utf8_to_uv prima_uv_to_utf8)}; @Prima_exports = sort keys %g; } sub setup_compiler { print "Checking if can compile... "; compile('int a;', 1) or die "no $see_makefile_log\n"; print "yes\n"; print "Checking if can link... "; compile( < < 1 } @INCPATH; push @INCPATH, $_ for grep { not exists $inc{$_}} $inc =~ /-I(\S+)/g; my $lib = `pkg-config --libs-only-l gtk+-2.0`; chomp $lib; my %lib = map { $_ => 1 } @LIBS; push @LIBS, $_ for grep { not exists $lib{$_}} $lib =~ /-l(\S+)/g; # now, try to compile with GTK. I've got lots of CPAN build failures # because GTK wasn't willing to compile or god knows what. print "Checking if can compile and link with gtk2... "; my $ok = compile( "#include \nint main() { return 0; }\n"); if ( $ok) { $DEFINES{WITH_GTK2} = 1; print "yes\n"; } else { $WITH_GTK2 = 0; @LIBS = @savelib; @INCPATH = @saveinc; print "no\n"; } } } print "Using Xft library\n" if $WITH_XFT; print "Using iconv library\n" if $WITH_ICONV; print "Using gtk2 library\n" if $WITH_GTK2; } sub generate_win32_def { open PRIMADEF, ">$DEFFILE" or die "Cannot create $DEFFILE: $!"; print PRIMADEF <$DEFFILE" or die "Cannot create $DEFFILE: $!"; print PRIMADEF < 1 } @LIBS; my @codecs; my @builtin_codecs; while ( ) { if ( m/prigraph/) { unshift @codecs, $_; # put it first } elsif ( m/codec_(bmp)/) { push @builtin_codecs, $1; } else { push @codecs, $_; } } my @codec_libpath = qd( $Config{installsitearch}); my @warn_codecs; for my $cx ( @codecs) { my @inc; my $foundlib; $cx =~ m/codec_(.*)\.c$/i; my ( $fn, $lib, $codec) = ( $cx, $1, $1); next unless open F, $fn; while() { push @inc, $_ if m/^\s*#include\s*\[ ord] = "^$_"; } $nmake_tbl->[ ord '%'] = '%%'; $nmake_tbl->[ ord '$'] = $make_tbl->[ ord '$'] = '$$'; $dmake_tbl->[ ord '#'] = '\\#'; $make_tbl->[ ord '#'] = '\\#'; %make_trans = ( make => $make_tbl, nmake => $nmake_tbl, dmake => $dmake_tbl, ); generate_win32_def if $Win32; generate_os2_def if $OS2; # check if we need dl_load_flags(0x01) if ( $DL_LOAD_FLAGS < 0) { print "Determining dl_load_flags... "; my $c1 = qd( tempfile( "$TMPDIR/pmts%04d.c")); $c1 =~ m/pmts([^\.]*).c$/; my ( $n1, $n2) = ( $1, sprintf("%04d", 1 + $1)); my $o1 = qd( "$TMPDIR/pmts$n1$OBJ_EXT"); my $o2 = qd( "$TMPDIR/pmts$n2$OBJ_EXT"); my $dl1 = qd( "$TMPDIR/pmts$n1$DL_EXT"); my $dl2 = qd( "$TMPDIR/pmts$n2$DL_EXT"); my @ex = map { qd("$TMPDIR/pmts$_")} map { ("$n1$_", "$n2$_") } ('.ilk', '.pdb'); open TMPSRC, ">$c1" or die "Creation of temporary file $c1 failed"; print TMPSRC < #include #include int test( void ) { return 1; } XS(boot_pmts$n1) { dXSARGS; XSRETURN(1); } D close TMPSRC; my $c2 = qd( tempfile( "$TMPDIR/pmts%04d.c")); open TMPSRC, ">$c2" or die "Creation of temporary file $c2 failed"; print TMPSRC < #include #include extern int test ( void ); XS(boot_pmts$n2) { dXSARGS; test(); XSRETURN(1); } D close TMPSRC; my @cc1 = grep !/^-W(all|error|\d)/i, cc_command_line( $c1, $o1, $dl1, 1, 1); my @cc2 = grep !/^-W(all|error|\d)/i, cc_command_line( $c2, $o2, $dl2, 1, 1); my @ld1 = ld_command_line( $dl1, $o1); my @ld2 = ld_command_line( $dl2, $o2); my $dlpl = "$^X -e '" . (join ' ', split("\n", < new(); } sub process_commandline { %overrideable = map { /^(.)(.*)$/; $2 => $1} @ovvars; # Script variables which may be overridden. my %expand = map { /^.(.*)$/; $1 => 1 } @path_expand_ovvars; my %no_compat = map { $_ => 1 } @no_compat; $ARGV_STR = join( " ", map { "\"$_\""} @ARGV); foreach my $arg ( @ARGV) { if ( $arg =~ /^\s*(\w+)\s*(\+?)\=(.*)$/) { my ( $varname, $setmode, $varval) = ( $1, $2 || '', $3); if ( $no_compat{ $varname}) { print "Variable $varname is not supported. Expect wrong behavior\n"; next; } die "Unknown variable $varname" unless $overrideable{ $varname}; $varval =~ s/~/$ENV{HOME}/g if $expand{ $varname}; if ( $overrideable{ $varname} eq '$') { if ( $setmode eq '+') { push @{ $USER_VARS_ADDONS{ $varname}}, $varval; } else { $USER_VARS{ $varname} = $varval; } die $@ if $@; } elsif ( $overrideable{ $varname} eq '@') { my @values = split /$path_sep/, $varval; if ( $expand{ $varname}) { s/~/$ENV{HOME}/g for @values; } if ( $setmode eq '+') { push @{ $USER_VARS_ADDONS{ $varname}}, @values; } else { $USER_VARS{ $varname} = \@values; } die $@ if $@; } } elsif ( $arg =~ /^-(D|U)(\w+)(?:(\+?)=(.*))?$/) { my ( $defmode, $defname, $setmode, $value) = ( $1, $2, $3 || '', $4 || ''); if ( $defmode eq 'U') { $USER_DEFINES{ $defname} = undef; # I.e. it will exists in the hash... } else { if ( $setmode eq '+') { push @{ $USER_DEFINES_ADDONS{ $defname}}, $value; } else { $USER_DEFINES{ $defname} = $value; } } } else { die "Unknown command line argument or wrong syntax: '$arg'"; } } } sub _find_file { my ( $fname, $dir) = @_; my ( $pathname, $found); $pathname = qd( "$dir/$fname"); return $pathname if -e $pathname; opendir D, $dir or die "Cannot open dir $dir: $!"; my @entries = map { qd( "$dir/$_")} grep { /^[^.]/ && -d qd( "$dir/$_")} readdir D; closedir D; foreach my $entry ( @entries) { $pathname = _find_file( $fname, $entry); next unless defined $pathname; return $pathname; } return undef; } sub find_file { my ( $fname) = @_; $fname =~ s/\\/\//g; $fname = qd($fname); return $cache_find_files{$fname} if exists $cache_find_files{$fname}; return $cache_find_files{$fname} = _find_file( $fname, '.'); } sub canon_name { my ( $fname) = @_; my $qdirsep = quotemeta( $dir_sep); $fname =~ s{[^$qdirsep]+$qdirsep\.\.(?:$qdirsep|\Z)}{} while $fname =~ /(?:$qdirsep|\A)\.\.(?:$qdirsep|\Z)/; $fname =~ s{(?:(?<=$qdirsep)|(?<=\A))\.(?=$qdirsep|\Z)$qdirsep?}{}g; return $fname; } sub find_cdeps { my ( $cfile, $deps, $included) = @_; $deps ||= {}; $included ||= {}; return () if exists $deps->{ $cfile}; $deps->{ $cfile} = []; return @{ $alldeps{ $cfile}} if exists $alldeps{ $cfile}; $alldeps{ $cfile} = []; return () unless -f $cfile; local *CF; open CF, "<$cfile" or die "Cannot open $cfile: $!"; while ( ) { chomp; next unless /^\s*\#\s*include\s+"([^\"]+)"/; my $incfile = $1; my $i = find_file( $incfile); $incfile = defined($i) ? $i : qd( "include/generic/$incfile"); $incfile = canon_name( $incfile); unless ( exists $included->{ $incfile}) { push @{ $alldeps{ $cfile}}, $incfile; push @{ $deps->{ $cfile}}, $incfile; $included->{ $incfile} = 1; } my @subdeps = find_cdeps( $incfile, $deps, $included); push @{ $deps->{ $cfile}}, @subdeps; push @{ $alldeps{ $cfile}}, @subdeps; } close CF; return @{ $deps->{ $cfile}}; } sub cmake { my ( $cfile) = @_; print "Finding dependencies for $cfile...\n"; my $ofile = "$1$OBJ_EXT" if $cfile =~ /^(.*)\.c$/; die "Internal error: illegal c file" unless defined $ofile; $cfile = qd( $cfile); $ofile = qd( $ofile); push @allclean, $ofile; push @allojects, $ofile; my @deps = find_cdeps( $cfile); return( "$ofile: Makefile $cfile @deps\n\t" . join( " ", cc_command_line( $cfile, $ofile, "", 1, 1)) . "\n\n" ); } sub clsmake { my ( $clsfile) = @_; print "Finding dependencies for $clsfile..."; my $classname = $1 if $clsfile =~ /^(.*)\.cls$/; die "Internal error: illegal cls file" unless defined $classname; my $mk = qd( "include/generic/$classname.h") . ": Makefile " . "$clsfile " . qd( "utils/gencls.pl ") . qd( "Prima/Gencls.pm "); push @alltml, qd( "include/generic/$classname.tml"); push @alltmldeps, qd( "include/generic/$classname.h"); push @allclean, ( qd( "include/generic/$classname.h"), qd( "include/generic/$classname.inc"), qd( "include/generic/$classname.tml") ); push @allinstall, qd( "include/generic/$classname.h"), $INSTALL_LIB . qd( "/CORE/generic"); my @ancestors = gencls( $clsfile, depend => 1); $mk .= qd( "include/generic/$_.h $_.cls ") foreach @ancestors; print "\n"; $mk .= "\n\t$^X -I. utils/gencls.pl --inc --h --tml $clsfile include/generic\n\n"; } sub qqd { my ( $path_str) = @_; $path_str =~ s[/][$dir_sep]g; $path_str =~ s[\\][\\\\]g; return $path_str; } sub manname { my ( $name, $section, $prefix) = @_; $prefix = quotemeta( $prefix ); my $ds = quotemeta($dir_sep); $name =~ s/^$prefix(?:[\\\/$ds])//; $name =~ s/[\\\/$ds]/::/g; $name =~ s/\.[^\.]*$/\.$section/; return (( $section == 3 ) ? $INSTALL_MAN3 : $INSTALL_MAN1) . $dir_sep . $name; } sub create_config_pm { my $_cwd = cwd; my $cwd = qqd($_cwd); my $ifs = ($Win32 && !$cygwin) ? '\\\\' : '/'; my @ip = map { qqd($_) } @INCPATH; $ip[0] = "$cwd${ifs}include"; $ip[1] = "$cwd${ifs}include${ifs}generic"; my $ipp = join(',', map {"\'$_\'"} @ip); $ip[0] = qqd("$INSTALLSITEARCH/Prima/CORE"); $ip[1] = qqd("$INSTALLSITEARCH/Prima/CORE/generic"); my $ippi = join(',', map {"\'$_\'"} @ip); my @cdefs = ('HAVE_CONFIG_H=1'); my $cdefs = join( ',', map {"'$_'"} @cdefs); my $lddef = ( $COMPILER eq 'msvc') ? '/def:' : '', my @libpath = @LIBPATH; my @libs = @LIBS; my $perllib = pop @libs; if ( $perllib =~ m/^(.*)\/([^\/]*)$/) { my $pfile = $2; push @libpath, $1; $pfile =~ s/$LIB_EXT$//; push @libs, $pfile; } else { push @libs, $perllib; } unless ( $PLATFORM eq 'unix' or $COMPILER eq 'gcc') { push @libpath, "$_cwd/auto/Prima"; push @libs, 'Prima' . $cc_specs{$COMPILER}->{ldlibext}; } my $libpath = qqd(join( ',', map {"'$_'"} @libpath)); unless ( $PLATFORM eq 'unix' or $COMPILER eq 'gcc') { $libpath[-1] = "$INSTALLSITEARCH/auto/Prima"; } my $libpathi = qqd(join( ',', map {"'$_'"} @libpath)); my $ldlibs = qqd(join( ',', map {"'$_'"} @libs)); my $perl = qqd($^X); my $pl = qqd( $PrimaLib); my $pt = qqd( $PrimaTarget); my $iscr = qqd($INSTALLSCRIPT); my $isa = qqd($INSTALLSITEARCH); my $define = join(' ', map { "-D$_" } @cdefs); my $inc = join(' ', map { "-I$_" } @ip); my $libs = ''; if ( $cygwin) { $libs = "-L$INSTALL_DL -lPrima"; } elsif ( $Win32 || $OS2) { $libs = "$INSTALLSITEARCH/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT"; } open F, "> Prima/Config.pm" or die "cannot open Prima/Config.pm:$!\n"; print F < [ $ippi ], gencls => '$iscr${ifs}gencls$SCRIPT_EXT', tmlink => '$iscr${ifs}tmlink$SCRIPT_EXT', libname => '$isa${ifs}auto${ifs}Prima${ifs}Prima$LIB_EXT', dlname => '$isa${ifs}$pt', ldpaths => [$libpathi], libs => '$libs', define => '$define', inc => '$inc', ); %Config = ( ifs => '$ifs', quote => '\\$SHQUOTE', platform => '$PLATFORM', compiler => '$COMPILER', incpaths => [ $ipp ], platform_path => '$cwd${ifs}$PLATFORM', gencls => '\\$SHQUOTE$perl\\$SHQUOTE $cwd${ifs}utils${ifs}gencls.pl', tmlink => '\\$SHQUOTE$perl\\$SHQUOTE $cwd${ifs}utils${ifs}tmlink.pl', scriptext => '$SCRIPT_EXT', genclsoptions => '--tml --h --inc', cc => '$CC', cflags => '-c $C_FLAGS $CCFLAGS', cdebugflags => '$cc_specs{$COMPILER}->{cdebugflags}', cincflag => '$CINCPATHFLAG', cobjflag => '$COUTOFLAG', cdefflag => '$CDEFFLAG', cdefs => [$cdefs], objext => '$OBJ_EXT', lib => '$LIB', liboutflag => '$LIBOFLAG', libext => '$LIB_EXT', libprefix => '$LIB_PREFIX', libname => '$cwd${ifs}$pl', libs => '$cwd${ifs}$pl', dlname => '$cwd${ifs}$pt', dlext => '$DL_EXT', ld => '$LD', ldflags => '$LD_FLAGS', lddefflag => '$lddef', lddebugflags => '$cc_specs{$COMPILER}->{lddebugflags}', ldoutflag => '$LDOUTFLAG', ldlibflag => '$LDLIBFLAG', ldlibpathflag => '$LDLIBPATHFLAG', ldpaths => [$libpath], ldlibs => [$ldlibs], ldlibext =>'$cc_specs{$COMPILER}->{ldlibext}', inline => '$DEFINES{__INLINE__}', perl => '$perl', dl_load_flags => $DL_LOAD_FLAGS, libs => '$libs', define => '$define', inc => '$inc', ); 1; CONFIG close F; } sub create_codecs_c { open F, "> img/codecs.c" or die "cannot open img/codecs.c:$!\n"; my $def1 = join("\n", map { "extern void apc_img_codec_$_(void);"} @ACTIVE_CODECS); my $def2 = join("\n", map { "\tapc_img_codec_$_();"} @ACTIVE_CODECS); print F <= 0 && $ARGV[ 0] =~ /^\-\-cp(bin)?$/) { my $isbin = defined $1; shift @ARGV; die qq(Even number of parameters expected) unless ( $#ARGV % 2); while ( scalar @ARGV) { my ( $src, $dst) = ( shift @ARGV, shift @ARGV); print qq(Installing $src -> $dst\n); next unless -f $src; if ( $isbin) { my $dstdir = dirname( $dst); mkpath $dstdir if $dstdir && ! -d $dstdir; unlink $dst; open SRCPL, "<$src" or die "Cannot open $src: $!"; open DSTPL, ">$dst" or die "Cannot create $dst: $!"; chmod 0755, $dst unless ($Win32 && !$cygwin) || $OS2; if ( $Win32 && !$cygwin) { print DSTPL <) { next if $filestart && /^\#\!/; $filestart = 0; print DSTPL; } if ( $Win32 && !$cygwin) { print DSTPL <= 0 && $ARGV[ 0] eq '--md') { shift @ARGV; mkpath \@ARGV; } elsif ( $#ARGV >= 0 && $ARGV[ 0] eq '--rm') { shift @ARGV; unlink @ARGV; } elsif ( $#ARGV >= 0 && $ARGV[ 0] eq '--rmdir') { shift @ARGV; rmdir for @ARGV; } elsif ( $#ARGV >= 0 && $ARGV[ 0] eq '--updateconfig') { shift @ARGV; my ( $fn_cfg, $fn_prima) = ( shift @ARGV, shift @ARGV); open F, $fn_cfg or die "cannot open $fn_cfg:$!\n"; open FF, "> $fn_cfg.tmp" or die "cannot open $fn_cfg.tmp:$!\n"; my ( $c_state, $ci_state) = (0,0); my %ci; print FF <) { if ( $ci_state == 0) { if ( m/\%Config_inst = \(/) { $ci_state = 1; } } elsif ( $ci_state == 1) { if ( m/^\);/) { $ci_state = 0; } else { $ci{$1} = $_ if m/^\s*(\S+)\s*/; } } if ( $c_state == 0) { if ( m/\%Config = \(/) { $c_state = 1; } } elsif ( $c_state == 1) { if ( m/^\);/) { $c_state = 0; } else { if ( m/^\s*(\S+)\s*/ && exists $ci{$1}) { print FF $ci{$1}; } else { print FF $_; } } } } print FF <; close F; $ct =~ s/(dl_load_flags\s*\{\s*)0x00/${1}0x01/; open F, "> $fn_prima" or die "cannot write $fn_prima:$!\n"; print F $ct; close F; } } elsif ( $#ARGV >= 2 && $ARGV[ 0] eq '--dist') { my $type = lc $ARGV[1]; my $cwd = cwd(); my $distname = $ARGV[2]; sub clean_dist { my @dirs; return unless -d $distname; print "Cleaning...\n"; finddepth( sub { my $f = "$File::Find::dir/$_"; -d($f) ? push(@dirs, $f) : unlink($f); }, "$cwd/$distname"); rmdir $_ for sort {length($b) <=> length($a)} @dirs; rmdir $distname; } sub cleanup { clean_dist; warn("$_[0]:$!\n") if defined $_[0]; exit(0); } clean_dist; my @dirs; my @files; finddepth( sub { return if $_ eq '.' || ($_ eq 'Makefile' && $File::Find::dir eq $cwd) || $_ eq 'makefile.log' || $_ eq '.packlist'; return if /\.(pdb|ncb|opt|dsp|dsw)$/i; # M$VC my $f = "$File::Find::dir/$_"; return if $f =~ /include.generic|CVS/; if ($type eq 'bin') { return if $f =~ /\.(c|cls|h)$/i; return if $f =~ /$cwd.(img|include|os2|win32|unix|Makefile.PL)/i; } else { return if $f =~ /auto/; } if ( -d $f) { $f =~ s/^$cwd/$distname/; push @dirs, $f; } else { return if $f =~ m/$Config{_o}$/; push @files, $f; } }, $cwd); print "Creating directories...\n"; for ( @dirs) { next if -d $_; cleanup( "Can't mkdir $_") unless mkpath $_; } print "Copying files...\n"; for ( @files) { my $f = $_; $f =~ s/^$cwd/$distname/; cleanup("Error copying $_ to $_") unless copy $_, $f; } if ( $type eq 'bin') { my $os_suffix = $^O; $os_suffix =~ s/\s/_/g; my $zipname = "$distname-$os_suffix.zip"; unlink $zipname; unlink "$distname/$zipname"; system "zip -r $zipname $distname"; } elsif ( $type eq 'zip') { my $zipname = "$distname.zip"; unlink $zipname; unlink "$distname/$zipname"; system "zip -r $zipname $distname"; } else { # tar dist my $tarname = "$distname.tar"; unlink $tarname; unlink "$distname/$tarname"; system "tar -cv -f $tarname $distname" } clean_dist; } elsif ( $#ARGV >= 0 && $ARGV[ 0] eq '--help') { print < { src => 'PREFIX', format => '%s/bin', }, INSTALLSITEARCH => { src => 'PREFIX', format => '%s', }, ); =cut process_commandline; setup_variables; setup_X11; setup_perl; setup_defines; setup_xft; my $config_dir = "include/generic"; my $config_h = "$config_dir/config.h"; print "Creating $config_h\n"; unless ( -d "$config_dir") { mkdir $config_dir, 0777; } open CONFIG, ">$config_h" or die "Creation of $config_h failed: $!"; print CONFIG < $INSTALL_LIB . qd( "/CORE/generic"); # install pod files print "Enumerating POD files\n"; push @allinstall, map { qd($_), $INSTALLSITEARCH} ; push @allman, map { qd($_), manname($_, 1, 'pod')} ; finddepth( sub { my $f = "$File::Find::dir/$_"; return unless -f $_; my $d = $File::Find::dir; $d =~ s/^pod[\\\/]Prima//; if ( m/pod$/) { push @allinstall, qd($f), qd("$INSTALL_LIB$d"); push @allman, qd($f), manname($f, 3, 'pod'); } elsif( m/gif$/) { push @allinstall, qd($f), qd("$INSTALL_LIB$d"); } }, "pod/Prima"); push @alldirs, qd( "include/generic"), qd( "auto/Prima"); print "Creating Prima::Config.pm\n"; create_config_pm; print "Creating img/codecs.c\n"; create_codecs_c; #exit; my $make = < { Prima::codecs::$binary_prereq=>q[0] } # PREREQ $make .= <) { $make .= clsmake( $_); } while ( <*.c>) { $make .= cmake( $_); } while ( ) { next if exists $PASSIVE_CODECS{$_}; $make .= cmake( $_); } while ( <$PLATFORM/*.c>) { next if !$WITH_XFT && m/xft.c/; $make .= cmake( $_); } while ( ) { if ( m/\.pl$/i) { push @allbins, $_, $INSTALL_EXAMPLES; } else { push @allinstall, $_, $INSTALL_EXAMPLES; } } while ( ) { push @allbins, $_, $INSTALLSCRIPT; } for ( @executables) { push @allbins, $_, $INSTALLSCRIPT; m/\/([^\/]+)$/; push @allman, qd($_), manname( $1, 1, ''); } my $thunks_tinc = qd( "include/generic/thunks.tinc"); push @allclean, $thunks_tinc; push @allrealclean, 'Makefile'; print "Writing Makefile..."; $make =~ tr[/][]s; open MAKE, ">Makefile" or die "Creation of Makefile failed: $!"; print MAKE $make; # dist-related veriables if ( $OS2) { print MAKE <\\n}. qq{\\tPrima\\n}. qq{\\tPerl GUI toolkit\\n}. qq{\\tDmitry Karasik\\n}. qq{\\t\\n}. qq{\\t\\t\\n}. qq{\\t\\t\\n}. qq{\\t\\t\\n}. qq{\\t\\n}. qq{\\n}" > Prima.ppd Makefile: Makefile.PL @Makefile_deps \t\@echo Rebuilding Makefile... \t\@$^X Makefile.PL $ARGV_STR \t\@$MAKE \t\@echo You are safe to ignore the following error... \t\@false EOF print MAKE < ) { next unless /^\=head1/; push @allman, qd($fn), manname( $fn, 3, ''); last; } close F; } } }, 'Prima'); delete $cp{qd($_)} for @executables; while (@allinstall) { my ( $src, $dst) = ( shift(@allinstall), shift(@allinstall)); next if $src =~ /CVS/; $cp{$src} = $dst; } while ( ) { my $dst = $_; $dst =~ s/^include/CORE/; $cp{$_} = dirname( qd( "$INSTALL_LIB/$dst")); } while ( ) { my $dst = $_; $dst =~ s/^include/CORE/; $cp{$_} = dirname( qd( "$INSTALL_LIB/$dst")); } my $i = 0; sub dump_cmd { my ( $line, $sub, $command) = ( 0, shift, shift); print MAKE "\t\@\$($command) \\\n" if scalar @_; for ( @_) { my $call = $sub->($_); if (( $line++ % 20) == 19) { print MAKE "\n\t\@\$($command) \\\n"; } elsif ( $line <= scalar @_ && $line > 1) { print MAKE " \\\n"; } print MAKE "\t$call"; } print MAKE "\n"; } print MAKE "\ninstall: all\n"; dump_cmd( sub { "$_[0] $cp{$_[0]}"}, 'CP', sort keys %cp); while ( scalar @allbins) { my ( $src, $dst) = ( shift @allbins, shift @allbins); $cp{qd( basename( $src, '.pl') . $SCRIPT_EXT)} = $dst; $cpbin{$src} = qd( "$dst/" . basename( $src, '.pl')) . $SCRIPT_EXT; } dump_cmd( sub { "$_[0] $cpbin{$_[0]}"}, 'CPBIN', sort keys %cpbin); dump_cmd( sub { $_[0] }, 'CHMOD', @chmodx); print MAKE "\n\t\@echo Updating config...\n"; print MAKE "\t$^X Makefile.PL --updateconfig $INSTALLSITEARCH/Prima/Config.pm"; print MAKE " $INSTALLSITEARCH/Prima.pm" if $DL_LOAD_FLAGS; my @man_to_remove; if ( $install_manuals) { my $cmd = "\t\@pod2man --lax --section=\%d \%s " . ( length( $Config{gzip} ) ? "| $Config{gzip} -c > \%s.gz\n" : "> \%s\n" ); print MAKE "\n\t\@echo Installing man pages...\n"; print MAKE "\t\@\$(MD) $INSTALL_MAN1 $INSTALL_MAN3\n"; while ( scalar @allman ) { my ( $src, $dest) = splice( @allman, 0, 2); $dest =~ s/::/./g if ($Win32 || $cygwin); push @man_to_remove, $dest; $dest =~ m/([^\/]+)\.(\d+)$/; print MAKE "\t\@echo $dest" . (length( $Config{gzip} ) ? '.gz' : ''). "\n"; printf MAKE $cmd, $2, $src, $dest; } if ( length $Config{gzip}) { s/$/.gz/ for @man_to_remove } } print MAKE "\n\ndeinstall:\n"; my %dirs_to_rm; dump_cmd( sub { $dirs_to_rm{$cp{$_[0]}} = 1; $_[0] =~ m/(\\|\/)?([^\\|\/]+)$/; my $rm = "$cp{$_[0]}$dir_sep$2"; $packlist->{$rm}++; return $rm; }, 'RM', keys %cp); dump_cmd( sub { $_ }, 'RM', @man_to_remove); delete $dirs_to_rm{$INSTALLSITEARCH}; delete $dirs_to_rm{$INSTALLSCRIPT}; dump_cmd( sub { $_[0] }, 'RMDIR', sort { length($b) <=> length($a) } keys %dirs_to_rm); print MAKE "\n"; print MAKE join( "\n", @footers), "\n"; close MAKE; $packlist-> write('.packlist'); print "\nAll done. Now you can run ${ MAKE}.\n"; }