Ejemplo n.º 1
0
 def _find_executables(self, destdir_prefix):
     executables = []
     # filter out files to strip
     for filename in fileutils.accumulate_dirtree_contents(destdir_prefix):
         dirname, basename = os.path.split(filename)
         fullfilename = os.path.join(destdir_prefix, dirname, basename)
         if not os.path.isfile(fullfilename) or os.path.islink(
                 fullfilename):
             continue
         if not os.access(fullfilename,
                          os.X_OK) and 'so' not in basename.split(
                              os.path.extsep):
             continue
         if filename.endswith('.debug'):
             continue
         fileinfo = ''
         try:
             fileinfo = subprocess.check_output(
                 ['file', '-b', fullfilename]).strip()
         except Exception:
             pass
         if not fileinfo.startswith('ELF '):
             continue
         executables.append(filename)
     return executables
Ejemplo n.º 2
0
    def process_install(self, buildscript, revision):
        assert self.supports_install_destdir
        destdir = self.get_destdir(buildscript)
        self._clean_la_files(buildscript, destdir)

        prefix_without_drive = os.path.splitdrive(buildscript.config.prefix)[1]
        stripped_prefix = prefix_without_drive[1:]

        previous_entry = buildscript.moduleset.packagedb.get(self.name)
        if previous_entry:
            previous_contents = previous_entry.get_manifest()
        else:
            previous_contents = None

        new_contents = fileutils.accumulate_dirtree_contents(destdir)

        install_succeeded = False
        save_broken_tree = False
        broken_name = destdir + '-broken'
        destdir_prefix = os.path.join(destdir, stripped_prefix)
        errors = []
        if os.path.isdir(destdir_prefix):
            destdir_install = True
            logging.info(
                _('Moving temporary DESTDIR %r into build prefix') %
                (destdir, ))
            num_copied = self._process_install_files(destdir, destdir_prefix,
                                                     buildscript.config.prefix,
                                                     errors)

            # Now the destdir should have a series of empty directories:
            # $JHBUILD_PREFIX/_jhbuild/root-foo/$JHBUILD_PREFIX
            # Remove them one by one to clean the tree to the state we expect,
            # so we can better spot leftovers or broken things.
            prefix_dirs = filter(lambda x: x != '',
                                 stripped_prefix.split(os.sep))
            while len(prefix_dirs) > 0:
                dirname = prefix_dirs.pop()
                subprefix = os.path.join(*([destdir] + prefix_dirs))
                target = os.path.join(subprefix, dirname)
                assert target.startswith(buildscript.config.prefix)
                try:
                    os.rmdir(target)
                except OSError, e:
                    pass

            remaining_files = os.listdir(destdir)
            if len(remaining_files) > 0:
                logging.warn(
                    _("Files remaining in buildroot %(dest)r; module may have installed files outside of prefix."
                      ) % {
                          'num': len(remaining_files),
                          'dest': broken_name
                      })
                save_broken_tree = True
            # Even if there are some files outside the DESTDIR, count that as success for now; we just warn
            install_succeeded = True
Ejemplo n.º 3
0
    def process_install(self, buildscript, revision):
        assert self.supports_install_destdir
        destdir = self.get_destdir(buildscript)
        self._clean_la_files(buildscript, destdir)

        prefix_without_drive = os.path.splitdrive(buildscript.config.prefix)[1]
        stripped_prefix = prefix_without_drive[1:]

        previous_entry = buildscript.moduleset.packagedb.get(self.name)
        if previous_entry:
            previous_contents = previous_entry.get_manifest()
        else:
            previous_contents = None

        new_contents = fileutils.accumulate_dirtree_contents(destdir)

        install_succeeded = False
        save_broken_tree = False
        broken_name = destdir + "-broken"
        destdir_prefix = os.path.join(destdir, stripped_prefix)
        if os.path.isdir(destdir_prefix):
            destdir_install = True
            logging.info(_("Moving temporary DESTDIR %r into build prefix") % (destdir,))
            num_copied = self._process_install_files(destdir, destdir_prefix, buildscript.config.prefix)
            logging.info(_("Install complete: %d files copied") % (num_copied,))

            # Now the destdir should have a series of empty directories:
            # $JHBUILD_PREFIX/_jhbuild/root-foo/$JHBUILD_PREFIX
            # Remove them one by one to clean the tree to the state we expect,
            # so we can better spot leftovers or broken things.
            prefix_dirs = filter(lambda x: x != "", stripped_prefix.split(os.sep))
            while len(prefix_dirs) > 0:
                dirname = prefix_dirs.pop()
                subprefix = os.path.join(*([destdir] + prefix_dirs))
                target = os.path.join(subprefix, dirname)
                assert target.startswith(buildscript.config.prefix)
                try:
                    os.rmdir(target)
                except OSError, e:
                    pass

            remaining_files = os.listdir(destdir)
            if len(remaining_files) > 0:
                logging.warn(
                    _("Files remaining in buildroot %(dest)r; module may have installed files outside of prefix.")
                    % {"num": len(remaining_files), "dest": broken_name}
                )
                save_broken_tree = True
            # Even if there are some files outside the DESTDIR, count that as success for now; we just warn
            install_succeeded = True
