From 73bc87a49f0392e69864aa6e01c85221b0366b87 Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Thu, 3 Jan 2008 14:35:35 +0000 Subject: [PATCH] Added simple perl script to re-write dependencies for Mac OS app bundles SVN-Revision: 5243 --- tools/darwin/makebundle.pl | 126 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100755 tools/darwin/makebundle.pl diff --git a/tools/darwin/makebundle.pl b/tools/darwin/makebundle.pl new file mode 100755 index 000000000..571fa5b82 --- /dev/null +++ b/tools/darwin/makebundle.pl @@ -0,0 +1,126 @@ +#!/opt/local/bin/perl + +# +# makebundle.pl - copies and makes portable a binary and all its dependencies +# Copyright (C) 2007 Christoph Sommer +# +# 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +use strict; +use warnings; + +# Script does some dangerous stuff - make sure a user will double-check everything before running it. +print "This script is highly experimental. Modify it to suit your needs and take care to run it only in controlled environments.\n"; + +# This line needs to be removed, the following lines adjusted. +exit 1; + +my $OUTPUTDIR='/tmp/SuperTux.app/Contents/MacOS'; +my $EXECUTABLE='./supertux2'; + +my %COPIED; +my @TOCOPY; +my %PATCHED; +my @TOPATCH; + +system('mkdir '.$OUTPUTDIR); + +push (@TOCOPY, $EXECUTABLE); + +# first, copy all direct and indirect dependencies to OUTPUTDIR +while (my $EXECUTABLE = pop @TOCOPY) { + + next if $COPIED{$EXECUTABLE}; + $COPIED{$EXECUTABLE} = 1; + + next unless $EXECUTABLE =~ /^(.*)\/(.*)$/; + my $PATH = $1; + my $FNAME = $2; + + print("copying ".$EXECUTABLE."\n"); + + system('cp '.$EXECUTABLE.' '.$OUTPUTDIR.'/'.$FNAME); + system('chmod u+w '.$OUTPUTDIR.'/'.$FNAME); + + # mark the copy as to-be-patched + push(@TOPATCH, $OUTPUTDIR.'/'.$FNAME); + + $EXECUTABLE = $OUTPUTDIR.'/'.$FNAME; + + my @LIBS = qx{/usr/bin/otool -L $EXECUTABLE}; + while ($_ = pop @LIBS) { + + # parse output of otool + next unless /^\t(.*) \(.*\).*$/; + my $FULLPATH = $1; + + # skip dependencies on things that are no .dylib + next unless $FULLPATH =~ /\.dylib$/; + + # skip dependencies that are already dynamic + next if $FULLPATH =~ /^@/; + + # skip dependencies that don't have an absolute path + next unless $FULLPATH =~ /^(.*)\/(.*)$/; + my $PATH = $1; + my $FNAME = $2; + + # skip dependencies on anything in /usr/lib + next if $PATH =~ q{^/usr/lib$}; + + # mark dependency as to-be-copied + push(@TOCOPY, $FULLPATH); + + } + +} + +# now patch all binaries we copied +while (my $EXECUTABLE = pop @TOPATCH) { + + next if $PATCHED{$EXECUTABLE}; + $PATCHED{$EXECUTABLE} = 1; + + print "patching ".$EXECUTABLE."\n"; + + my @LIBS = qx{/usr/bin/otool -L $EXECUTABLE}; + while ($_ = pop @LIBS) { + + # parse output of otool + next unless /^\t(.*) \(.*\).*$/; + my $FULLPATH = $1; + + # skip dependencies that are not .dylibs + next unless $FULLPATH =~ /\.dylib$/; + + # skip dependencies that are already dynamic + next if $FULLPATH =~ /^@/; + + # skip dependencies without absolute paths + next unless $FULLPATH =~ /^(.*)\/(.*)$/; + my $PATH = $1; + my $FNAME = $2; + + # skip dependencies on stuff in /usr/lib + next if $PATH =~ q{^/usr/lib$}; + + # patch binary to depend on copy in @executable_path instead + system('install_name_tool -change '.$FULLPATH.' @executable_path/'.$FNAME.' '.$EXECUTABLE); + + } + +} + -- 2.11.0