diff options
Diffstat (limited to 'snap/plugins')
-rw-r--r-- | snap/plugins/x-autotools-subsource.py | 66 | ||||
-rw-r--r-- | snap/plugins/x-gyp-cmake.py | 100 | ||||
-rw-r--r-- | snap/plugins/x-patched-python.py | 65 | ||||
-rw-r--r-- | snap/plugins/x-qtbuilder.py | 204 |
4 files changed, 435 insertions, 0 deletions
diff --git a/snap/plugins/x-autotools-subsource.py b/snap/plugins/x-autotools-subsource.py new file mode 100644 index 0000000000..330ea0b1b2 --- /dev/null +++ b/snap/plugins/x-autotools-subsource.py @@ -0,0 +1,66 @@ +# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- +# +# Author: Marco Trevisan <marco@ubuntu.com> +# Copyright (C) 2017-2018 Canonical Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import snapcraft + +from snapcraft.internal import sources +from snapcraft.plugins import autotools + +class Dict2Object(object): + def __init__(self, d): + for k, v in d.items(): + setattr(self, k.replace('-', '_'), v) + + +class AutotoolsSubsourcePlugin(autotools.AutotoolsPlugin): + + @classmethod + def schema(cls): + schema = super().schema() + + schema['properties']['sub-sources'] = { + 'type': 'array', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'object', + 'additionalProperties': True, + }, + 'default': [], + } + + return schema + + @classmethod + def get_pull_properties(cls): + return [ + 'sub-sources', + ] + + def pull(self): + super().pull() + + for src in self.options.sub_sources: + [name] = src.keys() + [values] = src.values() + + if 'source' in values: + dest = values['dest'] if 'dest' in values else '' + sources.get(os.path.join(self.sourcedir, dest), + os.path.join(self.build_basedir, dest), + Dict2Object(values)) diff --git a/snap/plugins/x-gyp-cmake.py b/snap/plugins/x-gyp-cmake.py new file mode 100644 index 0000000000..94a5ba1a89 --- /dev/null +++ b/snap/plugins/x-gyp-cmake.py @@ -0,0 +1,100 @@ +# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- +# +# Author: Marco Trevisan <marco@ubuntu.com> +# Copyright (C) 2017-2018 Canonical Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import snapcraft + +from snapcraft.plugins import cmake + + +class GypCMakePlugin(cmake.CMakePlugin): + """A basic plugin for snapcraft that generates CMake files from gyp""" + + @classmethod + def schema(cls): + schema = super().schema() + + schema['properties']['gyp-file'] = { + 'type': 'string' + } + + schema['properties']['build-type'] = { + 'type': 'string', + 'default': 'Release', + 'enum': ['Debug', 'Release'], + } + + schema['properties']['environment'] = { + 'type': 'array', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'object', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'string', + }, + }, + 'default': [], + } + + schema['required'].append('gyp-file') + + schema['build-properties'].extend([ + 'build-type', + 'gyp-file', + ]) + + return schema + + def __init__(self, name, options, project): + super().__init__(name, options, project) + self.build_packages.extend([ + 'binutils', + 'python', + ]) + self.builddir = os.path.join( + self.build_basedir, 'out', self.options.build_type) + + def build(self): + env = self._build_environment() + gyp_path = os.path.join(self.sourcedir, os.path.dirname(self.options.gyp_file)) + + for environ in self.options.environment: + [env_name] = list(environ) + env[env_name] = str(environ[env_name]) + + if not os.path.exists(os.path.join(self.builddir, 'CMakeLists.txt')): + gyp_command = ['gyp'] + self.options.configflags + ['--format=cmake'] + gyp_command.append('--generator-output={}'.format(self.build_basedir)) + gyp_command.append(os.path.basename(self.options.gyp_file)) + self.run(gyp_command, cwd=gyp_path) + + if not os.path.exists(os.path.join(self.builddir, 'Makefile')): + self.run(['cmake', '.'], env=env) + + self.make(env=env) + + if self.options.artifacts and self.options.build_type == 'Release': + for artifact in self.options.artifacts: + dest = os.path.join(self.installdir, artifact) + if os.path.isfile(dest): + mime_type = self.run_output( + 'file --mime-type -b {}'.format(dest).split()) + if 'application/x-executable' in mime_type: + self.run(['strip', dest]) diff --git a/snap/plugins/x-patched-python.py b/snap/plugins/x-patched-python.py new file mode 100644 index 0000000000..0444ac6676 --- /dev/null +++ b/snap/plugins/x-patched-python.py @@ -0,0 +1,65 @@ +# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- +# +# Author: Marco Trevisan <marco@ubuntu.com> +# Copyright (C) 2017-2018 Canonical Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import snapcraft +import requests + +from snapcraft.plugins import python + +class PatchedPythonPlugin(python.PythonPlugin): + + @classmethod + def schema(cls): + schema = super().schema() + + schema['properties']['patches'] = { + 'type': 'array', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'string', + }, + 'default': [], + } + + schema['pull-properties'].extend([ + 'patches', + ]) + + return schema + + def pull(self): + super().pull() + + for patch in self.options.patches: + patch_name = os.path.basename(patch) + patch_stamp = os.path.join( + self.sourcedir, '.snapcraft-patched-{}'.format(patch_name)) + + if not os.path.exists(patch_stamp): + if os.path.exists(patch): + patch_file = os.path.join(os.getcwd(), patch) + else: + patch_file = os.path.join( + self.sourcedir, 'snapcraft-patch-{}'.format(patch_name)) + with open(patch_file, 'wb') as file: + file.write(requests.get(patch).content) + + patch_cmd = 'git apply -v3 {}'.format(patch_file).split() + self.run(patch_cmd, cwd=self.sourcedir) + open(patch_stamp, 'a').close() diff --git a/snap/plugins/x-qtbuilder.py b/snap/plugins/x-qtbuilder.py new file mode 100644 index 0000000000..860cd448a4 --- /dev/null +++ b/snap/plugins/x-qtbuilder.py @@ -0,0 +1,204 @@ +# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- +# +# Author: Marco Trevisan <marco@ubuntu.com> +# Copyright (C) 2017-2018 Canonical Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import shutil +import snapcraft + +from snapcraft.plugins import make + +class QtBuilderPlugin(make.MakePlugin): + + @classmethod + def schema(cls): + schema = super().schema() + + schema['properties']['configflags'] = { + 'type': 'array', + 'minitems': 1, + 'uniqueItems': False, + 'items': { + 'type': 'string', + }, + 'default': [], + } + + schema['properties']['qt-source-git'] = { + 'type': 'string' + } + + schema['properties']['qt-source-depth'] = { + 'type': 'integer', + 'default': 1 + } + + schema['properties']['qt-version'] = { + 'type': 'string' + } + + schema['properties']['qt-patches-base-url'] = { + 'type': 'string' + } + + schema['properties']['qt-patches-path'] = { + 'type': 'string' + } + + schema['properties']['qt-submodules'] = { + 'type': 'array', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'string', + }, + 'default': [], + } + + schema['properties']['qt-extra-plugins'] = { + 'type': 'array', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'object', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'string', + }, + }, + 'default': [], + } + + schema['properties']['environment'] = { + 'type': 'array', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'object', + 'minitems': 0, + 'uniqueItems': True, + 'items': { + 'type': 'string', + }, + }, + 'default': [], + } + + schema['required'].append('qt-source-git') + + schema['build-properties'].append('configflags') + + return schema + + @classmethod + def get_pull_properties(cls): + return [ + 'qt-version', + 'qt-patches-base-url', + 'qt-patches-path', + 'qt-submodules', + 'qt-extra-plugins', + ] + + def __init__(self, name, options, project): + super().__init__(name, options, project) + self.build_packages.extend(['g++', 'patch', 'perl', 'wget']) + self.options.source_depth = self.options.qt_source_depth + + if self.options.qt_version: + if self.options.qt_version[0] == 'v': + self.options.source_branch = self.options.qt_version + self.options.qt_version = self.options.qt_version[1:] + else: + self.options.source_branch = '.'.join( + self.options.qt_version.split('.')[:-1]) + + + def pull(self): + if not os.path.exists(os.path.join(self.sourcedir, '.git')) or \ + not os.path.exists(os.path.join(self.sourcedir, 'init-repository')): + shutil.rmtree(self.sourcedir, ignore_errors=True) + command = 'git clone {} {}'.format( + self.options.qt_source_git, self.sourcedir).split() + if self.options.source_branch: + command.extend(['--branch', str(self.options.source_branch)]) + if self.options.source_depth: + command.extend(['--depth', str(self.options.source_depth)]) + + self.run(command) + + command = 'perl init-repository --branch -f'.split() + if len(self.options.qt_submodules): + command.extend('--module-subset={}'.format( + ','.join(self.options.qt_submodules)).split()) + self.run(command, cwd=self.sourcedir) + + if self.options.qt_version: + self.run("git submodule foreach git checkout v{}".format( + self.options.qt_version).split(), self.sourcedir) + + patch_file_template = '${{name}}{}.diff'.format( + '_' + self.options.qt_version.replace('.', '_') \ + if self.options.qt_version else '') + + if self.options.qt_patches_base_url: + patch_uri_template = '{}/{}'.format( + self.options.qt_patches_base_url, patch_file_template) + + patch_cmd = 'git submodule foreach -q'.split() + \ + ['[ -e {touch_file} ] || ' \ + 'wget -q -O - {patch_uri_template} | patch -p1 && ' \ + 'touch {touch_file}'.format( + patch_uri_template=patch_uri_template, + touch_file='.snapcraft-qt-patched')] + + self.run(patch_cmd, cwd=self.sourcedir) + + if self.options.qt_patches_path: + patch_path_template = os.path.join( + os.getcwd(), self.options.qt_patches_path, patch_file_template) + + patch_cmd = 'git submodule foreach -q'.split() + \ + ['[ -e {patch} ] && git apply -v3 {patch} || true'.format( + patch=patch_path_template)] + + self.run(patch_cmd, cwd=self.sourcedir) + + for extra_plugin in self.options.qt_extra_plugins: + [framework] = list(extra_plugin) + + final_path = os.path.join(self.sourcedir, 'qtbase', 'src', + 'plugins', framework) + + for repo in extra_plugin[framework]: + repo_path = os.path.basename(repo) + if repo_path.endswith('.git'): + repo_path = repo_path[:-4] + + if not os.path.exists(os.path.join(final_path, repo_path)): + command = 'git clone {}'.format(repo).split() + self.run(command, cwd=final_path) + + def build(self): + env = {} + + for environ in self.options.environment: + [env_name] = list(environ) + env[env_name] = str(environ[env_name]) + + self.run(['./configure'] + self.options.configflags, env=env) + super().build() |