Ejemplo n.º 4
0
    def _strip_debug_symbols(self, destdir_prefix, installroot):
        assert self.supports_stripping_debug_symbols

        for filename in fileutils.accumulate_dirtree_contents(destdir_prefix):
            dirname, basename = os.path.split(filename)
            fullfilename = os.path.join(destdir_prefix, dirname, basename)
            if not os.path.isfile(fullfilename) or os.path.islink(fullfilename):
                continue
            if not os.access(fullfilename, os.X_OK) and 'so' not in basename.split(os.path.extsep):
                continue
            fileinfo = ''
            try:
                fileinfo = subprocess.check_output(['file', '-b', fullfilename]).strip()
            except Exception:
                pass
            if not fileinfo.startswith('ELF ') or not fileinfo.endswith(', not stripped'):
                continue

            # make sure file is writable
            os.chmod(fullfilename, os.stat(fullfilename).st_mode | stat.S_IWUSR)

            # first create the /opt/debug/dirname
            fulldebugdirname = os.path.join(destdir_prefix, 'debug', dirname)
            if not os.path.exists(fulldebugdirname):
                os.makedirs(fulldebugdirname)
            fulldebugfilename = os.path.join(fulldebugdirname, basename + '.debug')

            # strip
            try:
                subprocess.check_call(['objcopy', '--only-keep-debug', fullfilename, fulldebugfilename])
                subprocess.check_call(['objcopy', '--remove-section', '.gnu_debuglink', fullfilename])
                subprocess.check_call(['objcopy', '--add-gnu-debuglink', fulldebugfilename, fullfilename])
                subprocess.check_call(['objcopy', '--strip-all', '--discard-all', '--preserve-dates', fullfilename])
            except Exception:
                continue

            # create a /opt/dirname/basename.debug link to /opt/debug/dirname/basename.debug
            fulldebuglinkname = os.path.join(destdir_prefix, dirname, basename + '.debug')
            if os.path.exists(fulldebuglinkname):
                os.remove(fulldebuglinkname)
            os.symlink(os.path.join(installroot, 'debug', dirname, basename + '.debug'), fulldebuglinkname)
Ejemplo n.º 5
0
 def _find_executables(self, destdir_prefix):
     executables = []
     # filter out files to strip
     for filename in fileutils.accumulate_dirtree_contents(destdir_prefix):
         dirname, basename = os.path.split(filename)
         fullfilename = os.path.join(destdir_prefix, dirname, basename)
         if not os.path.isfile(fullfilename) or os.path.islink(fullfilename):
             continue
         if not os.access(fullfilename, os.X_OK) and 'so' not in basename.split(os.path.extsep):
             continue
         if filename.endswith('.debug'):
             continue
         fileinfo = ''
         try:
             fileinfo = subprocess.check_output(['file', '-b', fullfilename]).strip()
         except Exception:
             pass
         if not fileinfo.startswith('ELF '):
             continue
         executables.append(filename)
     return executables
Ejemplo n.º 6
0
    def process_install(self, buildscript, revision):
        assert self.supports_install_destdir
        destdir = self.get_destdir(buildscript)
        self._clean_la_files(buildscript, destdir)
        self._clean_texinfo_dir_files(buildscript, destdir)

        prefix_without_drive = os.path.splitdrive(buildscript.config.prefix)[1]
        stripped_prefix = prefix_without_drive[1:]

        install_succeeded = False
        save_broken_tree = False
        broken_name = destdir + '-broken'
        destdir_prefix = os.path.join(destdir, stripped_prefix)
        new_contents = fileutils.accumulate_dirtree_contents(destdir_prefix)
        errors = []
        if os.path.isdir(destdir_prefix):
            logging.info(_('Moving temporary DESTDIR %r into build prefix') % (destdir, ))
            num_copied = self._process_install_files(destdir, destdir_prefix,
                                                     buildscript.config.prefix,
                                                     errors)

            # Now the destdir should have a series of empty directories:
            # $JHBUILD_PREFIX/_jhbuild/root-foo/$JHBUILD_PREFIX
            # Remove them one by one to clean the tree to the state we expect,
            # so we can better spot leftovers or broken things.
            prefix_dirs = filterlist(lambda x: x != '', stripped_prefix.split(os.sep))
            while len(prefix_dirs) > 0:
                dirname = prefix_dirs.pop()
                subprefix = os.path.join(*([destdir] + prefix_dirs))
                target = os.path.join(subprefix, dirname)
                assert target.startswith(buildscript.config.prefix)
                try:
                    os.rmdir(target)
                except OSError:
                    pass

            remaining_files = os.listdir(destdir)
            if len(remaining_files) > 0:
                logging.warn(_("Files remaining in buildroot %(dest)r; module may have installed files outside of prefix.") % {'num': len(remaining_files),
                                                                                                                               'dest': broken_name})
                save_broken_tree = True
            # Even if there are some files outside the DESTDIR, count that as success for now; we just warn
            install_succeeded = True
        else:
            save_broken_tree = True

        if save_broken_tree:
            if os.path.exists(broken_name):
                assert broken_name.startswith(buildscript.config.top_builddir)
                shutil.rmtree(broken_name)
            fileutils.rename(destdir, broken_name)
        else:
            assert destdir.startswith(buildscript.config.prefix)
            os.rmdir(destdir)

        if not install_succeeded:
            raise CommandError(_("Module failed to install into DESTDIR %(dest)r") % {'dest': broken_name})
        else:
            to_delete = set()
            previous_entry = buildscript.moduleset.packagedb.get(self.name)
            if previous_entry:
                previous_contents = previous_entry.manifest
                if previous_contents:
                    to_delete.update(fileutils.filter_files_by_prefix(self.config, previous_contents))

            for filename in new_contents:
                to_delete.discard (os.path.join(self.config.prefix, filename))

            if to_delete:
                # paranoid double-check
                assert to_delete == set(fileutils.filter_files_by_prefix(self.config, to_delete))

                logging.info(_('%d files remaining from previous build') % (len(to_delete),))
                for (path, was_deleted, error_string) in fileutils.remove_files_and_dirs(to_delete, allow_nonempty_dirs=True):
                    if was_deleted:
                        logging.info(_('Deleted: %(file)r') % { 'file': path, })
                    elif error_string is None:
                        # We don't warn on not-empty directories
                        pass
                    else:
                        logging.warn(_("Failed to delete no longer installed file %(file)r: %(msg)s") % { 'file': path,
                                                                                                          'msg': error_string})

            buildscript.moduleset.packagedb.add(self.name, revision or '',
                                                new_contents,
                                                self.configure_cmd)

        if errors:
            raise CommandError(_('Install encountered errors: %(num)d '
                                 'errors raised, %(files)d files copied. '
                                 'The errors are:\n  %(err)s') %
                               {'num'   : len(errors),
                                'files' : num_copied,
                                'err'   : '\n  '.join(errors)})
        else:
            logging.info(_('Install complete: %d files copied') %
                         (num_copied, ))
