diff --git a/Makefile b/Makefile index 92a75922e0307b3067dc2f55ead7e474d3c34f6e..60b68907e60725246cecafda343f6ad431526af7 100644 --- a/Makefile +++ b/Makefile @@ -10,46 +10,10 @@ _relocatabledir = endif install: - rm -fr relocatable-install - $(MAKE) install-amd64 install-i386 - install pressure-vessel-unruntime relocatable-install/bin/ - install pressure-vessel-wrap relocatable-install/bin/ - mkdir -p relocatable-install/sources - install -m644 THIRD-PARTY.md relocatable-install/sources/README.txt - install -m644 libcapsule/debian/copyright relocatable-install/sources/capsule-capture-libs.txt - install -m644 /usr/share/doc/zlib1g/copyright relocatable-install/sources/libz.txt - install -m644 /usr/share/doc/libelf1/copyright relocatable-install/sources/libelf.txt - dcmd install -m644 libcapsule*.dsc relocatable-install/sources/ - cd relocatable-install/sources; \ - apt-get --download-only source elfutils zlib - -install-%: - mkdir -p relocatable-install/bin - set -eu; \ - dhm="$$(dpkg-architecture -a"$*" -qDEB_HOST_MULTIARCH)"; \ - mkdir -p "relocatable-install/lib/$${dhm}"; \ - if [ -n "$(_relocatabledir)" ]; then \ - install $(_relocatabledir)/$${dhm}-capsule-capture-libs _build/; \ - install $(_relocatabledir)/$${dhm}-capsule-symbols _build/; \ - else \ - $(MAKE) -f Makefile.libcapsule $*; \ - install "_build/$*/libcapsule/capsule-capture-libs" "_build/$${dhm}-capsule-capture-libs"; \ - install "_build/$*/libcapsule/capsule-symbols" "_build/$${dhm}-capsule-symbols"; \ - chrpath -r "\$${ORIGIN}/../lib/$${dhm}" "_build/$${dhm}"-*; \ - install "_build/$${dhm}-capsule-capture-libs" relocatable-install/bin; \ - install "_build/$${dhm}-capsule-symbols" relocatable-install/bin; \ - fi; \ - mkdir -p _build/$*/lib; \ - "relocatable-install/bin/$${dhm}-capsule-capture-libs" \ - --dest=_build/$*/lib \ - --no-glibc \ - "soname:libelf.so.1" \ - "soname:libz.so.1" \ - $(NULL); \ - cp -a --dereference _build/$*/lib/*.so.* "relocatable-install/lib/$${dhm}" + ./build-relocatable-install.py $(_relocatabledir) check: - prove -v t/ + prove -v t/*.sh binary: $(MAKE) install diff --git a/THIRD-PARTY.md b/THIRD-PARTY.md index ae8f8e05f4031a516d27927ba03a979f7c8abee1..2cdb3204d59625f300d1019839666fc109820b06 100644 --- a/THIRD-PARTY.md +++ b/THIRD-PARTY.md @@ -3,7 +3,7 @@ Third-party modules pressure-vessel includes the capsule-capture-libs utility from libcapsule, which is licensed under [LGPL-2.1-or-later][]. See -capsule-capture-libs.txt. Complete source code can be obtained from the +libcapsule.txt. Complete source code can be obtained from the same place as pressure-vessel, or from <https://gitlab.collabora.com/vivek/libcapsule/>. @@ -11,9 +11,9 @@ Binary releases of pressure-vessel include the following third-party libraries: - libelf.so.1 from Red Hat elfutils: [GPL-2.0-or-later][] with linking - exception. See libelf.txt. + exception. See elfutils.txt. -- libz.so.1 from zlib: [Zlib][] license. See libz.txt. +- libz.so.1 from zlib: [Zlib][] license. See zlib.txt. Complete source code can be obtained from the same place as pressure-vessel, or from diff --git a/build-relocatable-install.py b/build-relocatable-install.py new file mode 100755 index 0000000000000000000000000000000000000000..2e2a0e0e4263d962ad0e48bb5defd584365fa596 --- /dev/null +++ b/build-relocatable-install.py @@ -0,0 +1,209 @@ +#!/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 glob +import os +import re +import shutil +import subprocess + +try: + import typing +except ImportError: + pass +else: + typing # silence pyflakes + + +# Debian architecture => Debian multiarch tuple +ARCHS = { + 'amd64': 'x86_64-linux-gnu', + 'i386': 'i386-linux-gnu', +} +# package to install from => source package for copyright information +DEPENDENCIES = { + 'libcapsule-tools-relocatable': 'libcapsule', + 'libelf1': 'elfutils', + 'zlib1g': 'zlib', +} +DESTDIR = 'relocatable-install' +SCRIPTS = ('pressure-vessel-unruntime', 'pressure-vessel-wrap') +TOOLS = ('capsule-capture-libs', 'capsule-symbols') + + +def install(src, dst, mode=0o644): + # type: (str, str, int) -> None + shutil.copy(src, dst) + + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + + os.chmod(dst, mode) + + +def install_exe(src, dst, mode=0o755): + # type: (str, str, int) -> None + install(src, dst, mode) + + +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('relocatabledir', default=None, nargs='?') + args = parser.parse_args() + + if os.path.exists(DESTDIR): + shutil.rmtree(DESTDIR) + + os.makedirs(os.path.join(DESTDIR, 'bin'), exist_ok=True) + os.makedirs(os.path.join(DESTDIR, 'sources'), exist_ok=True) + + for ma in ARCHS.values(): + os.makedirs( + os.path.join(DESTDIR, 'lib', ma), + exist_ok=True, + ) + + for script in SCRIPTS: + install_exe(script, os.path.join(DESTDIR, 'bin')) + + install( + 'THIRD-PARTY.md', + os.path.join(DESTDIR, 'sources', 'README.txt'), + 0o644, + ) + + if args.relocatabledir is not None: + for arch, ma in ARCHS.items(): + for tool in TOOLS: + install_exe( + os.path.join( + args.relocatabledir, + '{}-{}'.format(ma, tool), + ), + os.path.join(DESTDIR, 'bin'), + ) + + install( + '/usr/share/doc/libcapsule-tools-relocatable/copyright', + os.path.join(DESTDIR, 'sources', 'libcapsule.txt'), + ) + else: + v_check_call(['make', '-f', 'Makefile.libcapsule']) + + for arch, ma in ARCHS.items(): + for tool in TOOLS: + install_exe( + os.path.join('_build', arch, 'libcapsule', tool), + os.path.join('_build', '{}-{}'.format(ma, tool)), + ) + v_check_call([ + 'chrpath', '-r', + '${ORIGIN}/../lib/' + ma, + os.path.join('_build', '{}-{}'.format(ma, tool)), + ]) + install_exe( + os.path.join('_build', '{}-{}'.format(ma, tool)), + os.path.join(DESTDIR, 'bin'), + ) + + install( + os.path.join('libcapsule', 'debian', 'copyright'), + os.path.join(DESTDIR, 'sources', 'libcapsule.txt'), + ) + + for dsc in glob.glob('libcapsule*.dsc'): + v_check_call([ + 'dcmd', 'install', '-m644', dsc, + os.path.join(DESTDIR, 'sources'), + ]) + + for arch, ma in ARCHS.items(): + os.makedirs(os.path.join('_build', arch, 'lib'), exist_ok=True) + v_check_call([ + '{}/bin/{}-capsule-capture-libs'.format(DESTDIR, ma), + '--dest=_build/{}/lib'.format(arch), + '--no-glibc', + 'soname:libelf.so.1', + 'soname:libz.so.1', + ]) + + for so in glob.glob( + os.path.join('_build', arch, 'lib', '*.so.*'), + ): + install(so, os.path.join(DESTDIR, 'lib', 'ma')) + + source_to_download = set() # type: typing.Set[str] + + for package, source in DEPENDENCIES.items(): + if args.relocatabledir is None and source == 'libcapsule': + continue + + install( + '/usr/share/doc/{}/copyright'.format(package), + os.path.join(DESTDIR, 'sources', '{}.txt'.format(source)), + ) + install( + '/usr/share/doc/{}/copyright'.format(package), + os.path.join(DESTDIR, 'sources', '{}.txt'.format(source)), + ) + + for expr in set( + v_check_output([ + 'dpkg-query', + '-W', + '-f', '${source:Package}=${source:Version}\n', + package, + ], universal_newlines=True).splitlines() + ): + source_to_download.add(re.sub(r'[+]srt[0-9a-z.]+$', '', expr)) + + v_check_call( + [ + 'apt-get', + '--download-only', + '--only-source', + 'source', + ] + list(source_to_download), + cwd=os.path.join(DESTDIR, 'sources'), + ) + + +if __name__ == '__main__': + main() + +# vim:set sw=4 sts=4 et: diff --git a/t/mypy.sh b/t/mypy.sh new file mode 100755 index 0000000000000000000000000000000000000000..64238232c5d8d8bbc7354defa93b4f059ae2d32e --- /dev/null +++ b/t/mypy.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Copyright © 2016-2018 Simon McVittie +# Copyright © 2018 Collabora Ltd. +# +# SPDX-License-Identifier: MIT +# (See build-relocatable-install.py) + +set -e +set -u + +export MYPYPATH="${PYTHONPATH:=$(pwd)}" + +i=0 +for script in \ + ./*.py \ +; do + i=$((i + 1)) + if [ "x${MYPY:="$(command -v mypy || echo false)"}" = xfalse ]; then + echo "ok $i - $script # SKIP mypy not found" + elif "${MYPY}" \ + --python-executable="${PYTHON:=python3}" \ + --follow-imports=skip \ + --ignore-missing-imports \ + "$script"; then + echo "ok $i - $script" + else + echo "not ok $i - $script # TODO mypy issues reported" + fi +done +echo "1..$i" + +# vim:set sw=4 sts=4 et: diff --git a/t/pycodestyle.sh b/t/pycodestyle.sh new file mode 100755 index 0000000000000000000000000000000000000000..04209a490165d2ea7db1de7a7e76bfbda5a5c3b4 --- /dev/null +++ b/t/pycodestyle.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# Copyright © 2016-2018 Simon McVittie +# Copyright © 2018 Collabora Ltd. +# +# SPDX-License-Identifier: MIT +# (See build-relocatable-install.py) + +set -e +set -u + +if [ "x${PYCODESTYLE:=pycodestyle}" = xfalse ] || \ + [ -z "$(command -v "$PYCODESTYLE")" ]; then + echo "1..0 # SKIP pycodestyle not found" + exit 0 +fi + +echo "1..1" + +if "${PYCODESTYLE}" \ + ./*.py \ + >&2; then + echo "ok 1 - $PYCODESTYLE reported no issues" +else + echo "not ok 1 # TODO $PYCODESTYLE issues reported" +fi + +# vim:set sw=4 sts=4 et: diff --git a/t/pyflakes.sh b/t/pyflakes.sh new file mode 100755 index 0000000000000000000000000000000000000000..f90936a6ab89eb5db7a0860de7d22853423b91ef --- /dev/null +++ b/t/pyflakes.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# Copyright © 2016-2018 Simon McVittie +# Copyright © 2018 Collabora Ltd. +# +# SPDX-License-Identifier: MIT +# (See build-relocatable-install.py) + +set -e +set -u + +if [ "x${PYFLAKES:=pyflakes3}" = xfalse ] || \ + [ -z "$(command -v "$PYFLAKES")" ]; then + echo "1..0 # SKIP pyflakes3 not found" +elif "${PYFLAKES}" \ + ./*.py \ + >&2; then + echo "1..1" + echo "ok 1 - $PYFLAKES reported no issues" +else + echo "1..1" + echo "not ok 1 # TODO $PYFLAKES issues reported" +fi + +# vim:set sw=4 sts=4 et: diff --git a/t/shellcheck.t b/t/shellcheck.sh similarity index 94% rename from t/shellcheck.t rename to t/shellcheck.sh index 4fe7fcb3d57eeacdfc26ef0ab893eda1021cfd6b..663b73dd5335dd4e8ee7f6bd783a404b81b27961 100755 --- a/t/shellcheck.t +++ b/t/shellcheck.sh @@ -36,9 +36,7 @@ cd "$TOP_SRCDIR" n=0 for shell_script in \ - pressure-vessel-wrap \ - sysroot/*.sh \ - t/shellcheck.t \ + t/*.sh \ ; do n=$((n + 1))