Changeset View
Changeset View
Standalone View
Standalone View
bin/Packager/MacDMGPackager.py
Show First 20 Lines • Show All 184 Lines • ▼ Show 20 Line(s) | 183 | if not libPath.exists(): | |||
---|---|---|---|---|---|
185 | return False | 185 | return False | ||
186 | CraftCore.log.debug("Handling library dependency '%s'", libPath) | 186 | CraftCore.log.debug("Handling library dependency '%s'", libPath) | ||
187 | if not targetPath.exists(): | 187 | if not targetPath.exists(): | ||
188 | utils.copyFile(str(libPath), str(targetPath), linkOnly=False) | 188 | utils.copyFile(str(libPath), str(targetPath), linkOnly=False) | ||
189 | CraftCore.log.info("Added library dependency '%s' to bundle -> %s", libPath, targetPath) | 189 | CraftCore.log.info("Added library dependency '%s' to bundle -> %s", libPath, targetPath) | ||
190 | 190 | | |||
191 | if not self._fixupLibraryId(targetPath): | 191 | if not self._fixupLibraryId(targetPath): | ||
192 | return False | 192 | return False | ||
193 | for dep in self._getLibraryDeps(targetPath): | 193 | for path in utils.getLibraryDeps(str(targetPath)): | ||
194 | path = dep.split()[0] | | |||
195 | # check there aren't any references to the original location: | 194 | # check there aren't any references to the original location: | ||
196 | if path == str(libPath): | 195 | if path == str(libPath): | ||
197 | CraftCore.log.error("%s: failed to fix reference to original location for '%s'", targetPath, path) | 196 | CraftCore.log.error("%s: failed to fix reference to original location for '%s'", targetPath, path) | ||
198 | return False | 197 | return False | ||
199 | 198 | | |||
200 | if not self.bundleLibraryDependencies(targetPath): | 199 | if not self.bundleLibraryDependencies(targetPath): | ||
201 | CraftCore.log.error("%s: UNKNOWN ERROR adding '%s' into bundle", targetPath, libPath) | 200 | CraftCore.log.error("%s: UNKNOWN ERROR adding '%s' into bundle", targetPath, libPath) | ||
202 | return False | 201 | return False | ||
203 | if not os.path.exists(targetPath): | 202 | if not os.path.exists(targetPath): | ||
204 | CraftCore.log.error("%s: Library dependency '%s' doesn't exist after copying... Symlink error?", | 203 | CraftCore.log.error("%s: Library dependency '%s' doesn't exist after copying... Symlink error?", | ||
205 | targetPath, libPath) | 204 | targetPath, libPath) | ||
206 | return False | 205 | return False | ||
207 | self.checkedLibs.add(targetPath) | 206 | self.checkedLibs.add(targetPath) | ||
208 | return True | 207 | return True | ||
209 | 208 | | |||
210 | @staticmethod | | |||
211 | def _getLibraryDeps(fullPath): | | |||
212 | lines = io.StringIO(subprocess.check_output(["otool", "-L", str(fullPath)]).decode("utf-8")) | | |||
213 | deps = [] | | |||
214 | for line in lines: | | |||
215 | if line.startswith("\t"): | | |||
216 | deps.append(line.strip()) | | |||
217 | return deps | | |||
218 | | ||||
219 | @staticmethod | 209 | @staticmethod | ||
220 | def _updateLibraryReference(fileToFix: Path, oldRef: str, newRef: str = None) -> bool: | 210 | def _updateLibraryReference(fileToFix: Path, oldRef: str, newRef: str = None) -> bool: | ||
221 | if newRef is None: | 211 | if newRef is None: | ||
222 | newRef = "@executable_path/../Frameworks/" + os.path.basename(oldRef) | 212 | newRef = "@executable_path/../Frameworks/" + os.path.basename(oldRef) | ||
223 | with makeWritable(fileToFix): | 213 | with makeWritable(fileToFix): | ||
224 | if not utils.system(["install_name_tool", "-change", oldRef, newRef, str(fileToFix)], logCommand=False): | 214 | if not utils.system(["install_name_tool", "-change", oldRef, newRef, str(fileToFix)], logCommand=False): | ||
225 | CraftCore.log.error("%s: failed to update library dependency path from '%s' to '%s'", | 215 | CraftCore.log.error("%s: failed to update library dependency path from '%s' to '%s'", | ||
226 | fileToFix, oldRef, newRef) | 216 | fileToFix, oldRef, newRef) | ||
Show All 29 Lines | 245 | if fileToFix.stat().st_nlink > 1: | |||
256 | CraftCore.log.error("More than one hard link to library %s found! " | 246 | CraftCore.log.error("More than one hard link to library %s found! " | ||
257 | "This might modify another accidentally.", fileToFix) | 247 | "This might modify another accidentally.", fileToFix) | ||
258 | CraftCore.log.info("Fixing library dependencies for %s", fileToFix) | 248 | CraftCore.log.info("Fixing library dependencies for %s", fileToFix) | ||
259 | if not self._fixupLibraryId(fileToFix): | 249 | if not self._fixupLibraryId(fileToFix): | ||
260 | return False | 250 | return False | ||
261 | # Ensure we have the current library ID since we need to skip it in the otool -L output | 251 | # Ensure we have the current library ID since we need to skip it in the otool -L output | ||
262 | libraryId = self._getLibraryNameId(fileToFix) | 252 | libraryId = self._getLibraryNameId(fileToFix) | ||
263 | 253 | | |||
264 | for dep in self._getLibraryDeps(fileToFix): | 254 | for path in utils.getLibraryDeps(str(fileToFix)): | ||
265 | path = dep.split()[0] | | |||
266 | if path == libraryId: | 255 | if path == libraryId: | ||
267 | # The first line of the otool output is (usually?) the library itself: | 256 | # The first line of the otool output is (usually?) the library itself: | ||
268 | # $ otool -L PlugIns/printsupport/libcocoaprintersupport.dylib: | 257 | # $ otool -L PlugIns/printsupport/libcocoaprintersupport.dylib: | ||
269 | # PlugIns/printsupport/libcocoaprintersupport.dylib: | 258 | # PlugIns/printsupport/libcocoaprintersupport.dylib: | ||
270 | # libcocoaprintersupport.dylib (compatibility version 0.0.0, current version 0.0.0) | 259 | # libcocoaprintersupport.dylib (compatibility version 0.0.0, current version 0.0.0) | ||
271 | # /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1561.40.112) | 260 | # /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1561.40.112) | ||
272 | # @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport (compatibility version 5.11.0, current version 5.11.1) | 261 | # @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport (compatibility version 5.11.0, current version 5.11.1) | ||
273 | # .... | 262 | # .... | ||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | 318 | if not self.bundleLibraryDependencies(fullpath): | |||
331 | return False | 320 | return False | ||
332 | return True | 321 | return True | ||
333 | 322 | | |||
334 | def areLibraryDepsOkay(self, fullPath: Path): | 323 | def areLibraryDepsOkay(self, fullPath: Path): | ||
335 | CraftCore.log.debug("Checking library dependencies of %s", fullPath) | 324 | CraftCore.log.debug("Checking library dependencies of %s", fullPath) | ||
336 | found_bad_lib = False | 325 | found_bad_lib = False | ||
337 | libraryId = self._getLibraryNameId(fullPath) | 326 | libraryId = self._getLibraryNameId(fullPath) | ||
338 | relativePath = os.path.relpath(str(fullPath), self.appPath) | 327 | relativePath = os.path.relpath(str(fullPath), self.appPath) | ||
339 | for dep in self._getLibraryDeps(fullPath): | 328 | for dep in utils.getLibraryDeps(str(fullPath)): | ||
340 | path = dep.split()[0] | 329 | if dep == libraryId and not os.path.isabs(libraryId): | ||
341 | if path == libraryId and not os.path.isabs(libraryId): | | |||
342 | continue # non-absolute library id is fine | 330 | continue # non-absolute library id is fine | ||
343 | # @rpath and @executable_path is fine | 331 | # @rpath and @executable_path is fine | ||
344 | if dep.startswith("@rpath") or dep.startswith("@executable_path"): | 332 | if dep.startswith("@rpath") or dep.startswith("@executable_path"): | ||
345 | continue | 333 | continue | ||
346 | # Also allow /System/Library/Frameworks/ and /usr/lib: | 334 | # Also allow /System/Library/Frameworks/ and /usr/lib: | ||
347 | if dep.startswith("/usr/lib/") or dep.startswith("/System/Library/Frameworks/"): | 335 | if dep.startswith("/usr/lib/") or dep.startswith("/System/Library/Frameworks/"): | ||
348 | continue | 336 | continue | ||
349 | if dep.startswith(CraftStandardDirs.craftRoot()): | 337 | if dep.startswith(CraftStandardDirs.craftRoot()): | ||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |