def shortCut(name, target, icon="", parameter="", description=""): target = OsUtils.toUnixPath( os.path.join(self.__imagePrefix, target)) name = OsUtils.toUnixPath(name) if self.__sdkMode: name = f"{name} for Qt {CraftCore.settings.get('QtSDK', 'Version')} {CraftCore.settings.get('QtSDK', 'Compiler')}" return f'component.addOperation( "CreateShortcut", "@TargetDir@/{target}","@StartMenuDir@/{name}.lnk");'
def postInstall(self): cmakes = [ os.path.join(self.installDir(), "lib", "cmake", f"aqbanking-{self.subinfo.buildTarget[:-2]}", "aqbanking-config.cmake") ] for cmake in cmakes: with open(cmake, "rt") as f: cmakeFileContents = f.readlines() for i in range(len(cmakeFileContents)): if CraftCore.compiler.isMinGW(): m = re.search('set_and_check\(prefix "(?P<root>[^"]*)"\)', cmakeFileContents[i]) if m is not None: craftRoot = OsUtils.toUnixPath( CraftStandardDirs.craftRoot()) if craftRoot.endswith("/"): craftRoot = craftRoot[:-1] cmakeFileContents[i] = cmakeFileContents[i].replace( m.group('root'), craftRoot) elif CraftCore.compiler.isMacOS: m2 = re.search("(libaqbanking.so.(\d*))", cmakeFileContents[i]) if m2 is not None: cmakeFileContents[i] = cmakeFileContents[i].replace( m2.group(1), "libaqbanking.%s.dylib" % m2.group(2)) with open(cmake, "wt") as f: f.write(''.join(cmakeFileContents)) return AutoToolsPackageBase.postInstall(self)
def postInstall(self): cmakes = [ os.path.join(self.installDir(), "lib", "cmake", f"aqbanking-{self.subinfo.defaultTarget[:-2]}", "aqbanking-config.cmake") ] for cmake in cmakes: f = open(cmake, "r+") cmakeFileContents = f.readlines() for i in range(len(cmakeFileContents)): if CraftCore.compiler.isMinGW(): m = re.search('set_and_check\(prefix "(?P<root>[^"]*)"\)', cmakeFileContents[i]) if m is not None: craftRoot = OsUtils.toUnixPath( CraftStandardDirs.craftRoot()) if craftRoot.endswith("/"): craftRoot = craftRoot[:-1] cmakeFileContents[i] = cmakeFileContents[i].replace( m.group('root'), craftRoot) m2 = re.search("libaqbanking.so", cmakeFileContents[i]) if m2 is not None: cmakeFileContents[i] = cmakeFileContents[i].replace( "lib/libaqbanking.so", "bin/libaqbanking-35.dll") elif CraftCore.compiler.isMacOS: m2 = re.search("libaqbanking.so", cmakeFileContents[i]) if m2 is not None: cmakeFileContents[i] = cmakeFileContents[i].replace( "libaqbanking.so", "libaqbanking.35.dylib") f.seek(0) f.write(''.join(cmakeFileContents)) f.close() return AutoToolsPackageBase.postInstall(self)
def _fixInstallPrefix(self, prefix=CraftStandardDirs.craftRoot()): CraftCore.log.debug(f"Begin: fixInstallPrefix {self}: {prefix}") def stripPath(path): rootPath = os.path.splitdrive(path)[1] if rootPath.startswith(os.path.sep) or rootPath.startswith("/"): rootPath = rootPath[1:] return rootPath badPrefix = os.path.join(self.installDir(), stripPath(prefix)) if os.path.exists(badPrefix) and not os.path.samefile( self.installDir(), badPrefix): if not utils.mergeTree(badPrefix, self.installDir()): return False if CraftCore.settings.getboolean("QtSDK", "Enabled", False): qtDir = os.path.join(CraftCore.settings.get("QtSDK", "Path"), CraftCore.settings.get("QtSDK", "Version"), CraftCore.settings.get("QtSDK", "Compiler")) path = os.path.join(self.installDir(), stripPath(qtDir)) if os.path.exists(path) and not os.path.samefile( self.installDir(), path): if not utils.mergeTree(path, self.installDir()): return False if stripPath(prefix): oldPrefix = OsUtils.toUnixPath(stripPath(prefix)).split("/", 1)[0] utils.rmtree(os.path.join(self.installDir(), oldPrefix)) CraftCore.log.debug(f"End: fixInstallPrefix {self}") return True
def patchInstallPrefix( self, files: [str], oldPaths: [str] = None, newPath: str = CraftCore.standardDirs.craftRoot() ) -> bool: if isinstance(oldPaths, str): oldPaths = [oldPaths] elif not oldPaths: oldPaths = [self.subinfo.buildPrefix] newPathUnix = OsUtils.toUnixPath(newPath).encode() for fileName in files: if not os.path.exists(fileName): CraftCore.log.warning(f"File {fileName} not found.") return False with open(fileName, "rb") as f: content = f.read() dirty = False for oldPath in oldPaths: assert os.path.isabs(oldPath) oldPathPat = OsUtils.toUnixPath(oldPath) # allow front and back slashes oldPathPat = oldPathPat.replace("/", r"[/\\]+") # capture firs seperator oldPathPat = oldPathPat.replace(r"[/\\]+", r"(/+|\\+)", 1) oldPathPat = f"({oldPathPat})" oldPathPat = re.compile(oldPathPat.encode()) for match in set(oldPathPat.findall(content)): dirty = True oldPath = match[0] newPath = newPathUnix.replace(b"/", match[1]) if oldPath != newPath: CraftCore.log.info( f"Patching {fileName}: replacing {oldPath} with {newPath}" ) content = content.replace(oldPath, newPath) else: CraftCore.log.debug( f"Skip Patching {fileName}: prefix is unchanged {newPath}" ) if dirty: with utils.makeWritable(fileName): with open(fileName, "wb") as f: f.write(content) return True
def configureOptions(self, defines=""): """returns default configure options""" craftRoot = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) options = Arguments([defines]) options += [ "-DBUILD_TESTING={testing}".format( testing="ON" if self.buildTests else "OFF"), BuildSystemBase.configureOptions(self), f"-DCMAKE_INSTALL_PREFIX={craftRoot}", f"-DCMAKE_PREFIX_PATH={craftRoot}" ] if self.buildType() is not None: options.append(f"-DCMAKE_BUILD_TYPE={self.buildType()}") #if CraftCore.compiler.isGCC() and not CraftCore.compiler.isNative(): # options += " -DCMAKE_TOOLCHAIN_FILE=%s" % os.path.join(CraftStandardDirs.craftRoot(), "craft", "bin", "toolchains", "Toolchain-cross-mingw32-linux-%s.cmake" % CraftCore.compiler.architecture) if CraftCore.settings.getboolean("CMake", "KDE_L10N_AUTO_TRANSLATIONS", False): options.append("-DKDE_L10N_AUTO_TRANSLATIONS=ON") if CraftCore.compiler.isWindows: # people use InstallRequiredSystemLibraries.cmake wrong and unconditionally install the # msvc crt... options.append("-DCMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP=ON") elif CraftCore.compiler.isMacOS: options += [ f"-DKDE_INSTALL_BUNDLEDIR={OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot())}/Applications/KDE", "-DAPPLE_SUPPRESS_X11_WARNING=ON" ] elif CraftCore.compiler.isLinux: # use the same lib dir on all distributions options += ["-DCMAKE_INSTALL_LIBDIR=lib"] if CraftCore.compiler.isWindows or CraftCore.compiler.isMacOS: options.append("-DKDE_INSTALL_USE_QT_SYS_PATHS=ON") if self.subinfo.options.buildTools: options += self.subinfo.options.configure.toolsDefine if self.subinfo.options.buildStatic and self.subinfo.options.configure.staticArgs: options += self.subinfo.options.configure.staticArgs if CraftCore.compiler.isIntel(): # this is needed because otherwise it'll detect the MSVC environment options += " -DCMAKE_CXX_COMPILER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "icl.exe").replace("\\", "/") options += " -DCMAKE_C_COMPILER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "icl.exe").replace("\\", "/") options += " -DCMAKE_LINKER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "xilink.exe").replace("\\", "/") options += ["-S", self.configureSourceDir()] return options
def configureOptions(self, defines=""): """returns default configure options""" options = "-DBUILD_TESTING={testing} ".format( testing="ON" if self.buildTests else "OFF") options += BuildSystemBase.configureOptions(self) craftRoot = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) options += f" -DCMAKE_INSTALL_PREFIX=\"{craftRoot}\"" options += f" -DCMAKE_PREFIX_PATH=\"{craftRoot}\"" if (not self.buildType() == None): options += " -DCMAKE_BUILD_TYPE=%s" % self.buildType() if CraftCore.compiler.isGCC() and not CraftCore.compiler.isNative(): options += " -DCMAKE_TOOLCHAIN_FILE=%s" % os.path.join( CraftStandardDirs.craftRoot(), "craft", "bin", "toolchains", "Toolchain-cross-mingw32-linux-%s.cmake" % CraftCore.compiler.architecture) if CraftCore.settings.getboolean("CMake", "KDE_L10N_AUTO_TRANSLATIONS", False): options += " -DKDE_L10N_AUTO_TRANSLATIONS=ON" if OsUtils.isWin(): # people use InstallRequiredSystemLibraries.cmake wrong and unconditionally install the # msvc crt... options += " -DCMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP=ON" if OsUtils.isMac(): options += f" -DKDE_INSTALL_BUNDLEDIR=\"{OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot())}/Applications/KDE\" -DAPPLE_SUPPRESS_X11_WARNING=ON" if CraftCore.compiler.macUseSDK: # Ensure that we don't depend on SDK features only present on newer systems options += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + CraftCore.compiler.macOSDeploymentTarget if CraftCore.compiler.isWindows or CraftCore.compiler.isMacOS: options += " -DKDE_INSTALL_USE_QT_SYS_PATHS=ON" if self.subinfo.options.buildTools: options += " " + self.subinfo.options.configure.toolsDefine + " " if self.subinfo.options.buildStatic and self.subinfo.options.configure.staticArgs: options += " " + self.subinfo.options.configure.staticArgs + " " if CraftCore.compiler.isIntel(): # this is needed because otherwise it'll detect the MSVC environment options += " -DCMAKE_CXX_COMPILER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "icl.exe").replace("\\", "/") options += " -DCMAKE_C_COMPILER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "icl.exe").replace("\\", "/") options += " -DCMAKE_LINKER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "xilink.exe").replace("\\", "/") options += " \"%s\"" % self.configureSourceDir() return options
def __init__(self): CMakePackageBase.__init__(self) if OsUtils.isWin(): if CraftCore.compiler.isX64(): self.r_dir = os.path.join(CraftCore.standardDirs.craftRoot(), "lib", "R", "bin", "x64") else: self.r_dir = os.path.join(CraftCore.standardDirs.craftRoot(), "lib", "R", "bin", "i386") self.subinfo.options.configure.args = " -DR_EXECUTABLE=" + OsUtils.toUnixPath(os.path.join(self.r_dir, "R.exe")) elif OsUtils.isMac(): rhome = os.path.join(CraftCore.standardDirs.craftRoot(), "lib", "R", "R.framework", "Resources") self.subinfo.options.configure.args = " -DR_EXECUTABLE=" + os.path.join(rhome, "R") + " -DNO_CHECK_R=1 -DR_HOME=" + rhome + " -DR_INCLUDEDIR=" + os.path.join(rhome, "include") + " -DR_SHAREDLIBDIR=" + os.path.join(rhome, "lib")
def internalPostInstall(self): if not super().internalPostInstall(): return False # a post install routine to fix the prefix (make things relocatable) pkgconfigPath = os.path.join(self.imageDir(), "lib", "pkgconfig") newPrefix = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) oldPrefixes = [self.subinfo.buildPrefix] if CraftCore.compiler.isWindows: oldPrefixes += [ OsUtils.toUnixPath(self.subinfo.buildPrefix), OsUtils.toMSysPath(self.subinfo.buildPrefix) ] if os.path.exists(pkgconfigPath): for pcFile in os.listdir(pkgconfigPath): if pcFile.endswith(".pc"): path = os.path.join(pkgconfigPath, pcFile) if not self.patchInstallPrefix([path], oldPrefixes, newPrefix): return False return True
def __init__(self): CMakePackageBase.__init__(self) self.translations = CraftPackageObject.get("extragear/rkward/rkward-translations").instance if OsUtils.isWin(): if CraftCore.compiler.isX64(): self.r_dir = os.path.join(CraftCore.standardDirs.craftRoot(), "lib", "R", "bin", "x64") else: self.r_dir = os.path.join(CraftCore.standardDirs.craftRoot(), "lib", "R", "bin", "i386") self.subinfo.options.configure.args = " -DR_EXECUTABLE=" + OsUtils.toUnixPath(os.path.join(self.r_dir, "R.exe")) elif OsUtils.isMac(): self.subinfo.options.configure.args = " -DR_EXECUTABLE=" + os.path.join(CraftCore.standardDirs.craftRoot(), "lib", "R", "R.framework", "Resources", "R") if self.subinfo.hasSvnTarget: self.subinfo.options.configure.args += f" -DTRANSLATION_SRC_DIR={OsUtils.toUnixPath(self.translations.sourceDir())}"
def patchInstallPrefix( self, files: [str], oldPaths: [str] = None, newPath: str = CraftCore.standardDirs.craftRoot() ) -> bool: if isinstance(oldPaths, str): oldPaths = [oldPaths] elif not oldPaths: oldPaths = [self.subinfo.buildPrefix] newPathWin = OsUtils.toNativePath(newPath) newPathUnix = OsUtils.toUnixPath(newPath) newPath = newPathUnix for fileName in files: if not os.path.exists(fileName): CraftCore.log.warning(f"File {fileName} not found.") return False with open(fileName, "rb") as f: content = f.read() dirty = False for oldPath in oldPaths: assert os.path.isabs(oldPath) if CraftCore.compiler.isWindows: _, ext = os.path.splitext(fileName) # keep unix path sep or use unix path sep for specific type # prl and pri files might use \\\\ as sep which can be replaced by a / but not by a single \\ if oldPath[2] == "/" or ext in {".prl", ".pri"}: newPath = newPathUnix else: # keep windows sep newPath = newPathWin oldPathBinary = oldPath.encode() if oldPath != newPath and oldPathBinary in content: dirty = True CraftCore.log.info( f"Patching {fileName}: replacing {oldPath} with {newPath}" ) content = content.replace(oldPathBinary, newPath.encode()) if dirty: with utils.makeWritable(fileName): with open(fileName, "wb") as f: f.write(content) return True
def internlPostInstall(self): if not super().internlPostInstall(): return Fasle # a post install routine to fix the prefix (make things relocatable) pkgconfigPath = os.path.join(self.imageDir(), "lib", "pkgconfig") prefix_re = re.compile("^prefix=(.*)$", re.MULTILINE) newPrefix = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) if os.path.exists(pkgconfigPath): for pcFile in os.listdir(pkgconfigPath): if pcFile.endswith(".pc"): path = os.path.join(pkgconfigPath, pcFile) with open(path, "rt+") as f: config = f.read() prefix = prefix_re.findall(config) if len(prefix) != 1: CraftCore.log.error(f"Failed to patch {path}") return False prefix = prefix[0] CraftCore.log.info(f"Patching {path}, replacing {prefix} with {newPrefix}") config = config.replace(prefix, newPrefix) with open(path, "wt+") as f: f.write(config) return True
def internalPostInstall(self): if not super().internalPostInstall(): return False # fix absolute symlinks for sym in utils.filterDirectoryContent(self.installDir(), lambda x, root: x.is_symlink(), lambda x, root: True, allowBadSymlinks=True): target = Path(os.readlink(sym)) if target.is_absolute(): sym = Path(sym) target = Path(self.imageDir()) / target.relative_to( CraftCore.standardDirs.craftRoot()) sym.unlink() # we can't use relative_to here sym.symlink_to(os.path.relpath(target, sym.parent)) # a post install routine to fix the prefix (make things relocatable) newPrefix = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) oldPrefixes = [self.subinfo.buildPrefix] if CraftCore.compiler.isWindows: oldPrefixes += [OsUtils.toMSysPath(self.subinfo.buildPrefix)] files = utils.filterDirectoryContent( self.installDir(), whitelist=lambda x, root: Path( x).suffix in BuildSystemBase.PatchableFile, blacklist=lambda x, root: True) if not self.patchInstallPrefix(files, oldPrefixes, newPrefix): return False if (CraftCore.compiler.isMacOS and os.path.isdir(self.installDir())): files = utils.filterDirectoryContent( self.installDir(), lambda x, root: utils.isBinary(x.path), lambda x, root: True) for f in files: if os.path.islink(f): continue # replace the old prefix or add it if missing if not utils.system([ "install_name_tool", "-rpath", os.path.join(self.subinfo.buildPrefix, "lib"), os.path.join(newPrefix, "lib"), f ]): utils.system([ "install_name_tool", "-add_rpath", os.path.join(newPrefix, "lib"), f ]) # update prefix if self.subinfo.buildPrefix != newPrefix: if os.path.splitext(f)[1] in {".dylib", ".so"}: # fix dylib id with io.StringIO() as log: utils.system(["otool", "-D", f], stdout=log) oldId = log.getvalue().strip().split("\n") # the first line is the file name # the second the id, if we only get one line, there is no id to fix if len(oldId) == 2: oldId = oldId[1].strip() newId = oldId.replace(self.subinfo.buildPrefix, newPrefix) if newId != oldId: if not utils.system( ["install_name_tool", "-id", newId, f]): return False # fix dependencies for dep in utils.getLibraryDeps(f): if dep.startswith(self.subinfo.buildPrefix): newDep = dep.replace(self.subinfo.buildPrefix, newPrefix) if newDep != dep: if not utils.system([ "install_name_tool", "-change", dep, newDep, f ]): return False # Install pdb files on MSVC if they are not found next to the dll # skip if we are a release build or from cache if not self.subinfo.isCachedBuild and CraftCore.compiler.isMSVC( ) and self.buildType() in {"RelWithDebInfo", "Debug"}: files = utils.filterDirectoryContent( self.installDir(), lambda x, root: utils.isBinary(x.path), lambda x, root: True) for f in files: if not os.path.exists(f"{os.path.splitext(f)[0]}.pdb"): pdb = utils.getPDBForBinary(f) if not pdb: CraftCore.log.warning(f"Could not find a PDB for {f}") continue if not os.path.exists(pdb): CraftCore.log.warning( f"PDB {pdb} for {f} does not exist") continue pdbDestination = os.path.join(os.path.dirname(f), os.path.basename(pdb)) CraftCore.log.info( f"Install pdb: {pdbDestination} for {os.path.basename(f)}" ) utils.copyFile(pdb, pdbDestination, linkOnly=False) return True
def configureOptions(self, defines=""): """returns default configure options""" craftRoot = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) options = Arguments([defines]) options += [ "-DBUILD_TESTING={testing}".format( testing="ON" if self.buildTests else "OFF"), "-DBUILD_SHARED_LIBS={shared}".format( shared="OFF" if self.subinfo.options.buildStatic else "ON"), BuildSystemBase.configureOptions(self), f"-DCMAKE_INSTALL_PREFIX={craftRoot}", f"-DCMAKE_PREFIX_PATH={craftRoot}" ] if self.buildType() is not None: options.append(f"-DCMAKE_BUILD_TYPE={self.buildType()}") #if CraftCore.compiler.isGCC() and not CraftCore.compiler.isNative(): # options += " -DCMAKE_TOOLCHAIN_FILE=%s" % os.path.join(CraftStandardDirs.craftRoot(), "craft", "bin", "toolchains", "Toolchain-cross-mingw32-linux-%s.cmake" % CraftCore.compiler.architecture) if CraftCore.settings.getboolean("CMake", "KDE_L10N_AUTO_TRANSLATIONS", False): options.append("-DKDE_L10N_AUTO_TRANSLATIONS=ON") if CraftCore.compiler.isWindows: # people use InstallRequiredSystemLibraries.cmake wrong and unconditionally install the # msvc crt... options.append("-DCMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP=ON") elif CraftCore.compiler.isMacOS: options += [ f"-DKDE_INSTALL_BUNDLEDIR={OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot())}/Applications/KDE", "-DAPPLE_SUPPRESS_X11_WARNING=ON" ] elif CraftCore.compiler.isLinux: # use the same lib dir on all distributions options += ["-DCMAKE_INSTALL_LIBDIR=lib"] elif CraftCore.compiler.isAndroid: nativeToolingRoot = CraftCore.settings.get("General", "KF5HostToolingRoot", "/opt/nativetooling") nativeToolingCMake = CraftCore.settings.get( "General", "KF5HostToolingCMakePath", "/opt/nativetooling/lib/x86_64-linux-gnu/cmake/") additionalFindRoots = ";".join( filter(None, [ CraftCore.settings.get( "General", "AndroidAdditionalFindRootPath", ""), craftRoot ])) options += [ f"-DCMAKE_TOOLCHAIN_FILE={nativeToolingRoot}/share/ECM/toolchain/Android.cmake", f"-DECM_ADDITIONAL_FIND_ROOT_PATH='{additionalFindRoots}'", f"-DKF5_HOST_TOOLING={nativeToolingCMake}", f"-DANDROID_APK_OUTPUT_DIR={self.packageDestinationDir()}", f"-DANDROID_FASTLANE_METADATA_OUTPUT_DIR={self.packageDestinationDir()}" ] self.__autodetectAndroidApkTargets() if self.androidApkTargets != None and len( self.androidApkTargets) > 0: options += [ f"-DQTANDROID_EXPORTED_TARGET={';'.join(self.androidApkTargets)}", f"-DANDROID_APK_DIR={';'.join(self.androidApkDirs)}" ] if self.buildType() == "Release" or self.buildType( ) == "MinSizeRel": options += ["-DANDROIDDEPLOYQT_EXTRA_ARGS=--release"] if CraftCore.compiler.isWindows or CraftCore.compiler.isMacOS: options.append("-DKDE_INSTALL_USE_QT_SYS_PATHS=ON") if self.subinfo.options.buildTools: options += self.subinfo.options.configure.toolsDefine if self.subinfo.options.buildStatic and self.subinfo.options.configure.staticArgs: options += self.subinfo.options.configure.staticArgs if CraftCore.compiler.isIntel(): # this is needed because otherwise it'll detect the MSVC environment options += " -DCMAKE_CXX_COMPILER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "icl.exe").replace("\\", "/") options += " -DCMAKE_C_COMPILER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "icl.exe").replace("\\", "/") options += " -DCMAKE_LINKER=\"%s\" " % os.path.join( os.getenv("BIN_ROOT"), os.getenv("ARCH_PATH"), "xilink.exe").replace("\\", "/") options += ["-S", self.configureSourceDir()] return options
def internalPostInstall(self): if not super().internalPostInstall(): return False # a post install routine to fix the prefix (make things relocatable) pkgconfigPath = os.path.join(self.imageDir(), "lib", "pkgconfig") newPrefix = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) oldPrefixes = [self.subinfo.buildPrefix] if CraftCore.compiler.isWindows: oldPrefixes += [ OsUtils.toUnixPath(self.subinfo.buildPrefix), OsUtils.toMSysPath(self.subinfo.buildPrefix) ] if os.path.exists(pkgconfigPath): for pcFile in os.listdir(pkgconfigPath): if pcFile.endswith(".pc"): path = os.path.join(pkgconfigPath, pcFile) if not self.patchInstallPrefix([path], oldPrefixes, newPrefix): return False if (CraftCore.compiler.isMacOS and os.path.isdir(self.installDir())): files = utils.filterDirectoryContent( self.installDir(), lambda x, root: utils.isBinary(x.path), lambda x, root: True) for f in files: if os.path.islink(f): continue _, ext = os.path.splitext(f) if ext in {".dylib", ".so"}: # fix dylib id with io.StringIO() as log: utils.system(["otool", "-D", f], stdout=log) oldId = log.getvalue().strip().split("\n") # the first line is the file name # the second the id, if we only get one line, there is no id to fix if len(oldId) == 2: oldId = oldId[1].strip() newId = oldId.replace(self.subinfo.buildPrefix, newPrefix) # TODO: meh, maybe there is a better way newId = newId.replace("@rpath", os.path.join(newPrefix, "lib")) if newId != oldId: if not utils.system( ["install_name_tool", "-id", newId, f]): return False else: # add rpath # TODO: only call add rpath if its not set yet, calling it twice causes an error utils.system([ "install_name_tool", "-add_rpath", os.path.join(newPrefix, "lib"), f ]) # fix dependencies for dep in utils.getLibraryDeps(f): if dep.startswith(self.subinfo.buildPrefix): newDep = dep.replace(self.subinfo.buildPrefix, newPrefix) if not utils.system( ["install_name_tool", "-change", dep, newDep, f]): return False return True
def internalPostInstall(self): if not super().internalPostInstall(): return False # a post install routine to fix the prefix (make things relocatable) newPrefix = OsUtils.toUnixPath(CraftCore.standardDirs.craftRoot()) oldPrefixes = [self.subinfo.buildPrefix] if CraftCore.compiler.isWindows: oldPrefixes += [ self.subinfo.buildPrefix.replace("\\", "\\\\"), OsUtils.toUnixPath(self.subinfo.buildPrefix), OsUtils.toMSysPath(self.subinfo.buildPrefix) ] pattern = [re.compile("^.*(pc|pri|prl|cmake|bat|cmd|ini|pl)$")] files = utils.filterDirectoryContent( self.installDir(), whitelist=lambda x, root: utils.regexFileFilter(x, root, pattern), blacklist=lambda x, root: True) if not self.patchInstallPrefix(files, oldPrefixes, newPrefix): return False if (CraftCore.compiler.isMacOS and os.path.isdir(self.installDir())): files = utils.filterDirectoryContent( self.installDir(), lambda x, root: utils.isBinary(x.path), lambda x, root: True) for f in files: if os.path.islink(f): continue _, ext = os.path.splitext(f) if ext in {".dylib", ".so"}: # fix dylib id with io.StringIO() as log: utils.system(["otool", "-D", f], stdout=log) oldId = log.getvalue().strip().split("\n") # the first line is the file name # the second the id, if we only get one line, there is no id to fix if len(oldId) == 2: oldId = oldId[1].strip() newId = oldId.replace(self.subinfo.buildPrefix, newPrefix) # TODO: meh, maybe there is a better way newId = newId.replace("@rpath", os.path.join(newPrefix, "lib")) if newId != oldId: if not utils.system( ["install_name_tool", "-id", newId, f]): return False else: # add rpath # TODO: only call add rpath if its not set yet, calling it twice causes an error utils.system([ "install_name_tool", "-add_rpath", os.path.join(newPrefix, "lib"), f ]) # fix dependencies for dep in utils.getLibraryDeps(f): if dep.startswith(self.subinfo.buildPrefix): newDep = dep.replace(self.subinfo.buildPrefix, newPrefix) if not utils.system( ["install_name_tool", "-change", dep, newDep, f]): return False # Install pdb files on MSVC if they are not found next to the dll if CraftCore.compiler.isMSVC and ( self.buildType() == "RelWithDebInfo" or self.buildType() == "Debug") and CraftCore.cache.findApplication("peparser"): files = utils.filterDirectoryContent( self.installDir(), lambda x, root: utils.isBinary(x.path), lambda x, root: True) regexp = re.compile('{.*} (.*)') exclude = re.compile(r'icudt[0-9]*.dll') for f in files: if not os.path.exists(f"{os.path.splitext(f)[0]}.pdb"): peparserOutput = CraftCore.cache.getCommandOutput( "peparser", f"--pdb {f}")[1].strip() pdbs = regexp.findall(peparserOutput) if not exclude.match(os.path.basename(f)): assert len(pdbs) > 0, f"No pdb file available: {f}" for pdb in pdbs: pdbDestination = os.path.join(os.path.dirname(f), os.path.basename(pdb)) CraftCore.log.info( f"Install pdb: {pdbDestination} for {os.path.basename(f)}" ) utils.copyFile(pdb, pdbDestination, linkOnly=False) return True