~ubuntu-branches/ubuntu/wily/scribus/wily-proposed

« back to all changes in this revision

Viewing changes to OSX-package/linktools/MachO.py

  • Committer: Package Import Robot
  • Author(s): Mattia Rizzolo
  • Date: 2014-05-11 16:29:44 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20140511162944-y6jnp08arsfefy26
Tags: 1.4.2.dfsg.1+r18267-0.1
* Non-maintainer upload.
* Repack the source to remove some non-free contents. (Closes: #741666)
* debian/README.source: update to reflect the above changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import os
2
 
import re
3
 
import shutil
4
 
 
5
 
 
6
 
def findFramework(path, name = None):
7
 
        "find the framework folder for FW name"
8
 
        if path == "" or path == "@executable_path" or path == "/":
9
 
                return None
10
 
        elif name == None:
11
 
                return findFramework(os.path.dirname(path), 
12
 
                                                         os.path.basename(path))
13
 
        elif os.path.basename(path) == name + ".framework":
14
 
                return path
15
 
        elif len(os.path.dirname(path)) >= len(path):
16
 
                print "MachO.findFramework: Oops '" + path + "', '" + name + "'"
17
 
                return None
18
 
        else:
19
 
                return findFramework(os.path.dirname(path), name)
20
 
        
21
 
 
22
 
 
23
 
def stripPrefix(prefix, path):
24
 
        "Returns the relative path r such that os.path.join(prefix, r) == path"
25
 
        prefix = os.path.normpath(prefix)
26
 
        prefixLen = len(prefix)
27
 
        path = os.path.normpath(path)
28
 
        if path[0 : prefixLen] == prefix:
29
 
                if path[prefixLen] == os.sep:
30
 
                        return path[prefixLen+1 : ]
31
 
                else:
32
 
                        return path[prefixLen : ]
33
 
        else:
34
 
                return path
35
 
                
36
 
                
37
 
class Executable:
38
 
        "Represents an Mach-O executable."      
39
 
        
40
 
        def __init__(self, path, kind):
41
 
                self.Location = path
42
 
                self.Kind = kind
43
 
                
44
 
                
45
 
        def __repr__(self):
46
 
                return self.Location + " (" + self.Kind + ")"
47
 
                
48
 
                
49
 
        def getDependencies(self):
50
 
                "Return a list of MachO.Fixes describing the dependencies."
51
 
                "Uses otool -L"
52
 
                f = os.popen("otool -L " + self.Location, "r")
53
 
                result = []
54
 
                pat = re.compile("\s*([^(]*)\s\((.+)\)")
55
 
                for line in f:
56
 
                        m = pat.match(line)
57
 
                        if m != None:
58
 
                                result.append(Fix(m.group(1), m.group(2)))
59
 
                status = f.close()
60
 
                return result
61
 
                
62
 
        def applyFixes(self, changes, log):
63
 
                "Uses install_name_tool to change the links to dependencies."
64
 
                "changes is a dictionary mapping links (as strings) to Fixes."
65
 
                args = ""
66
 
                for dep in self.getDependencies():
67
 
                        if dep.Link in changes:
68
 
                                args = args + changes[dep.Link].getChange()
69
 
                log.append(">> " + "install_name_tool " + args + self.Location)
70
 
                if len(args) > 0:
71
 
                        os.system("install_name_tool " + args + self.Location)
72
 
                pat = re.compile("(library)|(universal binary)")
73
 
                if pat.search(self.Kind):
74
 
                        relName = os.path.basename(self.Location) # FIXME: rel to fw
75
 
                        log.append(">> " + "install_name_tool -id " + relName + 
76
 
                                                " " + self.Location)
77
 
                        os.system("install_name_tool -id " + relName + 
78
 
                                                " " + self.Location)
79
 
 
80
 
 
81
 
def findExecutables(bundleDir):
82
 
        "Return a list of MachO.Executables found in bundleDir"
83
 
        result = []
84
 
        pat = re.compile("Mach-O (.+)")
85
 
        for root, dirs, files in os.walk(bundleDir):
86
 
                for n in files:
87
 
                        p = os.path.join(root, n)
88
 
                        f = os.popen("file -b " + p, "r")
89
 
                        m = pat.match(f.readline())
90
 
                        if m != None:
91
 
                                result.append(Executable(p, m.group(1)))
92
 
                                print "found " + m.group(1) + ": " + n
93
 
                        f.close()
94
 
        return result
95
 
 
96
 
 
97
 
 
98
 
class Fix:
99
 
        "Represents a fix for a library link."
100
 
        
101
 
        def __init__(self, dependency, versionString="?"):
102
 
                self.Link = dependency
103
 
                self.Location = dependency
104
 
                self.NewLink = dependency
105
 
                self.NewLocation = dependency
106
 
                self.versionString = versionString # not used yet
107
 
                self.fwPath = None
108
 
                self.relPath = None
109
 
                
110
 
        def __repr__(self):
111
 
                return (self.Link + " (" + self.versionString + ")")
112
 
                
113
 
        def isAbsolute(self):
114
 
                return os.path.isabs(self.Link)
115
 
                
116
 
        def isBundleRelative(self):
117
 
                return self.Link[0:17] == "@executable_path/"
118
 
                
119
 
        def isSystem(self):
120
 
                return (self.Location[0:8] == "/usr/lib"     # also matches libexec
121
 
                                or self.Location[0:8] == "/usr/X11"  # also matches X11R6
122
 
                                or self.Location[0:8] == "/System/")
123
 
                                
124
 
        def getChange(self):
125
 
                "Returns argument for install_name_tool."
126
 
                if self.Link == self.NewLink:
127
 
                        return ""
128
 
                else:
129
 
                        return "-change " + self.Link + " " + self.NewLink + " "
130
 
                
131
 
        def findLocation(self, exePath=None):
132
 
                if self.isBundleRelative():
133
 
                        if exePath != None:
134
 
                                self.Location = os.path.normpath(
135
 
                                                                os.path.join(exePath, self.Link[17:]))
136
 
                        else:
137
 
                                self.Location = self.Link[17:]
138
 
                else:
139
 
                        self.Location = self.Link
140
 
 
141
 
                # check if done
142
 
                if (os.path.isabs(self.Location) and
143
 
                        os.path.isfile(self.Location)):
144
 
                        self.NewLocation = self.Location
145
 
                        return True
146
 
                
147
 
                # search for frameworks in /System/Library and /Library
148
 
                fwPath = findFramework(self.Location)
149
 
                if fwPath:
150
 
                        fwdir = os.path.dirname(fwPath)
151
 
                        self.relPath = stripPrefix(fwdir, self.Location)
152
 
                        for d in        ["/Library/Frameworks", 
153
 
                                                "/System/Library/Frameworks"]:
154
 
                                if os.path.isfile(os.path.join(d, self.relPath)):
155
 
#                                       self.Location = os.path.join(d, self.relPath)
156
 
                                        self.Location = os.path.join(d, self.relPath)
157
 
                                        self.NewLocation = self.Location
158
 
                                        self.fwPath = os.path.join(d, os.path.basename(fwPath))
159
 
                                        self.relPath = stripPrefix(self.fwPath, self.Location)
160
 
                                        return True
161
 
                
162
 
                # ok, try libs
163
 
                lib = os.path.basename(self.Location)
164
 
                self.relPath = None
165
 
                for d in        ["/usr/local/lib", "/opt/local/lib", 
166
 
                                        "/usr/lib", "/opt/lib"]:
167
 
                        if os.path.isfile(os.path.join(d, lib)):
168
 
                                self.Location = os.path.join(d, lib)
169
 
                                self.NewLocation = self.Location
170
 
                                return True
171
 
 
172
 
                # not found
173
 
                return False
174
 
                
175
 
                
176
 
        def moveLibrary(self, destBundlePath, stripFW, log):
177
 
                "Copies the library or fw to destBundlePath."
178
 
                "Also sets NewLink and NewLocation properties"
179
 
                "Returns a list of copied executables"
180
 
                
181
 
                # dont do this if we are already inside the bundle:
182
 
                if stripPrefix(destBundlePath, self.Location) != self.Location:
183
 
                        log.append("-- ignoring " + self.Location)
184
 
                        return []
185
 
                
186
 
                if self.relPath != None and not stripFW:
187
 
                        # copy framework
188
 
                        newFwPath = os.path.join(destBundlePath, 
189
 
                                                                                "Contents/Frameworks", 
190
 
                                                                                os.path.basename(self.fwPath))
191
 
                        log.append(">> " + self.fwPath + " ===> " + newFwPath)
192
 
                        if (os.path.exists(destBundlePath) and
193
 
                                not os.path.exists(newFwPath)):
194
 
                                shutil.copytree(self.fwPath, newFwPath, True)
195
 
                        self.NewLocation = os.path.join(newFwPath, self.relPath)
196
 
                        self.NewLink = ("@executable_path/" 
197
 
                                                        + os.path.join("../Frameworks", 
198
 
                                                                                        os.path.basename(self.fwPath),
199
 
                                                                                        self.relPath))
200
 
                        return findExecutables(newFwPath)
201
 
                else:
202
 
                        # copy lib to bundle.app/Contents/Frameworks/
203
 
                        self.NewLocation = os.path.join(destBundlePath, 
204
 
                                                                                        "Contents/Frameworks",
205
 
                                                                                        os.path.basename(self.Location))
206
 
                        self.NewLink = ("@executable_path/" 
207
 
                                                        + os.path.join("../Frameworks", 
208
 
                                                                                        os.path.basename(self.Location)))
209
 
                        log.append(">> " + self.Location + " ---> " + self.NewLocation)
210
 
                        if (os.path.exists(destBundlePath) and
211
 
                                not os.path.exists(self.NewLocation)):
212
 
                                shutil.copy(self.Location, self.NewLocation)
213
 
                        return [Executable(self.NewLocation, "lib")]
214
 
                        
215
 
        
 
 
b'\\ No newline at end of file'