Ejemplo n.º 7
0
    def process_install(self, buildscript, revision):
        assert self.supports_install_destdir
        destdir = self.get_destdir(buildscript)
        self._clean_la_files(buildscript, destdir)
        self._clean_texinfo_dir_files(buildscript, destdir)

        prefix_without_drive = os.path.splitdrive(buildscript.config.prefix)[1]
        stripped_prefix = prefix_without_drive[1:]

        install_succeeded = False
        save_broken_tree = False
        broken_name = destdir + '-broken'
        destdir_prefix = os.path.join(destdir, stripped_prefix)

        # simon: dump sysdeps
        logging.info(_('Finding system dependencies ...'))
        systemdependencies, notfounds, rdependencies = self._find_executable_system_dependencies(destdir_prefix, buildscript.config.prefix)
        if notfounds:
            broken = set()
            missing = set()
            for lib, notfound in notfounds.iteritems():
                broken.add(lib)
                missing.update(notfound)

            # collect broken binaries
            brokenqueue = set(broken)
            while brokenqueue:
                rdepend = rdependencies[brokenqueue.pop()]
                brokenqueue.update(set(rdepend).difference(broken))
                broken.update(rdepend)

            for filename in broken:
                # os.unlink(os.path.join(destdir_prefix, filename))
                logging.warn(_('Broken binary: %s') % filename)
            logging.warn(_('Missing system dependencies: %s') % ', '.join(sorted(missing)))

        # simon: strip debug info before install
        if self.supports_stripping_debug_symbols:
            logging.info(_('Stripping debug symbols ...'))
            self._strip_debug_symbols(destdir_prefix, buildscript.config.prefix)

        new_contents = fileutils.accumulate_dirtree_contents(destdir_prefix)
        errors = []

        if os.path.isdir(destdir_prefix):
            destdir_install = True
            logging.info(_('Moving temporary DESTDIR %r into build prefix') % (destdir, ))
            num_copied = self._process_install_files(destdir, destdir_prefix,
                                                     buildscript.config.prefix,
                                                     errors)
            # Now the destdir should have a series of empty directories:
            # $JHBUILD_PREFIX/_jhbuild/root-foo/$JHBUILD_PREFIX
            # Remove them one by one to clean the tree to the state we expect,
            # so we can better spot leftovers or broken things.
            prefix_dirs = filter(lambda x: x != '', stripped_prefix.split(os.sep))
            while len(prefix_dirs) > 0:
                dirname = prefix_dirs.pop()
                subprefix = os.path.join(*([destdir] + prefix_dirs))
                target = os.path.join(subprefix, dirname)
                # liuhuan: need to disable this assertion to allow custom top_builddir
                #assert target.startswith(buildscript.config.prefix)
                try:
                    os.rmdir(target)
                except OSError as e:
                    pass

            remaining_files = os.listdir(destdir)
            if len(remaining_files) > 0:
                logging.warn(_("Files remaining in buildroot %(dest)r; module may have installed files outside of prefix.") % {'num': len(remaining_files),
                                                                                                                               'dest': broken_name})
                save_broken_tree = True
            # Even if there are some files outside the DESTDIR, count that as success for now; we just warn
            install_succeeded = True
        else:
            save_broken_tree = True

        if save_broken_tree:
            if os.path.exists(broken_name):
                assert broken_name.startswith(buildscript.config.top_builddir)
                shutil.rmtree(broken_name)
            fileutils.rename(destdir, broken_name)
        else:
            # liuhuan: need to disable this assertion to allow custom top_builddir
            #assert destdir.startswith(buildscript.config.prefix)
            os.rmdir(destdir)

        if not install_succeeded:
            raise CommandError(_("Module failed to install into DESTDIR %(dest)r") % {'dest': broken_name})
        else:
            to_delete = set()
            previous_entry = buildscript.moduleset.packagedb.get(self.name)
            if previous_entry:
                previous_contents = previous_entry.get_manifest()
                if previous_contents:
                    to_delete.update(fileutils.filter_files_by_prefix(self.config, previous_contents))

            for filename in new_contents:
                to_delete.discard (os.path.join(self.config.prefix, filename))

            if to_delete:
                # paranoid double-check
                assert to_delete == set(fileutils.filter_files_by_prefix(self.config, to_delete))

                logging.info(_('%d files remaining from previous build') % (len(to_delete),))
                for (path, was_deleted, error_string) in fileutils.remove_files_and_dirs(to_delete, self.config, allow_nonempty_dirs=True):
                    if was_deleted:
                        logging.info(_('Deleted: %(file)r') % { 'file': path, })
                    elif error_string is None:
                        # We don't warn on not-empty directories
                        pass
                    else:
                        logging.warn(_("Failed to delete no longer installed file %(file)r: %(msg)s") % { 'file': path,
                                                                                                          'msg': error_string})

            buildscript.moduleset.packagedb.add(self.name, revision or '',
                                                new_contents,
                                                self.configure_cmd,
                                                systemdependencies)

        if errors:
            raise CommandError(_('Install encountered errors: %(num)d '
                                 'errors raised, %(files)d files copied. '
                                 'The errors are:\n  %(err)s') %
                               {'num'   : len(errors),
                                'files' : num_copied,
                                'err'   : '\n  '.join(errors)})
        else:
            logging.info(_('Install complete: %d files copied') %
                         (num_copied, ))
