sgielen / make_independent

Make an .app bundle independent (no non-system dylibs needed).
3 stars 0 forks source link

Fails to copy "invalid" dynamic linker lines, but they aren't invalid #1

Open NickNick opened 11 years ago

NickNick commented 11 years ago

In a case we have,

nick@Nicks-MacBook-Pro:~/Documents/Code/onegame/create_packages/test-backup$ otool -X -L beamer 
    libboost_chrono.dylib (compatibility version 0.0.0, current version 0.0.0)

That line is causing trouble, however, OSX (or whatever specific tool is used to load the dylibs) thinks it's fine. I'm not sure where OSX looks for these "relative" dylibs, but I guess the fix is to look there and copy them.

NickNick commented 11 years ago

I made a find_lib function which, unsurprisingly, finds a lib. Still not sure where OSX looks, but in my case it found the specific lib in /usr/local/lib (since it was the only version I had).

Here's the how I use it, and the sub itself:

        } elsif(is_relative_path($dylib)) {
            my $found_it = find_lib($dylib);
            if($found_it){
                $dylib = $found_it;
            } else {
                warn "${spaces}Failed to find $dylib, update sub find_lib to find it!";
            }
        }

        my ($newpath, $newpath_relative) = copy_lib($dylib, $spaces);
sub find_lib {
    my ($lib) = @_;
    foreach(qw(/usr/local/lib)) {
        my $full_path = join "/", $_, $lib;
        if(-f $full_path){
            return $full_path;
        }
    }

    return 0;
}
NickNick commented 11 years ago

Our highly caffeinated monkeys found out it was the right sub at the wrong location. In exchange for 2 bananas they gave me a better place to call find_lib, namely in copy_lib. This way, the correct names are passed into fix_names, making sure it'll look next to the binary for the libraries.

sub copy_lib {
    my ($lib, $s) = @_;
    if(is_relative_path($lib)) {
        my $found_it = find_lib($lib);
        if($found_it){
            $lib = $found_it;
        } else {
            warn "${s}Failed to find $lib, update sub find_lib to find it (and then run me again!)";
        }
    }
    my $basename = basename($lib);
    my $newpath = "$libdir/$basename";
    my $int_path = "\@rpath/$basename";
    my $relative_path = "$basename";
    if(!-f $newpath) {
        print "${s}Copy $lib into app\n";
        unless($DRYRUN) {
            copy($lib, $newpath) or die "${s}Failed to copy: $!\n";
        }
    }

    return ($int_path, $relative_path);
}

Of course, this removes the need for the check if $dylib is a relative path in sub fix, so just remove that condition.