예제 #1
0
    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)
예제 #2
0
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)
예제 #3
0
    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)
예제 #4
0
 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
예제 #5
0
  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)
예제 #6
0
    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)
예제 #7
0
    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
예제 #8
0
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)
예제 #9
0
def MakeDirIfNeeded(filename):
  dirname = os.path.dirname(filename)
  if not os.path.isdir(dirname):
    util.Makedirs(dirname)