Ejemplo n.º 8
0
    def process_install(self, buildscript, revision):
        assert self.supports_install_destdir
        destdir = self.get_destdir(buildscript)
        self._clean_la_files(buildscript, destdir)
        self._clean_texinfo_dir_files(buildscript, destdir)

        prefix_without_drive = os.path.splitdrive(buildscript.config.prefix)[1]
        stripped_prefix = prefix_without_drive[1:]

        install_succeeded = False
        save_broken_tree = False
        broken_name = destdir + '-broken'
        destdir_prefix = os.path.join(destdir, stripped_prefix)

        # simon: dump sysdeps
        logging.info(_('Finding system dependencies ...'))
        systemdependencies, notfounds, rdependencies = self._find_executable_system_dependencies(
            destdir_prefix, buildscript.config.prefix)
        if notfounds:
            broken = set()
            missing = set()
            for lib, notfound in notfounds.iteritems():
                broken.add(lib)
                missing.update(notfound)

            # collect broken binaries
            brokenqueue = set(broken)
            while brokenqueue:
                rdepend = rdependencies[brokenqueue.pop()]
                brokenqueue.update(set(rdepend).difference(broken))
                broken.update(rdepend)

            for filename in broken:
                # os.unlink(os.path.join(destdir_prefix, filename))
                logging.warn(_('Broken binary: %s') % filename)
            logging.warn(
                _('Missing system dependencies: %s') %
                ', '.join(sorted(missing)))

        # simon: strip debug info before install
        if self.supports_stripping_debug_symbols:
            logging.info(_('Stripping debug symbols ...'))
            self._strip_debug_symbols(destdir_prefix,
                                      buildscript.config.prefix)

        new_contents = fileutils.accumulate_dirtree_contents(destdir_prefix)
        errors = []

        if os.path.isdir(destdir_prefix):
            destdir_install = True
            logging.info(
                _('Moving temporary DESTDIR %r into build prefix') %
                (destdir, ))
            num_copied = self._process_install_files(destdir, destdir_prefix,
                                                     buildscript.config.prefix,
                                                     errors)
            # Now the destdir should have a series of empty directories:
            # $JHBUILD_PREFIX/_jhbuild/root-foo/$JHBUILD_PREFIX
            # Remove them one by one to clean the tree to the state we expect,
            # so we can better spot leftovers or broken things.
            prefix_dirs = filter(lambda x: x != '',
                                 stripped_prefix.split(os.sep))
            while len(prefix_dirs) > 0:
                dirname = prefix_dirs.pop()
                subprefix = os.path.join(*([destdir] + prefix_dirs))
                target = os.path.join(subprefix, dirname)
                # liuhuan: need to disable this assertion to allow custom top_builddir
                #assert target.startswith(buildscript.config.prefix)
                try:
                    os.rmdir(target)
                except OSError as e:
                    pass

            remaining_files = os.listdir(destdir)
            if len(remaining_files) > 0:
                logging.warn(
                    _("Files remaining in buildroot %(dest)r; module may have installed files outside of prefix."
                      ) % {
                          'num': len(remaining_files),
                          'dest': broken_name
                      })
                save_broken_tree = True
            # Even if there are some files outside the DESTDIR, count that as success for now; we just warn
            install_succeeded = True
        else:
            save_broken_tree = True

        if save_broken_tree:
            if os.path.exists(broken_name):
                assert broken_name.startswith(buildscript.config.top_builddir)
                shutil.rmtree(broken_name)
            fileutils.rename(destdir, broken_name)
        else:
            # liuhuan: need to disable this assertion to allow custom top_builddir
            #assert destdir.startswith(buildscript.config.prefix)
            os.rmdir(destdir)

        if not install_succeeded:
            raise CommandError(
                _("Module failed to install into DESTDIR %(dest)r") %
                {'dest': broken_name})
        else:
            to_delete = set()
            previous_entry = buildscript.moduleset.packagedb.get(self.name)
            if previous_entry:
                previous_contents = previous_entry.get_manifest()
                if previous_contents:
                    to_delete.update(
                        fileutils.filter_files_by_prefix(
                            self.config, previous_contents))

            for filename in new_contents:
                to_delete.discard(os.path.join(self.config.prefix, filename))

            if to_delete:
                # paranoid double-check
                assert to_delete == set(
                    fileutils.filter_files_by_prefix(self.config, to_delete))

                logging.info(
                    _('%d files remaining from previous build') %
                    (len(to_delete), ))
                for (path, was_deleted,
                     error_string) in fileutils.remove_files_and_dirs(
                         to_delete, self.config, allow_nonempty_dirs=True):
                    if was_deleted:
                        logging.info(
                            _('Deleted: %(file)r') % {
                                'file': path,
                            })
                    elif error_string is None:
                        # We don't warn on not-empty directories
                        pass
                    else:
                        logging.warn(
                            _("Failed to delete no longer installed file %(file)r: %(msg)s"
                              ) % {
                                  'file': path,
                                  'msg': error_string
                              })

            # determine branch
            branch = None
            if self.branch is not None and hasattr(
                    self.branch,
                    'repomodule') and self.branch.repomodule is not None:
                branch = {self.branch.repomodule: revision}
                logging.info(_('Installed branch: %s') % json.dumps(branch))

            buildscript.moduleset.packagedb.add(self.name, revision or '',
                                                new_contents,
                                                self.configure_cmd,
                                                systemdependencies, branch,
                                                self.module_hash)

        if errors:
            raise CommandError(
                _('Install encountered errors: %(num)d '
                  'errors raised, %(files)d files copied. '
                  'The errors are:\n  %(err)s') % {
                      'num': len(errors),
                      'files': num_copied,
                      'err': '\n  '.join(errors)
                  })
        else:
            logging.info(
                _('Install complete: %d files copied') % (num_copied, ))
