From aaf9671cb2048a54ec1c4c998e0e06d0cd7f85d2 Mon Sep 17 00:00:00 2001 From: Dmitry Karasik Date: Thu, 11 Aug 2011 11:49:35 +0200 Subject: [PATCH] - rewrite Makefile.PL with ExtUtils::MakeMaker --- Makefile.PL | 2730 ++++++++++++++++------------------------------- Makefile_old.PL | 2730 +++++++++++++++++++++++++++++++++++++++++++++++ README | 21 +- 3 files changed, 3678 insertions(+), 1803 deletions(-) create mode 100755 Makefile_old.PL diff --git a/Makefile.PL b/Makefile.PL index d23ff7113..b1ac05205 100755 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,189 +1,324 @@ -#! /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$ -# - -BEGIN { - unshift @INC, '.'; -}; - -my $END; -END { - print $END if defined $END; -}; - -require 5.00502; +package MY; use strict; +use warnings; +use lib '.'; +use Cwd; use Config; -my %Config = %Config::Config; # original %Config is read-only +use DynaLoader; +use Prima::Gencls; +use ExtUtils::MakeMaker; use File::Find; -use File::Basename; use File::Path; +use File::Basename; 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 + +# XXX +# - binary_prereq under automated CPAN +# - msvc warnings +# - msvc ld debug flags /DEBUG + +use vars qw( + $ARGV_STR + $COUTOFLAG + $COUTEXEFLAG + $CLIBPATHFLAG + $CLINKPREFIX + $LDLIBFLAG + $LDOUTFLAG $TMPDIR $NULLDEV - $MAKE - $RM - $SHQUOTE - $MAKETYPE - $DEFFILE - $DISTNAME - $DISTVERSION - $DL_LOAD_FLAGS - $DEBUG - $WITH_XFT - $WITH_ICONV - $WITH_GTK2 - $AUTOMATED_RUN - $CYGWIN_X11 -); - -use vars @path_expand_ovvars = qw( + $SCRIPT_EXT + $LD_LIB_EXT + $LIB_EXT + $LIB_PREFIX + @LIBS @INCPATH @LIBPATH - $INC - $LIBS - $COMPILER - $PREFIX - $X11BASE - $INSTALLSCRIPT - $INSTALLSITEARCH - $INSTALL_BASE - $INSTALL_LIB - $INSTALL_DL - $INSTALL_EXAMPLES - $INSTALL_MAN3 - $INSTALL_MAN1 - $TMPDIR - $MAKE - $RM + %DEFINES + %PREREQ + %PASSIVE_CODECS + @ACTIVE_CODECS + $DL_LOAD_FLAGS + $DISTNAME + $CWD + $OS2DLLF + $SHQUOTE $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 + $OPTIMIZE ); use vars qw( - $CWD + %cmd_options $Win32 $Win64 - $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 + $unix + $cygwin + $platform + $path_sep + $dir_sep %alldeps - @allinstall - @allbins - @alldirs - @allman - @headers - @footers - @Makefile_deps - $PrimaLib - $PrimaTarget - @Prima_exports - $extralibs - @executables - $install_manuals - $packlist + %files + @pm_files + @prima_files + @pod_files + @c_files + @h_files + @o_files + @exe_files + @cls_files + @target_clean %cache_find_files $binary_prereq - $win32_use_dlltool - $win32_dlltool $compiler_version + @Prima_exports ); +my $END; +END { + print $END if defined $END; +}; + my $see_makefile_log = "(see also makefile.log for details)"; -sub print_config +sub usage +{ + print < can("command_$1"); + die "invalid command $ARGV[0]\n" unless $sub; + shift @ARGV; + $sub->(@ARGV); + exit; +} + +setup_argv(); +setup_variables(); +setup_environment(); +setup_compiler(); +setup_exports(); +setup_defines(); +setup_dl_loadflags(); +setup_X11() if $unix; +setup_xlibs() if $unix; +setup_codecs(); +create_codecs_c(); +create_config_h(); +create_config_pm(); +setup_files(); + +sub setup_argv +{ + $ARGV_STR = join(' ', @ARGV); + + %cmd_options = ( + X11BASE => undef, + WITH_XFT => 1, + WITH_ICONV => 1, + WITH_GTK2 => 1, + CYGWIN_X11 => 0, + DEBUG => 0, + + # service vars + AUTOMATED_RUN => 0, + DL_LOAD_FLAGS => undef, + ); + + @ARGV = grep { + my ( $k, $v) = split( '=', $_, 2 ); + exists($cmd_options{$k}) ? ($cmd_options{$k} = $v, 0) : 1; + } @ARGV; +} + +sub setup_variables { - foreach my $var ( sort keys %Config) { - print "$var='", $Config{ $var} || '', "'\n"; + $DL_LOAD_FLAGS = 0; + if ( $^O =~ /mswin32/i) { + $Win32 = 1; + $platform = 'win32'; + } elsif ( $^O =~ /cygwin/i) { + if ( $cmd_options{CYGWIN_X11}) { + $unix = 1; + $platform = 'unix'; + } else { + $Win32 = 1; + $platform = 'win32'; + } + $cygwin = 1; + } elsif ( $^O =~ /os2/i ) { + $platform = 'os2'; + } else { + $platform = 'unix'; + $unix = 1; + $DL_LOAD_FLAGS = -1; # check later } + + $DL_LOAD_FLAGS = $cmd_options{DL_LOAD_FLAGS} if defined $cmd_options{DL_LOAD_FLAGS}; + + $dir_sep = (( ( $path_sep = $Config{ path_sep}) eq ':') || ( defined $Config{ emxpath})) ? '/' : '\\'; } -sub qd +sub extmap { - my ( $path_str) = @_; - $path_str =~ s[/][$dir_sep]g; - return $path_str; + my $newext = shift; + return map { my $x = $_; $x =~ s/\.\w+$/$newext/; $x } @_; +} + +sub ffind +{ + my ( $mask, $fdir ) = @_; + $fdir = '.' unless defined $fdir; + my @ret; + File::Find::finddepth( sub { + return unless -f and m/$mask/; + my $dir = $File::Find::dir; + $dir =~ s/^\.[\\\/]?//; + return if $dir =~ /^blib/; + my $f = length($dir) ? "$dir/$_" : $_; + push @ret, $f; + }, $fdir); + return @ret; +} + +sub setup_files +{ + @prima_files = ('Prima.pm', ffind( qr/./, 'Prima' )); + @pod_files = ffind( qr/\.pod$/ ); + @pm_files = ffind( qr/\.pm$/ ); + @c_files = ( + <*.c>, + (grep { not $PASSIVE_CODECS{$_} } ), + <$platform/*.c>, + ); + @cls_files = ( <*.cls> ); + @h_files = ( + , + , + , + map { "include/generic/$_" } extmap( '.h', @cls_files), + ); + @o_files = extmap( $Config{_o}, @c_files ); + + @exe_files = ( + , + + ); + + @target_clean = ( + "include/generic/*", + "*$Config{_o}", + "img/*$Config{_o}", + "$platform/*$Config{_o}", + ); + + # I still like to have my scripts as .pl, but installed without + # extension. Hack, hack, hack. See also corresponding part in the postamble + if ($unix or $cygwin) { + @exe_files = extmap('', @exe_files); + push @target_clean, @exe_files; + } + + + %files = ( + POD => \@pod_files, + PM => \@pm_files, + C => \@c_files, + H => \@h_files, + O => \@o_files, + CLS => \@cls_files, + EXE => \@exe_files, + PRIMA => \@prima_files, + ); +} + +sub setup_environment +{ + if ( $Win32 and not $cygwin ) { + $SCRIPT_EXT = '.bat'; + $SHQUOTE = '"'; + } elsif ( $OS2 ) { + $SCRIPT_EXT = '.cmd'; + $SHQUOTE = "'"; + } else { + $SCRIPT_EXT = ''; + $SHQUOTE = "'"; + } + + $OPTIMIZE = $Config{optimize}; + + if ( $Config{ccname} eq 'cl') { + $COUTOFLAG = '-Fo'; + $COUTEXEFLAG = '-Fe'; + $CLIBPATHFLAG = '/LIBPATH:'; + $CLINKPREFIX = '/link'; + $LDLIBFLAG = ''; + $LDOUTFLAG = '/OUT:'; + $LD_LIB_EXT = '.lib'; + $OPTIMIZE = '-Zi' if $cmd_options{DEBUG}; + } + else { + $COUTOFLAG = '-o'; + $COUTEXEFLAG = '-o'; + $CLIBPATHFLAG = '-L'; + $CLINKPREFIX = ''; + $LDLIBFLAG = '-l'; + $LDOUTFLAG = '-o'; + $LD_LIB_EXT = ''; + $OPTIMIZE = '-g' if $cmd_options{DEBUG}; + } + + $DEFFILE = 'Prima.def'; + $LIB_EXT = ($cygwin ? '.dll' : '') . $Config{ _a}; + $LIB_PREFIX = $cygwin ? 'lib' : ''; + + 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"; + + my $os_suffix = $^O; + $os_suffix =~ s/\s/_/g; + $DISTNAME = "Prima-$ver1.$ver2-$os_suffix-$Config{PERL_REVISION}.$Config{PATCHLEVEL}.$Config{SUBVERSION}"; + + %DEFINES = ( + PRIMA_VERSION => $ver1, + PRIMA_SUBVERSION => $ver2, + PERL_PATCHLEVEL => $Config{PATCHLEVEL}, + PERL_SUBVERSION => $Config{SUBVERSION}, + PRIMA_CORE => 1, + PERL_POLLUTE => 1, + PRIMA_DEBUG => 0, + ); + + $TMPDIR = $ENV{ TMPDIR} || $ENV{ TEMPDIR} || ( $Win32 ? ( $ENV{ TEMP} || "$ENV{SystemDrive}\\TEMP") : "/tmp"); + $NULLDEV = 'makefile.log'; + + $OS2DLLF = 'Prima'; + $OS2DLLF = &DynaLoader::mod2fname([$OS2DLLF]) if $OS2 && defined &DynaLoader::mod2fname; } sub qtilde @@ -194,96 +329,112 @@ sub qtilde return $ENV{HOME} . $path; } -sub quoted_split +sub qd { - 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; - } + my ( $path_str) = @_; + $path_str =~ s[/][$dir_sep]g; + return $path_str; +} + +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 @neww; + return undef; } -sub fatal +sub find_file { - open ERRLOG, ">". qd "$CWD/makefile.log"; - print ERRLOG @_; - close ERRLOG; - die @_; + 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 quotemake +sub canon_name { - return join '', map { $make_trans{ $MAKETYPE}->[ ord]} split //, $_[ 0]; + 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 tempfile +sub find_cdeps { - my $mask = shift; - my $name; - my $n = 0; - do { - $name = sprintf $mask, $n++; - } while ( -e $name); - return $name; + 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 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, ( $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; + my $ccflags = $Config{ccflags}; + $ccflags =~ s/\b\-W(all|error|\d)w*//i; + my $cc = "$Config{cc} $ccflags"; + $cc .= " $Config{cccdlflags}" if $dl; + $cc .= " $Config{ccdlflags}" if $dl && !$compile_only; + $cc .= " -c " if $compile_only; + $cc .= ' ' . join(' ', map { "-I$_" } @INCPATH); + $cc .= $compile_only ? " $COUTOFLAG$objf" : " $COUTEXEFLAG$exef"; + $cc .= " $COUTOFLAG$objf" if $Config{ccname} eq 'cl' && !$compile_only; + $cc .= ' ' . join( map { "$CLIBPATHFLAG$_"} @LIBPATH) unless $compile_only || ( $Config{ccname} eq 'cl'); + $cc .= " $srcf"; + return $cc if $compile_only; + $cc .= " $CLINKPREFIX"; + $cc .= ' ' . join(' ', map { "\"$CLIBPATHFLAG\\\"$_\\\"\"" } @LIBPATH) if $Config{ccname} eq 'cl'; + $cc .= ' ' . join(' ', map { "$LDLIBFLAG$_$LD_LIB_EXT"} @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; + my $ld = "$Config{ld} $Config{lddlflags}"; + $ld .= " $LDOUTFLAG$dstf @_"; + $ld .= ' ' . join(' ', map { "$LDLIBFLAG$_$LD_LIB_EXT"} @LIBS); + return $ld; } sub null_output @@ -296,8 +447,8 @@ sub null_output close STDOUT; close STDERR; } - open STDOUT, ">>$NULLDEV" or fatal "STDOUT redirect failed: $!"; - open STDERR, ">&STDOUT" or fatal "STDERR redirect failed: $!"; + open STDOUT, ">>$NULLDEV" or die "STDOUT redirect failed: $!"; + open STDERR, ">&STDOUT" or die "STDERR redirect failed: $!"; } sub restore_output @@ -306,18 +457,29 @@ sub restore_output close STDOUT; close STDERR; } - open STDOUT, ">&OLDSTDOUT" or fatal "STDOUT restoration failed: $!"; - open STDERR, ">&OLDSTDERR" or fatal "STDERR restoration failed: $!"; + open STDOUT, ">&OLDSTDOUT" or die "STDOUT restoration failed: $!"; + open STDERR, ">&OLDSTDERR" or die "STDERR restoration failed: $!"; close OLDSTDOUT; close OLDSTDERR; } +sub tempfile +{ + my $mask = shift; + my $name; + my $n = 0; + do { + $name = sprintf $mask, $n++; + } while ( -e $name); + return $name; +} + 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 $tmpo = qd( tempfile( "$TMPDIR/pmts%04d$Config{_o}")); + my $tmpexe = qd( tempfile( "$TMPDIR/pmts%04d$Config{_exe}")); my @tmpextras = ( $tmpsrc, $tmpsrc); $tmpextras[0] =~ s/\.[^\.+]$/.ilk/; $tmpextras[1] =~ s/\.[^\.+]$/.pdb/; @@ -327,10 +489,10 @@ sub compile 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"); + my $cc = cc_command_line( $tmpsrc, $tmpo, $tmpexe, $compile_only || 0); + $cc .= ' ' . join(' ', @extra) if @extra; + print STDERR "$cc\n"; + my $rc = system($cc); restore_output; unlink $tmpsrc; unlink $tmpo if -w $tmpo; @@ -343,8 +505,8 @@ sub compile_and_run { my ( $text) = @_; 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 $tmpo = qd( tempfile( "$TMPDIR/pmts%04d$Config{_o}")); + my $tmpexe = qd( tempfile( "$TMPDIR/pmts%04d$Config{_exe}")); my @tmpextras = ( $tmpsrc, $tmpsrc); $tmpextras[0] =~ s/\.[^\.+]$/.ilk/; $tmpextras[1] =~ s/\.[^\.+]$/.pdb/; @@ -354,9 +516,9 @@ sub compile_and_run close TMPSRC; null_output; - my @cc = grep !/^-W(all|error|\d)/i, cc_command_line( $tmpsrc, $tmpo, $tmpexe, 0); - print STDERR "@cc\n"; - my $rc = system("@cc"); + my $cc = cc_command_line( $tmpsrc, $tmpo, $tmpexe, 0); + print STDERR "$cc\n"; + my $rc = system($cc); restore_output; unlink $tmpsrc; unlink $tmpo if -w $tmpo; @@ -472,11 +634,7 @@ sub have_define chdir $TMPDIR; my $tmpsrc = qd( tempfile( "pmts%04d.c")); my $tmpo = $tmpsrc; - if ( $COMPILER eq 'msvc') { - $tmpo =~ s/\.c$/\.obj/; - } else { - $tmpo =~ s/\.c$/\.o/; - } + $tmpo =~ s/\.c$/\.$Config{_o}/; open TMPSRC, ">$tmpsrc" or die "Creation of temporary file $tmpsrc failed $see_makefile_log"; print TMPSRC <{ 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"; - } -} + print "Compiler: $Config{ccname}\n"; + + print "Checking if can compile... "; + compile('int a;', 1) or die "no $see_makefile_log\n"; + print "yes\n"; -sub env_true + print "Checking if can link... "; + compile( <; - close F; - return ( $x =~ m/\bextern\s+\w+(?:\s*\*\s*)?\s+(\w+)\s*\(.*?;/gs ); + if ( $Config{ccname} eq 'cl' ) { + print "Checking MSVC version... "; + $compiler_version = compile_and_run(<<'MSCVER'); +#include +int main() { + printf("%d\n", _MSC_VER); + return 0; } +MSCVER + print "$compiler_version\n"; -sub setup_variables -{ - setvar( 'CYGWIN_X11', 0); - $Win32 = 0 if $CYGWIN_X11; - - my $platform; - $NeedX11 = 0; - if ( $Win32) { - $platform = 'win32'; - } - elsif ( $OS2) { - $platform = 'os2'; + # kill annoying warnings + if ( $compiler_version < 1400) { + $OPTIMIZE .= " -D_CRT_SECURE_NO_DEPRECATE"; + } + if ( $compiler_version >= 1600 ) { + $OPTIMIZE .= " -D_CRT_SECURE_NO_WARNINGS"; + $OPTIMIZE .= " /wd4244"; # '=' : conversion from 'Bool' to 'char', possible loss of data + $OPTIMIZE .= " /wd4267"; # '=' : conversion from 'size_t' to 'int', possible loss of data + $OPTIMIZE .= " /wd4018"; # '<' : signed/unsigned mismatch"; + } } - else { - $platform = 'unix'; - $NeedX11 = 1; + + if ($Win32) { + print "Checking windows subsystem..."; + $Win64 = have_define('_WIN64'); + print $Win64 ? " 64" : " 32"; + print " bits\n"; + $DISTNAME =~ s/(mswin)32/${1}64/i if $Win64; } - 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", - 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++", - }, + + @INCPATH = ( + 'include', + 'include/generic', ); - 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 ? '"' : "'"); + @LIBS = qw(gdi32 mpr winspool comdlg32) if $Win32; # add more when appropriate + push @LIBPATH, '/usr/lib/w32api' if $cygwin; - 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; - } +sub setup_defines +{ + have_header( "io.h"); + have_header( "unistd.h"); + have_header( "strings.h"); - 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; - $win32_dlltool = $Config{dlltool} || 'dlltool'; - - # 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"), - qtilde($Config{archlib}) . 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' and - $LD !~ /^g\+\+/ # g++ and gcc together are weird kind - g++ does -lgcc itself - ) { - push @libs, 'gcc'; - } - my @flibs; - - if ( $Win32 ) { - if ( $COMPILER eq 'gcc') { - $Config{libperl} =~ s/^lib(.*)\.a$/$1/i; - push @libs, qw(gdi32 mpr winspool comdlg32); # add more when appropriate - } -# push @libs, map { $_ . $cc_specs{$COMPILER}->{ldlibext} } -# qw(imm32); # add more when appropriate - } - if ( $CYGWIN_X11) { - $Config{libperl} =~ s/^lib(.*)\.a$/$1/i; - } + my @int_types = qw(int8_t int16_t int32_t); + my @uint_types = qw(uint8_t uint16_t uint32_t uint64_t); + my @u_int_types = qw(u_int8_t u_int16_t u_int32_t u_int64_t); + have_types_in( "sys/types.h", @int_types) + || have_types_in( "sys/bitypes.h", @int_types) + || have_types_in( "sys/inttypes.h", @int_types) + || have_types_in( "stdint.h", @int_types); + have_types_in( "sys/types.h", @uint_types) + || have_types_in( "sys/bitypes.h", @uint_types) + || have_types_in( "sys/inttypes.h", @uint_types) + || have_types_in( "stdint.h", @uint_types); + have_types_in( "sys/types.h", @u_int_types) + || have_types_in( "sys/bitypes.h", @u_int_types) + || have_types_in( "sys/inttypes.h", @u_int_types) + || have_types_in( "stdint.h", @u_int_types); - 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; + if ( $unix) { + have_header( "sys/ipc.h", "sys/types.h"); + have_header( "sys/shm.h", "sys/types.h"); + have_header( "X11/extensions/shape.h", "X11/X.h", "X11/Xlib.h", "X11/Xutil.h"); + have_header( "X11/extensions/XShm.h", "X11/X.h", "X11/Xlib.h", "X11/Xutil.h"); } - close F; - die "Cannot find VERSION string in Prima.pm\n" unless defined $ver1; - print "Version: $ver1.$ver2\n"; - setvar( 'DISTNAME', "Prima-$ver1.$ver2"); - setvar( 'DISTVERSION', "$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"; - } + have_funcs_in( 'strings.h', 'strcasecmp'); + have_funcs_in( 'strings.h', 'strncasecmp'); + have_funcs_in( 'strings.h', 'strcasestr'); + have_funcs_in( 'string.h', 'stricmp'); + have_funcs_in( 'string.h', 'strnicmp'); + have_funcs_in( 'stdio.h', 'snprintf'); + have_funcs_in( 'stdio.h', '_snprintf'); + have_funcs_in( 'stdlib.h', 'reallocf'); + have_funcs_in( 'strings.h', 'bzero'); + if ( $Win32) { + have_type( "BOOLEAN", "windows.h"); } + find_inline(); +} - @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; - } +sub setup_dl_loadflags +{ + return if $DL_LOAD_FLAGS >= 0; + + print "Determining dl_load_flags... "; - if ( $COMPILER eq 'msvc') { - # crazy activestate/msvc stuff - if ( $compiler_version < 1400) { - $DEFINES{_CRT_SECURE_NO_DEPRECATE} = 1; - # to be invoked on command line - $CFLAGS .= " -D_CRT_SECURE_NO_DEPRECATE"; - } - if ( $compiler_version >= 1600 ) { - delete $DEFINES{_USE_32BIT_TIME_T}; - $DEFINES{_CRT_SECURE_NO_WARNINGS} = 1; - $CFLAGS .= " -D_CRT_SECURE_NO_WARNINGS"; - $CFLAGS .= " /wd4244"; # warning C4244: '=' : conversion from 'Bool' to 'char', possible loss of data - $CFLAGS .= " /wd4267"; # warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data - $CFLAGS .= " /wd4018"; # warning C4018: '<' : signed/unsigned mismatch"; - } - } + local @INCPATH = ( qtilde($Config{archlib}) . qd( "/CORE")); - # 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 '$MAKETYPE'" unless $MAKETYPE =~ /(nmake|dmake|make)/; - $MAKETYPE = $1; - - 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 = ''; + my $c1 = qd( tempfile( "$TMPDIR/pmts%04d.c")); + $c1 =~ m/pmts([^\.]*).c$/; + my ( $n1, $n2) = ( $1, sprintf("%04d", 1 + $1)); - @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; -} + my $o1 = qd( "$TMPDIR/pmts$n1$Config{_o}"); + my $o2 = qd( "$TMPDIR/pmts$n2$Config{_o}"); + my $dl1 = qd( "$TMPDIR/pmts$n1.$Config{dlext}"); + my $dl2 = qd( "$TMPDIR/pmts$n2.$Config{dlext}"); + my @ex = map { qd("$TMPDIR/pmts$_")} map { ("$n1$_", "$n2$_") } ('.ilk', '.pdb'); -sub setup_compiler -{ - print "Checking if can compile... "; - compile('int a;', 1) or die "no $see_makefile_log\n"; - print "yes\n"; + open TMPSRC, ">$c1" or die "Creation of temporary file $c1 failed"; + print TMPSRC < +#include +#include - print "Checking if can link... "; - compile( < -int main() { - printf("%d\n", _MSC_VER); - return 0; + 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); } -MSCVER - print "$compiler_version\n"; +D + close TMPSRC; + + my $cc1 = cc_command_line( $c1, $o1, $dl1, 1, 1); + my $cc2 = 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", <$DEFFILE" or die "Cannot create $DEFFILE: $!"; print PRIMADEF <; + close F; + return ( $x =~ m/\bextern\s+\w+(?:\s*\*\s*)?\s+(\w+)\s*\(.*?;/gs ); +} + +sub setup_exports +{ + @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; + generate_win32_def() if $Win32; + generate_os2_def() if $OS2; +} sub setup_codecs { @@ -1536,7 +1304,6 @@ sub setup_codecs close F; AGAIN: - $lib.='.lib' if ( $COMPILER eq 'msvc') || $OS2; print "Checking for $codec library... "; if ( $libs{$lib} || @@ -1566,6 +1333,7 @@ sub setup_codecs unless ( @ACTIVE_CODECS) { $binary_prereq = $prereq; + $PREREQ{"Prima::codecs::$prereq"} = 0; $END .= <[ 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 +sub create_codecs_c { - 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; -} + print "Creating img/codecs.c\n"; + open F, "> img/codecs.c" or die "cannot open img/codecs.c:$!\n"; -sub find_cdeps -{ - my ( $cfile, $deps, $included) = @_; + my $def1 = join("\n", map { "extern void apc_img_codec_$_(void);"} @ACTIVE_CODECS); + my $def2 = join("\n", map { "\tapc_img_codec_$_();"} @ACTIVE_CODECS); - $deps ||= {}; - $included ||= {}; + print F <{ $cfile}; - $deps->{ $cfile} = []; - return @{ $alldeps{ $cfile}} if exists $alldeps{ $cfile}; - $alldeps{ $cfile} = []; - return () unless -f $cfile; +#include "img.h" - 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}}; -} +#ifdef __cplusplus +extern "C" { +#endif -sub cmake +$def1 + +void +prima_cleanup_image_subsystem(void) { - 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" - ); + apc_img_done(); } -sub clsmake +void +prima_init_image_subsystem(void) { - 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"; + apc_img_init(); +$def2 } -sub qqd -{ - my ( $path_str) = @_; - $path_str =~ s[/][$dir_sep]g; - $path_str =~ s[\\][\\\\]g; - return $path_str; +#ifdef __cplusplus +} +#endif + +CONTENT + + close F; } -sub manname +sub create_config_h { - 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; + 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 <{ldlibext}; + my $libpath = qd(join( ',', map {"'$_'"} @libpath)); + unless ( $unix or $Config{ccname} eq 'gcc') { + $libpath[-1] = '$(lib)/auto/Prima'; } - 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 = ''; + my $libpathi = qd(join( ',', map {"'$_'"} @libpath)); + my $ldlibs = qd(join( ',', map {"'$_'"} @libs)); + + my ($libs, $libsi) = ('',''); if ( $cygwin) { - $libs = "-L$INSTALL_DL -lPrima"; + $libs = "-L$cwd/blib/arch/auto/Prima -lPrima"; + $libsi = '-L$(lib)/auto/Prima -lPrima'; } elsif ( $Win32 || $OS2) { - $libs = "$INSTALLSITEARCH/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT"; + $libs = qd("$cwd/blib/arch/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT"); + $libsi = '$(lib)' . qd("/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT"); } open F, "> Prima/Config.pm" or die "cannot open Prima/Config.pm:$!\n"; @@ -1993,61 +1506,46 @@ use vars qw(%Config %Config_inst); %Config_inst = ( incpaths => [ $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', + gencls => '\$(bin)${ifs}gencls$SCRIPT_EXT', + tmlink => '\$(bin)${ifs}tmlink$SCRIPT_EXT', + libname => '\$(lib)${ifs}auto${ifs}Prima${ifs}${LIB_PREFIX}Prima$LIB_EXT', + dlname => '\$(lib)${ifs}auto${ifs}Prima${ifs}$OS2DLLF.$Config{dlext}', ldpaths => [$libpathi], - libs => '$libs', - define => '$define', - inc => '$inc', + inc => '$inci', + libs => '$libsi', ); %Config = ( - ifs => '$ifs', + ifs => '\\$ifs', quote => '\\$SHQUOTE', - platform => '$PLATFORM', - compiler => '$COMPILER', + platform => '$platform', incpaths => [ $ipp ], - platform_path => ${_quote("$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', + gencls => ${_quotepath("$cwd/blib/script/gencls$SCRIPT_EXT")}, + tmlink => ${_quotepath("$cwd/blib/script/tmlink$SCRIPT_EXT")}, + scriptext => ${_quote($SCRIPT_EXT)}, genclsoptions => '--tml --h --inc', - cc => ${_quote($CC)}, - cflags => ${_quote("-c $C_FLAGS $CCFLAGS")}, - cdebugflags => ${_quote($cc_specs{$COMPILER}->{cdebugflags})}, - cincflag => ${_quote($CINCPATHFLAG)}, cobjflag => ${_quote($COUTOFLAG)}, - cdefflag => ${_quote($CDEFFLAG)}, - cdefs => [$cdefs], - objext => ${_quote($OBJ_EXT)}, - lib => ${_quote($LIB)}, - liboutflag => ${_quote($LIBOFLAG)}, + coutexecflag => ${_quote($COUTEXEFLAG)}, + clinkprefix => ${_quote($CLINKPREFIX)}, + clibpathflag => ${_quote($CLIBPATHFLAG)}, + cdefs => [], libext => ${_quote($LIB_EXT)}, libprefix => ${_quote($LIB_PREFIX)}, - libname => ${_quote("$cwd${ifs}$pl")}, - libs => ${_quote("$cwd${ifs}$pl")}, - dlname => ${_quote("$cwd${ifs}$pt")}, - dlext => ${_quote($DL_EXT)}, - ld => ${_quote($LD)}, - ldflags => ${_quote($LD_FLAGS)}, - lddefflag => ${_quote($lddef)}, - lddebugflags => ${_quote($cc_specs{$COMPILER}->{lddebugflags})}, + libname => ${_quotepath("$cwd/blib/arch/auto/Prima/${LIB_PREFIX}Prima$LIB_EXT")}, + dlname => ${_quotepath("$cwd/blib/arch/auto/Prima/$OS2DLLF.$Config{dlext}")}, ldoutflag => ${_quote($LDOUTFLAG)}, ldlibflag => ${_quote($LDLIBFLAG)}, - ldlibpathflag => ${_quote($LDLIBPATHFLAG)}, + ldlibpathflag => ${_quote($CLIBPATHFLAG)}, ldpaths => [$libpath], ldlibs => [$ldlibs], - ldlibext => ${_quote($cc_specs{$COMPILER}->{ldlibext})}, + ldlibext => ${_quote($LD_LIB_EXT)}, inline => ${_quote($DEFINES{__INLINE__})}, - perl => ${_quote($perl)}, dl_load_flags => $DL_LOAD_FLAGS, - libs => '$libs', - define => '$define', inc => '$inc', + define => '', + libs => '$libs', ); 1; @@ -2055,179 +1553,36 @@ CONFIG close F; } -sub create_meta_yml -{ - open F, '>', 'META.yml' or die "Can't open META.yml:$!\n"; -print F < -license: BSD -resources: - homepage: http://www.prima.eu.org/ - repository: http://github.com/dk/Prima -distribution_type: module -no_index: - directory: - - include - - img - - os2 - - test - - unix - - win32 - file: - - Makefile.PL - - test.pl - - ms_install.pl -generated_by: Prima/Makefile.PL -meta-spec: - url: http://module-build.sourceforge.net/META-spec-v1.4.html - version: 1.4 -YAML - 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 <; + close F; + $ct =~ s/(dl_load_flags\s*\{\s*)0x00/${1}0x01/; + open F, "> $f" or die "cannot write $f:$!\n"; + print F $ct; + close F; } -} -elsif ( $#ARGV >= 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); + + my $fn_cfg = "$opt{lib}/Prima/Config.pm"; + print "Updating config $fn_cfg\n"; 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; + my (%ci, %vars); + + %vars = %opt; + if ( $^O =~ /mswin32/i) { + s/\//\\/g for values %vars; + } 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 command_bindist +{ + $CWD = cwd(); + $DISTNAME = shift; sub clean_dist { my @dirs; - return unless -d $distname; + return unless -d $DISTNAME; print "Cleaning...\n"; finddepth( sub { my $f = "$File::Find::dir/$_"; -d($f) ? push(@dirs, $f) : unlink($f); - }, "$cwd/$distname"); + }, "$CWD/$DISTNAME"); rmdir $_ for sort {length($b) <=> length($a)} @dirs; - rmdir $distname; + rmdir $DISTNAME; } sub cleanup @@ -2314,28 +1662,25 @@ FOOTER my @files; finddepth( sub { return if $_ eq '.' || - ($_ eq 'Makefile' && $File::Find::dir eq $cwd) || + ($_ eq 'Makefile' && $File::Find::dir eq $CWD) || $_ eq 'makefile.log' || m/^\./; - return if /\.(pdb|ncb|opt|dsp|dsw)$/i; # M$VC + return if /\.(pdb|ncb|opt|dsp|dsw)$/i; # MSVC my $f = "$File::Find::dir/$_"; - return if $f =~ /include.generic|CVS|\.git/; - 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/; - } + return if $f =~ /include.generic|\.git|blib|dll.base|dll.exp|Prima.bs|Prima.def/; + return if $f =~ /\.(c|cls|h)$/i; + return if $f =~ /$CWD.(img|include|os2|win32|unix|Makefile.PL)/i; if ( -d $f) { - $f =~ s/^$cwd/$distname/; + $f =~ s/^$CWD/$DISTNAME/; push @dirs, $f; } else { return if $f =~ m/$Config{_o}$/; push @files, $f; } - }, $cwd); + }, $CWD); print "Creating directories...\n"; + push @dirs, "$DISTNAME/auto/Prima"; for ( @dirs) { next if -d $_; cleanup( "Can't mkdir $_") unless mkpath $_; @@ -2344,387 +1689,204 @@ FOOTER print "Copying files...\n"; for ( @files) { my $f = $_; - $f =~ s/^$cwd/$distname/; + $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" + for () { + next if m/(\.exists|Prima\.bs)$/; + my $f = $_; + $f =~ s[^blib/arch][$DISTNAME]; + cleanup("Error copying $_ to $_") unless copy $_, $f; } - clean_dist; -} elsif ( $#ARGV >= 0 && $ARGV[ 0] eq '--help') { - print <', $to or die "Cannot open $to:$!\n"; + print TO "#!$Config{perlpath} -w\n"; + print TO ; + close TO; + close FROM; + chmod 0755, $to; +} - $| = 1; +# EU::MM overridden stuff - print "Setting up working environment.\n"; -=pod - %USER_VARS_LINKS = ( - INSTALLSCRIPT => { - 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 < SUPER::c_o(@_); + unless ( $t =~ /.c\$\(OBJ_EXT\):\n\t.*\$\*\$\(OBJ_EXT\)/ ) { + $t =~ s/(\.c\$\(OBJ_EXT\):\n\t.*)/$1 $COUTOFLAG\$*\$(OBJ_EXT)/; } - 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; - print "Creating META.yml\n"; - create_meta_yml; - #exit; - - my $make = < { Prima::codecs::$binary_prereq=>q[0] } -# -PREREQ + return $t; +} - $make .= <SUPER::special_targets(@_); + $t .= <) { - $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; +sub postamble +{ + my $self = shift; + my $t = $self->SUPER::postamble(@_); - push @allrealclean, 'Makefile'; + my @alltml; + my @alltmldeps; + + for my $clsfile ( @cls_files) { + my ( $base ) = $clsfile =~ m/^(.*?).cls$/; + print "Finding dependencies for $clsfile...\n"; + my $ancestors = join(' ', map { "include/generic/$_.h $_.cls" } gencls( $clsfile, depend => 1)); + $t .= <Makefile" or die "Creation of Makefile failed: $!"; - print MAKE $make; +include/generic/$base.h: Makefile $base.cls $ancestors +\t$^X -I. utils/gencls.pl --inc --h --tml $clsfile include/generic -# dist-related veriables - if ( $OS2) { - print MAKE < . +$_: $_.pl +\t$^X $0 --cpbin $_.pl $_ -ppd: -\t\@$^X -e "print qq{\\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")); +H } - 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 $MAKETYPE.\n"; + return $t; } +# generate Prima.def ourselves - too many symbols, EU::MM dies with "command like too long" +sub dlsyms { '' } + +sub install +{ + my $self = shift; + my $t = $self->SUPER::install(@_); + my $n = $t =~ s[ + (pure_\w+_install.*?) # 1 + (INST_ARCHLIB\)\s+)(\$\(DEST\w+\))(.*?) # 2,3,4 + (INST_BIN\)\s+)(\$\(DEST\w+\))(.*?) # 5,6,7 + (.*?) # 8 + \n\n + ][ + "$1$2$3$4$5$6$7$8\n\t\$(NOECHO) \$(ABSPERL) $0 --postinstall lib=$3 bin=$6 dl=$DL_LOAD_FLAGS\n\n" + ]xgse; + + $END .= < 'Prima', + VERSION_FROM => 'Prima.pm', + ABSTRACT_FROM => 'Prima.pm', + AUTHOR => 'Dmitry Karasik ', + PM => { + # PM + ( map { $_ => '$(INST_LIBDIR)/'. $_ } @prima_files ), + # INC + ( map { + my $k = $_; + s/^include\///; + ( $k => '$(INST_LIBDIR)/Prima/CORE/' . $_ ) + } @h_files ) + }, + OPTIMIZE => $OPTIMIZE, + PREREQ_PM => \%PREREQ, + OBJECT => "@o_files", + INC => join(' ', map { "-I$_" } @INCPATH ), + LIBS => [ + join(' ', map { "-L$_" } @LIBPATH) . ' ' . + join(' ', map { "-l$_" } @LIBS), + ], + LICENSE => 'BSD', + EXE_FILES => \@exe_files, + PL_FILES => {}, + MAN3PODS => { + map { + my $target = $_; + $target =~ s/^pod\///; + $target =~ s/\//::/g; + $target =~ s/\.\w+$//; + $_ => '$(INST_MAN3DIR)/'. $target . '.$(MAN3EXT)' + } + (@pm_files, @pod_files) + }, + META_MERGE => { + resources => { + homepage => 'http://www.prima.eu.org/', + repository => 'http://github.com/dk/Prima', + }, + no_index => { + directory => [qw(include img test os2 unix win32)], + file => [qw(Makefile.PL test.pl ms_install.pl)], + }, + }, + clean => { FILES => "@target_clean" }, +); diff --git a/Makefile_old.PL b/Makefile_old.PL new file mode 100755 index 000000000..d23ff7113 --- /dev/null +++ b/Makefile_old.PL @@ -0,0 +1,2730 @@ +#! /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$ +# + +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 + $DISTVERSION + $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 + $Win64 + $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 + $win32_dlltool + $compiler_version +); + +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 qtilde +{ + my $path = shift; + return $path unless $path =~ s/^~//; + die "** path '~$path' begins with '~' but no HOME is set\n" unless exists $ENV{HOME}; + return $ENV{HOME} . $path; +} + +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, ( $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 compile_and_run +{ + my ( $text) = @_; + 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, 0); + print STDERR "@cc\n"; + my $rc = system("@cc"); + restore_output; + unlink $tmpsrc; + unlink $tmpo if -w $tmpo; + my $ret = `$tmpexe`; + chomp $ret; + unlink $tmpexe if -w $tmpexe; + unlink $_ for @tmpextras; + return $ret; +} + +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", + 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; + $win32_dlltool = $Config{dlltool} || 'dlltool'; + + # 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"), + qtilde($Config{archlib}) . 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' and + $LD !~ /^g\+\+/ # g++ and gcc together are weird kind - g++ does -lgcc itself + ) { + push @libs, 'gcc'; + } + my @flibs; + + if ( $Win32 ) { + if ( $COMPILER eq 'gcc') { + $Config{libperl} =~ s/^lib(.*)\.a$/$1/i; + push @libs, qw(gdi32 mpr winspool comdlg32); # add more when appropriate + } +# push @libs, map { $_ . $cc_specs{$COMPILER}->{ldlibext} } +# qw(imm32); # 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"); + setvar( 'DISTVERSION', "$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') { + # crazy activestate/msvc stuff + if ( $compiler_version < 1400) { + $DEFINES{_CRT_SECURE_NO_DEPRECATE} = 1; + # to be invoked on command line + $CFLAGS .= " -D_CRT_SECURE_NO_DEPRECATE"; + } + if ( $compiler_version >= 1600 ) { + delete $DEFINES{_USE_32BIT_TIME_T}; + $DEFINES{_CRT_SECURE_NO_WARNINGS} = 1; + $CFLAGS .= " -D_CRT_SECURE_NO_WARNINGS"; + $CFLAGS .= " /wd4244"; # warning C4244: '=' : conversion from 'Bool' to 'char', possible loss of data + $CFLAGS .= " /wd4267"; # warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data + $CFLAGS .= " /wd4018"; # warning C4018: '<' : signed/unsigned mismatch"; + } + } + + # 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 '$MAKETYPE'" unless $MAKETYPE =~ /(nmake|dmake|make)/; + $MAKETYPE = $1; + + 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( < +int main() { + printf("%d\n", _MSC_VER); + return 0; +} +MSCVER + print "$compiler_version\n"; + } + + if ($Win32) { + print "Checking windows subsystem..."; + $Win64 = have_define('_WIN64'); + print $Win64 ? " 64" : " 32"; + print " bits\n"; + } + +} + +sub setup_X11 +{ + # find X11 include files + print "Checking for X11 headers..."; + push @INCPATH, "$X11BASE/include" if defined($X11BASE) and -d "$X11BASE/include"; + for ( 'local/', 'freeware/', 'gnu/', 'opt/') { + push @INCPATH, qd( "/usr/${_}include") if -d "/usr/${_}include"; + } + my $incpath = find_header( qd( "X11/Xlib.h"), + qd( "/usr/X11R6/include"), + qd( "/usr/X11/include"), + qd("/usr/X/include"), + qd("/usr/openwin/include"), + qd("/opt/X11/include") + ); + + unless ( defined $incpath) { + print "no\n"; + return unless $NeedX11; + warn + "Prima needs X11 headers for compilation! ". + "Set X11BASE='/path/to/X' or INCPATH+='/path/to/X/include' ". + "if you have a non-standard path to X. $see_makefile_log\n"; + exit(0); + } + + print "yes"; + if ( -d $incpath) { + print ", in $incpath"; + push @INCPATH, $incpath; + } + print "\n"; + + # find X11 libraries + my @libpath = ( "X11", '', + (defined($X11BASE) ? "$X11BASE/lib" : ()), + "/usr/X11R6/lib", + "/usr/X11/lib", + "/usr/X/lib", + "/usr/openwin/lib", + "/opt/X11/lib" + ); + # using /usr/X11R6/lib64 ? + unshift @libpath, map { s/lib$/lib64/; $_ } grep { /lib$/ } @libpath + if $Config{intsize} == 8; + + print "Checking for library X11... "; + my $libpath = find_lib( @libpath); + unless ( defined $libpath) { + print "no\n"; + unless ( $NeedX11) { + pop @INCPATH if @INCPATH and $INCPATH[-1] eq $incpath; + return; + } + warn + "Prima needs X11 libraries for compilation! ". + "Set X11BASE='/path/to/X' or LIBPATH+='/path/to/X/lib' ". + "if you have a non-standard path to X. $see_makefile_log\n"; + exit(0); + } + + print "yes"; + if ( -d $libpath) { + print ", in $libpath"; + push @LIBPATH, $libpath; + } + print "\n"; + + if ( $NeedX11) { + push @LIBS, 'X11'; + if (defined find_lib( "Xext", '', '')) { + print "Xext library found.\n"; + push @LIBS, "Xext"; + } + } +} + +sub setup_perl +{ + if ( $Win32 || $cygwin || $OS2) { + print "Checking for perl library... "; + my $libperl = $Config{ libperl}; + $libperl =~ s/\.dll$//i if $cygwin; + $libperl =~ s/\.lib$// if $Win32 and $COMPILER eq 'gcc' and not $cygwin; + my $libpath = find_lib( $libperl, '', "", qtilde(qd( "$Config{ archlib}/CORE"))); + unless ( defined $libpath) { + print "no\n"; + die "Cannot find perl library $see_makefile_log\n" + } + print "yes"; + print ", in $libpath" if length($libpath); + print "\n"; + push @LIBPATH, $libpath if $libpath; + push @LIBS, $libperl; + } +} + +sub setup_defines +{ + have_header( "io.h"); + have_header( "unistd.h"); + have_header( "strings.h"); + + my @int_types = qw(int8_t int16_t int32_t); + my @uint_types = qw(uint8_t uint16_t uint32_t uint64_t); + my @u_int_types = qw(u_int8_t u_int16_t u_int32_t u_int64_t); + have_types_in( "sys/types.h", @int_types) + || have_types_in( "sys/bitypes.h", @int_types) + || have_types_in( "sys/inttypes.h", @int_types) + || have_types_in( "stdint.h", @int_types); + have_types_in( "sys/types.h", @uint_types) + || have_types_in( "sys/bitypes.h", @uint_types) + || have_types_in( "sys/inttypes.h", @uint_types) + || have_types_in( "stdint.h", @uint_types); + have_types_in( "sys/types.h", @u_int_types) + || have_types_in( "sys/bitypes.h", @u_int_types) + || have_types_in( "sys/inttypes.h", @u_int_types) + || have_types_in( "stdint.h", @u_int_types); + + if ( $NeedX11) { + have_header( "sys/ipc.h", "sys/types.h"); + have_header( "sys/shm.h", "sys/types.h"); + have_header( "X11/extensions/shape.h", "X11/X.h", "X11/Xlib.h", "X11/Xutil.h"); + have_header( "X11/extensions/XShm.h", "X11/X.h", "X11/Xlib.h", "X11/Xutil.h"); + } + if ( $OS2 && defined $ENV{ PRIMA_PMPRINTF}) { + if ( have_header( "pmprintf.h", "os2.h")) { + my $libpath = find_lib( 'pmprintf', '', ""); + die "There is no library for pmprintf $see_makefile_log\n" unless defined $libpath; + push @LIBS, 'pmprintf'; + } + else { + warn "PRIMA_PMPRINTF defined, but there is no pmprintf.h in include path"; + } + } + if ( $useGC) { + have_header( 'gc.h'); + } + + have_funcs_in( 'strings.h', 'strcasecmp'); + have_funcs_in( 'strings.h', 'strncasecmp'); + have_funcs_in( 'strings.h', 'strcasestr'); + have_funcs_in( 'string.h', 'stricmp'); + have_funcs_in( 'string.h', 'strnicmp'); + have_funcs_in( 'stdio.h', 'snprintf'); + have_funcs_in( 'stdio.h', '_snprintf'); + have_funcs_in( 'stdlib.h', 'reallocf'); + have_funcs_in( 'strings.h', 'bzero'); + if ( $Win32) { + have_type( "BOOLEAN", "windows.h"); + } + find_inline(); + + foreach my $defname ( keys %USER_DEFINES) { + if ( defined $USER_DEFINES{ $defname}) { + $DEFINES{ $defname} = $USER_DEFINES{ $defname}; + } + else { + delete $DEFINES{ $defname} if exists $DEFINES{ $defname}; + } + } + foreach my $defname ( keys %USER_DEFINES_ADDONS) { + $DEFINES{ $defname} = ( $DEFINES{ $defname} || '') . join( '', @{ $USER_DEFINES_ADDONS{ $defname}}); + } +} + +sub setup_xft +{ + if ( $WITH_XFT) { + my $HAVE_XFT = 0; + my $NEED_XFT = 4; + my @pre_xft_libs = @LIBS; + + my @ft_incpaths = ( "", + ( defined($X11BASE) ? qd("$X11BASE/include/freetype2") : ()), + qd("/usr/include/freetype2"), + qd("/usr/X11R6/include/freetype2"), + qd("/usr/X11/include/freetype2"), + qd("/usr/X/include/freetype2"), + qd("/usr/openwin/include/freetype2"), + qd("/opt/X11/include/freetype2"), + qd("/usr/local/include/freetype2"), + qd("/usr/gnu/include/freetype2"), + qd("/usr/freeware/include/freetype2"), + qd("/usr/opt/include/freetype2") + ); + my $have_ft2build_h = find_header( qd("ft2build.h"), @ft_incpaths ); + + print "Checking for presence of freetype/freetype.h... "; + my $incpath; + if ($have_ft2build_h) { + $DEFINES{HAVE_FT2BUILD_H} = undef; + $incpath = find_header( + qd("freetype/freetype.h"), { + Code => <\nint main() { iconv_close(0); return 0; }\n"); + if ( $ok ) { + print "no, but works as part of libc\n"; + } else { + $DEFINES{HAVE_ICONV_H} = undef; + $WITH_ICONV = 0; + print "no\n"; + } + } + } else { + $WITH_ICONV = 0; + } + + if ( $WITH_GTK2) { + print "Checking for presence of gtk2... "; + my $pkg_config = `which pkg-config`; + chomp $pkg_config; + unless ( -f $pkg_config) { + $WITH_GTK2 = 0; + print "no pkg-config, no gtk2\n"; + } + + if ( $WITH_GTK2) { + my $vers = `pkg-config --modversion gtk+-2.0`; + chomp $vers; + if ( $vers =~ /^[\d\.]+$/) { + $DEFINES{GTK_VERSION} = "\"$vers\""; + print "yes, $vers\n"; + } else { + $WITH_GTK2 = 0; + print "no\n"; + } + } + + if ( $WITH_GTK2) { + my @saveinc = @INCPATH; + my @savelib = @LIBS; + + my $inc = `pkg-config --cflags-only-I gtk+-2.0`; + chomp $inc; + my %inc = map { $_ => 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 _quote +{ + my $name = shift; + $name =~ s/'/\\'/g; + return \ "'$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; + 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 => ${_quote("$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 => ${_quote($CC)}, + cflags => ${_quote("-c $C_FLAGS $CCFLAGS")}, + cdebugflags => ${_quote($cc_specs{$COMPILER}->{cdebugflags})}, + cincflag => ${_quote($CINCPATHFLAG)}, + cobjflag => ${_quote($COUTOFLAG)}, + cdefflag => ${_quote($CDEFFLAG)}, + cdefs => [$cdefs], + objext => ${_quote($OBJ_EXT)}, + lib => ${_quote($LIB)}, + liboutflag => ${_quote($LIBOFLAG)}, + libext => ${_quote($LIB_EXT)}, + libprefix => ${_quote($LIB_PREFIX)}, + libname => ${_quote("$cwd${ifs}$pl")}, + libs => ${_quote("$cwd${ifs}$pl")}, + dlname => ${_quote("$cwd${ifs}$pt")}, + dlext => ${_quote($DL_EXT)}, + ld => ${_quote($LD)}, + ldflags => ${_quote($LD_FLAGS)}, + lddefflag => ${_quote($lddef)}, + lddebugflags => ${_quote($cc_specs{$COMPILER}->{lddebugflags})}, + ldoutflag => ${_quote($LDOUTFLAG)}, + ldlibflag => ${_quote($LDLIBFLAG)}, + ldlibpathflag => ${_quote($LDLIBPATHFLAG)}, + ldpaths => [$libpath], + ldlibs => [$ldlibs], + ldlibext => ${_quote($cc_specs{$COMPILER}->{ldlibext})}, + inline => ${_quote($DEFINES{__INLINE__})}, + perl => ${_quote($perl)}, + dl_load_flags => $DL_LOAD_FLAGS, + + libs => '$libs', + define => '$define', + inc => '$inc', +); + +1; +CONFIG + close F; +} + +sub create_meta_yml +{ + open F, '>', 'META.yml' or die "Can't open META.yml:$!\n"; +print F < +license: BSD +resources: + homepage: http://www.prima.eu.org/ + repository: http://github.com/dk/Prima +distribution_type: module +no_index: + directory: + - include + - img + - os2 + - test + - unix + - win32 + file: + - Makefile.PL + - test.pl + - ms_install.pl +generated_by: Prima/Makefile.PL +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +YAML + 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' || + m/^\./; + return if /\.(pdb|ncb|opt|dsp|dsw)$/i; # M$VC + my $f = "$File::Find::dir/$_"; + return if $f =~ /include.generic|CVS|\.git/; + 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; + print "Creating META.yml\n"; + create_meta_yml; + #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 $MAKETYPE.\n"; +} + diff --git a/README b/README index 9f08fd722..f8c1993a1 100644 --- a/README +++ b/README @@ -63,25 +63,8 @@ that means you don't have image libraries that Prima supports in your path. See PREREQUISITES section. If some of the required libraries or include files can not be found, -INCPATH+=/some/include and LIBPATH+=/some/lib semantics should be used to tell -Makefile.PL about these. - -To install Prima into a non-default directory, for example your home -directory: - - perl Makefile.PL PREFIX=$HOME/lib/perl - -If compilation process fails because Makefile contains invalid switches for -your compiler or linker, try changing these by specifying arguments to -Makefile.PL, where the most useful are: - - COMPILER - type of compiler ( gcc, emx, mscv32, bcc32, irixcc) - CC - compiler command - CFLAGS - compiler arguments - LD - linked command - LDFLAGS - linker arguments - -Look in Makefile.PL for details. +INC=-I/some/include and LIBS=-L/some/lib semantics should be used to tell +Makefile.PL about these. Check ExtUtils::MakeMaker for more. GTK2 ----