#!/usr/bin/env python """ Shared functionality used by `client` and `server` when generating or preparing to generate SWIG on the local machine. """ # Future imports from __future__ import absolute_import from __future__ import print_function # Python modules import argparse import imp import io import logging import os import subprocess import sys import tempfile import zipfile # LLDB modules import use_lldb_suite # Package imports from lldbsuite.support import fs class LocalConfig(object): src_root = None target_dir = None languages = None swig_executable = None def pack_archive(bytes_io, src_root, filters): logging.info("Creating input file package...") zip_file = None try: # It's possible that a custom-built interpreter will not have the # standard zlib module. If so, we can only store, not compress. By # try to compress since we usually have a standard Python distribution. zip_file = zipfile.ZipFile(bytes_io, mode='w', compression=zipfile.ZIP_DEFLATED) except RuntimeError: zip_file = zipfile.ZipFile(bytes_io, mode='w', compression=zipfile.ZIP_STORED) archive_entries = [] if filters is not None: def filter_func(t): subfolder = t[0] ext = t[1] full_path = os.path.normpath(os.path.join(src_root, subfolder)) candidates = [os.path.normpath(os.path.join(full_path, f)) for f in os.listdir(full_path)] actual = filter( lambda f: os.path.isfile(f) and os.path.splitext(f)[1] == ext, candidates) return (subfolder, map(lambda f: os.path.basename(f), actual)) archive_entries = map(filter_func, filters) else: for (root, dirs, files) in os.walk(src_root): logging.debug("Adding files {} from directory {} to output package" .format(files, root)) if len(files) > 0: rel_root = os.path.relpath(root, src_root) archive_entries.append((rel_root, files)) archive_entries = list(archive_entries) for entry in archive_entries: subfolder = entry[0] files = list(entry[1]) for file in files: rel_path = os.path.normpath(os.path.join(subfolder, file)) full_path = os.path.join(src_root, rel_path) logging.info("{} -> {}".format(full_path, rel_path)) zip_file.write(full_path, rel_path) return zip_file def unpack_archive(folder, archive_bytes): zip_data = io.BytesIO(archive_bytes) logging.debug("Opening zip archive...") zip_file = zipfile.ZipFile(zip_data, mode='r') zip_file.extractall(folder) zip_file.close() def generate(options): include_folder = os.path.join(options.src_root, "include") in_file = os.path.join(options.src_root, "scripts", "lldb.swig") include_folder = os.path.normcase(include_folder) for lang in options.languages: lang = lang.lower() out_dir = os.path.join(options.target_dir, lang.title()) if not os.path.exists(out_dir): os.makedirs(out_dir) out_file = os.path.join(out_dir, "LLDBWrap{}.cpp".format(lang.title())) swig_command = [ options.swig_executable, "-c++", ] swig_command.append("-" + lang) if lang == "python": swig_command.append("-threads") swig_command.extend([ "-I" + include_folder, "-D__STDC_LIMIT_MACROS", "-D__STDC_CONSTANT_MACROS", "-outdir", out_dir, "-o", out_file, in_file ]) logging.info("generating swig {} bindings into {}" .format(lang, out_dir)) logging.debug("swig command line: {}".format(swig_command)) try: # Execute swig swig_output = subprocess.check_output( swig_command, stderr=subprocess.STDOUT, universal_newlines=True) logging.info("swig generation succeeded") if swig_output is not None and len(swig_output) > 0: logging.info("swig output: %s", swig_output) return (0, swig_output) except subprocess.CalledProcessError as e: logging.error("An error occurred executing swig. returncode={}" .format(e.returncode)) logging.error(e.output) return (e.returncode, e.output)