Ejemplo n.º 9
0
    def _strip_debug_symbols(self, destdir_prefix, installroot):
        assert self.supports_stripping_debug_symbols

        for filename in fileutils.accumulate_dirtree_contents(destdir_prefix):
            dirname, basename = os.path.split(filename)
            fullfilename = os.path.join(destdir_prefix, dirname, basename)
            if not os.path.isfile(fullfilename) or os.path.islink(
                    fullfilename):
                continue
            if not os.access(fullfilename,
                             os.X_OK) and 'so' not in basename.split(
                                 os.path.extsep):
                continue
            fileinfo = ''
            try:
                fileinfo = subprocess.check_output(
                    ['file', '-b', fullfilename]).strip()
            except Exception:
                pass
            if not fileinfo.startswith('ELF ') or not fileinfo.endswith(
                    ', not stripped'):
                continue

            # make sure file is writable
            os.chmod(fullfilename,
                     os.stat(fullfilename).st_mode | stat.S_IWUSR)

            # first create the /opt/debug/dirname
            fulldebugdirname = os.path.join(destdir_prefix, 'debug', dirname)
            if not os.path.exists(fulldebugdirname):
                os.makedirs(fulldebugdirname)
            fulldebugfilename = os.path.join(fulldebugdirname,
                                             basename + '.debug')

            # strip
            try:
                subprocess.check_call([
                    'objcopy', '--only-keep-debug', fullfilename,
                    fulldebugfilename
                ])
                subprocess.check_call([
                    'objcopy', '--remove-section', '.gnu_debuglink',
                    fullfilename
                ])
                subprocess.check_call([
                    'objcopy', '--add-gnu-debuglink', fulldebugfilename,
                    fullfilename
                ])
                subprocess.check_call([
                    'objcopy', '--strip-all', '--discard-all',
                    '--preserve-dates', fullfilename
                ])
            except Exception:
                continue

            # create a /opt/dirname/basename.debug link to /opt/debug/dirname/basename.debug
            fulldebuglinkname = os.path.join(destdir_prefix, dirname,
                                             basename + '.debug')
            if os.path.exists(fulldebuglinkname):
                os.remove(fulldebuglinkname)
            os.symlink(
                os.path.join(installroot, 'debug', dirname,
                             basename + '.debug'), fulldebuglinkname)
