#!/usr/bin/perl # This is a simple configure script for MacOS and MPW. # Note that this script can't be run directly from MPW perl # because it has the wrong end-of-line characters. See README. # Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. # # This file is part of the GNU MP Library. # # The GNU MP Library is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 3 of the License, or (at your # option) any later version. # # The GNU MP Library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. # ***************************** NOTE ************************************** # This script tries to figure out things about this release but has a hard # time doing it. It reads some lines in "configure", "Makefile.am" and # "mp*/Makefile.am" and try to guess things. With every new release # this script has to be tested. # ***************************** NOTE ************************************** use strict; ########################################################################### # # Platform dependent # ########################################################################### $/ = "\012" # Input files use Unix end-of-line chars if $^O eq 'MacOS'; ########################################################################### # # Constants # ########################################################################### # Directories to create my @dirs = ( 'MpfObj', 'MpnObj', 'MpqObj', 'MpzObj', 'PrintfObj', 'ScanfObj', 'CmnObj', 'AsmObj', 'Asm', 'MpfBin', 'MpqBin', 'MpzBin', ); my $cfg; # Will point to %cfg_apple or %cfg_cw my %cfg_apple = ( 'cc' => 'MrC', 'coptions' => ['-ansi on -i : -i :: -i ::mpn:powerpc32 -i ::mpz', '-opt speed -inline on'], 'link' => 'PPCLink', 'linkoptions' => '-sym on -xm library', 'tooloptions' => "-t 'MPST' -c 'MPS'", 'asm' => 'PPCAsm', 'aoptions' => '-sym on', 'syslibs' => [ '"{SharedLibraries}"StdCLib', '"{SharedLibraries}"InterfaceLib', '"{SharedLibraries}"MathLib', '"{PPCLibraries}"StdCRuntime.o', '"{PPCLibraries}"PPCCRuntime.o', ], ); my %cfg_cw = ( 'cc' => 'MWCPPC', 'coptions' => [ '-opt all -w nounusedvar,noextended', '-i :: -i ::mpn:powerpc32 -i ::mpz', '-sym full', ], 'link' => 'MWLinkPPC', 'linkoptions' => '-sym fullpath -library', 'tooloptions' => '-mpwtool', 'asm' => 'PPCAsm', 'aoptions' => '-sym on', 'syslibs' => [ '"{SharedLibraries}"InterfaceLib', '"{MWPPCLibraries}MSL MPWCRuntime.Lib"', '"{MWPPCLibraries}MSL C.PPC MPW(NL).Lib"', '"{SharedLibraries}"MathLib', ], ); # We only set the variables that have a value my %vars = ( 'BITS_PER_MP_LIMB' => 32, 'HAVE_HOST_CPU_FAMILY_power' => 0, 'HAVE_HOST_CPU_FAMILY_powerpc' => 1, 'GMP_NAIL_BITS' => 0, 'DEFN_LONG_LONG_LIMB' => '', 'LIBGMP_DLL' => 0, ); my $make_in = 'Makefile.in'; my $make = 'Makefile'; my $configure = mf("../configure"); my $configure_in = mf("../configure.in"); my $config_in = mf("../config.in"); my $gmp_h = mf('../gmp.h'); my $gmp_h_in = mf('../gmp-h.in'); my $mpn_asm_dir = "../mpn/powerpc32"; my $mpn_gen_dir = "../mpn/generic"; my $config_h = 'config.h'; my $asm_start = "\ttoc"; # No dot, like ".dot"? ########################################################################### # # Read command line # ########################################################################### $cfg = \%cfg_apple; # Default if (@ARGV and $ARGV[0] =~ /^cw|co/) { $cfg = \%cfg_cw; $make .= '.cw'; } ########################################################################### # # Parse top configure file for mpn files # ########################################################################### my ($files,$optional,$package,$version) = parse_top_configure($configure); my %mpn_objects = map {$_ => 1} (@$files,@$optional); my %mpn_optional = map {$_ => 1} @$optional; ########################################################################### # # Create config.h from ../config.in # ########################################################################### my @asm_files; open(CONFIG_IN, $config_in) or die "Can't open \"$config_in\"\n"; open(CONFIG_H, ">$config_h") or die "Can't create \"$config_h\"\n"; while () { chomp; if (/^\s*#\s*undef\s+HAVE_NATIVE_mpn_(\w+)/ and -r mf("$mpn_asm_dir/$1.asm")) { if (defined delete $mpn_objects{$1}) { push(@asm_files, $1); print CONFIG_H "\#define HAVE_NATIVE_mpn_$1 1\n"; } else { print STDERR "Warning: Found asm file \"$1\" but no corresponding C file - ignoring\n"; } } elsif (/^\s*#\s*undef\s+inline\b/) { print CONFIG_H "\#define inline\n"; } elsif (/^\s*#\s*undef\s+HAVE_STDARG\b/) { print CONFIG_H "\#define HAVE_STDARG 1\n"; } elsif (/^\s*#\s*undef\s+HAVE_STRCHR\b/) { print CONFIG_H "\#define HAVE_STRCHR 1\n"; } elsif (/^\s*#\s*undef\s+HAVE_HOST_CPU_FAMILY_powerpc\b/) { print CONFIG_H "\#define HAVE_HOST_CPU_FAMILY_powerpc 1\n"; } elsif (/^\s*#\s*undef\s+WANT_TMP_NOTREENTRANT\b/) { print CONFIG_H "\#define WANT_TMP_NOTREENTRANT 1\n"; } elsif (/^\s*#\s*undef\s+PACKAGE\b/) { print CONFIG_H "\#define PACKAGE \"$package\"\n"; } elsif (/^\s*#\s*undef\s+VERSION\b/) { print CONFIG_H "\#define VERSION \"$version\"\n"; } elsif (/^\s*#\s*undef\s+STDC_HEADERS\b/) { print CONFIG_H "\#define STDC_HEADERS 1\n"; } else { # Blank line, leave it print CONFIG_H "$_\n"; } } close CONFIG_H; close CONFIG_IN; ########################################################################### # # Create gmp.h from ../gmp-h.in # ########################################################################### open(GMP_H_IN, $gmp_h_in) or die "Can't open \"$gmp_h_in\"\n"; open(GMP_H, ">$gmp_h") or die "Can't create \"$gmp_h\"\n"; while () { chomp; # Remove whatever ending it was # Do the variable substitution s/\@([^\@]+)\@/exists $vars{$1} ? $vars{$1} : ''/ge; print GMP_H "$_\n"; } close GMP_H; close GMP_H_IN; ########################################################################### # # Create directories # ########################################################################### foreach (@dirs) { -d $_ or mkdir $_, 0775 or die "Can't create directory \"$_\"\n"; } ########################################################################### # # Parse the *.asm files found and convert them to MPW format # ########################################################################### my $file; foreach $file (@asm_files) { my $ifile = mf("$mpn_asm_dir/$file.asm"); my $ofile = mf("Asm/$file.s"); my $func; my %defs = (); open(ASM, $ifile) or die "Can't read file \"$ifile\"\n"; open(NEW, ">$ofile") or die "Can't create file \"$ofile\"\n"; while () { chomp; # Remove whatever ending it was s/\bdnl\b/;/ or s/\bC\b/;/; # Use ; comments s/include\s*\(.*?\)//; # Don't use include macro s/ASM_START\s*\(.*?\)/$asm_start/; if (s/PROLOGUE\s*\(\s*(.*?)\s*\)/asm_prologue($1)/e) { $func = $1; } s/EPILOGUE\s*\(\s*(.*?)\s*\)/asm_epilogue($func)/e; s/L\(([^)]*)\)/L$1/g; # L() style labels # register name defines if (/\bdefine\(`?([a-zA-Z0-9]+)'?,`?([^')]*)\'?\)/) { $defs{$1} = $2; $_ = "\n"; } foreach my $i (keys %defs) { s/\b\Q$i\E\b/$defs{$i}/g; } s/\n/\x0D/g; print NEW "$_\x0D"; # Use MacOS end-of-line character } close ASM; close NEW; } ########################################################################### # # Parse the Makefile.in and produce the Makefile # ########################################################################### # Check if we have optional left in C directory foreach (keys %mpn_objects) { delete $mpn_objects{$_} if $mpn_optional{$_} and !-r mf("$mpn_gen_dir/$_.c"); } my $mpn_objects = join(' ', map {"{MpnObjDir}$_.o"} sort keys %mpn_objects); $mpn_objects =~ s/(.{1,66})\s/$1 \xB6\x0D\t/g; my @asm_objects = @asm_files; my @asm_sources = @asm_files; # Adjust configuration foreach (keys %{$cfg}) { $$cfg{$_} = join(" \xB6\x0D\t\t", @{$$cfg{$_}}) if ref $$cfg{$_}; } my %config = ( 'version' => $version, 'package' => $package, 'c' => "\xB6", 'dep' => "\xC4", 'wildcard'=> "\xC5", 'asm_objects' => join(" \xB6\x0D\t",map {$_ = "{AsmObjDir}$_.o"} sort @asm_objects), 'asm_sources' => join(" \xB6\x0D\t",map {$_ = "{AsmSrcDir}$_.s"} sort @asm_sources), 'mpn_objects' => $mpn_objects, 'mpz_objects' => what_objects("mpz","../mpz","{MpzObjDir}"), 'mpf_objects' => what_objects("mpf","../mpf","{MpfObjDir}"), 'mpq_objects' => what_objects("mpq","../mpq","{MpqObjDir}"), 'printf_objects' => what_objects("printf","../printf","{PrintfObjDir}"), 'scanf_objects' => what_objects("scanf","../scanf","{ScanfObjDir}"), 'gmp_objects' => what_objects("gmp","..", "{CmnObjDir}"), %{$cfg}, ); open(IN, $make_in) or die "Can't read file \"$make_in\"\n"; open(OUT, ">$make") or die "Can't create file \"$make\"\n"; while () { chomp; # Remove whatever ending it was # Do the variable substitution s/\@([^\@]+)\@/exists $config{$1} ? $config{$1} : ''/ge; print OUT "$_\x0D"; # Use MacOS end-of-line character } close IN; close OUT; ########################################################################### # # Parse the configure.in file to find the mpn files to compile and link # Find package name and version # ########################################################################### sub parse_top_configure { my $cfg = shift; open(CONFIGURE, $cfg) or die "Can't open \"$cfg\"\n"; my $old_eol = $/; undef $/; my $text = ; $/ = $old_eol; close CONFIGURE; my ($package) = $text =~ /(?:\n|\r)PACKAGE_NAME\s*=\s*(\S+)/; my ($version) = $text =~ /(?:\n|\r)PACKAGE_VERSION\s*=\s*(\S+)/; my $files = join(' ',$text =~ /(?:\n|\r)gmp_mpn_functions\s*=\s*\"([^\"]+)/); $files =~ s/\\/ /g; $files =~ s/\$\{?\w*\}?//g; my @files = sort split(' ',$files); $files = join(' ',$text =~ /(?:\n|\r)gmp_mpn_functions_optional\s*=\s*\"([^\"]+)/); $files =~ s/\\/ /g; $files =~ s/\$\{?\w*\}?//g; my @optional = sort split(' ',$files); @files > 30 or die "Can't find mpn files in \"$cfg\"\n"; defined $package or die "Can't find package name in \"$cfg\"\n"; defined $version or die "Can't find version name in \"$cfg\"\n"; return (\@files,\@optional,$package,$version); } ########################################################################### # # Find the C files for mpz, mpf ..... # ########################################################################### sub what_objects { my $part = shift; my $srcdir = shift; my $dstdir = shift; my $makefile_am = mf("$srcdir/Makefile.am"); # We look in the Makefile.am file open(MAKEFILE_AM, $makefile_am) or die "Can't open file \"$makefile_am\"\n"; # I had as short version of this using more advanced # regular expressions on the whole file content but # MacPerl freezes my Mac every time..... :-( my $line; my $text = ''; while (defined($line = ) ) { chomp $line; if ($line =~ s/^lib${part}_la_SOURCES\s*=//) { do { chomp $line; if ($line =~ s/\\\s*$//) { $text .= " $line"; } else { $text .= " $line"; next; } } while (defined($line = )); } if ($line =~ s/^nodist_lib${part}_la_SOURCES\s*=//) { do { chomp $line; if ($line =~ s/\\\s*$//) { $text .= " $line"; } else { $text .= " $line"; last; } } while (defined($line = )); } } close MAKEFILE_AM; my @ofiles = split(' ',$text); @ofiles > 8 or die "Can't find $part files in \"$makefile_am\"\n"; my $ofiles = join(' ', map {/^(.+)\.c$/ and $_ = "$dstdir$1.o"} @ofiles); $ofiles =~ s/(.{1,66})\s/$1 \xB6\x0D\t/g; return $ofiles; } ########################################################################### # # Assembler # ########################################################################### sub asm_epilogue { my $func = shift; return "\tcsect .__g$func\[pr]"; } sub asm_prologue { my $func = shift; my $asm = <