def CreatePkgFile(self): """Create and pkg file for use with the FreeBSD pkg tool. Create a package from the result of the package's InstallStep. """ install_dir = self.GetInstallLocation() if not os.path.exists(install_dir): Log('Skiping pkg creation. Install dir not found: %s' % install_dir) return # Strip all elf or pexe files in the install directory (except .o files # since we don't want to strip, for example, crt1.o) if not self.config.debug and self.config.toolchain != 'emscripten': strip = util.GetStrip(self.config) for root, _, files in os.walk(install_dir): for filename in files: fullname = os.path.join(root, filename) if (os.path.isfile(fullname) and util.IsElfFile(fullname) and os.path.splitext(fullname)[1] != '.o'): Log('stripping: %s %s' % (strip, fullname)) subprocess.check_call([strip, fullname]) abi = 'pkg_' + self.config.toolchain if self.config.arch != self.config.toolchain: abi += "_" + util.arch_to_pkgarch[self.config.arch] abi_dir = os.path.join(paths.PUBLISH_ROOT, abi) pkg_file = os.path.join(abi_dir, '%s-%s.tbz' % (self.NAME, self.VERSION)) util.Makedirs(abi_dir) deps = self.DEPENDS if self.config.toolchain != 'glibc': deps = [] bsd_pkg.CreatePkgFile(self.NAME, self.VERSION, self.config.arch, self.GetInstallLocation(), pkg_file, deps)
def WriteStamp(stamp_file, stamp_contents): """Write a stamp file to disk with the given file contents.""" stamp_dir = os.path.dirname(stamp_file) util.Makedirs(stamp_dir) with open(stamp_file, 'w') as f: f.write(stamp_contents) Log('Wrote stamp: %s' % stamp_file)
def Extract(self): """Extract the package archive into its build location. This method assumes the package has already been downloaded. """ if self.IsGitUpstream(): self.GitClone() return archive = self.DownloadLocation() if not archive: self.Log('Skipping extract; No upstream archive') return dest = self.GetBuildLocation() output_path, new_foldername = os.path.split(dest) util.Makedirs(output_path) # Check existing stamp file contents stamp_file = self.GetExtractStamp() stamp_contents = self.GetExtractStampContent() if os.path.exists(dest): if StampContentsMatch(stamp_file, stamp_contents): Log('Already up-to-date: %s' % util.RelPath(dest)) return raise Error("Upstream archive or patch has changed.\n" + "Please remove existing checkout and try again: '%s'" % dest) util.LogHeading('Extracting') util.Makedirs(paths.OUT_DIR) tmp_output_path = tempfile.mkdtemp(dir=paths.OUT_DIR) try: ExtractArchive(archive, tmp_output_path) src = os.path.join(tmp_output_path, new_foldername) if not os.path.isdir(src): raise Error('Archive contents not found: %s' % src) LogVerbose("renaming '%s' -> '%s'" % (src, dest)) os.rename(src, dest) finally: util.RemoveTree(tmp_output_path) self.RemoveStamps() WriteStamp(stamp_file, stamp_contents)
def Download(self, package_name, config): if not os.path.exists(PREBUILT_ROOT): util.Makedirs(PREBUILT_ROOT) info = self.packages[(package_name, config)] filename = os.path.join(PREBUILT_ROOT, os.path.basename(info['BIN_URL'])) if os.path.exists(filename): try: util.VerifyHash(filename, info['BIN_SHA1']) return filename except util.HashVerificationError: pass util.Log('Downloading prebuilt binary ...') util.DownloadFile(filename, info['BIN_URL']) util.VerifyHash(filename, info['BIN_SHA1']) return filename
def _InstallFiles(self, force): dest = util.GetInstallRoot(self.config) dest_tmp = os.path.join(dest, 'install_tmp') if os.path.exists(dest_tmp): shutil.rmtree(dest_tmp) if self.IsAnyVersionInstalled(): raise error.Error('package already installed: %s' % self.InfoString()) self.LogStatus('Installing') util.LogVerbose('installing from: %s' % self.filename) util.Makedirs(dest_tmp) names = [] try: with tarfile.open(self.filename) as tar: for info in tar: if info.isdir(): continue name = posixpath.normpath(info.name) if name == 'pkg_info': continue if not name.startswith(PAYLOAD_DIR + '/'): raise error.PkgFormatError('invalid file in package: %s' % name) name = name[len(PAYLOAD_DIR) + 1:] names.append(name) if not force: for name in names: full_name = os.path.join(dest, name) if os.path.exists(full_name): raise error.Error('file already exists: %s' % full_name) tar.extractall(dest_tmp) payload_tree = os.path.join(dest_tmp, PAYLOAD_DIR) names = FilterOutExecutables(names, payload_tree) for name in names: InstallFile(name, payload_tree, dest) finally: shutil.rmtree(dest_tmp) for name in names: RelocateFile(name, dest) self.WriteFileList(names)
def Build(self, build_deps, force=None): self.CheckBuildable() if build_deps: self.InstallDeps(force) if not force and self.IsBuilt(): self.LogStatus('Already built') return log_root = os.path.join(paths.OUT_DIR, 'logs') util.Makedirs(log_root) self.LogStatus('Building') if util.log_level > util.LOG_INFO: log_filename = None else: log_filename = os.path.join( log_root, '%s_%s.log' % (self.NAME, str(self.config).replace('/', '_'))) if os.path.exists(log_filename): os.remove(log_filename) start = time.time() with util.DirLock(self.root): try: with RedirectStdoutStderr(log_filename): old_log_level = util.log_level util.log_level = util.LOG_VERBOSE try: self.Download() self.Extract() self.Patch() self.RunBuildSh() self.CreatePkgFile() finally: util.log_level = old_log_level except: if log_filename: with open(log_filename) as log_file: sys.stdout.write(log_file.read()) raise duration = FormatTimeDelta(time.time() - start) util.LogHeading('Build complete', ' [took %s]' % duration)
def DownloadArchive(self, force_mirror): """Download the archive to the local cache directory. Args: force_mirror: force downloading from mirror only. """ filename = self.DownloadLocation() if not filename or os.path.exists(filename): return util.Makedirs(os.path.dirname(filename)) # Always try the mirror URL first mirror_url = self.GetMirrorURL() try: util.DownloadFile(filename, mirror_url) except Error as e: if not force_mirror: # Fall back to the original upstream URL util.DownloadFile(filename, self.URL) else: raise e
def InstallFile(filename, old_root, new_root): """Install a single file by moving it into a new location. Args: filename: Relative name of file to install. old_root: The current location of the file. new_root: The new desired root for the file. """ oldname = os.path.join(old_root, filename) util.LogVerbose('install: %s' % filename) newname = os.path.join(new_root, filename) dirname = os.path.dirname(newname) if not os.path.isdir(dirname): util.Makedirs(dirname) os.rename(oldname, newname) # When install binaries ELF files into the toolchain direcoties, remove # the X bit so that they do not found when searching the PATH. if util.IsElfFile(newname) or util.IsPexeFile(newname): mode = os.stat(newname).st_mode mode = mode & ~(stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) os.chmod(newname, mode)
def MakeDirIfNeeded(filename): dirname = os.path.dirname(filename) if not os.path.isdir(dirname): util.Makedirs(dirname)