diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/botan/src/scripts/install.py | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/botan/src/scripts/install.py')
-rwxr-xr-x | comm/third_party/botan/src/scripts/install.py | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/scripts/install.py b/comm/third_party/botan/src/scripts/install.py new file mode 100755 index 0000000000..32a7a7e9e8 --- /dev/null +++ b/comm/third_party/botan/src/scripts/install.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python + +""" +Botan install script + +(C) 2014,2015,2017 Jack Lloyd + +Botan is released under the Simplified BSD License (see license.txt) +""" + +import errno +import json +import logging +import optparse # pylint: disable=deprecated-module +import os +import shutil +import sys +import traceback + +def parse_command_line(args): + + parser = optparse.OptionParser() + + parser.add_option('--verbose', action='store_true', default=False, + help='Show debug messages') + parser.add_option('--quiet', action='store_true', default=False, + help='Show only warnings and errors') + + build_group = optparse.OptionGroup(parser, 'Source options') + build_group.add_option('--build-dir', metavar='DIR', default='build', + help='Location of build output (default \'%default\')') + parser.add_option_group(build_group) + + install_group = optparse.OptionGroup(parser, 'Installation options') + install_group.add_option('--prefix', default='/usr/local', + help='Set output directory (default %default)') + install_group.add_option('--bindir', default='bin', metavar='DIR', + help='Set binary subdir (default %default)') + install_group.add_option('--libdir', default='lib', metavar='DIR', + help='Set library subdir (default %default)') + install_group.add_option('--includedir', default='include', metavar='DIR', + help='Set include subdir (default %default)') + install_group.add_option('--docdir', default='share/doc', metavar='DIR', + help='Set documentation subdir (default %default)') + install_group.add_option('--pkgconfigdir', default='pkgconfig', metavar='DIR', + help='Set pkgconfig subdir (default %default)') + + install_group.add_option('--umask', metavar='MASK', default='022', + help='Umask to set (default %default)') + parser.add_option_group(install_group) + + (options, args) = parser.parse_args(args) + + def log_level(): + if options.verbose: + return logging.DEBUG + if options.quiet: + return logging.WARNING + return logging.INFO + + logging.getLogger().setLevel(log_level()) + + return (options, args) + + +class PrependDestdirError(Exception): + pass + + +def is_subdir(path, subpath): + return os.path.relpath(path, start=subpath).startswith("..") + + +def prepend_destdir(path): + """ + Needed because os.path.join() discards the first path if the + second one is absolute, which is usually the case here. Still, we + want relative paths to work and leverage the os awareness of + os.path.join(). + """ + destdir = os.environ.get('DESTDIR', "") + + if destdir: + # DESTDIR is non-empty, but we only join absolute paths on UNIX-like file systems + if os.path.sep != "/": + raise PrependDestdirError("Only UNIX-like file systems using forward slash " \ + "separator supported when DESTDIR is set.") + if not os.path.isabs(path): + raise PrependDestdirError("--prefix must be an absolute path when DESTDIR is set.") + + path = os.path.normpath(path) + # Remove / or \ prefixes if existent to accomodate for os.path.join() + path = path.lstrip(os.path.sep) + path = os.path.join(destdir, path) + + if not is_subdir(destdir, path): + raise PrependDestdirError("path escapes DESTDIR (path='%s', destdir='%s')" % (path, destdir)) + + return path + + +def makedirs(dirname, exist_ok=True): + try: + logging.debug('Creating directory %s' % (dirname)) + os.makedirs(dirname) + except OSError as e: + if e.errno != errno.EEXIST or not exist_ok: + raise e + +# Clear link and create new one +def force_symlink(target, linkname): + try: + os.unlink(linkname) + except OSError as e: + if e.errno != errno.ENOENT: + raise e + os.symlink(target, linkname) + +def calculate_exec_mode(options): + out = 0o777 + if 'umask' in os.__dict__: + umask = int(options.umask, 8) + logging.debug('Setting umask to %s' % oct(umask)) + os.umask(int(options.umask, 8)) + out &= (umask ^ 0o777) + return out + +def main(args): + # pylint: disable=too-many-locals,too-many-branches,too-many-statements + + logging.basicConfig(stream=sys.stdout, + format='%(levelname) 7s: %(message)s') + + (options, args) = parse_command_line(args) + + exe_mode = calculate_exec_mode(options) + + def copy_file(src, dst): + logging.debug('Copying %s to %s' % (src, dst)) + shutil.copyfile(src, dst) + + def copy_executable(src, dst): + copy_file(src, dst) + logging.debug('Make %s executable' % dst) + os.chmod(dst, exe_mode) + + with open(os.path.join(options.build_dir, 'build_config.json')) as f: + cfg = json.load(f) + + ver_major = int(cfg['version_major']) + ver_minor = int(cfg['version_minor']) + ver_patch = int(cfg['version_patch']) + target_os = cfg['os'] + build_shared_lib = bool(cfg['build_shared_lib']) + build_static_lib = bool(cfg['build_static_lib']) + build_cli = bool(cfg['build_cli_exe']) + out_dir = cfg['out_dir'] + + bin_dir = options.bindir + lib_dir = options.libdir + target_include_dir = os.path.join(options.prefix, + options.includedir, + 'botan-%d' % (ver_major), + 'botan') + + for d in [options.prefix, lib_dir, bin_dir, target_include_dir]: + makedirs(prepend_destdir(d)) + + build_include_dir = os.path.join(options.build_dir, 'include', 'botan') + + for include in sorted(os.listdir(build_include_dir)): + if include == 'internal': + continue + copy_file(os.path.join(build_include_dir, include), + prepend_destdir(os.path.join(target_include_dir, include))) + + build_external_include_dir = os.path.join(options.build_dir, 'include', 'external') + + for include in sorted(os.listdir(build_external_include_dir)): + copy_file(os.path.join(build_external_include_dir, include), + prepend_destdir(os.path.join(target_include_dir, include))) + + if build_static_lib or target_os == 'windows': + static_lib = cfg['static_lib_name'] + copy_file(os.path.join(out_dir, static_lib), + prepend_destdir(os.path.join(lib_dir, os.path.basename(static_lib)))) + + if build_shared_lib: + if target_os == "windows": + libname = cfg['libname'] + soname_base = libname + '.dll' + copy_executable(os.path.join(out_dir, soname_base), + prepend_destdir(os.path.join(bin_dir, soname_base))) + else: + soname_patch = cfg['soname_patch'] + soname_abi = cfg['soname_abi'] + soname_base = cfg['soname_base'] + + copy_executable(os.path.join(out_dir, soname_patch), + prepend_destdir(os.path.join(lib_dir, soname_patch))) + + if target_os != "openbsd": + prev_cwd = os.getcwd() + try: + os.chdir(prepend_destdir(lib_dir)) + force_symlink(soname_patch, soname_abi) + force_symlink(soname_patch, soname_base) + finally: + os.chdir(prev_cwd) + + if build_cli: + copy_executable(cfg['cli_exe'], prepend_destdir(os.path.join(bin_dir, cfg['cli_exe_name']))) + + if 'botan_pkgconfig' in cfg: + pkgconfig_dir = os.path.join(options.prefix, options.libdir, options.pkgconfigdir) + makedirs(prepend_destdir(pkgconfig_dir)) + copy_file(cfg['botan_pkgconfig'], + prepend_destdir(os.path.join(pkgconfig_dir, os.path.basename(cfg['botan_pkgconfig'])))) + + if 'ffi' in cfg['mod_list'] and cfg['build_shared_lib'] is True and cfg['install_python_module'] is True: + for ver in cfg['python_version'].split(','): + py_lib_path = os.path.join(lib_dir, 'python%s' % (ver), 'site-packages') + logging.debug('Installing python module to %s' % (py_lib_path)) + makedirs(prepend_destdir(py_lib_path)) + + py_dir = cfg['python_dir'] + + copy_file(os.path.join(py_dir, 'botan2.py'), + prepend_destdir(os.path.join(py_lib_path, 'botan2.py'))) + + if cfg['with_documentation']: + target_doc_dir = os.path.join(options.prefix, options.docdir, + 'botan-%d.%d.%d' % (ver_major, ver_minor, ver_patch)) + + shutil.rmtree(prepend_destdir(target_doc_dir), True) + shutil.copytree(cfg['doc_output_dir'], prepend_destdir(target_doc_dir)) + + copy_file(os.path.join(cfg['base_dir'], 'license.txt'), + prepend_destdir(os.path.join(target_doc_dir, 'license.txt'))) + copy_file(os.path.join(cfg['base_dir'], 'news.rst'), + prepend_destdir(os.path.join(target_doc_dir, 'news.txt'))) + for f in [f for f in os.listdir(cfg['doc_dir']) if f.endswith('.txt')]: + copy_file(os.path.join(cfg['doc_dir'], f), prepend_destdir(os.path.join(target_doc_dir, f))) + + if cfg['with_rst2man']: + man1_dir = prepend_destdir(os.path.join(options.prefix, os.path.join(cfg['mandir'], 'man1'))) + makedirs(man1_dir) + + copy_file(os.path.join(cfg['build_dir'], 'botan.1'), + os.path.join(man1_dir, 'botan.1')) + + logging.info('Botan %s installation complete', cfg['version']) + return 0 + +if __name__ == '__main__': + try: + sys.exit(main(sys.argv)) + except Exception as e: # pylint: disable=broad-except + logging.error('Failure: %s' % (e)) + logging.info(traceback.format_exc()) + sys.exit(1) |