From e5d8d6b206c4204b7d3f4f406a931c135d0c8de8 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Thu, 15 Aug 2019 18:46:55 +0100 Subject: [PATCH] Install a script that builds the relocatable installation Signed-off-by: Simon McVittie <smcv@collabora.com> --- .gitignore | 2 + .gitlab-ci.yml | 11 +-- README.md | 6 +- build-relocatable-install.in | 7 ++ build-relocatable-install.py | 150 ++++++++++------------------------- ci/Jenkinsfile | 11 +-- copy-source-code.py | 112 ++++++++++++++++++++++++++ debian/rules | 1 + meson.build | 26 ++++++ meson_options.txt | 1 + 10 files changed, 206 insertions(+), 121 deletions(-) create mode 100644 build-relocatable-install.in create mode 100644 copy-source-code.py diff --git a/.gitignore b/.gitignore index 2a3819ea9..329b876b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.*.sw? +/.mypy_cache /_build/ /libcapsule/ /libcapsule_*.dsc diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 32d343650..fd63f5ef6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,17 +45,18 @@ build:scout: meson \ ${NULL+} - meson --prefix="$(pwd)/_build/prefix" -Dpython=python3.5 _build + meson \ + --prefix="$(pwd)/_build/prefix" \ + -Dpython=python3.5 \ + -Dsrcdir=src \ + _build ninja -C _build meson test --verbose -C _build ninja -C _build install rm -fr _build/relocatable-install - ./build-relocatable-install.py \ - --srcdir . \ - --builddir _build \ + _build/prefix/bin/pressure-vessel-build-relocatable-install \ --output _build/relocatable-install \ --archive "$(pwd)/_build" \ - --set-version "$(cat .tarball-version)" \ ${NULL+} prove -v ./tests/relocatable-install.py :: \ "$(pwd)/_build/relocatable-install" diff --git a/README.md b/README.md index e996ccdbd..59fa4850f 100644 --- a/README.md +++ b/README.md @@ -149,14 +149,12 @@ or available via apt-get. For example, you could do the build in a SteamRT 1 'scout' SDK Docker image that has those packages already. Then you can do: - meson --prefix="$(pwd)/_build/prefix" _build + meson --prefix="$(pwd)/_build/prefix" -Dsrcdir=src _build ninja -C _build meson test -v -C _build # optional ninja -C _build install rm -fr _build/relocatable-install - ./build-relocatable-install.py \ - --srcdir . \ - --builddir _build \ + _build/prefix/bin/pressure-vessel-build-relocatable-install \ --output _build/relocatable-install \ --archive . ./tests/relocatable-install.py _build/relocatable-install # optional diff --git a/build-relocatable-install.in b/build-relocatable-install.in new file mode 100644 index 000000000..9395e4424 --- /dev/null +++ b/build-relocatable-install.in @@ -0,0 +1,7 @@ +#!@sh@ +exec "@python@" \ +"${DESTDIR}@prefix@/@srcdir@/build-relocatable-install.py" \ +--prefix "@prefix@" \ +--srcdir "@srcdir@" \ +--set-version "@version@" \ +"$@" diff --git a/build-relocatable-install.py b/build-relocatable-install.py index e74b7e80c..61a005c13 100755 --- a/build-relocatable-install.py +++ b/build-relocatable-install.py @@ -25,7 +25,6 @@ import argparse import glob -import json import os import re import shutil @@ -135,42 +134,30 @@ def main(): # type: () -> None parser = argparse.ArgumentParser() - parser.add_argument( - '--destdir', default=os.getenv('DESTDIR', '')) - parser.add_argument( - '--srcdir', default=os.getenv('MESON_SOURCE_ROOT', '.')) - parser.add_argument( - '--builddir', default=os.getenv('MESON_BUILD_ROOT', '_build')) + parser.add_argument('--destdir', default=os.getenv('DESTDIR')) parser.add_argument('--prefix', default=None) + parser.add_argument('--srcdir', default=None) parser.add_argument('--output', '-o', default=None) parser.add_argument('--archive', default=None) - parser.add_argument('--set-version', dest='version', default='unknown') + parser.add_argument('--set-version', dest='version', default=None) args = parser.parse_args() - if args.destdir: - args.destdir = os.path.abspath(args.destdir) + if args.srcdir is None: + args.srcdir = os.path.dirname(__file__) - args.srcdir = os.path.abspath(args.srcdir) - args.builddir = os.path.abspath(args.builddir) + if args.prefix is None: + args.prefix = '/usr/lib/pressure-vessel/relocatable' - if args.archive is None: - args.archive = args.builddir - else: - args.archive = os.path.abspath(args.archive) + if not os.path.isabs(args.srcdir): + args.srcdir = os.path.join(args.prefix, args.srcdir) - if args.prefix is None: - blob = subprocess.check_output([ - 'meson', 'introspect', args.builddir, '--buildoptions', - ], universal_newlines=True) - for opt in json.loads(blob): - if opt['name'] == 'prefix': - args.prefix = opt['value'] - break - else: - raise RuntimeError( - 'Unable to determine installation prefix from Meson, ' - 'please specify --prefix' - ) + if args.destdir: + args.prefix = args.destdir + args.prefix + args.srcdir = args.destdir + args.srcdir + + if args.version is None: + with open(os.path.join(args.srcdir, '.tarball-version')) as reader: + args.version = reader.read().strip() with tempfile.TemporaryDirectory(prefix='pressure-vessel-') as tmpdir: if args.output is None: @@ -181,8 +168,6 @@ def main(): if os.path.exists(installation): raise RuntimeError('--output directory must not already exist') - destdir_prefix = args.destdir + args.prefix - os.makedirs(os.path.join(installation, 'bin'), exist_ok=True) os.makedirs(os.path.join(installation, 'metadata'), exist_ok=True) @@ -194,13 +179,13 @@ def main(): for script in SCRIPTS: install_exe( - os.path.join(destdir_prefix, 'bin', script), + os.path.join(args.prefix, 'bin', script), os.path.join(installation, 'bin'), ) for exe in EXECUTABLES: install_exe( - os.path.join(destdir_prefix, 'bin', exe), + os.path.join(args.prefix, 'bin', exe), os.path.join(installation, 'bin'), ) @@ -430,82 +415,33 @@ def main(): exist_ok=True, ) - for src_tar in ( - os.path.join( - args.srcdir, - '..', - 'pressure-vessel_{}.orig.tar.xz'.format(args.version), - ), - os.path.join( - args.builddir, - 'meson-dist/pressure-vessel-{}.tar.gz'.format( - args.version, - ), - ), - os.path.join( - args.srcdir, - 'pressure-vessel-{}.tar.xz'.format(args.version), + tar = subprocess.Popen([ + 'tar', + '-C', args.srcdir, + '--exclude=.*.sw?', + '--exclude=./.git', + '--exclude=./.mypy_cache', + '--exclude=./_build', + '--exclude=./debian', + '--exclude=./relocatable-install', + '-cf-', + '.', + ], stdout=subprocess.PIPE) + subprocess.check_call([ + 'tar', + '-C', os.path.join( + installation, + 'sources', + 'pressure-vessel', ), - ): - if os.path.exists(src_tar): - subprocess.check_call([ - 'tar', - '-C', os.path.join( - installation, - 'sources', - 'pressure-vessel', - ), - '--strip-components=1', - '-xvf', src_tar, - ]) - break - else: - if os.path.exists('/usr/bin/git'): - git_archive = subprocess.Popen([ - 'git', 'archive', '--format=tar', 'HEAD', - ], cwd=args.srcdir, stdout=subprocess.PIPE) - subprocess.check_call([ - 'tar', - '-C', os.path.join( - installation, - 'sources', - 'pressure-vessel', - ), - '-xvf-', - ], stdin=git_archive.stdout) - - if git_archive.wait() != 0: - raise subprocess.CalledProcessError( - returncode=git_archive.returncode, - cmd=git_archive.args, - ) - else: - tar = subprocess.Popen([ - 'tar', - '-C', args.srcdir, - '--exclude=./.git', - '--exclude=./_build', - '--exclude=./relocatable-install', - '--exclude=./.mypy_cache', - '--exclude=.*.swp', - '-cf-', - '.', - ], stdout=subprocess.PIPE) - subprocess.check_call([ - 'tar', - '-C', os.path.join( - installation, - 'sources', - 'pressure-vessel', - ), - '-xvf-', - ], stdin=tar.stdout) + '-xvf-', + ], stdin=tar.stdout) - if tar.wait() != 0: - raise subprocess.CalledProcessError( - returncode=git_archive.returncode, - cmd=git_archive.args, - ) + if tar.wait() != 0: + raise subprocess.CalledProcessError( + returncode=tar.returncode, + cmd=tar.args, + ) with open( os.path.join( diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile index 06737163f..8b9153c1d 100644 --- a/ci/Jenkinsfile +++ b/ci/Jenkinsfile @@ -109,17 +109,18 @@ pipeline { sh ''' set -eu cd src - meson --prefix="$(pwd)/_build/prefix" -Dpython=python3.5 _build + meson \ + --prefix="$(pwd)/_build/prefix" \ + -Dpython=python3.5 \ + -Dsrcdir=src \ + _build ninja -C _build meson test --verbose -C _build ninja -C _build install rm -fr ../relocatable-install - ./build-relocatable-install.py \ - --srcdir . \ - --builddir _build \ + _build/prefix/bin/pressure-vessel-build-relocatable-install \ --output "${WORKSPACE}/relocatable-install" \ --archive "${WORKSPACE}" \ - --set-version "$(cat .tarball-version)" \ ${NULL+} prove -v ./tests/relocatable-install.py :: \ "${WORKSPACE}/relocatable-install" diff --git a/copy-source-code.py b/copy-source-code.py new file mode 100644 index 000000000..c60187a75 --- /dev/null +++ b/copy-source-code.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 + +# Copyright © 2017-2019 Collabora Ltd. +# +# SPDX-License-Identifier: MIT +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import argparse +import os +import subprocess + +try: + import typing +except ImportError: + pass +else: + typing # silence pyflakes + + +def v_check_call(command, **kwargs): + print('# {}'.format(command)) + subprocess.check_call(command, **kwargs) + + +def v_check_output(command, **kwargs): + print('# {}'.format(command)) + return subprocess.check_output(command, **kwargs) + + +def main(): + # type: () -> None + + parser = argparse.ArgumentParser() + parser.add_argument( + '--destdir', default=os.getenv('DESTDIR', '')) + parser.add_argument( + '--srcdir', default=os.getenv('MESON_SOURCE_ROOT', '.')) + parser.add_argument('--set-version', default='0.0.0', dest='version') + parser.add_argument('--prefix', default='/usr') + parser.add_argument('output') + args = parser.parse_args() + + args.srcdir = os.path.abspath(args.srcdir) + args.prefix = os.path.abspath(args.prefix) + + if not os.path.isabs(args.output): + args.output = os.path.join(args.prefix, args.output) + + if args.destdir: + args.destdir = os.path.abspath(args.destdir) + args.output = args.destdir + args.output + + os.makedirs(os.path.join(args.output), exist_ok=True) + + tar = subprocess.Popen([ + 'tar', + '-C', args.srcdir, + '--exclude=.*.sw?', + '--exclude=./.git', + '--exclude=./.mypy_cache', + '--exclude=./_build', + '--exclude=./debian', + '--exclude=./relocatable-install', + '-cf-', + '.', + ], stdout=subprocess.PIPE) + subprocess.check_call([ + 'tar', + '-C', os.path.join( + args.output, + ), + '-xvf-', + ], stdin=tar.stdout) + + if tar.wait() != 0: + raise subprocess.CalledProcessError( + returncode=tar.returncode, + cmd=tar.args, + ) + + with open( + os.path.join( + args.output, + '.tarball-version', + ), + 'w', + ) as writer: + writer.write('{}\n'.format(args.version)) + + +if __name__ == '__main__': + main() + +# vim:set sw=4 sts=4 et: diff --git a/debian/rules b/debian/rules index b3e17e206..8c670bcab 100755 --- a/debian/rules +++ b/debian/rules @@ -26,6 +26,7 @@ override_dh_auto_configure: meson _build \ --prefix=/usr/lib/pressure-vessel/relocatable \ -Dpython=/usr/bin/$$python \ + -Dsrcdir=src \ -Dversion=$(DEB_VERSION) \ $(NULL) diff --git a/meson.build b/meson.build index 02d71b653..90bb29a2c 100644 --- a/meson.build +++ b/meson.build @@ -179,4 +179,30 @@ executable( install_rpath : '${ORIGIN}/../' + get_option('libdir'), ) +if get_option('srcdir') != '' + conf_data = configuration_data() + conf_data.set('prefix', get_option('prefix')) + conf_data.set('python', python.path()) + conf_data.set('sh', sh.path()) + conf_data.set('srcdir', get_option('srcdir')) + conf_data.set('version', version) + install_data( + configure_file( + input : 'build-relocatable-install.in', + output : 'pressure-vessel-build-relocatable-install', + configuration : conf_data, + ), + install_dir : get_option('bindir'), + install_mode : 'rwxr-xr-x', + ) + meson.add_install_script( + python.path(), + meson.current_source_dir() / 'copy-source-code.py', + '--srcdir', meson.current_source_dir(), + '--prefix', get_option('prefix'), + '--set-version', version, + get_option('srcdir'), + ) +endif + # vim:set sw=2 sts=2 et: diff --git a/meson_options.txt b/meson_options.txt index cba6f7c59..fe6a3e81e 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,2 +1,3 @@ option('python', type : 'string', value : 'python3') +option('srcdir', type : 'string', value : '') option('version', type : 'string', value : 'auto') -- GitLab