diff --git a/Makefile b/Makefile deleted file mode 100644 index 136e2e6e74c1bee4c1746181cf5215701da7282e..0000000000000000000000000000000000000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -VERSION := $(shell ./build-aux/git-version-gen .tarball-version) -PYTHON ?= python3 -relocatabledir = /usr/lib/libcapsule/relocatable - -all: binary - -ifeq (,$(wildcard libcapsule_*.dsc)) -_relocatabledir = $(relocatabledir) -else -_relocatabledir = -endif - -install: - $(PYTHON) ./build-relocatable-install.py $(_relocatabledir) - -check: - prove -v t/*.sh - -binary: - $(MAKE) install - tar --transform='s,^relocatable-install,pressure-vessel-$(VERSION),' -zcvf pressure-vessel-$(VERSION)-bin+src.tar.gz.tmp relocatable-install - tar --transform='s,^relocatable-install,pressure-vessel-$(VERSION),' --exclude=sources -zcvf pressure-vessel-$(VERSION)-bin.tar.gz.tmp relocatable-install - mv pressure-vessel-$(VERSION)-bin+src.tar.gz.tmp pressure-vessel-$(VERSION)-bin+src.tar.gz - mv pressure-vessel-$(VERSION)-bin.tar.gz.tmp pressure-vessel-$(VERSION)-bin.tar.gz - -clean: - rm -fr pressure-vessel-[0-9]*.tar.gz - rm -fr _build - rm -fr relocatable-install - rm -fr libcapsule diff --git a/Makefile.libcapsule b/Makefile.libcapsule deleted file mode 100644 index 6e2334396123857ada5c507d58df7ec935a0d92d..0000000000000000000000000000000000000000 --- a/Makefile.libcapsule +++ /dev/null @@ -1,46 +0,0 @@ -all: amd64 i386 -amd64 i386: %: _build/%/build.stamp - -libcapsule/configure: $(wildcard libcapsule*.dsc) - rm -fr libcapsule - first=; \ - for t in libcapsule*.dsc; do \ - if [ -z "$$first" ]; then \ - first="$$t"; \ - else \ - echo "Exactly one libcapsule*.dsc is required" >&2; \ - exit 1; \ - fi; \ - done - dpkg-source -x libcapsule*.dsc - mv libcapsule-*/ libcapsule - set -e; cd libcapsule; NOCONFIGURE=1 ./autogen.sh - -_build/%/config.stamp: libcapsule/configure - mkdir -p _build/$*/libcapsule - set -eu; \ - DEB_BUILD_ARCH="$$(dpkg-architecture -a"$*" -qDEB_BUILD_ARCH)"; \ - DEB_HOST_ARCH="$$(dpkg-architecture -a"$*" -qDEB_HOST_ARCH)"; \ - DEB_BUILD_GNU_TYPE="$$(dpkg-architecture -a"$*" -qDEB_BUILD_GNU_TYPE)"; \ - DEB_HOST_GNU_TYPE="$$(dpkg-architecture -a"$*" -qDEB_HOST_GNU_TYPE)"; \ - DEB_HOST_MULTIARCH="$$(dpkg-architecture -a"$*" -qDEB_HOST_MULTIARCH)"; \ - case "$${DEB_BUILD_ARCH}/$${DEB_HOST_ARCH}" in \ - (amd64/i386) \ - export CC="cc -m32"; \ - ;; \ - esac; \ - cd _build/$*/libcapsule; \ - ../../../libcapsule/configure \ - --build="$${DEB_BUILD_GNU_TYPE}" \ - --host="$${DEB_HOST_GNU_TYPE}" \ - --enable-host-prefix="$${DEB_HOST_MULTIARCH}-" \ - --enable-tools-rpath="/_ORIGIN_/__/lib/$${DEB_HOST_MULTIARCH}" \ - --disable-shared \ - --disable-gtk-doc \ - --without-glib \ - $(NULL) - touch $@ - -_build/%/build.stamp: _build/%/config.stamp - $(MAKE) -C _build/$*/libcapsule - touch $@ diff --git a/README.md b/README.md index 66f9035b0f5118bc91e06558d3d86a0347472a27..4595e77a8a9cebdbf2c9a15169a72de081db2785 100644 --- a/README.md +++ b/README.md @@ -42,15 +42,35 @@ The most straightforward method is to have a prebuilt version of libcapsule-tools-relocatable:amd64 and libcapsule-tools-relocatable:i386 in your build environment. For example, you could do the build in a SteamRT 1 'scout' or SteamRT 1.5 'heavy' Docker image that has those -packages already. Then you can just do: +packages already. Then you can do: - make + meson --prefix=$(pwd)/_build/relocatable-install _build + ninja -C _build + meson test -v -C _build # optional + ninja -C _build install -Or, if your build environment has those packages available but -uninstalled, you can unpack them with `dpkg-deb -x` and use something +For more convenient use on a development system, if you have a +SteamRT 1 'scout' SDK tarball or an unpacked sysroot, you can place a +tarball at `_build/sysroot.tar.gz` or unpack a sysroot into +`_build/sysroot`, and prefix those commands with +`./sysroot/run-in-sysroot.py`: + + ./sysroot/run-in-sysroot.py meson ... + +(Or put them in different locations and pass the `--sysroot` and +`--tarball` options to `./sysroot/run-in-sysroot.py`.) + +If your build environment has `libcapsule-tools-relocatable` available +but uninstalled, you can unpack them with `dpkg-deb -x` and use something like: - make relocatabledir=./usr/lib/libcapsule/relocatable + meson \ + --prefix=$(pwd)/_build/relocatable-install \ + -Drelocatabledir=./usr/lib/libcapsule/relocatable \ + _build + ninja -C _build + meson test -v -C _build # optional + ninja -C _build install Alternatively, build a Debian source package (`.dsc`, `.debian.tar.*`, `.orig.tar.*` for libcapsule 0.20190402.0 or later, which will require @@ -59,41 +79,12 @@ Put it in the top-level directory of `pressure-vessel`, for example: dcmd cp ../build-area/libcapsule_0.20190402.0-0co1.dsc . -After that, the simplest way is (again) to do the build already inside -a suitable container: - - make - -Alternatively, you can use `bubblewrap` to enter a sysroot prepared -using [debos][] and [qemu-system-x86_64][qemu]. If -you have all those, you can just run: - - make -C sysroot - -which will automatically build and use the sysroot. (This sysroot -won't have libcapsule-tools-relocatable, so you will need a -`libcapsule_*.dsc` or the `relocatabledir` variable, as above.) - -Alternatively, prepare a Debian jessie sysroot with `deb` -and `deb-src` sources and an `i386` foreign architecture (see -`sysroot/configure-sources.sh`), all the packages listed in -`sysroot/install-dependencies.sh`, and optionally -libcapsule-tools-relocatable. Then use: - - make -C sysroot sysroot=/path/to/sysroot - -or compress a similar chroot into a gzipped tar file (containing `./etc`, -`./usr` and so on, as used by [lxc][] and [pbuilder][]) and use: - - make -C sysroot tarball=/path/to/tarball.tar.gz - -Whichever method you use, binaries and source code end up in -`relocatable-install/` which can be copied to wherever you want. +There is experimental support in `sysroot/` for building a container +for the build using debos, but it requires an unusual container +(Debian jessie or SteamRT 1.5 'heavy' with a backport of meson) and +so is not currently recommended. -[debos]: https://github.com/go-debos/debos -[lxc]: https://github.com/lxc/lxc -[pbuilder]: https://pbuilder.alioth.debian.org/ -[qemu]: https://www.qemu.org/ +The relocatable install ends up in `_build/relocatable-install`. Instructions for testing ------------------------ diff --git a/build-relocatable-install.py b/build-relocatable-install.py index e48f46ef1b80211bd505433ca8ba66f9302970d9..80550123a6bbe12e29cd797d9d3d63a7ccc5a80e 100755 --- a/build-relocatable-install.py +++ b/build-relocatable-install.py @@ -27,7 +27,6 @@ import argparse import glob import os import re -import shlex import shutil import subprocess @@ -81,7 +80,6 @@ PRIMARY_ARCH_DEPENDENCIES = { 'libselinux1': 'libselinux', 'libpcre3': 'pcre3', } -DESTDIR = 'relocatable-install' SCRIPTS = [ 'pressure-vessel-unruntime', 'pressure-vessel-wrap' @@ -121,31 +119,57 @@ def main(): # type: () -> None parser = argparse.ArgumentParser() - parser.add_argument('relocatabledir', default=None, nargs='?') + 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', '.')) + parser.add_argument( + '--prefix', + default=os.getenv( + 'MESON_INSTALL_PREFIX', + os.path.abspath('relocatable-build'), + ), + ) + parser.add_argument( + '--archive', default=os.getenv('MESON_BUILD_ROOT', '.')) + parser.add_argument('--relocatabledir', default='') + parser.add_argument('--set-version', dest='version', default='unknown') args = parser.parse_args() - if os.path.exists(DESTDIR): - shutil.rmtree(DESTDIR) + os.chdir(args.builddir) + + destdir_prefix = os.getenv( + 'MESON_INSTALL_DESTDIR_PREFIX', + args.destdir + args.prefix, + ) - os.makedirs(os.path.join(DESTDIR, 'bin'), exist_ok=True) - os.makedirs(os.path.join(DESTDIR, 'sources'), exist_ok=True) + if os.path.exists(destdir_prefix): + shutil.rmtree(destdir_prefix) + + os.makedirs(os.path.join(destdir_prefix, 'bin'), exist_ok=True) + os.makedirs(os.path.join(destdir_prefix, 'sources'), exist_ok=True) for arch in ARCHS: os.makedirs( - os.path.join(DESTDIR, 'lib', arch.multiarch), + os.path.join(destdir_prefix, 'lib', arch.multiarch), exist_ok=True, ) for script in SCRIPTS: - install_exe(script, os.path.join(DESTDIR, 'bin')) + install_exe( + os.path.join(args.srcdir, script), + os.path.join(destdir_prefix, 'bin'), + ) install( - 'THIRD-PARTY.md', - os.path.join(DESTDIR, 'sources', 'README.txt'), + os.path.join(args.srcdir, 'THIRD-PARTY.md'), + os.path.join(destdir_prefix, 'sources', 'README.txt'), 0o644, ) - if args.relocatabledir is not None: + if args.relocatabledir: for arch in ARCHS: for tool in TOOLS: install_exe( @@ -153,22 +177,25 @@ def main(): args.relocatabledir, '{}-{}'.format(arch.multiarch, tool), ), - os.path.join(DESTDIR, 'bin'), + os.path.join(destdir_prefix, 'bin'), ) install( '/usr/share/doc/libcapsule-tools-relocatable/copyright', - os.path.join(DESTDIR, 'sources', 'libcapsule.txt'), + os.path.join(destdir_prefix, 'sources', 'libcapsule.txt'), ) else: - v_check_call(['make', '-f', 'Makefile.libcapsule']) - for arch in ARCHS: for tool in TOOLS: install_exe( - os.path.join('_build', arch.name, 'libcapsule', tool), os.path.join( - '_build', + 'build-relocatable', + arch.name, + 'libcapsule', + tool, + ), + os.path.join( + 'build-relocatable', '{}-{}'.format(arch.multiarch, tool), ), ) @@ -176,27 +203,34 @@ def main(): 'chrpath', '-r', '${ORIGIN}/../lib/' + arch.multiarch, os.path.join( - '_build', + 'build-relocatable', '{}-{}'.format(arch.multiarch, tool), ), ]) install_exe( os.path.join( - '_build', + 'build-relocatable', '{}-{}'.format(arch.multiarch, tool), ), - os.path.join(DESTDIR, 'bin'), + os.path.join(destdir_prefix, 'bin'), ) install( - os.path.join('libcapsule', 'debian', 'copyright'), - os.path.join(DESTDIR, 'sources', 'libcapsule.txt'), + os.path.join( + args.builddir, + 'libcapsule', + 'debian', + 'copyright', + ), + os.path.join(destdir_prefix, 'sources', 'libcapsule.txt'), ) - for dsc in glob.glob('libcapsule*.dsc'): + for dsc in glob.glob( + os.path.join(args.srcdir, 'libcapsule*.dsc') + ): v_check_call([ 'dcmd', 'install', '-m644', dsc, - os.path.join(DESTDIR, 'sources'), + os.path.join(destdir_prefix, 'sources'), ]) primary_architecture = subprocess.check_output([ @@ -204,11 +238,17 @@ def main(): ]).decode('utf-8').strip() for arch in ARCHS: - os.makedirs(os.path.join('_build', arch.name, 'lib'), exist_ok=True) + os.makedirs( + os.path.join('build-relocatable', arch.name, 'lib'), + exist_ok=True, + ) v_check_call([ - '{}/bin/{}-capsule-capture-libs'.format(DESTDIR, arch.multiarch), - '--dest=_build/{}/lib'.format(arch.name), + '{}/bin/{}-capsule-capture-libs'.format( + destdir_prefix, + arch.multiarch, + ), + '--dest=build-relocatable/{}/lib'.format(arch.name), '--no-glibc', 'soname:libelf.so.1', 'soname:libz.so.1', @@ -217,10 +257,10 @@ def main(): if arch.name == primary_architecture: v_check_call([ '{}/bin/{}-capsule-capture-libs'.format( - DESTDIR, + destdir_prefix, arch.multiarch, ), - '--dest=_build/{}/lib'.format(arch.name), + '--dest=build-relocatable/{}/lib'.format(arch.name), '--no-glibc', 'soname:libcap.so.2', 'soname:libpcre.so.3', @@ -228,9 +268,9 @@ def main(): ]) for so in glob.glob( - os.path.join('_build', arch.name, 'lib', '*.so.*'), + os.path.join('build-relocatable', arch.name, 'lib', '*.so.*'), ): - install(so, os.path.join(DESTDIR, 'lib', arch.multiarch)) + install(so, os.path.join(destdir_prefix, 'lib', arch.multiarch)) # For bwrap (and possibly other programs in future) we don't have # a relocatable version with a RPATH/RUNPATH, so we wrap a script @@ -246,10 +286,12 @@ def main(): package, ]) v_check_call( - 'dpkg-deb -x {}_*.deb _build'.format(shlex.quote(package)), + 'dpkg-deb -x {}_*.deb build-relocatable'.format( + shlex.quote(package), + ), shell=True, ) - path = '_build/usr/bin/{}'.format(exe) + path = 'build-relocatable/usr/bin/{}'.format(exe) for arch in ARCHS: if arch.name != primary_architecture: @@ -257,11 +299,11 @@ def main(): install_exe( path, - os.path.join(DESTDIR, 'bin', exe + '.bin'), + os.path.join(destdir_prefix, 'bin', exe + '.bin'), ) with open( - os.path.join('_build', arch.name, exe), + os.path.join('build-relocatable', arch.name, exe), 'w', ) as writer: writer.write('#!/bin/sh\n') @@ -277,8 +319,8 @@ def main(): ) install_exe( - os.path.join('_build', arch.name, exe), - os.path.join(DESTDIR, 'bin', exe), + os.path.join('build-relocatable', arch.name, exe), + os.path.join(destdir_prefix, 'bin', exe), ) source_to_download = set() # type: typing.Set[str] @@ -286,13 +328,17 @@ def main(): for package, source in ( list(DEPENDENCIES.items()) + list(PRIMARY_ARCH_DEPENDENCIES.items()) ): - if args.relocatabledir is None and source == 'libcapsule': + if not args.relocatabledir and source == 'libcapsule': continue if os.path.exists('/usr/share/doc/{}/copyright'.format(package)): install( '/usr/share/doc/{}/copyright'.format(package), - os.path.join(DESTDIR, 'sources', '{}.txt'.format(source)), + os.path.join( + destdir_prefix, + 'sources', + '{}.txt'.format(source), + ), ) for expr in set( @@ -306,8 +352,12 @@ def main(): source_to_download.add(re.sub(r'[+]srt[0-9a-z.]+$', '', expr)) else: install( - '_build/usr/share/doc/{}/copyright'.format(package), - os.path.join(DESTDIR, 'sources', '{}.txt'.format(source)), + 'build-relocatable/usr/share/doc/{}/copyright'.format(package), + os.path.join( + destdir_prefix, + 'sources', + '{}.txt'.format(source), + ), ) source_to_download.add(source) @@ -318,9 +368,36 @@ def main(): '--only-source', 'source', ] + list(source_to_download), - cwd=os.path.join(DESTDIR, 'sources'), + cwd=os.path.join(destdir_prefix, 'sources'), ) + bin_tar = 'pressure-vessel-{}-bin.tar.gz'.format(args.version) + src_tar = 'pressure-vessel-{}-bin+src.tar.gz'.format(args.version) + + subprocess.check_call([ + 'tar', + r'--transform=s,^\(\.\(/\|$\)\)\?,pressure-vessel-{}/,'.format( + args.version, + ), + '-zcvf', src_tar + '.tmp', + '-C', destdir_prefix, + '.', + ]) + subprocess.check_call([ + 'tar', + r'--transform=s,^\(\.\(/\|$\)\)\?,pressure-vessel-{}/,'.format( + args.version, + ), + '--exclude=sources', + '-zcvf', bin_tar + '.tmp', + '-C', destdir_prefix, + '.', + ]) + os.rename(bin_tar + '.tmp', bin_tar) + os.rename(src_tar + '.tmp', src_tar) + print('Generated {}'.format(os.path.abspath(bin_tar))) + print('Generated {}'.format(os.path.abspath(src_tar))) + if __name__ == '__main__': main() diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile index c0d9a2261a86a3865eb2befb781aa5dcc522257f..270f34e91c7bdcafd79b84f966b551f8daf2e30a 100644 --- a/ci/Jenkinsfile +++ b/ci/Jenkinsfile @@ -62,8 +62,11 @@ pipeline { docker.image("${env.CI_DOCKER_REGISTRY}/steamrt/sdk:scout").inside('--mount type=tmpfs,destination=/var/cache/apt/archives') { sh ''' set -eu - make -C src PYTHON=python3.5 - make -C src check PYTHON=python3.5 + cd src + meson --prefix="${WORKSPACE}/src/_build/relocatable-install" -Dpython=python3.5 _build + ninja -C _build + ninja -C _build install + meson test --verbose -C _build ''' } } @@ -73,14 +76,18 @@ pipeline { docker.image('debian:buster-slim').inside() { sh ''' set -eu + export G_TEST_SRCDIR="${WORKSPACE}/src" + export G_TEST_BUILDDIR="${WORKSPACE}/src/_build" cd src ./t/relocatable-install.sh ''' } } - archiveArtifacts 'src/pressure-vessel-*-bin.tar.gz' - archiveArtifacts 'src/pressure-vessel-*-bin+src.tar.gz' + dir('src/_build') { + archiveArtifacts 'pressure-vessel-*-bin.tar.gz' + archiveArtifacts 'pressure-vessel-*-bin+src.tar.gz' + } } } } diff --git a/configure-libcapsule.sh b/configure-libcapsule.sh new file mode 100644 index 0000000000000000000000000000000000000000..435cfb8affe2697d22c36616f8759a219388870c --- /dev/null +++ b/configure-libcapsule.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# +# Copyright © 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. + +set -eu +NULL= + +DEB_BUILD_ARCH="$(dpkg-architecture -a"$1" -qDEB_BUILD_ARCH)" +DEB_HOST_ARCH="$(dpkg-architecture -a"$1" -qDEB_HOST_ARCH)" +DEB_BUILD_GNU_TYPE="$(dpkg-architecture -a"$1" -qDEB_BUILD_GNU_TYPE)" +DEB_HOST_GNU_TYPE="$(dpkg-architecture -a"$1" -qDEB_HOST_GNU_TYPE)" +DEB_HOST_MULTIARCH="$(dpkg-architecture -a"$1" -qDEB_HOST_MULTIARCH)" + +case "${DEB_BUILD_ARCH}/${DEB_HOST_ARCH}" in + (amd64/i386) + export CC="cc -m32" + ;; +esac + +mkdir -p "build-relocatable/$1/libcapsule" + +( + cd "build-relocatable/$1/libcapsule" + ../../../libcapsule/configure \ + --build="${DEB_BUILD_GNU_TYPE}" \ + --host="${DEB_HOST_GNU_TYPE}" \ + --enable-host-prefix="${DEB_HOST_MULTIARCH}-" \ + --enable-tools-rpath="/_ORIGIN_/__/lib/${DEB_HOST_MULTIARCH}" \ + --disable-shared \ + --disable-gtk-doc \ + --without-glib \ + ${NULL} +) + +touch "$2" + +# vim:set sw=2 sts=2 et: diff --git a/meson.build b/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..0d3c7e0478475aa64036547569a386a28bbf34c1 --- /dev/null +++ b/meson.build @@ -0,0 +1,166 @@ +# Copyright © 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. + +project('pressure-vessel', 'c') + +prove = find_program('prove', required : false) +python = find_program(get_option('python'), required : true) +sh = find_program('sh', required : true) + +version = get_option('version') +if version == 'auto' + git_version_gen = run_command( + sh, + files('build-aux/git-version-gen'), + join_paths(meson.current_source_dir(), '.tarball-version'), + check : true, + ) + version = git_version_gen.stdout().strip() +endif + +scripts = [ + 'pressure-vessel-wrap', + 'pressure-vessel-unruntime', +] + +tests = [ + 'mypy', + 'pycodestyle', + 'pyflakes', + 'relocatable-install', + 'shellcheck', +] + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) + +foreach test_name : tests + if prove.found() + test( + test_name, prove, + args : ['-v', files('t/' + test_name + '.sh')], + env : test_env, + ) + endif +endforeach + +foreach script : scripts + install_data( + script, + install_dir : get_option('bindir'), + ) +endforeach + +relocatabledir = get_option('relocatabledir') + +if relocatabledir == 'auto' + dsc_exists = run_command( + sh, + '-euc', + ''' + cd "$MESON_SOURCE_ROOT" + if test -e libcapsule_*.dsc + then echo libcapsule_*.dsc + else + exit 1 + fi + ''', + ) + if dsc_exists.returncode() == 0 + libcapsule_dsc = dsc_exists.stdout().strip() + relocatabledir = '' + else + libcapsule_dsc = '' + relocatabledir = '/usr/lib/libcapsule/relocatable' + endif +endif + +if libcapsule_dsc != '' + libcapsule_configure = custom_target( + 'libcapsule_configure', + command: [ + sh, + '-euc', + ''' + rm -fr libcapsule + dpkg-source -x "$1" + mv libcapsule-* libcapsule + ( cd libcapsule; NOCONFIGURE=1 ./autogen.sh ) + touch "$2" + ''', + 'sh', + '@INPUT@', + '@OUTPUT@', + ], + input : files(libcapsule_dsc), + output : 'libcapsule_configure.stamp', + build_by_default : true, + ) + + foreach arch : ['amd64', 'i386'] + config_stamp = custom_target( + 'build-relocatable_' + arch + '_config.stamp', + command : [ + sh, + files('configure-libcapsule.sh'), + arch, + '@OUTPUT@', + ], + depends : libcapsule_configure, + output : 'build-relocatable_' + arch + '_config.stamp', + build_by_default : true, + ) + + custom_target( + 'build-relocatable_' + arch + '_build.stamp', + command: [ + sh, + '-euc', + ''' + make -C "build-relocatable/$1/libcapsule" + touch "$2" + ''', + 'sh', + arch, + '@OUTPUT@', + ], + depends : config_stamp, + output : 'build-relocatable_' + arch + '_build.stamp', + build_by_default : true, + ) + endforeach +endif + +meson.add_install_script( + python.path(), + join_paths(meson.current_source_dir(), 'build-relocatable-install.py'), + '--srcdir', meson.current_source_dir(), + '--builddir', meson.current_build_dir(), + '--relocatabledir', relocatabledir, + '--prefix', get_option('prefix'), + '--archive', meson.current_build_dir(), + '--set-version', version, +) + +# vim:set sw=2 sts=2 et: diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000000000000000000000000000000000000..fef87a65d198f3bfb9eb4b851a5c3c1181740bcc --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,3 @@ +option('python', type : 'string', value : 'python3') +option('relocatabledir', type : 'string', value : 'auto') +option('version', type : 'string', value : 'auto') diff --git a/sysroot/Makefile b/sysroot/Makefile deleted file mode 100644 index 48c712070e38ddd1bc176304e1860d4adc2cc117..0000000000000000000000000000000000000000 --- a/sysroot/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -top_srcdir = $(dir $(CURDIR)) -top_builddir = $(dir $(CURDIR)) - -all: - -mirror = http://deb.debian.org/debian -security_mirror = http://security.debian.org/debian-security -tarball = $(top_builddir)/_build/sysroot.tar.gz -sysroot = $(top_builddir)/_build/sysroot - -$(top_builddir)/_build/sysroot/etc/debian_version: $(tarball) - rm -fr $(top_builddir)/_build/sysroot - mkdir -p $(top_builddir)/_build/sysroot - tar -zxf $(tarball) --exclude="./dev/*" -C $(top_builddir)/_build/sysroot - touch $@ - -$(top_builddir)/_build/sysroot.tar.gz: $(wildcard *) - mkdir -p $(dir $@) - set -e; \ - debos -t mirror:$(mirror) -t security_mirror:$(security_mirror) -t ospack:sysroot.tar.gz --artifactdir=$(top_builddir)/_build debos.yaml - -ifeq ($(sysroot),/) -in_sysroot = -else -in_sysroot = \ - bwrap \ - --ro-bind $(sysroot) / \ - --dev-bind /dev /dev \ - --ro-bind /etc/resolv.conf /etc/resolv.conf \ - --tmpfs /tmp \ - --tmpfs /home \ - --bind $(top_builddir) $(top_builddir) \ - --bind $(top_srcdir) $(top_srcdir) \ - --chdir $(top_builddir) \ - --setenv LC_ALL C.UTF-8 \ - $(NULL) -endif - -all binary check install: $(sysroot)/etc/debian_version - $(in_sysroot) $(MAKE) -C $(top_builddir) $@ - -clean: - if [ -e $(sysroot)/etc/debian_version ]; then \ - $(in_sysroot) $(MAKE) -C $(top_builddir) $@; \ - else \ - $(MAKE) -C $(top_builddir) $@; \ - fi diff --git a/sysroot/install-dependencies.sh b/sysroot/install-dependencies.sh index 7dea20906350b2545fc235f2751646853e20651f..12b2d191ca544f5cbc680a2bb986c6fa83dcb506 100755 --- a/sysroot/install-dependencies.sh +++ b/sysroot/install-dependencies.sh @@ -42,6 +42,7 @@ apt-get -q -y --no-install-recommends install \ libelf-dev libelf-dev:i386 \ libipc-run-perl \ libjpeg62-turbo libjpeg62-turbo:i386 \ + meson \ perl \ xsltproc \ zlib1g zlib1g:i386 \ diff --git a/sysroot/run-in-sysroot.py b/sysroot/run-in-sysroot.py new file mode 100755 index 0000000000000000000000000000000000000000..948b1e3107cf58dd887fcc09c044b0e2635a5284 --- /dev/null +++ b/sysroot/run-in-sysroot.py @@ -0,0 +1,120 @@ +#!/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 logging +import os +import subprocess +import sys + +try: + import typing +except ImportError: + pass +else: + typing # silence pyflakes + + +logger = logging.getLogger('run-in-sysroot') + + +def main(): + # type: () -> int + + parser = argparse.ArgumentParser() + parser.add_argument('--srcdir', default='.') + parser.add_argument('--builddir', default='_build') + parser.add_argument('--sysroot', default=None) + parser.add_argument('--tarball', default=None) + parser.add_argument('command') + parser.add_argument('args', nargs=argparse.REMAINDER) + args = parser.parse_args() + + abs_srcdir = os.path.abspath(args.srcdir) + abs_builddir = os.path.abspath(args.builddir) + + if args.sysroot is None: + args.sysroot = os.path.join(abs_builddir, 'sysroot') + + if args.tarball is None: + args.tarball = os.path.join(abs_builddir, 'sysroot.tar.gz') + + abs_sysroot = os.path.abspath(args.sysroot) + + if not os.path.exists(os.path.join(abs_sysroot, 'usr', 'bin', 'env')): + if not os.path.exists(args.tarball): + logger.error( + 'A sysroot tarball (--tarball or %s) is required)', + args.tarball, + ) + return 1 + + os.makedirs(abs_sysroot, exist_ok=True) + subprocess.check_call([ + 'tar', + '-xvf', + args.tarball, + '--exclude=./dev/*', + '--exclude=dev/*', + '-C', abs_sysroot, + ]) + + os.makedirs(os.path.join(abs_sysroot, 'tmp'), exist_ok=True) + os.makedirs(os.path.join(abs_sysroot, 'home'), exist_ok=True) + os.makedirs( + os.path.join( + abs_sysroot, + 'var', 'cache', 'apt', 'archives', 'partial', + ), exist_ok=True, + ) + os.makedirs( + os.path.join(abs_sysroot, './' + abs_srcdir), exist_ok=True) + os.makedirs( + os.path.join(abs_sysroot, './' + abs_builddir), exist_ok=True) + + os.execvp( + 'bwrap', + [ + 'bwrap', + '--ro-bind', abs_sysroot, '/', + '--dev-bind', '/dev', '/dev', + '--ro-bind', '/etc/resolv.conf', '/etc/resolv.conf', + '--proc', '/proc', + '--tmpfs', '/tmp', + '--tmpfs', '/var/tmp', + '--tmpfs', '/home', + '--bind', abs_srcdir, abs_srcdir, + '--bind', abs_builddir, abs_builddir, + '--chdir', os.getcwd(), + '--setenv', 'LC_ALL', 'C.UTF-8', + args.command, + ] + args.args, + ) + + +if __name__ == '__main__': + sys.exit(main()) + +# vim:set sw=4 sts=4 et: diff --git a/t/mypy.sh b/t/mypy.sh index 64238232c5d8d8bbc7354defa93b4f059ae2d32e..3d0d9c44d2b38687bf2e415aa9a7596e27cec1bb 100755 --- a/t/mypy.sh +++ b/t/mypy.sh @@ -8,11 +8,20 @@ set -e set -u -export MYPYPATH="${PYTHONPATH:=$(pwd)}" +if [ -z "${G_TEST_SRCDIR-}" ]; then + me="$(readlink -f "$0")" + srcdir="${me%/*}" + G_TEST_SRCDIR="${srcdir%/*}" +fi + +cd "$G_TEST_SRCDIR" + +export MYPYPATH="${PYTHONPATH:="$(pwd)"}" i=0 for script in \ - ./*.py \ + "${G_TEST_SRCDIR}"/*.py \ + "${G_TEST_SRCDIR}"/sysroot/*.py \ ; do i=$((i + 1)) if [ "x${MYPY:="$(command -v mypy || echo false)"}" = xfalse ]; then diff --git a/t/pycodestyle.sh b/t/pycodestyle.sh index 04209a490165d2ea7db1de7a7e76bfbda5a5c3b4..f3481eddba5445dfec04b0fe66f3bf79dcee2386 100755 --- a/t/pycodestyle.sh +++ b/t/pycodestyle.sh @@ -8,6 +8,14 @@ set -e set -u +if [ -z "${G_TEST_SRCDIR-}" ]; then + me="$(readlink -f "$0")" + srcdir="${me%/*}" + G_TEST_SRCDIR="${srcdir%/*}" +fi + +cd "$G_TEST_SRCDIR" + if [ "x${PYCODESTYLE:=pycodestyle}" = xfalse ] || \ [ -z "$(command -v "$PYCODESTYLE")" ]; then echo "1..0 # SKIP pycodestyle not found" @@ -17,7 +25,8 @@ fi echo "1..1" if "${PYCODESTYLE}" \ - ./*.py \ + "$G_TEST_SRCDIR"/*.py \ + "${G_TEST_SRCDIR}"/sysroot/*.py \ >&2; then echo "ok 1 - $PYCODESTYLE reported no issues" else diff --git a/t/pyflakes.sh b/t/pyflakes.sh index f90936a6ab89eb5db7a0860de7d22853423b91ef..db2c87e91f7c938e40434f2f4707a156acbbcce8 100755 --- a/t/pyflakes.sh +++ b/t/pyflakes.sh @@ -8,11 +8,20 @@ set -e set -u +if [ -z "${G_TEST_SRCDIR-}" ]; then + me="$(readlink -f "$0")" + srcdir="${me%/*}" + G_TEST_SRCDIR="${srcdir%/*}" +fi + +cd "$G_TEST_SRCDIR" + if [ "x${PYFLAKES:=pyflakes3}" = xfalse ] || \ [ -z "$(command -v "$PYFLAKES")" ]; then echo "1..0 # SKIP pyflakes3 not found" elif "${PYFLAKES}" \ - ./*.py \ + "${G_TEST_SRCDIR}"/*.py \ + "${G_TEST_SRCDIR}"/sysroot/*.py \ >&2; then echo "1..1" echo "ok 1 - $PYFLAKES reported no issues" diff --git a/t/relocatable-install.sh b/t/relocatable-install.sh index c7fcba6c19a062e476ea042a2d73005af57635c2..9d9c1f571a76a06ade87ee7ee446cd11e4715cb0 100755 --- a/t/relocatable-install.sh +++ b/t/relocatable-install.sh @@ -1,6 +1,14 @@ #!/bin/sh set -eu +if [ -z "${G_TEST_SRCDIR-}" ]; then + me="$(readlink -f "$0")" + srcdir="${me%/*}" + G_TEST_SRCDIR="${srcdir%/*}" +fi + +: "${G_TEST_BUILDDIR:=.}" + n=0 failed= @@ -18,15 +26,17 @@ pressure-vessel-wrap pressure-vessel-unruntime " -if ! [ -e relocatable-install ]; then - echo "1..0 # SKIP relocatable-install not built" +relocatable_install="${G_TEST_BUILDDIR}/relocatable-install" + +if ! [ -e "${relocatable_install}" ]; then + echo "1..0 # SKIP relocatable-install not in expected location" exit 0 fi for exe in $EXES; do n=$(( n + 1 )) - if "relocatable-install/bin/$exe" --help >&2; then + if "${relocatable_install}/bin/$exe" --help >&2; then echo "ok $n - $exe --help" else echo "not ok $n - $exe --help" @@ -45,7 +55,7 @@ for basename in $MULTIARCH; do n=$(( n + 1 )) - if [ -x "relocatable-install/bin/$exe" ]; then + if [ -x "${relocatable_install}/bin/$exe" ]; then echo "ok $n - $exe exists and is executable" else echo "not ok $n - $exe not executable" @@ -58,7 +68,7 @@ for basename in $MULTIARCH; do echo "ok $n - $exe # SKIP: $ld_so not found" elif [ "$basename" = "capsule-symbols" ]; then echo "ok $n - $exe # SKIP: capsule-symbols has no --help yet" - elif "relocatable-install/bin/$exe" --help >&2; then + elif "${relocatable_install}/bin/$exe" --help >&2; then echo "ok $n - $exe --help" else echo "not ok $n - $exe --help" @@ -72,7 +82,7 @@ for exe in $SCRIPTS; do if ! [ -x /bin/bash ]; then echo "ok $n - $exe # SKIP Cannot run a bash script without bash" - elif "relocatable-install/bin/$exe" --help >&2; then + elif "${relocatable_install}/bin/$exe" --help >&2; then echo "ok $n - $exe --help" else echo "not ok $n - $exe --help" diff --git a/t/shellcheck.sh b/t/shellcheck.sh index 663b73dd5335dd4e8ee7f6bd783a404b81b27961..f5e72ef97fbf8f6e5f1a208893696a03950bf2ae 100755 --- a/t/shellcheck.sh +++ b/t/shellcheck.sh @@ -26,16 +26,18 @@ if ! command -v shellcheck >/dev/null 2>&1; then exit 0 fi -if [ -z "${TOP_SRCDIR-}" ]; then +if [ -z "${G_TEST_SRCDIR-}" ]; then me="$(readlink -f "$0")" srcdir="${me%/*}" - TOP_SRCDIR="${srcdir%/*}" + G_TEST_SRCDIR="${srcdir%/*}" fi -cd "$TOP_SRCDIR" +cd "$G_TEST_SRCDIR" n=0 for shell_script in \ + *.sh \ + sysroot/*.sh \ t/*.sh \ ; do n=$((n + 1))