#!/usr/bin/env -i /usr/bin/perl # -*- mode: Perl; tab-width: 4; -*- # vim: ts=4 sw=4 noet # # bootstrap - perl script to install and bootstrap a Fink # installation from source # # Fink - a package manager that downloads source and installs it # Copyright (c) 2001 Christoph Pfisterer # Copyright (c) 2001-2023 The Fink Package Manager Team # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA. # use 5.008_001; # perl 5.8.1 or newer required use strict; use warnings; $ENV{'PATH'} = "/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/X11/bin:/opt/X11/bin"; use FindBin; use lib "$FindBin::RealBin/perlmod"; use IO::Handle; use version 0.77; # beware of old, stray FinkVersion.pm files unlink "$FindBin::RealBin/perlmod/Fink/FinkVersion.pm"; # load some Fink modules require Fink::CLI; Fink::CLI->import(qw(&print_breaking &prompt &prompt_boolean &prompt_selection)); require Fink::Services; Fink::Services->import(qw(&execute &version_cmp &is_accessible)); $| = 1; my $homebase = $FindBin::RealBin; chdir $homebase; ### choose root method if ($> != 0) { # not root now...prompt to determine how to relaunch self my $sel_intro = "Fink must be installed and run with superuser (root) ". "privileges. Fink can automatically try to become ". "root when it's run from a user account. Since you're ". "currently running this script as a normal user, the ". "method you choose will also be used immediately for ". "this script. Available methods:"; my $answer = &prompt_selection("Choose a method:", intro => $sel_intro, default => [ value => "sudo" ], choices => [ "Use sudo" => "sudo", "Use su" => "su", "None, fink must be run as root" => "none" ] ); my $cmd = "'$homebase/bootstrap' .$answer"; if ($#ARGV >= 0) { $cmd .= " '".join("' '", @ARGV)."'"; } if ($answer eq "sudo") { my $env = ''; $env = "/usr/bin/env PERL5LIB='$ENV{'PERL5LIB'}'" if (exists $ENV{'PERL5LIB'} and defined $ENV{'PERL5LIB'}); $cmd = "/usr/bin/sudo $env $cmd"; } elsif ($answer eq "su") { $cmd = "$cmd | /usr/bin/su"; } else { print "ERROR: Can't continue as non-root.\n"; exit 1; } print "\n"; exit &execute($cmd, quiet=>1); } ### get the architecture... (and offer a choice to users where appropriate) my $arch; foreach ('/usr/bin/uname', '/bin/uname') { # check some common places (why aren't we using $ENV{PATH}?) if (-x $_) { chomp($arch = `$_ -p 2>/dev/null`); chomp($arch = `$_ -m 2>/dev/null`) if ($arch eq ""); last; } } if (not defined $arch) { die "Could not find an 'arch' executable\n"; } ### if architecture is i386, and darwin is at least 9, then test for ### 64bit capability my ($version, $vers); foreach (split /:/, $ENV{PATH}) { # check some common places (why aren't we using $ENV{PATH}?) if (-x $_) { chomp($version = `$_/uname -r 2>/dev/null`); last; } } ($vers) = split( /\./, $version ); # are we on intel? if ($arch eq "i386") { # is Darwin at least 9? if ((defined $vers) and ($vers >= 9)) { # check for 64bit capability my $is64bit = 0; if (open(SYSCTL, 'sysctl -a 2>/dev/null |')) { my ($key, $value); while () { ($key, $value) = $_ =~ /^(\S+)\s*\:\s*(.*?)\s*$/; next unless (defined $key and defined $value); if ($key =~ /^(hw.optional.x86_64|hw.optional.64bitops|hw.cpu64bit_capable)$/ and $value eq "1") { $is64bit = 1; last; } } close(SYSCTL); } if (!$is64bit && $vers > 10) { # 10.7+ 32bit: non-supported configuration! print "ERROR: fink requires a 64-bit-capable CPU for your version of macOS\n"; exit 1; } elsif ($vers >= 11) { # on 10.7+ we support only 64-bit $arch = "x86_64"; # check that JDK/Legacy Java SDK is installed (otherwise Lion+ autoinstalls it on-demand) if (-x '/usr/bin/javac') { my $need_java_sdk = `/usr/bin/javac -version 2>&1>/dev/null`; if ($need_java_sdk =~ m/No Java runtime present\, requesting install\./) { die "Please install an Oracle JDK from\n" . "https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html\n" . "or\n" . "https://www.oracle.com/technetwork/java/javase/downloads/index.html\n" . "or the Apple Legacy Java package (macOS 10.7-10.13) from\n" . "https://support.apple.com/kb/DL1572\n" . "before re-attempting the fink bootstrap.\n"; } } } elsif ($is64bit) { # 10.[56] can do either 32- or 64-bit: user choice if ($vers == 10) { # prefer 64-bit on 10.6 though: my $arch_intro= "Your hardware is a 64bit-compatible intel " . "processor, so you have the option of running Fink in ". "64bit-only mode. This is recommended for most ". "users, since newer versions of macOS are all 64bit-only, ". "so using the 64bit-only distribution should be closer ". "to the distributions for newer OSes. It used to be ". "the case that the 32-bit distribution had significantly ". "more packages than the 32-bit one, but that gap has ". "closed recently, and the 64bit-only distribution does ". "actually contain some 32-bit packages. ". "Which mode would you like to use?"; $arch = &prompt_selection("Choose a mode:", intro => $arch_intro, default => [ value => "x86_64" ], choices => [ "mostly 32bit" => "i386" , "mostly 64bit" => "x86_64" ]); } elsif ($vers == 9) { my $arch_intro= "Your hardware is a 64bit-compatible intel " . "processor, so you have the option of running Fink in ". "64bit-only mode. This is not recommended for most ". "users, since many more packages are available for the ". "default mode (which is mostly 32bit but includes some ". "64bit packages). Which mode would you like to use?"; $arch = &prompt_selection("Choose a mode:", intro => $arch_intro, default => [ value => "i386" ], choices => [ "Default (mostly 32bit)" => "i386" , "64bit-only" => "x86_64" ]); # it is already the case that $vers == 9 in this condition, so no need to check for it again: if ($arch eq "x86_64") { my $answer = &prompt_boolean("\nWARNING: On Mac OS X 10.5, ". "selecting 64bit-only mode will ". "not allow you to build perl ". "modules that work with the ". "built-in /usr/bin/perl. (They ". "will work with fink's perl ". "however.) Are you sure you ". "want to do this?", default => 0); &print_breaking("\n"); $arch = "i386" unless ($answer); } } } # 32-bit-only machines get no choice, and $arch is already set to 'i386', so do nothing else. } } ### patch FinkVersion.pm.in ### { my $output = "$FindBin::RealBin/perlmod/Fink/FinkVersion.pm"; my $outputhandle = IO::Handle->new(); my $input = $output . '.in'; my $inputhandle = IO::Handle->new(); chomp(my $version = `cat VERSION`); open($inputhandle, '<', $input ) or die "ERROR: Cannot open $input for reading: $!\n"; open($outputhandle, '>', $output) or die "ERROR: Cannot open $output for writing: $!\n"; while (defined ($_=<$inputhandle>)) { s/\@VERSION\@/$version/g; s/\@ARCHITECTURE\@/$arch/g; print $outputhandle $_; } close $inputhandle; close $outputhandle; } ### check if we are unharmed ### print "Checking package..."; require Fink::Bootstrap; Fink::Bootstrap->import(qw(&check_host &check_files)); require Fink::FinkVersion; Fink::FinkVersion->import(qw(&fink_version &default_binary_version &get_arch)); if( check_files() == 1 ) { exit 1; } printf " looks good (fink-%s).\n", fink_version(); ### load some modules require Fink::Services; Fink::Services->import(qw(&read_config &execute)); require Fink::CLI; Fink::CLI->import(qw(&print_breaking &prompt &prompt_boolean &prompt_selection)); Fink::Bootstrap->import(qw(&create_tarball &fink_packagefiles ©_description &get_version_revision &get_selfupdatetrees &get_bsbase)); ### check if we like this system print "Checking system..."; my ($host, $distribution); $host = `update/config.guess`; chomp($host); if ($host =~ /^\s*$/) { print " ERROR: Can't determine host type.\n"; exit 1; } print " $host\n"; $distribution = check_host($host,1,$arch); if (($distribution eq "unknown") or (version->parse('v'.$distribution) lt version->parse("v10.7"))) { exit(1); } print "Distribution: $distribution\n"; print "Architecture: $arch\n"; ### get version my ($packageversion, $packagerevision) = &get_version_revision(".",$distribution); # root method has already been chosen # (so I'm not sure why this code is still here...) my ($rootmethod); if (defined $ARGV[0] and substr($ARGV[0],0,1) eq ".") { $rootmethod = shift; $rootmethod = substr($rootmethod,1); } else { print "\n"; &print_breaking("Fink must be installed and run with superuser (root) ". "privileges. Fink can automatically try to become ". "root when it's run from a user account. ". "Available methods:"); $rootmethod = &prompt_selection("Choose a method:", default => [ value => "sudo" ], choices => [ "Use sudo" => "sudo", "Use su" => "su", "None, fink must be run as root" => "none" ] ); } umask oct("022"); ### run some more system tests print "Checking cc..."; if (-x "/usr/bin/cc") { print " looks good.\n"; } else { print " not found.\n"; &print_breaking("ERROR: There is no C compiler on your system. ". "Make sure that the Developer Tools are installed."); exit 1; } print "Checking make..."; if (-x "/usr/bin/make") { my $response = `/usr/bin/make --version 2>&1`; if ($response =~ /GNU Make/si) { print " looks good.\n"; } else { print " is not GNU make.\n"; &print_breaking("ERROR: /usr/bin/make exists, but is not the ". "GNU version. You must correct this situation before ". "installing Fink. /usr/bin/make should be a symlink ". "pointing to /usr/bin/gnumake."); exit 1; } } else { print " not found.\n"; &print_breaking("ERROR: There is no make utility on your system. ". "Make sure that the Developer Tools are installed."); exit 1; } print "Checking head..."; if (-x "/usr/bin/head") { my $response = `/usr/bin/head -1 /dev/null 2>&1`; if ($response =~ /Unknown option/si) { print " is broken.\n"; &print_breaking("ERROR: /usr/bin/head seems to be corrupted. ". "This can happen if you manually installed Perl libwww. ". "You'll have to restore /usr/bin/head from another ". "machine or from installation media."); exit 1; } else { print " looks good.\n"; } } else { print " not found.\n"; &print_breaking("ERROR: There is no head utility on your system. ". "Make sure that the Developer Tools are installed."); exit 1; } ### Check for allowable Xcode my $xcode_version; { # Compare Xcode version to allowed range via Fink::Services::version_cmp(). # AKH Maybe replace with 'use version', qv() , and the standard comparison # operators once 10.5 is no longer supported, as long as we don't use # epochs in the xcode* virtual packages. # minimum Xcode versions: my ($min_xcode, $max_xcode); if ($vers == 9) { $min_xcode="3.0"; $max_xcode="3.1.4"; } elsif ($vers == 10) { $min_xcode="3.2"; $max_xcode="4.2"; } elsif ($vers == 11) { $min_xcode="4.1"; $max_xcode="4.6.3"; } elsif ($vers == 12) { $min_xcode="4.4"; $max_xcode="5.1.1"; } elsif ($vers == 13) { $min_xcode="5.0"; $max_xcode="6.2"; } elsif ($vers == 14) { $min_xcode="6.0"; $max_xcode="7.2.1"; } elsif ($vers == 15) { $min_xcode="7.0"; $max_xcode="8.2.1"; } elsif ($vers == 16) { $min_xcode="8.0"; $max_xcode="9.2"; } elsif ($vers == 17) { $min_xcode="9.0"; $max_xcode="10.1"; } elsif ($vers == 18) { $min_xcode="10.0"; $max_xcode="11.3.1"; } elsif ($vers == 19) { $min_xcode="11.0"; $max_xcode="12.4"; } elsif ($vers == 20) { $min_xcode="12.0"; $max_xcode="13.2.1"; } elsif ($vers == 21) { $min_xcode="13.0"; # Only set the maximum xcode version once it's definite to avoid deadlocks. $max_xcode="99.99.99"; } elsif ($vers >= 22) { $min_xcode="14.1"; # Only set the maximum xcode version once it's definite to avoid deadlocks. $max_xcode="99.99.99"; } else { die "ERROR:\n\tUnsupported macOS version.\n"; } print "Verifying that installed Xcode Command Line Tools version is supported...\n"; # Die if there are no Xcode CLI tools, at minimum. die "ERROR:\n\tNo Xcode command-line tools installed. Install them (or all of Xcode).\n" unless (-x "/usr/bin/xcodebuild"); # check Xcode version here since there are monolithic Xcode options for 10.7 ($xcode_version) = (`xcodebuild -version` =~ /Xcode\s(\d+\.\d+\.?(\d+)?)\n/); $xcode_version = '0.0' if !defined $xcode_version; # set a value for later # Check that we're using the right CLI tools for the OS. my ($receipt_to_check, $os_dep_error_msg, $error_msg)=('','',''); my $os_indep_error_msg1 = "ERROR: I couldn't find the correct receipt for the Command Line Tools\n". "for your OS X version. Tools from a prior OS X version won't work properly.\n"; my $os_indep_error_msg2 = "or downloading them from developer.apple.com.\n". "After they are installed, try the bootstrap operation again.\n" ; if ($vers >= 13) { $receipt_to_check = "com.apple.pkg.CLTools_Executables"; $os_dep_error_msg = "You can install them by running the command\n". "\n\txcode-select --install\n\n". "in a terminal window and then selecting Install in the dialog window that\n". "pops up, "; } elsif ($vers == 12 or $vers == 11) { # 10.7 or 10.8 $receipt_to_check = "com.apple.pkg.DeveloperToolsCLI"; $os_dep_error_msg = "You can install them via the Downloads Pane of the Xcode Preferences,\n"; } else { # 10.6- $receipt_to_check = "com.apple.pkg.bogus"; } # this will look insane for a monolithic xcode, but should not be seen in that case. $error_msg = $os_indep_error_msg1 . $os_dep_error_msg . $os_indep_error_msg2; chomp(my $result = `pkgutil --pkg-info $receipt_to_check 2>&1`); if (not $?) { # didn't fail # iterate over output lines and grab version my $version; foreach (split /\n/, $result) { ($version) = /version:\s(.*)$/; last if $version; } # TODO: Should we check if we're in the legal range of CLI tools on 10.7/10.8? print "$version is OK\n"; # We'll continue to use &version_cmp() in case we need to put an Epoch on an Xcode # version someday. } elsif (&version_cmp ("$xcode_version", "<<", "4.3")) { # failed, but using monolithic Xcode print "Skipping.\nXcode $xcode_version is monolithic and includes command-line tools.\n"; } else { # all other failures die $error_msg; } print "Verifying that installed Xcode app version is supported...\n"; if ($xcode_version eq '0.0') { # OS version specific messages if ($vers < 11) { die "ERROR:\n\tXcode is not set up properly.\n"; } else{ warn "\nNOTE: If you are using only the Command-line Tools for Xcode,\n". "it's OK to ignore the messages immediately above and below this one.\n\n". "If you _do_ want the full Xcode to work with Fink, then\n". "you'll want to verify where your Xcode application actually\n". "is, and use\n". "\n\tsudo xcode-select -switch /path/to/Xcode.app\n\n". "to switch that (replacing /path/to by the path to it, of course).\n"; } } else { print "Found Xcode version: $xcode_version"; if (&version_cmp ("$xcode_version", "<<", "$min_xcode")) { & print_breaking ( "\nERROR: This version of fink needs at least ". "Xcode ".$min_xcode." on this OS X version.\n"); exit 1; } elsif (&version_cmp ("$xcode_version", ">>", "$max_xcode")) { & print_breaking ( "\nERROR: This version of fink needs at most ". "Xcode ".$max_xcode." on this OS X version.\n"); exit 1; } else { print " is OK.\n"; } } } ## Check for required features which are normally installed. ## Currently quit if pod2man isn't available and executable, ## to avoid folks nearly building fink and then having it crap out. system "./pre-build-test.sh" and exit 1; ### setup the correct packages directory # (no longer needed: we just use $distribution directly...) # #if (-e "packages") { # rename "packages", "packages-old"; # unlink "packages"; #} #symlink "$distribution", "packages" or die "Cannot create symlink"; ### choose installation path # Check if a location has installed software sub has_installed_software { my $loc = shift; return (0 != grep {-d "$loc/$_"} (qw/ bin lib include etc /)); } my $retrying = 0; my $nonstandard_warning = 0; my $installto = shift || ""; OPT_BASEPATH: { ### install path redo block # ask if the path wasn't passed as a parameter if ($retrying || not $installto) { my $default; my $install_path; if ($vers <= 18) { $default = '/sw'; $install_path = $default; } else { $default = '/opt/sw'; $install_path = $default; } while (1) { last if !has_installed_software($install_path); $install_path =~ /^(.*?)(\d*)$/; $install_path = $1 . (($2 || 1) + 1); } print "\n"; if ($install_path ne $default && !$nonstandard_warning) { print "It looks like you already have Fink installed in $default, trying " . "$install_path instead.\n\n" . "WARNING: This is a non-standard location.\n\n"; $nonstandard_warning = 1; } my $prompt = "Please choose the path where Fink should be installed. Note " . "that you will normally be able to use a binary distribution only if you " . "choose '/opt/sw' (or '/sw' on systems before 10.15)."; $installto = &prompt($prompt, default => $install_path); } $retrying = 1; print "\n"; # catch formal errors if ($installto eq "") { print "ERROR: Install path is empty.\n"; redo OPT_BASEPATH; } if (substr($installto,0,1) ne "/") { print "ERROR: Install path '$installto' doesn't start with a slash.\n"; redo OPT_BASEPATH; } if ($installto =~ /\s/) { print "ERROR: Install path '$installto' contains whitespace.\n"; redo OPT_BASEPATH; } # consolidate slashes (foo//bar == foo/bar but could confuse parsers) $installto =~ s,//+,/,g; # remove trailing slash $installto =~ s,^(/.*?)/*$,$1,; # check well-known path (NB: these are regexes!) foreach my $forbidden ( qw(/ /etc /usr /var /bin /sbin /lib /tmp /dev /usr/lib /usr/include /usr/bin /usr/sbin /usr/share /usr/libexec /usr/X11R6 /usr/X11 /opt/X11 /root /private /cores /boot /debian /debian/.* /usr/local /usr/local/.* /opt/local /opt/local/.* /opt/homebrew /opt/homebrew/.*) ) { if ($installto =~ /^$forbidden$/i) { print "ERROR: Refusing to install into '$installto'.\n"; if ($installto =~ /^\/usr\/local/) { &print_breaking( "/usr/local is a common place that other third-party software ". "uses, so installing in that area often leads to conflicts ". "between them and breakage of fink and/or other things there. ". "In addition, this hierarchy is automatically used by Xcode and ". "other compilers, which often leads to unexpected and sometimes ". "unpredictable results for when fink-supplied files are installed ". "there and for fink itself."); } if ($installto =~ /^\/opt\/local/) { &print_breaking( "/opt/local is the default location that Macports ". "uses, so installing there is likely to lead to problems."); } if ($installto =~ /^\/opt\/homebrew/) { &print_breaking( "/opt/homebrew is the default location that Homebrew ". "uses on M1 systems, so installing there is likely to ". "lead to problems."); } redo OPT_BASEPATH; } } # Check whether the whole path containing basepath is world-accessible, # since the fink-bld user can't operate when it isn't. my ($status,$path_test) = &is_accessible($installto,'5'); # we need at least world-read and world-execute if ($status) { &print_breaking("ERROR: '$path_test' is not a directory. ". "Pick a different directory."); redo OPT_BASEPATH; } if ($path_test) { &print_breaking("ERROR: '$path_test' is not both world-readable and world-executable, ". "as required to build most Fink packages. Either ". "change the permissions via:". "\n\nsudo chmod -R o+rx $path_test\n\n". "or install Fink into a different directory."); redo OPT_BASEPATH; } if (-d $installto) { # check existing contents if (has_installed_software $installto) { &print_breaking("ERROR: '$installto' exists and contains installed ". "software. Refusing to install there."); redo OPT_BASEPATH; } else { &print_breaking("WARNING: '$installto' already exists. If bootstrapping ". "fails, try removing the directory altogether and ". "re-run bootstrap."); } } else { &print_breaking("OK, installing into '$installto'."); } print "\n"; } ### create directories print "Creating directories...\n"; if (not -d $installto) { if (&execute("/bin/mkdir -p -m755 $installto")) { print "ERROR: Can't create directory '$installto'.\n"; exit 1; } } { my @cmd_out = `/bin/df -P "$installto"`; @cmd_out = split /\s+/, $cmd_out[1]; my $cmd = "/usr/sbin/diskutil info \"$cmd_out[-1]\" 2>&1"; @cmd_out = `$cmd`; if (!@cmd_out || $?) { &print_breaking("Could not run `$cmd` so we cannot test that the target volume has permissions enabled. Continuing anyway, but there may be failures if permissions are not enabled on target volume."); } else { @cmd_out = map { /(?:Permissions|Owners):\s*(Enabled|Disabled)/ } @cmd_out; if (@cmd_out != 1) { &print_breaking("Could not find Owners or Permissions flag in output of `$cmd` so we cannot test that the target volume has permissions enabled. Continuing anyway, but there may be failures if permissions are not enabled on target volume."); } elsif ($cmd_out[0] ne 'Enabled') { &print_breaking("ERROR: Target volume does not have permissions enabled."); exit 1; } } } my $selfupdatetrees = get_selfupdatetrees($distribution); my $fink_trees = &Fink::Config::fink_tree_default($distribution); my @dirlist = qw(etc etc/alternatives etc/apt src fink fink/debs var var/lib var/lib/fink); push @dirlist, "fink/$selfupdatetrees", "fink/$selfupdatetrees/stable", "fink/$selfupdatetrees/local"; foreach my $dir (split(/ /,$fink_trees)) { push @dirlist, "fink/$selfupdatetrees/$dir", "fink/$selfupdatetrees/$dir/finkinfo", "fink/$selfupdatetrees/$dir/binary-darwin-$arch"; } foreach my $dir (@dirlist) { if (not -d "$installto/$dir") { if (&execute("/bin/mkdir -m755 $installto/$dir")) { print "ERROR: Can't create directory '$installto/$dir'.\n"; exit 1; } } } # install the initial Release and Packages.gz files my ($dr,$arv,$comp); foreach $dr (split(/ /,$fink_trees)) { ($arv,$comp) = split(/\//, $dr); &execute("/usr/bin/sed -e \"s,\@ARV\@,$arv,\" -e \"s,\@COMP\@,$comp,\" -e \"s,\@ARCH\@,$arch,\" < Release > $installto/fink/$selfupdatetrees/$dr/binary-darwin-$arch/Release; /usr/bin/touch $installto/fink/$selfupdatetrees/$dr/binary-darwin-$arch/Packages; /usr/bin/gzip $installto/fink/$selfupdatetrees/$dr/binary-darwin-$arch/Packages"); } unlink "$installto/fink/dists"; symlink "$distribution", "$installto/fink/dists" or die "ERROR: Can't create symlink $installto/fink/dists\n"; ### for now, we simply symlink $distribution to $selfupdatetrees, but eventually we may need to do something more complicated if (not $selfupdatetrees eq $distribution) { symlink "$selfupdatetrees", "$installto/fink/$distribution" or die "ERROR: Can't create symlink $installto/fink/$distribution\n"; } ### create fink tarball for bootstrap my $packagefiles = &fink_packagefiles(); if ( &create_tarball($installto, "fink", $packageversion, $packagefiles) == 1 ) { exit 1; } ### copy package info needed for bootstrap { my $script = "/bin/mkdir -p $installto/fink/dists/stable/main/finkinfo/base\n"; $script .= "/bin/cp $selfupdatetrees/*.info $selfupdatetrees/*.patch $installto/fink/dists/stable/main/finkinfo/base/\n"; $script .= "echo \"bootstrap\" > $installto/fink/dists/VERSION\n"; $script .= "/bin/chmod 644 $installto/fink/dists/VERSION\n"; if (($arch eq "x86_64") and ($distribution eq "10.5")) { if ( ©_description($script,$installto, "fink", $packageversion, $packagerevision, "stable/main/finkinfo/base", "fink-x86_64.info", "fink-x86_64.info.in" ) == 1 ) { exit 1; } } else { if ( ©_description($script,$installto, "fink", $packageversion, $packagerevision, "stable/main/finkinfo/base", "fink-$distribution.info", "fink.info.in" ) == 1 ) { exit 1; } } } ### create f-v-p bootstrap { print "Creating f-v-p bootstrap configuration...\n"; my $cmd = 'sed -e "s|@BASEPATH@|' . $installto . '|g" -e "s|@LIBPATH@|' . $homebase . '/perlmod|g" < "fink-virtual-pkgs.in" > "fink-virtual-pkgs-bootstrap";'; $cmd .= "chmod +x fink-virtual-pkgs-bootstrap;"; if (&execute($cmd, quiet=>0)) { exit 1; } } ### load the Fink modules require Fink::Config; require Fink::Engine; require Fink::Configure; require Fink::Bootstrap; ### setup initial configuration print "Creating initial configuration...\n"; my ($configpath, $config); $configpath = "$installto/etc/fink.conf"; open(CONFIG, '>', $configpath) or die "can't create configuration $configpath: $!\n"; print CONFIG <<"EOF"; # Fink configuration, initially created by bootstrap Basepath: $installto RootMethod: $rootmethod Trees: $fink_trees Distribution: $distribution SelfUpdateTrees: $selfupdatetrees EOF close(CONFIG) or die "can't write configuration $configpath: $!\n"; $config = &read_config($configpath); # override path to data files (update, mirror) no warnings 'once'; $Fink::Config::libpath = $homebase; use warnings 'once'; Fink::Engine->new_with_config($config); ### interactive configuration Fink::Configure::configure(); if (($arch eq "x86_64") and ($distribution eq "10.5")) { Fink::Bootstrap::bootstrap1("perl588-bootstrap"); } else { Fink::Bootstrap::bootstrap1(); } my $bsbase = get_bsbase(); my $cmd = "'$homebase/bootstrap-phase2.pl'"; my $perlexe = "/usr/bin/perl"; #default # override defaults if ($distribution eq "10.6") { $perlexe = "/usr/bin/arch -arch $arch /usr/bin/perl5.10.0"; } elsif (($distribution eq "10.7") or ($distribution eq "10.8")) { $perlexe = "/usr/bin/arch -arch $arch /usr/bin/perl5.12"; } elsif ($distribution eq "10.9") { $perlexe = "/usr/bin/arch -arch $arch /usr/bin/perl5.16"; } elsif ($distribution eq "10.10") { $perlexe = "/usr/bin/arch -arch $arch /usr/bin/perl5.18"; } elsif (($arch eq "x86_64") and ($distribution eq "10.5")) { $perlexe = "$bsbase/bin/perl5.8.8"; } $cmd = "/usr/bin/env -i $perlexe $cmd $installto"; &execute($cmd, quiet=>0); if (&execute($cmd, quiet=>0)) { print "\nERROR: Bootstrap phase 2 failed!\n"; exit 1; } Fink::Bootstrap::bootstrap3(); ### remove tar-bootstrap.info, tar-bootstrap.patch, dpkg-bootstrap.info, dpkg-bootstrap.patch, and perl588-bootstrap.info to avoid later confusion &execute("/bin/rm -f $installto/fink/dists/stable/main/finkinfo/base/tar-bootstrap.info $installto/fink/dists/stable/main/finkinfo/base/tar-bootstrap.patch $installto/fink/dists/stable/main/finkinfo/base/dpkg-bootstrap.info $installto/fink/dists/stable/main/finkinfo/base/dpkg-bootstrap.patch $installto/fink/dists/stable/main/finkinfo/base/perl588-bootstrap.info"); ### copy included package info tree if present my $showversion = ""; if ($packageversion !~ /cvs/) { $showversion = "-$packageversion"; } my $endmsg = "Internal error."; my $dbv = default_binary_version($distribution); if (-d "$homebase/pkginfo") { if (&execute("cd $homebase/pkginfo && ./inject.pl $installto -quiet")) { # inject failed $endmsg = <<"EOF"; Copying the package description tree failed. This is no big harm; your Fink installation should work nonetheless. You can add the package descriptions at a later time if you want to compile packages yourself. You can get them EOF $endmsg .= " by running either of the commands: 'fink selfupdate-rsync', to update via rsync (generally preferred); or 'fink selfupdate-svn', to update via svn (more likely to work through a firewall)." ; } else { # inject worked $endmsg = <<"EOF"; You should now have a working Fink installation in '$installto'. EOF } } else { # this was not the 'full' tarball $endmsg = <<"EOF"; You should now have a working Fink installation in '$installto'. You still need package descriptions if you want to compile packages yourself. You can get them EOF if (defined $dbv) { $endmsg .= "by installing the dists-$distribution-$dbv.tar.gz tarball, or"; } $endmsg .= " by running either of the commands: 'fink selfupdate-rsync', to update via rsync (generally preferred); or 'fink selfupdate-svn', to update via svn (more likely to work through a firewall)."; } ### create Packages.gz files for apt ### we use the just-installed fink rather than directly calling ### Fink::Engine::cmd_scanpackages() because we might be running ### under the wrong perl &execute("$installto/bin/fink scanpackages"); ### the final words... $endmsg =~ s/\s+/ /gs; $endmsg =~ s/ $//; $endmsg .= " You should also run 'sudo xcodebuild -license' and accept the Xcode ". "license, since some packages will require this.\n" if (&version_cmp ("$xcode_version", ">=", "4.3")); print "\n"; &print_breaking($endmsg); print "\n"; &print_breaking( "Run '. $installto/bin/init.sh' to set up this terminal session ". "environment to use Fink. To make the software installed by Fink ". "available in all of your future terminal shells, add ". "'. $installto/bin/init.sh' to the init scripts '.zprofile', ". "'.profile', or '.bash_profile' in your home directory. The program ". "$installto/bin/pathsetup.sh can help with this. Enjoy." ); print "\n"; ### eof exit 0;