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 toNativePath(path) -> Path: if OsUtils.isWin(): return OsUtils.toMSysPath(path) else: return Path(path)
def configure(self): """configure the target""" self.enterBuildDir() configure = Arguments([ self.sourceDir() / (self.subinfo.options.configure.projectFile or "configure") ]) self.shell.environment[ "CFLAGS"] = self.subinfo.options.configure.cflags + " " + self.shell.environment[ "CFLAGS"] self.shell.environment[ "CXXFLAGS"] = self.subinfo.options.configure.cxxflags + " " + self.shell.environment[ "CXXFLAGS"] self.shell.environment[ "LDFLAGS"] = self.subinfo.options.configure.ldflags + " " + self.shell.environment[ "LDFLAGS"] self.shell.environment["MAKE"] = self.makeProgram env = {"CLICOLOR_FORCE": None} if self.supportsCCACHE: cxx = CraftCore.standardDirs.craftRoot( ) / "dev-utils/ccache/bin" / Path(os.environ["CXX"]).name if CraftCore.compiler.isWindows and not cxx.suffix: cxx = Path(str(cxx) + CraftCore.compiler.executableSuffix) if cxx.exists(): env["CXX"] = OsUtils.toMSysPath(cxx) env["CC"] = OsUtils.toMSysPath(cxx.parent / Path(os.environ["CC"]).name) with utils.ScopedEnv(env): autogen = self.sourceDir() / "autogen.sh" if self.subinfo.options.configure.bootstrap and autogen.exists(): mode = os.stat(autogen).st_mode if mode & stat.S_IEXEC == 0: os.chmod(autogen, mode | stat.S_IEXEC) self.shell.execute(self.sourceDir(), autogen) elif self.subinfo.options.configure.autoreconf and ( (self.sourceDir() / "configure.ac").exists() or (self.sourceDir() / "configure.in").exists()): includesArgs = Arguments() if self.subinfo.options.configure.useDefaultAutoreconfIncludes: includes = [] dataDirs = [ CraftCore.standardDirs.craftRoot() / "dev-utils/cmake/share" ] if CraftCore.compiler.isWindows: # on Windows data location lies outside of the autotools prefix (msys) dataDirs.append(CraftCore.standardDirs.locations.data) for i in dataDirs: aclocalDir = i / "aclocal" if aclocalDir.is_dir(): includes += [ f"-I{self.shell.toNativePath(aclocalDir)}" ] includesArgs += includes if not self.shell.execute( self.sourceDir(), "autoreconf", Arguments( self.subinfo.options.configure.autoreconfArgs) + includesArgs): return False return self.shell.execute(self.buildDir(), configure, self.configureOptions(self))
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 toMSysPath(path): return OsUtils.toMSysPath(path)
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