Ejemplo n.º 10
0
    def process_install(self, buildscript, revision):
        assert self.supports_install_destdir
        destdir = self.get_destdir(buildscript)
        self._clean_la_files(buildscript, destdir)
        self._clean_texinfo_dir_files(buildscript, destdir)

        prefix_without_drive = os.path.splitdrive(buildscript.config.prefix)[1]
        stripped_prefix = prefix_without_drive[1:]

        install_succeeded = False
        save_broken_tree = False
        broken_name = destdir + "-broken"
        destdir_prefix = os.path.join(destdir, stripped_prefix)
        new_contents = fileutils.accumulate_dirtree_contents(destdir_prefix)
        errors = []
        if os.path.isdir(destdir_prefix):
            destdir_install = True
            logging.info(_("Moving temporary DESTDIR %r into build prefix") % (destdir,))
            num_copied = self._process_install_files(destdir, destdir_prefix, buildscript.config.prefix, errors)

            # Now the destdir should have a series of empty directories:
            # $JHBUILD_PREFIX/_jhbuild/root-foo/$JHBUILD_PREFIX
            # Remove them one by one to clean the tree to the state we expect,
            # so we can better spot leftovers or broken things.
            prefix_dirs = filter(lambda x: x != "", stripped_prefix.split(os.sep))
            while len(prefix_dirs) > 0:
                dirname = prefix_dirs.pop()
                subprefix = os.path.join(*([destdir] + prefix_dirs))
                target = os.path.join(subprefix, dirname)
                assert target.startswith(buildscript.config.prefix)
                try:
                    os.rmdir(target)
                except OSError as e:
                    pass

            remaining_files = os.listdir(destdir)
            if len(remaining_files) > 0:
                logging.warn(
                    _("Files remaining in buildroot %(dest)r; module may have installed files outside of prefix.")
                    % {"num": len(remaining_files), "dest": broken_name}
                )
                save_broken_tree = True
            # Even if there are some files outside the DESTDIR, count that as success for now; we just warn
            install_succeeded = True
        else:
            save_broken_tree = True

        if save_broken_tree:
            if os.path.exists(broken_name):
                assert broken_name.startswith(buildscript.config.top_builddir)
                shutil.rmtree(broken_name)
            fileutils.rename(destdir, broken_name)
        else:
            assert destdir.startswith(buildscript.config.prefix)
            os.rmdir(destdir)

        if not install_succeeded:
            raise CommandError(_("Module failed to install into DESTDIR %(dest)r") % {"dest": broken_name})
        else:
            to_delete = set()
            previous_entry = buildscript.moduleset.packagedb.get(self.name)
            if previous_entry:
                previous_contents = previous_entry.get_manifest()
                if previous_contents:
                    to_delete.update(fileutils.filter_files_by_prefix(self.config, previous_contents))

            for filename in new_contents:
                to_delete.discard(os.path.join(self.config.prefix, filename))

            if to_delete:
                # paranoid double-check
                assert to_delete == set(fileutils.filter_files_by_prefix(self.config, to_delete))

                logging.info(_("%d files remaining from previous build") % (len(to_delete),))
                for (path, was_deleted, error_string) in fileutils.remove_files_and_dirs(
                    to_delete, allow_nonempty_dirs=True
                ):
                    if was_deleted:
                        logging.info(_("Deleted: %(file)r") % {"file": path})
                    elif error_string is None:
                        # We don't warn on not-empty directories
                        pass
                    else:
                        logging.warn(
                            _("Failed to delete no longer installed file %(file)r: %(msg)s")
                            % {"file": path, "msg": error_string}
                        )

            buildscript.moduleset.packagedb.add(self.name, revision or "", new_contents, self.configure_cmd)

        if errors:
            raise CommandError(
                _(
                    "Install encountered errors: %(num)d "
                    "errors raised, %(files)d files copied. "
                    "The errors are:\n  %(err)s"
                )
                % {"num": len(errors), "files": num_copied, "err": "\n  ".join(errors)}
            )
        else:
            logging.info(_("Install complete: %d files copied") % (num_copied,))