From 8ccab9852d672d9781cd25cf486e4128cb202f2c Mon Sep 17 00:00:00 2001 From: Eloston Date: Thu, 15 Feb 2018 07:46:18 +0000 Subject: [PATCH] Implement genpkg, refactor packaging, and other improvements * buildkit: Implement genpkg with current packaging types * Revert Debian minimal packaging type to files because patches require more effort to implement propertly * Some tweaks to packaging scripts * Various improvements to buildkit --- buildkit/cli.py | 140 +++++++++--- buildkit/common.py | 19 +- buildkit/config.py | 128 ++++++----- buildkit/domain_substitution.py | 8 +- buildkit/packaging/__init__.py | 0 .../packaging}/_common.py | 16 +- .../packaging}/debian.py | 72 ++++-- buildkit/packaging/linux_simple.py | 52 +++++ buildkit/packaging/macos.py | 51 +++++ buildkit/source_retrieval.py | 18 +- resources/packaging/debian/minimal.patch | 104 --------- resources/packaging/debian/minimal/clean | 1 + resources/packaging/debian/minimal/compat | 1 + resources/packaging/debian/minimal/control | 216 ++++++++++++++++++ resources/packaging/debian/minimal/rules.in | 115 ++++++++++ .../ungoogled-chromium-common.install.in | 6 + resources/packaging/linux_simple/build.sh.in | 4 +- .../packaging/linux_simple/package.sh.in | 2 +- resources/packaging/macos/build.sh.in | 6 +- .../_build_files_generators/linux_simple.py | 50 ---- utilikit/_build_files_generators/macos.py | 51 ----- 21 files changed, 718 insertions(+), 342 deletions(-) create mode 100644 buildkit/packaging/__init__.py rename {utilikit/_build_files_generators => buildkit/packaging}/_common.py (79%) rename {utilikit/_build_files_generators => buildkit/packaging}/debian.py (65%) create mode 100644 buildkit/packaging/linux_simple.py create mode 100644 buildkit/packaging/macos.py delete mode 100644 resources/packaging/debian/minimal.patch create mode 100644 resources/packaging/debian/minimal/clean create mode 100644 resources/packaging/debian/minimal/compat create mode 100644 resources/packaging/debian/minimal/control create mode 100755 resources/packaging/debian/minimal/rules.in create mode 100644 resources/packaging/debian/minimal/ungoogled-chromium-common.install.in delete mode 100644 utilikit/_build_files_generators/linux_simple.py delete mode 100644 utilikit/_build_files_generators/macos.py diff --git a/buildkit/cli.py b/buildkit/cli.py index 61bdd9b7..51b435b3 100644 --- a/buildkit/cli.py +++ b/buildkit/cli.py @@ -23,16 +23,14 @@ from pathlib import Path from . import config from . import source_retrieval from . import domain_substitution -from .common import CONFIG_BUNDLES_DIR, get_resources_dir, get_logger +from .common import ( + CONFIG_BUNDLES_DIR, BUILDSPACE_DOWNLOADS, BUILDSPACE_TREE, + BUILDSPACE_TREE_PACKAGING, BUILDSPACE_USER_BUNDLE, + BuildkitAbort, get_resources_dir, get_logger) from .config import ConfigBundle # Classes -class _MainArgumentParserFormatter(argparse.RawTextHelpFormatter, - argparse.ArgumentDefaultsHelpFormatter): - """Custom argparse.HelpFormatter for the main argument parser""" - pass - class _CLIError(RuntimeError): """Custom exception for printing argument parser errors from callbacks""" pass @@ -60,7 +58,7 @@ class _NewBaseBundleAction(argparse.Action): #pylint: disable=too-few-public-met except ValueError as exc: get_logger().error('Base bundle metadata has an issue: %s', exc) parser.exit(status=1) - except Exception as exc: #pylint: disable=broad-except + except BaseException: get_logger().exception('Unexpected exception caught.') parser.exit(status=1) setattr(namespace, self.dest, base_bundle) @@ -77,7 +75,7 @@ def setup_bundle_group(parser): 'Mutually exclusive with --user-bundle-path. ' 'Default value is nothing; a default is specified by --user-bundle-path.')) config_group.add_argument( - '-u', '--user-bundle-path', dest='bundle', default='buildspace/user_bundle', + '-u', '--user-bundle-path', dest='bundle', default=BUILDSPACE_USER_BUNDLE, type=lambda x: ConfigBundle(Path(x)), help=('The path to a user bundle to use. ' 'Mutually exclusive with --base-bundle-name. ')) @@ -122,14 +120,14 @@ def _add_genbun(subparsers): except ValueError as exc: get_logger().error('Error with base bundle: %s', exc) raise _CLIError() - except Exception as exc: + except BaseException: get_logger().exception('Unexpected exception caught.') raise _CLIError() parser = subparsers.add_parser( 'genbun', formatter_class=argparse.ArgumentDefaultsHelpFormatter, help=_add_genbun.__doc__, description=_add_genbun.__doc__) parser.add_argument( - '-u', '--user-bundle-path', type=Path, default='buildspace/user_bundle', + '-u', '--user-bundle-path', type=Path, default=BUILDSPACE_USER_BUNDLE, help=('The output path for the user config bundle. ' 'The path must not already exist. ')) parser.add_argument( @@ -159,27 +157,28 @@ def _add_getsrc(subparsers): except source_retrieval.HashMismatchError as exc: get_logger().error('Archive checksum is invalid: %s', exc) raise _CLIError() - except Exception as exc: + except BaseException: get_logger().exception('Unexpected exception caught.') raise _CLIError() parser = subparsers.add_parser( - 'getsrc', formatter_class=argparse.ArgumentDefaultsHelpFormatter, - help=_add_getsrc.__doc__ + '.', description=_add_getsrc.__doc__ + '; ' + ( + 'getsrc', help=_add_getsrc.__doc__ + '.', + description=_add_getsrc.__doc__ + '; ' + ( 'these are the Chromium source code and any extra dependencies. ' 'By default, binary pruning is performed during extraction. ' - 'The buildspace/downloads directory must already exist for storing downloads. ' + 'The %s directory must already exist for storing downloads. ' 'If the buildspace tree already exists or there is a checksum mismatch, ' 'this command will abort. ' 'Only files that are missing will be downloaded. ' 'If the files are already downloaded, their checksums are ' - 'confirmed and unpacked if necessary.')) + 'confirmed and then they are unpacked.') % BUILDSPACE_DOWNLOADS) setup_bundle_group(parser) parser.add_argument( - '-t', '--tree', type=Path, default='buildspace/tree', - help='The buildspace tree path') + '-t', '--tree', type=Path, default=BUILDSPACE_TREE, + help='The buildspace tree path. Default: %s' % BUILDSPACE_TREE) parser.add_argument( - '-d', '--downloads', type=Path, default='buildspace/downloads', - help='Path to store archives of Chromium source code and extra deps.') + '-d', '--downloads', type=Path, default=BUILDSPACE_DOWNLOADS, + help=('Path to store archives of Chromium source code and extra deps. ' + 'Default: %s') % BUILDSPACE_DOWNLOADS) parser.add_argument( '--disable-binary-pruning', action='store_false', dest='prune_binaries', help='Disables binary pruning during extraction.') @@ -207,18 +206,17 @@ def _add_prubin(subparsers): if missing_file: raise _CLIError() parser = subparsers.add_parser( - 'prubin', formatter_class=argparse.ArgumentDefaultsHelpFormatter, - help=_add_prubin.__doc__, description=_add_prubin.__doc__ + ( + 'prubin', help=_add_prubin.__doc__, description=_add_prubin.__doc__ + ( ' This is NOT necessary if the source code was already pruned ' 'during the getsrc command.')) setup_bundle_group(parser) parser.add_argument( - '-t', '--tree', type=Path, default='buildspace/tree', - help='The buildspace tree path to apply binary pruning.') + '-t', '--tree', type=Path, default=BUILDSPACE_TREE, + help='The buildspace tree path to apply binary pruning. Default: %s' % BUILDSPACE_TREE) parser.set_defaults(callback=_callback) def _add_subdom(subparsers): - """Substitutes domain names in buildspace tree with blockable strings.""" + """Substitutes domain names in buildspace tree or patches with blockable strings.""" def _callback(args): try: if not args.only or args.only == 'tree': @@ -232,8 +230,7 @@ def _add_subdom(subparsers): get_logger().error('Patches directory does not exist: %s', exc) raise _CLIError() parser = subparsers.add_parser( - 'subdom', formatter_class=argparse.ArgumentDefaultsHelpFormatter, - help=_add_subdom.__doc__, description=_add_subdom.__doc__ + ( + 'subdom', help=_add_subdom.__doc__, description=_add_subdom.__doc__ + ( ' By default, it will substitute the domains on both the buildspace tree and ' 'the bundle\'s patches.')) setup_bundle_group(parser) @@ -242,27 +239,98 @@ def _add_subdom(subparsers): help=('Specifies a component to exclusively apply domain substitution to. ' '"tree" is for the buildspace tree, and "patches" is for the bundle\'s patches.')) parser.add_argument( - '-t', '--tree', type=Path, default='buildspace/tree', + '-t', '--tree', type=Path, default=BUILDSPACE_TREE, help=('The buildspace tree path to apply domain substitution. ' - 'Not applicable when --only is "patches".')) + 'Not applicable when --only is "patches". Default: %s') % BUILDSPACE_TREE) + parser.set_defaults(callback=_callback) + +def _add_genpkg_debian(subparsers): + """Generate Debian packaging files""" + def _callback(args): + from .packaging import debian as packaging_debian + try: + packaging_debian.generate_packaging(args.bundle, args.flavor, args.output) + except FileExistsError as exc: + get_logger().error('debian directory already exists: %s', exc) + raise _CLIError() + except FileNotFoundError as exc: + get_logger().error( + 'Parent directories do not exist for path: %s', exc) + raise _CLIError() + parser = subparsers.add_parser( + 'debian', help=_add_genpkg_debian.__doc__, description=_add_genpkg_debian.__doc__) + parser.add_argument( + '-f', '--flavor', required=True, help='The Debian packaging flavor to use.') + parser.add_argument( + '-o', '--output', type=Path, default='%s/debian' % BUILDSPACE_TREE, + help=('The path to the debian directory to be created. ' + 'It must not already exist, but the parent directories must exist. ' + 'Default: %s/debian') % BUILDSPACE_TREE) + parser.set_defaults(callback=_callback) + +def _add_genpkg_linux_simple(subparsers): + """Generate Linux Simple packaging files""" + def _callback(args): + from .packaging import linux_simple as packaging_linux_simple + try: + packaging_linux_simple.generate_packaging(args.bundle, args.output) + except FileExistsError as exc: + get_logger().error('Output directory already exists: %s', exc) + raise _CLIError() + except FileNotFoundError as exc: + get_logger().error( + 'Parent directories do not exist for path: %s', exc) + raise _CLIError() + parser = subparsers.add_parser( + 'linux_simple', help=_add_genpkg_linux_simple.__doc__, + description=_add_genpkg_linux_simple.__doc__) + parser.add_argument( + '-o', '--output', type=Path, default=BUILDSPACE_TREE_PACKAGING, + help=('The directory to store packaging files. ' + 'It must not already exist, but the parent directories must exist. ' + 'Default: %s') % BUILDSPACE_TREE_PACKAGING) + parser.set_defaults(callback=_callback) + +def _add_genpkg_macos(subparsers): + """Generate macOS packaging files""" + def _callback(args): + from .packaging import macos as packaging_macos + try: + packaging_macos.generate_packaging(args.bundle, args.output) + except FileExistsError as exc: + get_logger().error('Output directory already exists: %s', exc) + raise _CLIError() + except FileNotFoundError as exc: + get_logger().error( + 'Parent directories do not exist for path: %s', exc) + raise _CLIError() + parser = subparsers.add_parser( + 'macos', help=_add_genpkg_macos.__doc__, description=_add_genpkg_macos.__doc__) + parser.add_argument( + '-o', '--output', type=Path, default=BUILDSPACE_TREE_PACKAGING, + help=('The directory to store packaging files. ' + 'It must not already exist, but the parent directories must exist. ' + 'Default: %s') % BUILDSPACE_TREE_PACKAGING) parser.set_defaults(callback=_callback) def _add_genpkg(subparsers): """Generates a packaging script.""" parser = subparsers.add_parser( - 'genpkg', formatter_class=argparse.ArgumentDefaultsHelpFormatter, help=_add_genpkg.__doc__, + 'genpkg', help=_add_genpkg.__doc__, description=_add_genpkg.__doc__ + ' Specify no arguments to get a list of different types.') setup_bundle_group(parser) - parser.add_argument( - '-o', '--output-path', type=Path, default='buildspace/tree/ungoogled_packaging', - help=('The directory to store packaging files. ' - 'If it does not exist, just the leaf directory will be created. ' - 'If it already exists, this command will abort. ')) + # Add subcommands to genpkg for handling different packaging types in the same manner as main() + # However, the top-level argparse.ArgumentParser will be passed the callback. + subsubparsers = parser.add_subparsers(title='Available packaging types', dest='packaging') + subsubparsers.required = True # Workaround for http://bugs.python.org/issue9253#msg186387 + _add_genpkg_debian(subsubparsers) + _add_genpkg_linux_simple(subsubparsers) + _add_genpkg_macos(subsubparsers) def main(arg_list=None): """CLI entry point""" parser = argparse.ArgumentParser(description=__doc__, - formatter_class=_MainArgumentParserFormatter) + formatter_class=argparse.RawTextHelpFormatter) subparsers = parser.add_subparsers(title='Available commands', dest='command') subparsers.required = True # Workaround for http://bugs.python.org/issue9253#msg186387 @@ -276,5 +344,5 @@ def main(arg_list=None): args = parser.parse_args(args=arg_list) try: args.callback(args=args) - except _CLIError: + except (_CLIError, BuildkitAbort): parser.exit(status=1) diff --git a/buildkit/common.py b/buildkit/common.py index 4c259991..0f59a372 100644 --- a/buildkit/common.py +++ b/buildkit/common.py @@ -18,9 +18,26 @@ CONFIG_BUNDLES_DIR = "config_bundles" PACKAGING_DIR = "packaging" PATCHES_DIR = "patches" +BUILDSPACE_DOWNLOADS = 'buildspace/downloads' +BUILDSPACE_TREE = 'buildspace/tree' +BUILDSPACE_TREE_PACKAGING = 'buildspace/tree/ungoogled_packaging' +BUILDSPACE_USER_BUNDLE = 'buildspace/user_bundle' + _ENV_FORMAT = "BUILDKIT_{}" -# Module-wide methods +# Public classes + +class BuildkitError(Exception): + """Represents a generic custom error from buildkit""" + +class BuildkitAbort(BuildkitError): + """ + Exception thrown when all details have been logged and buildkit aborts. + + It should only be caught by the user of buildkit's library interface. + """ + +# Public methods def get_logger(name=__package__, initial_level=logging.DEBUG): '''Gets the named logger''' diff --git a/buildkit/config.py b/buildkit/config.py index 20472a99..972e0727 100644 --- a/buildkit/config.py +++ b/buildkit/config.py @@ -15,7 +15,9 @@ import itertools import re import shutil -from .common import ENCODING, CONFIG_BUNDLES_DIR, get_logger, get_resources_dir +from pathlib import Path + +from .common import ENCODING, CONFIG_BUNDLES_DIR, BuildkitAbort, get_logger, get_resources_dir from .third_party import schema # Constants @@ -32,11 +34,13 @@ VERSION_INI = "version.ini" # Helpers for third_party.schema -def _DictCast(data): #pylint: disable=invalid-name +def schema_dictcast(data): + """Cast data to dictionary for third_party.schema and configparser data structures""" return schema.And(schema.Use(dict), data) -def _IniSchema(data): #pylint: disable=invalid-name - return _DictCast({configparser.DEFAULTSECT: object, **data}) +def schema_inisections(data): + """Cast configparser data structure to dict and remove DEFAULT section""" + return schema_dictcast({configparser.DEFAULTSECT: object, **data}) # Classes @@ -48,7 +52,8 @@ class _ConfigABC(abc.ABC): Initializes the config class. path is a pathlib.Path to a config file or directory. - name is a type identifier and the actual file or directory name. + name is the actual file or directory name. This is also used for type identification. + Defaults to the last element of path. Raises FileNotFoundError if path does not exist. """ @@ -163,7 +168,7 @@ class IniConfigFile(_CacheConfigMixin, _ConfigABC): def _parse_data(self): """ Returns a parsed INI file. - Raises third_party.schema.SchemaError if validation fails + Raises BuildkitAbort if validation fails """ parsed_ini = configparser.ConfigParser() for ini_path in self._path_order: @@ -171,10 +176,10 @@ class IniConfigFile(_CacheConfigMixin, _ConfigABC): parsed_ini.read_file(ini_file, source=str(ini_path)) try: self._schema.validate(parsed_ini) - except schema.SchemaError as exc: - get_logger().error( + except schema.SchemaError: + get_logger().exception( 'Merged INI files failed schema validation: %s', tuple(self._path_order)) - raise exc + raise BuildkitAbort() return parsed_ini def write(self, path): @@ -225,6 +230,12 @@ class MappingConfigFile(_CacheConfigMixin, _ConfigABC): """Returns an iterator over the keys""" return iter(self._config_data) + def items(self): + """ + Returns an iterator of (key, value) tuples, like dict.items() + """ + return self._config_data.items() + def _parse_data(self): """Return a dictionary of the mapping of keys and values""" new_dict = dict() @@ -299,6 +310,31 @@ class ConfigBundle(_CacheConfigMixin, _ConfigABC): """ return item in self._config_data + def __getattr__(self, name): #pylint: disable=too-many-return-statements + """ + Friendly interface to access config file objects via attributes. + + Raises BuildkitAbort if a config file is missing + """ + try: + if name == 'pruning': + return self._config_data[PRUNING_LIST] + elif name == 'domain_regex': + return self._config_data[DOMAIN_REGEX_LIST] + elif name == 'domain_substitution': + return self._config_data[DOMAIN_SUBSTITUTION_LIST] + elif name == 'extra_deps': + return self._config_data[EXTRA_DEPS_INI] + elif name == 'gn_flags': + return self._config_data[GN_FLAGS_MAP] + elif name == 'patches': + return self._config_data[PATCH_ORDER_LIST] + elif name == 'version': + return self._config_data[VERSION_INI] + except KeyError as exc: + get_logger().error('Bundle is missing requested file: %s', exc) + raise BuildkitAbort() + def _parse_data(self): """ Returns a dictionary of config file names to their respective objects. @@ -334,46 +370,11 @@ class ConfigBundle(_CacheConfigMixin, _ConfigABC): for config_file in self._config_data.values(): config_file.write(path / config_file.name) - @property - def pruning(self): - """Property to access pruning.list config file""" - return self._config_data[PRUNING_LIST] - - @property - def domain_regex(self): - """Property to access domain_regex.list config file""" - return self._config_data[DOMAIN_REGEX_LIST] - - @property - def domain_substitution(self): - """Property to access domain_substitution.list config file""" - return self._config_data[DOMAIN_SUBSTITUTION_LIST] - - @property - def extra_deps(self): - """Property to access extra_deps.ini config file""" - return self._config_data[EXTRA_DEPS_INI] - - @property - def gn_flags(self): - """Property to access gn_flags.map config file""" - return self._config_data[GN_FLAGS_MAP] - - @property - def patches(self): - """Property to access patch_order.list and patches""" - return self._config_data[PATCH_ORDER_LIST] - - @property - def version(self): - """Property to access version.ini config file""" - return self._config_data[VERSION_INI] - class BaseBundleMetaIni(IniConfigFile): """Represents basebundlemeta.ini files""" - _schema = schema.Schema(_IniSchema({ - 'basebundle': _DictCast({ + _schema = schema.Schema(schema_inisections({ + 'basebundle': schema_dictcast({ 'display_name': schema.And(str, len), schema.Optional('depends'): schema.And(str, len), }) @@ -430,7 +431,7 @@ class DomainRegexList(ListConfigFile): Generates a regex pair tuple with inverted pattern and replacement for the given line. - Raises undetermined exceptions if this fragile code breaks or some assumption + Raises BuildkitAbort if this fragile code breaks or some assumption checking fails. """ # Because domain substitution regex expressions are really simple, some @@ -483,9 +484,9 @@ class DomainRegexList(ListConfigFile): self._regex_escaped_period_repl, replacement) return self._regex_pair_tuple(re.compile(pattern), replacement) - except Exception as exc: + except BaseException: get_logger().error('Error inverting regex for line: %s', line) - raise exc + raise BuildkitAbort() def _check_invertible(self): """ @@ -539,8 +540,8 @@ class ExtraDepsIni(IniConfigFile): _optional_keys = ('strip_leading_dirs') _passthrough_properties = (*_required_keys, *_optional_keys) - _schema = schema.Schema(_IniSchema({ - schema.And(str, len): _DictCast({ + _schema = schema.Schema(schema_inisections({ + schema.And(str, len): schema_dictcast({ **{x: schema.And(str, len) for x in _required_keys}, **{schema.Optional(x): schema.And(str, len) for x in _optional_keys}, schema.Or(*_hashes): schema.And(str, len), @@ -609,20 +610,37 @@ class PatchesConfig(ListConfigFile): for relative_path in self: yield self._get_patches_dir() / relative_path + def export_patches(self, path, series=Path('series')): + """ + Writes patches and a series file to the directory specified by path. + This is useful for writing a quilt-compatible patches directory and series file. + + path is a pathlib.Path to the patches directory to create. It must not already exist. + series is a pathlib.Path to the series file, relative to path. + + Raises FileExistsError if path already exists. + Raises FileNotFoundError if the parent directories for path do not exist. + """ + path.mkdir() # Raises FileExistsError, FileNotFoundError + for relative_path in self: + destination = path / relative_path + destination.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(str(self._get_patches_dir() / relative_path), str(destination)) + super().write(path / series) + def write(self, path): """Writes patch_order and patches/ directory to the same directory""" super().write(path) for relative_path in self: destination = path.parent / PATCHES_DIR / relative_path - if not destination.parent.exists(): - destination.parent.mkdir(parents=True) + destination.parent.mkdir(parents=True, exist_ok=True) shutil.copyfile(str(self._get_patches_dir() / relative_path), str(destination)) class VersionIni(IniConfigFile): """Representation of a version.ini file""" - _schema = schema.Schema(_IniSchema({ - 'version': _DictCast({ + _schema = schema.Schema(schema_inisections({ + 'version': schema_dictcast({ 'chromium_version': schema.And(str, len), 'release_revision': schema.And(str, len), schema.Optional('release_extra'): schema.And(str, len), diff --git a/buildkit/domain_substitution.py b/buildkit/domain_substitution.py index da6f441e..9f321c50 100644 --- a/buildkit/domain_substitution.py +++ b/buildkit/domain_substitution.py @@ -8,7 +8,7 @@ Module for substituting domain names in buildspace tree with blockable strings. """ -from .common import ENCODING, get_logger +from .common import ENCODING, BuildkitAbort, get_logger from .third_party import unidiff def substitute_domains_for_files(regex_iter, file_iter, log_warnings=True): @@ -26,9 +26,9 @@ def substitute_domains_for_files(regex_iter, file_iter, log_warnings=True): try: encoding = ENCODING # TODO: Try other encodings on failure content = file_bytes.decode(encoding) - except Exception as exc: - get_logger().error('Exception thrown while substituting: %s', path) - raise exc + except BaseException: + get_logger().exception('Exception thrown while substituting: %s', path) + raise BuildkitAbort() file_subs = 0 for regex_pair in regex_iter: content, sub_count = regex_pair.pattern.subn( diff --git a/buildkit/packaging/__init__.py b/buildkit/packaging/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/utilikit/_build_files_generators/_common.py b/buildkit/packaging/_common.py similarity index 79% rename from utilikit/_build_files_generators/_common.py rename to buildkit/packaging/_common.py index efa5ae2f..25d19629 100644 --- a/utilikit/_build_files_generators/_common.py +++ b/buildkit/packaging/_common.py @@ -1,6 +1,6 @@ # -*- coding: UTF-8 -*- -# Copyright (c) 2017 The ungoogled-chromium Authors. All rights reserved. +# Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -9,6 +9,16 @@ import string import re +from pathlib import Path + +# Constants + +SHARED_PACKAGING = 'shared' +LIST_BUILD_OUTPUTS = 'list_build_outputs.py' +DEFAULT_BUILD_OUTPUT = Path('out/Default') + +# Classes + class BuildFileStringTemplate(string.Template): """ Custom string substitution class @@ -26,7 +36,9 @@ class BuildFileStringTemplate(string.Template): ) """.format(delim=re.escape("$ungoog"), id=string.Template.idpattern) -def generate_from_templates(root_dir, build_file_subs): +# Methods + +def process_templates(root_dir, build_file_subs): """Substitute '$ungoog' strings in '.in' template files and remove the suffix""" for old_path in root_dir.glob("*.in"): new_path = root_dir / old_path.stem diff --git a/utilikit/_build_files_generators/debian.py b/buildkit/packaging/debian.py similarity index 65% rename from utilikit/_build_files_generators/debian.py rename to buildkit/packaging/debian.py index 530ad50f..d2d39421 100644 --- a/utilikit/_build_files_generators/debian.py +++ b/buildkit/packaging/debian.py @@ -1,6 +1,6 @@ # -*- coding: UTF-8 -*- -# Copyright (c) 2017 The ungoogled-chromium Authors. All rights reserved. +# Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -11,14 +11,34 @@ import datetime import os import shutil -from .. import _common -from .. import export_resources as _export_resources -from . import _common as _build_files_common +from ..third_party import schema + +from ..common import PACKAGING_DIR, PATCHES_DIR, get_resources_dir +from ..config import IniConfigFile, schema_inisections, schema_dictcast +from ._common import DEFAULT_BUILD_OUTPUT, process_templates # Private definitions +_DEPENDENCIES_INI = 'dependencies.ini' + +class _DependenciesIni(IniConfigFile): + _schema = schema.Schema(schema_inisections({ + schema.And(str, len): schema_dictcast({ + 'parent': schema.And(str, len), + }), + })) + + def get_parent(self, name): + """ + Returns the parent name for the given flavor, or None if there is no parent. + """ + try: + return self._config_data[name]['parent'] + except KeyError: + return None + def _get_packaging_resources(): - return _common.get_resources_dir() / _common.PACKAGING_DIR / "debian" + return get_resources_dir() / PACKAGING_DIR / 'debian' def _traverse_directory(directory): """Traversal of an entire directory tree in random order""" @@ -35,7 +55,7 @@ def _traverse_directory(directory): class _Flavor: """ - Represents a certain flavor + Represents a Debian packaging flavor """ _loaded_flavors = dict() @@ -63,10 +83,8 @@ class _Flavor: @classmethod def _get_parent_name(cls, child): if not cls._flavor_tree: - cls._flavor_tree = _common.read_ini(_get_packaging_resources() / "dependencies.ini") - if child in cls._flavor_tree and "parent" in cls._flavor_tree[child]: - return cls._flavor_tree[child]["parent"] - return None + cls._flavor_tree = _DependenciesIni(_get_packaging_resources() / _DEPENDENCIES_INI) + return cls._flavor_tree.get_parent(child) @property def parent(self): @@ -132,26 +150,30 @@ def _get_parsed_gn_flags(gn_flags): # Public definitions -def generate_build_files(resources, output_dir, build_output, flavor, #pylint: disable=too-many-arguments - distribution_version, apply_domain_substitution): +def generate_packaging(config_bundle, flavor, debian_dir, + build_output=DEFAULT_BUILD_OUTPUT, distro_version='stable'): """ - Generates the `debian` directory in `output_dir` using resources from - `resources` + Generates a debian directory in the buildspace tree + + config_bundle is a config.ConfigBundle to use for configuration + flavor is a Debian packaging flavor name to use + debian_dir is a pathlib.Path to the Debian directory to be created. + build_output is the pathlib.Path for building intermediates and outputs to be stored + distro_version is the distribution version name to use in debian/changelog + + Raises FileExistsError if debian_dir already exists. + Raises FileNotFoundError if the parent directories for debian_dir do not exist. """ + # Use config_bundle.version.version_string for Debian version string build_file_subs = dict( - changelog_version="{}-{}".format(*resources.read_version()), + changelog_version=config_bundle.version.version_string, changelog_datetime=_get_dpkg_changelog_datetime(), build_output=build_output, - distribution_version=distribution_version, - gn_flags=_get_parsed_gn_flags(resources.read_gn_flags()) + distribution_version=distro_version, + gn_flags=_get_parsed_gn_flags(config_bundle.gn_flags) ) - debian_dir = output_dir / "debian" - debian_dir.mkdir(exist_ok=True) + debian_dir.mkdir() # Raises FileNotFoundError, FileExistsError _Flavor(flavor).assemble_files(debian_dir) - _export_resources.export_patches_dir(resources, debian_dir / _common.PATCHES_DIR, - apply_domain_substitution) - _common.write_list(debian_dir / _common.PATCHES_DIR / "series", - resources.read_patch_order()) - - _build_files_common.generate_from_templates(debian_dir, build_file_subs) + process_templates(debian_dir, build_file_subs) + config_bundle.patches.export_patches(debian_dir / PATCHES_DIR) diff --git a/buildkit/packaging/linux_simple.py b/buildkit/packaging/linux_simple.py new file mode 100644 index 00000000..33e859d6 --- /dev/null +++ b/buildkit/packaging/linux_simple.py @@ -0,0 +1,52 @@ +# -*- coding: UTF-8 -*- + +# Copyright (c) 2017 The ungoogled-chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Linux Simple-specific build files generation code""" + +import shutil + +from ..common import PACKAGING_DIR, PATCHES_DIR, get_resources_dir +from ._common import DEFAULT_BUILD_OUTPUT, process_templates + +# Private definitions + +def _get_packaging_resources(): + return get_resources_dir() / PACKAGING_DIR / 'linux_simple' + +def _copy_from_resources(name, output_dir): + shutil.copyfile( + str(_get_packaging_resources() / name), + str(output_dir / name)) + +# Public definitions + +def generate_packaging(config_bundle, output_dir, build_output=DEFAULT_BUILD_OUTPUT): + """ + Generates the linux_simple packaging into output_dir + + config_bundle is the config.ConfigBundle to use for configuration + output_dir is the pathlib.Path directory that will be created to contain packaging files + build_output is a pathlib.Path for building intermediates and outputs to be stored + + Raises FileExistsError if output_dir already exists. + Raises FileNotFoundError if the parent directories for output_dir do not exist. + """ + build_file_subs = dict( + build_output=build_output, + gn_args_string=' '.join( + '{}={}'.format(flag, value) for flag, value in config_bundle.gn_flags.items()), + version_string=config_bundle.version.version_string + ) + + output_dir.mkdir() # Raises FileNotFoundError, FileExistsError + + # Build and packaging scripts + _copy_from_resources('build.sh.in', output_dir) + _copy_from_resources('package.sh.in', output_dir) + process_templates(output_dir, build_file_subs) + + # Patches + config_bundle.patches.export_patches(output_dir / PATCHES_DIR) diff --git a/buildkit/packaging/macos.py b/buildkit/packaging/macos.py new file mode 100644 index 00000000..f8772c9d --- /dev/null +++ b/buildkit/packaging/macos.py @@ -0,0 +1,51 @@ +# -*- coding: UTF-8 -*- + +# Copyright (c) 2017 The ungoogled-chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""macOS-specific build files generation code""" + +import shutil + +from ..common import PACKAGING_DIR, PATCHES_DIR, get_resources_dir +from ._common import DEFAULT_BUILD_OUTPUT, process_templates + +# Private definitions + +def _get_packaging_resources(): + return get_resources_dir() / PACKAGING_DIR / 'macos' + +def _copy_from_resources(name, output_dir): + shutil.copyfile( + str(_get_packaging_resources() / name), + str(output_dir / name)) + +# Public definitions + +def generate_packaging(config_bundle, output_dir, build_output=DEFAULT_BUILD_OUTPUT): + """ + Generates the macOS packaging into output_dir + + config_bundle is the config.ConfigBundle to use for configuration + output_dir is the pathlib.Path directory that will be created to contain packaging files + build_output is a pathlib.Path for building intermediates and outputs to be stored + + Raises FileExistsError if output_dir already exists. + Raises FileNotFoundError if the parent directories for output_dir do not exist. + """ + build_file_subs = dict( + build_output=build_output, + gn_args_string=' '.join( + '{}={}'.format(flag, value) for flag, value in config_bundle.gn_flags.items()), + version_string=config_bundle.version.version_string + ) + + output_dir.mkdir() # Raises FileNotFoundError, FileExistsError + + # Build script + _copy_from_resources('build.sh.in', output_dir) + process_templates(output_dir, build_file_subs) + + # Patches + config_bundle.patches.export_patches(output_dir / PATCHES_DIR) diff --git a/buildkit/source_retrieval.py b/buildkit/source_retrieval.py index 94ee7dbe..89039927 100644 --- a/buildkit/source_retrieval.py +++ b/buildkit/source_retrieval.py @@ -14,7 +14,7 @@ import urllib.request import hashlib from pathlib import Path, PurePosixPath -from .common import ENCODING, get_logger +from .common import ENCODING, BuildkitAbort, get_logger # Constants @@ -48,7 +48,7 @@ def _extract_tar_file(tar_path, buildspace_tree, unpack_dir, ignore_files, relat relative_to is a pathlib.Path for directories that should be stripped relative to the root of the archive. - May raise undetermined exceptions during unpacking. + Raises BuildkitAbort if unexpected issues arise during unpacking. """ class NoAppendList(list): @@ -66,10 +66,10 @@ def _extract_tar_file(tar_path, buildspace_tree, unpack_dir, ignore_files, relat # Symlinks probably not supported get_logger().info('System does not support symlinks. Ignoring them.') symlink_supported = False - except Exception as exc: + except BaseException: # Unexpected exception - get_logger().error('Unexpected exception during symlink support check.') - raise exc + get_logger().exception('Unexpected exception during symlink support check.') + raise BuildkitAbort() resolved_tree = buildspace_tree.resolve() @@ -100,9 +100,9 @@ def _extract_tar_file(tar_path, buildspace_tree, unpack_dir, ignore_files, relat if destination.is_symlink(): destination.unlink() tar_file_obj._extract_member(tarinfo, str(destination)) # pylint: disable=protected-access - except Exception as exc: - get_logger().error('Exception thrown for tar member: %s', tarinfo.name) - raise exc + except BaseException: + get_logger().exception('Exception thrown for tar member: %s', tarinfo.name) + raise BuildkitAbort() class _UrlRetrieveReportHook: #pylint: disable=too-few-public-methods """Hook for urllib.request.urlretrieve to log progress information to console""" @@ -170,7 +170,7 @@ def _setup_chromium_source(config_bundle, buildspace_downloads, buildspace_tree, if source_hashes.exists() and not source_hashes.is_file(): raise NotAFileError(source_hashes) - get_logger().info('Download Chromium source code...') + get_logger().info('Downloading Chromium source code...') _download_if_needed( source_archive, _SOURCE_ARCHIVE_URL.format(config_bundle.version.chromium_version), diff --git a/resources/packaging/debian/minimal.patch b/resources/packaging/debian/minimal.patch deleted file mode 100644 index 7a24efdf..00000000 --- a/resources/packaging/debian/minimal.patch +++ /dev/null @@ -1,104 +0,0 @@ ---- a/clean -+++ b/clean -@@ -1,23 +1 @@ - debian/files -- --Makefile --third_party/flot/*.js --chrome/test/data/webui/i18n_process_css_test.html -- --third_party/ffmpeg/BUILD.gn --third_party/flac/BUILD.gn --base/third_party/libevent/BUILD.gn --build/secondary/third_party/libjpeg_turbo/BUILD.gn --third_party/libdrm/BUILD.gn --third_party/libpng/BUILD.gn --third_party/libvpx/BUILD.gn --third_party/libwebp/BUILD.gn --third_party/libxml/BUILD.gn --third_party/libxslt/BUILD.gn --third_party/re2/BUILD.gn --third_party/snappy/BUILD.gn --third_party/yasm/yasm_assemble.gni --third_party/zlib/BUILD.gn --third_party/icu/BUILD.gn --third_party/opus/BUILD.gn --third_party/freetype/BUILD.gn ---- a/compat -+++ b/compat -@@ -1 +1 @@ --10 -+9 ---- a/control -+++ b/control -@@ -12,7 +12,7 @@ Build-Depends: - # clang (>= 3.5), - clang-3.9, - llvm-3.9-dev, -- debhelper (>= 10), -+ debhelper (>= 9), - python, - python3, - pkg-config, -@@ -51,7 +51,6 @@ Build-Depends: - libffi-dev, - libkrb5-dev, - libexif-dev, -- libflac-dev, - libudev-dev, - libopus-dev, - libwebp-dev, -@@ -67,13 +66,12 @@ Build-Depends: - libsnappy-dev, - libgconf2-dev, - libavutil-dev, -- libavcodec-dev (>= 7), - libavformat-dev, - libglib2.0-dev, - libasound2-dev, - libsqlite3-dev, - libjsoncpp-dev, -- libspeechd-dev (>= 0.8.3), -+ libspeechd-dev, - libminizip-dev, - libhunspell-dev, - libharfbuzz-dev, ---- a/rules.in -+++ b/rules.in -@@ -42,12 +42,8 @@ - njobs=-j$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) - endif - --# paths to files needed by flot --flotpaths=/usr/share/javascript/jquery/*min.js \ -- /usr/share/javascript/jquery-flot/*min.js \ -- - %: -- dh $@ -+ dh $@ --parallel - - $ungoog{build_output}/gn: - mkdir -p $ungoog{build_output} || true -@@ -56,13 +52,6 @@ $ungoog{build_output}/gn: - override_dh_auto_configure: - # output compiler information - $(CXX) --version -- # use system flot -- for file in $(flotpaths); do ln -sf $$file third_party/flot; done -- # strip out system third_party libraries -- cp third_party/freetype/src/src/psnames/pstables.h . -- ./debian/scripts/unbundle -- mkdir -p third_party/freetype/src/src/psnames -- mv pstables.h third_party/freetype/src/src/psnames - - override_dh_auto_build-arch: $ungoog{build_output}/gn - ./$ungoog{build_output}/gn gen $ungoog{build_output} --args="$(defines)" --fail-on-unused-args ---- a/ungoogled-chromium-common.install.in -+++ b/ungoogled-chromium-common.install.in -@@ -1 +1,6 @@ - $ungoog{build_output}/*.bin usr/lib/chromium -+$ungoog{build_output}/icudtl.dat usr/lib/chromium -+$ungoog{build_output}/libEGL.so usr/lib/chromium -+$ungoog{build_output}/libGLESv2.so usr/lib/chromium -+$ungoog{build_output}/xdg-mime usr/lib/chromium -+$ungoog{build_output}/xdg-settings usr/lib/chromium diff --git a/resources/packaging/debian/minimal/clean b/resources/packaging/debian/minimal/clean new file mode 100644 index 00000000..bbe760d4 --- /dev/null +++ b/resources/packaging/debian/minimal/clean @@ -0,0 +1 @@ +debian/files diff --git a/resources/packaging/debian/minimal/compat b/resources/packaging/debian/minimal/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/resources/packaging/debian/minimal/compat @@ -0,0 +1 @@ +9 diff --git a/resources/packaging/debian/minimal/control b/resources/packaging/debian/minimal/control new file mode 100644 index 00000000..20aad651 --- /dev/null +++ b/resources/packaging/debian/minimal/control @@ -0,0 +1,216 @@ +Source: ungoogled-chromium-browser +Section: web +Priority: optional +Maintainer: ungoogled-chromium Maintainers +Uploaders: + Maintainer , +Vcs-Git: https://github.com/Eloston/ungoogled-chromium.git +Vcs-Browser: https://github.com/Eloston/ungoogled-chromium +Homepage: https://github.com/Eloston/ungoogled-chromium +Build-Depends: +# TODO: Should we depend on a specific version of clang or the system default? +# clang (>= 3.5), + clang-3.9, + llvm-3.9-dev, + debhelper (>= 9), + python, + python3, + pkg-config, + ninja-build, + python-jinja2, + ca-certificates, + time, + wget, + flex, + yasm, + xvfb, + wdiff, + gperf, + bison, + valgrind, + xz-utils, + x11-apps, + xfonts-base, + libglew-dev, + libgl1-mesa-dev, + libglu1-mesa-dev, + libegl1-mesa-dev, + libgles2-mesa-dev, + mesa-common-dev, + libxt-dev, + libre2-dev, + libgbm-dev, + libpng-dev, + libxss-dev, + libelf-dev, + libvpx-dev, + libpci-dev, + libcap-dev, + libdrm-dev, + libicu-dev, + libffi-dev, + libkrb5-dev, + libexif-dev, + libudev-dev, + libopus-dev, + libwebp-dev, + libxtst-dev, + libsrtp-dev, + libjpeg-dev, + libxml2-dev, + libgtk-3-dev, + libxslt1-dev, + liblcms2-dev, + libpulse-dev, + libpam0g-dev, + libsnappy-dev, + libgconf2-dev, + libavutil-dev, + libavformat-dev, + libglib2.0-dev, + libasound2-dev, + libsqlite3-dev, + libjsoncpp-dev, + libspeechd-dev, + libminizip-dev, + libhunspell-dev, + libharfbuzz-dev, + libusb-1.0-0-dev, + libmodpbase64-dev, + libnss3-dev (>= 3.12.3), + libnspr4-dev (>= 2:4.9), + libcups2-dev (>= 1.5.0), + libevent-dev (>= 1.4.13), + libjs-jquery, + libjs-excanvas, + libjs-jquery-flot, + libgcrypt20-dev, + libva-dev, +Standards-Version: 4.1.2 + +Package: ungoogled-chromium +Architecture: i386 amd64 arm64 armhf +Built-Using: ${Built-Using} +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + ungoogled-chromium-common (= ${binary:Version}), +Recommends: + fonts-liberation, + libva1, +Suggests: + ungoogled-chromium-l10n, + ungoogled-chromium-shell, + ungoogled-chromium-driver, + ungoogled-chromium-widevine, +Provides: + www-browser, + gnome-www-browser, +Conflicts: + libnettle4, + libsecret-1-0 (<< 0.18), + libgl1-mesa-swx11, +Replaces: + chromium, + chromium-browser, +Breaks: + chromium, + chromium-browser, +Description: web browser + Web browser that aims to build a safer, faster, and more stable internet + browsing experience. + . + This package contains the web browser component. + +Package: ungoogled-chromium-l10n +Architecture: all +Section: localization +Depends: + ${misc:Depends}, + ungoogled-chromium (>= ${source:Version}), + ungoogled-chromium (<< ${source:Version}.1~), +Replaces: + chromium-l10n, +Breaks: + chromium-l10n, +Description: web browser - language packs + Web browser that aims to build a safer, faster, and more stable internet + browsing experience. + . + This package contains language packages for: + am, ar, bg, bn, ca, cs, da, de, el, en-GB, es-419, es, et, fi, fil, fr, gu, he, + hi, hr, hu, id, it, ja, kn, ko, lt, lv, ml, mr, nb, nl, pl, pt-BR, pt-PT, + ro, ru, sk, sl, sr, sv, sw, ta, te, th, tr, uk, vi, zh-CN, zh-TW + +Package: ungoogled-chromium-shell +Architecture: i386 amd64 arm64 armhf +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + ungoogled-chromium-common (= ${binary:Version}), +Replaces: + chromium-shell, +Breaks: + chromium-shell, +Description: web browser - minimal shell + Web browser that aims to build a safer, faster, and more stable internet + browsing experience. + . + This package provides a minimal version of the chromium user interface + (the content shell). + +Package: ungoogled-chromium-widevine +Section: contrib/web +Architecture: i386 amd64 arm64 armhf +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + ungoogled-chromium (= ${binary:Version}), +Replaces: + chromium-widevine, +Breaks: + chromium-widevine, +Description: web browser - widevine content decryption support + Web browser that aims to build a safer, faster, and more stable internet + browsing experience. + . + This package provides support for the widevine content decryption module. + +Package: ungoogled-chromium-driver +Architecture: i386 amd64 arm64 armhf +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + ungoogled-chromium (= ${binary:Version}), +Replaces: + chromedriver, + chromium-driver, +Breaks: + chromium-driver, +Description: web browser - WebDriver support + Web browser that aims to build a safer, faster, and more stable internet + browsing experience. + . + This package provides a bridge between the browser component and the selenium + automatic webdriver. + . + See http://code.google.com/p/selenium/wiki/ChromeDriver for details. + +Package: ungoogled-chromium-common +Architecture: i386 amd64 arm64 armhf +Depends: + ${misc:Depends}, + x11-utils, + xdg-utils, +Breaks: + ungoogled-chromium (<< 60.0.3112.72-1), + chromium-common, +Replaces: + ungoogled-chromium (<< 60.0.3112.72-1), + chromium-common, +Description: web browser - common resources used by ungoogled-chromium packages + Web browser that aims to build a safer, faster, and more stable internet + browsing experience. + . + This package contains resources that are in common to different + ungoogled-chromium packages. diff --git a/resources/packaging/debian/minimal/rules.in b/resources/packaging/debian/minimal/rules.in new file mode 100755 index 00000000..afceb298 --- /dev/null +++ b/resources/packaging/debian/minimal/rules.in @@ -0,0 +1,115 @@ +#!/usr/bin/make -f + +# enable verbose build messages +export DH_VERBOSE=1 + +# enable all build hardening flags +export DEB_BUILD_MAINT_OPTIONS=hardening=+all + +export CLANG_BASE_PATH=/usr/lib/llvm-3.9 + +# more verbose linker output +defines+=target_extra_ldflags=\"-Wl,--stats\" + +# avoid error in v8's garbage collector (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=68853) +defines+=target_extra_cxxflags=\"-fno-delete-null-pointer-checks -Wno-deprecated-declarations\" + +# set the appropriate cpu architecture +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +ifeq (i386,$(DEB_HOST_ARCH)) +defines+=host_cpu=\"x86\" +endif +ifeq (amd64,$(DEB_HOST_ARCH)) +defines+=host_cpu=\"x64\" +endif +ifeq (arm64,$(DEB_HOST_ARCH)) +defines+=host_cpu=\"arm64\" +endif +ifeq (armhf,$(DEB_HOST_ARCH)) +defines+=host_cpu=\"arm\" \ + arm_use_neon=false +endif + +# auto-inserted gn flags +$ungoog{gn_flags} + +# some notes about embedded libraries +# can't use system nss since net/third_party/nss is heavily patched +# can't use system ots (open text *summarizer*) since that's not google's ots (open text *sanitizer*) + +# handle parallel build options +ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +njobs=-j$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +endif + +%: + dh $@ --parallel + +$ungoog{build_output}/gn: + mkdir -p $ungoog{build_output} || true + ./tools/gn/bootstrap/bootstrap.py -o $ungoog{build_output}/gn -s $(njobs) + +override_dh_auto_configure: + # output compiler information + $(CXX) --version + +override_dh_auto_build-arch: $ungoog{build_output}/gn + ./$ungoog{build_output}/gn gen $ungoog{build_output} --args="$(defines)" --fail-on-unused-args + ninja $(njobs) -C $ungoog{build_output} chrome chrome_sandbox content_shell chromedriver + cp $ungoog{build_output}/chrome $ungoog{build_output}/chromium + cp $ungoog{build_output}/content_shell $ungoog{build_output}/chromium-shell + cp $ungoog{build_output}/chrome_sandbox $ungoog{build_output}/chrome-sandbox + cp $ungoog{build_output}/locales/en-US.pak $ungoog{build_output}/resources + chmod 4755 $ungoog{build_output}/chrome-sandbox # suid sandbox + sed -e s/@@PACKAGE@@/chromium/g -e s/@@MENUNAME@@/Chromium/g \ + < chrome/app/resources/manpage.1.in > $ungoog{build_output}/chromium.1 + +override_dh_auto_build-indep: $ungoog{build_output}/gn + ./$ungoog{build_output}/gn gen $ungoog{build_output} --args="$(defines)" --fail-on-unused-args + ninja $(njobs) -C $ungoog{build_output} packed_resources + rm -f $ungoog{build_output}/locales/en-US.pak + +override_dh_auto_install-arch: + dh_auto_install + # create /etc/chromium.d README file + echo "Any files placed in this directory will be sourced prior to executing chromium." \ + > debian/ungoogled-chromium/etc/chromium.d/README + # update launcher script with build information + sed 's|@BUILD_DIST@|$(shell printf "%s %s/%s" $(shell lsb_release -si) $(shell lsb_release -sc) $(shell lsb_release -sr))|' \ + < debian/scripts/chromium > debian/ungoogled-chromium/usr/bin/chromium + # move icons into /usr/share + ./debian/scripts/icons + +override_dh_fixperms: + dh_fixperms --exclude chrome-sandbox + +override_dh_strip: + dh_strip --no-automatic-dbgsym # Do not build any debug packages + +override_dh_gencontrol: + dh_gencontrol -- -VBuilt-Using="$(shell dpkg-query -f '$${source:Package} (= $${source:Version}), ' -W libjs-jquery libjs-jquery-flot)" + +override_dh_auto_clean: + rm -rf out + find . -name \*.pyc -execdir rm -f {} \; + dh_auto_clean + +###################### upstream source downloading ############################ + +url=https://gsdview.appspot.com/chromium-browser-official +version=$(shell dpkg-parsechangelog -S Version | sed s/-.*//) +extract=chromium-$(version) +tarball=$(extract).tar.xz +debian=chromium-browser_$(version) +output=$(debian).orig.tar.xz +removed=$(debian).files-removed + +get-orig-source: + wget -nv --show-progress -c $(url)/$(tarball) -O ../$(tarball) + /usr/bin/time --portability ./debian/scripts/mk-origtargz ../$(tarball) > ../$(removed) + test ! -e $(extract) || rm -rf $(extract) + /usr/bin/time --portability tar xaf ../$(tarball) + while read line; do rm -rf $$line; done < ../$(removed) + test ! -e ../$(output) || rm -f ../$(output) + /usr/bin/time --portability tar caf ../$(output) $(extract) + /usr/bin/time --portability rm -rf $(extract) diff --git a/resources/packaging/debian/minimal/ungoogled-chromium-common.install.in b/resources/packaging/debian/minimal/ungoogled-chromium-common.install.in new file mode 100644 index 00000000..892c78d5 --- /dev/null +++ b/resources/packaging/debian/minimal/ungoogled-chromium-common.install.in @@ -0,0 +1,6 @@ +$ungoog{build_output}/*.bin usr/lib/chromium +$ungoog{build_output}/icudtl.dat usr/lib/chromium +$ungoog{build_output}/libEGL.so usr/lib/chromium +$ungoog{build_output}/libGLESv2.so usr/lib/chromium +$ungoog{build_output}/xdg-mime usr/lib/chromium +$ungoog{build_output}/xdg-settings usr/lib/chromium diff --git a/resources/packaging/linux_simple/build.sh.in b/resources/packaging/linux_simple/build.sh.in index b7d435a4..7dd2f2f6 100755 --- a/resources/packaging/linux_simple/build.sh.in +++ b/resources/packaging/linux_simple/build.sh.in @@ -11,7 +11,7 @@ true ${CLANG_BASE_PATH:=/usr} # http://www.tldp.org/LDP/abs/html/parameter-subst rm -rf out || true mkdir out mkdir $ungoog{build_output} -env QUILT_PATCHES=$ungoog{build_files_dir}/patches quilt push -a -./tools/gn/bootstrap/bootstrap.py -o $ungoog{build_output}/gn -s -j 2 +env QUILT_PATCHES=$(dirname $(readlink -f $0))/patches quilt push -a +./tools/gn/bootstrap/bootstrap.py -o $ungoog{build_output}/gn -s -j 4 ./$ungoog{build_output}/gn gen $ungoog{build_output} --args='$ungoog{gn_args_string}' --fail-on-unused-args ninja -C $ungoog{build_output} chrome chrome_sandbox chromedriver diff --git a/resources/packaging/linux_simple/package.sh.in b/resources/packaging/linux_simple/package.sh.in index 39ef13e2..2af5a787 100755 --- a/resources/packaging/linux_simple/package.sh.in +++ b/resources/packaging/linux_simple/package.sh.in @@ -2,7 +2,7 @@ set -eux -FILENAME=ungoogled-chromium_$ungoog{version}_linux.tar.xz +FILENAME=ungoogled-chromium_$ungoog{version_string}_linux.tar.xz OUTPUT=$(dirname $(dirname $(readlink -f $0)))/$FILENAME # TODO: Use scripts/list_build_outputs.py to create a .tar.xz archive of build outputs using tar diff --git a/resources/packaging/macos/build.sh.in b/resources/packaging/macos/build.sh.in index c8881e32..3e9bcf0d 100755 --- a/resources/packaging/macos/build.sh.in +++ b/resources/packaging/macos/build.sh.in @@ -4,11 +4,13 @@ set -eux # Simple build script for macOS +packaging_dir=$(dirname $(greadlink -f $0)) + rm -rf out || true mkdir out mkdir $ungoog{build_output} -env QUILT_PATCHES=$ungoog{build_files_dir}/patches quilt push -a +env QUILT_PATCHES="${packaging_dir}/patches" quilt push -a ./tools/gn/bootstrap/bootstrap.py -o $ungoog{build_output}/gn -s -j 2 ./$ungoog{build_output}/gn gen $ungoog{build_output} --args='$ungoog{gn_args_string}' --fail-on-unused-args ninja -C $ungoog{build_output} chrome chromedriver -chrome/installer/mac/pkg-dmg --source /var/empty --target "$ungoog{build_files_dir}/ungoogled-chromium_$ungoog{chromium_version}-$ungoog{release_revision}_macos.dmg" --format UDBZ --verbosity 2 --volname Chromium --copy "$ungoog{build_output}/Chromium.app/:/Chromium.app/" --symlink "/Applications:/Drag to here to install" +chrome/installer/mac/pkg-dmg --source /var/empty --target "${packaging_dir}/ungoogled-chromium_$ungoog{version_string}_macos.dmg" --format UDBZ --verbosity 2 --volname Chromium --copy "$ungoog{build_output}/Chromium.app/:/Chromium.app/" --symlink "/Applications:/Drag to here to install" diff --git a/utilikit/_build_files_generators/linux_simple.py b/utilikit/_build_files_generators/linux_simple.py deleted file mode 100644 index f79e4450..00000000 --- a/utilikit/_build_files_generators/linux_simple.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: UTF-8 -*- - -# Copyright (c) 2017 The ungoogled-chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Linux Simple-specific build files generation code""" - -import os -import shutil -import pathlib - -from .. import _common -from .. import export_resources as _export_resources -from . import _common as _build_files_common - -_BUILD_FILES_DIR = "ungoogled_linux_simple" - -def _get_packaging_resources(): - return _common.get_resources_dir() / _common.PACKAGING_DIR / "linux_simple" - -def generate_build_files(resources, output_dir, build_output, apply_domain_substitution): - """ - Generates the `linux_simple` directory in `output_dir` using resources from - `resources` - """ - gn_flags = resources.read_gn_flags() - build_file_subs = dict( - build_output=build_output, - build_files_dir=_BUILD_FILES_DIR, - gn_args_string=" ".join( - [flag + "=" + value for flag, value in gn_flags.items()] - ) - ) - - linux_simple_dir = output_dir / _BUILD_FILES_DIR - os.makedirs(str(linux_simple_dir), exist_ok=True) - - # Build script - shutil.copy( - str(_get_packaging_resources() / "build.sh.in"), - str(linux_simple_dir / "build.sh.in") - ) - _build_files_common.generate_from_templates(linux_simple_dir, build_file_subs) - - # Patches - _export_resources.export_patches_dir(resources, linux_simple_dir / _common.PATCHES_DIR, - apply_domain_substitution) - _common.write_list(linux_simple_dir / _common.PATCHES_DIR / "series", - resources.read_patch_order()) diff --git a/utilikit/_build_files_generators/macos.py b/utilikit/_build_files_generators/macos.py deleted file mode 100644 index 06a6285a..00000000 --- a/utilikit/_build_files_generators/macos.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: UTF-8 -*- - -# Copyright (c) 2017 The ungoogled-chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""macOS-specific build files generation code""" - -import shutil -import pathlib - -from .. import _common -from .. import export_resources as _export_resources -from . import _common as _build_files_common - -_BUILD_FILES_DIR = "ungoogled_macos" - -def _get_packaging_resources(): - return _common.get_resources_dir() / _common.PACKAGING_DIR / "macos" - -def generate_build_files(resources, output_dir, build_output, apply_domain_substitution): - """ - Generates the `macos` directory in `output_dir` using resources from - `resources` - """ - gn_flags = resources.read_gn_flags() - build_file_subs = dict( - build_output=build_output, - build_files_dir=_BUILD_FILES_DIR, - gn_args_string=" ".join( - [flag + "=" + value for flag, value in gn_flags.items()] - ), - chromium_version=resources.read_version()[0], - release_revision=resources.read_version()[1] - ) - - macos_dir = output_dir / _BUILD_FILES_DIR - macos_dir.mkdir(exist_ok=True) - - # Build script - shutil.copy( - str(_get_packaging_resources() / "build.sh.in"), - str(macos_dir / "build.sh.in") - ) - _build_files_common.generate_from_templates(macos_dir, build_file_subs) - - # Patches - _export_resources.export_patches_dir(resources, macos_dir / _common.PATCHES_DIR, - apply_domain_substitution) - _common.write_list(macos_dir / _common.PATCHES_DIR / "series", - resources.read_patch_order())