4 # makebundle.pl - copies and makes portable a binary and all its dependencies
5 # Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License
9 # as published by the Free Software Foundation; either version 2
10 # of the License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 # Script does some dangerous stuff - make sure a user will double-check everything before running it.
26 print "This script is highly experimental. Modify it to suit your needs and take care to run it only in controlled environments.\n";
28 # This line needs to be removed, the following lines adjusted.
31 my $OUTPUTDIR='/tmp/SuperTux.app/Contents/MacOS';
32 my $EXECUTABLE='./supertux2';
39 system('mkdir '.$OUTPUTDIR);
41 push (@TOCOPY, $EXECUTABLE);
43 # first, copy all direct and indirect dependencies to OUTPUTDIR
44 while (my $EXECUTABLE = pop @TOCOPY) {
46 next if $COPIED{$EXECUTABLE};
47 $COPIED{$EXECUTABLE} = 1;
49 next unless $EXECUTABLE =~ /^(.*)\/(.*)$/;
53 print("copying ".$EXECUTABLE."\n");
55 system('cp '.$EXECUTABLE.' '.$OUTPUTDIR.'/'.$FNAME);
56 system('chmod u+w '.$OUTPUTDIR.'/'.$FNAME);
58 # mark the copy as to-be-patched
59 push(@TOPATCH, $OUTPUTDIR.'/'.$FNAME);
61 $EXECUTABLE = $OUTPUTDIR.'/'.$FNAME;
63 my @LIBS = qx{/usr/bin/otool -L $EXECUTABLE};
64 while ($_ = pop @LIBS) {
66 # parse output of otool
67 next unless /^\t(.*) \(.*\).*$/;
70 # skip dependencies on things that are no .dylib
71 next unless $FULLPATH =~ /\.dylib$/;
73 # skip dependencies that are already dynamic
74 next if $FULLPATH =~ /^@/;
76 # skip dependencies that don't have an absolute path
77 next unless $FULLPATH =~ /^(.*)\/(.*)$/;
81 # skip dependencies on anything in /usr/lib
82 next if $PATH =~ q{^/usr/lib$};
84 # mark dependency as to-be-copied
85 push(@TOCOPY, $FULLPATH);
91 # now patch all binaries we copied
92 while (my $EXECUTABLE = pop @TOPATCH) {
94 next if $PATCHED{$EXECUTABLE};
95 $PATCHED{$EXECUTABLE} = 1;
97 print "patching ".$EXECUTABLE."\n";
99 my @LIBS = qx{/usr/bin/otool -L $EXECUTABLE};
100 while ($_ = pop @LIBS) {
102 # parse output of otool
103 next unless /^\t(.*) \(.*\).*$/;
106 # skip dependencies that are not .dylibs
107 next unless $FULLPATH =~ /\.dylib$/;
109 # skip dependencies that are already dynamic
110 next if $FULLPATH =~ /^@/;
112 # skip dependencies without absolute paths
113 next unless $FULLPATH =~ /^(.*)\/(.*)$/;
117 # skip dependencies on stuff in /usr/lib
118 next if $PATH =~ q{^/usr/lib$};
120 # patch binary to depend on copy in @executable_path instead
121 system('install_name_tool -change '.$FULLPATH.' @executable_path/'.$FNAME.' '.$EXECUTABLE);