diff options
Diffstat (limited to '')
-rwxr-xr-x | src/boost/tools/build/test/MockToolset.py | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/src/boost/tools/build/test/MockToolset.py b/src/boost/tools/build/test/MockToolset.py new file mode 100755 index 000000000..834a56b0f --- /dev/null +++ b/src/boost/tools/build/test/MockToolset.py @@ -0,0 +1,267 @@ +#!/usr/bin/python + +# Copyright (C) 2013 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at +# https://www.bfgroup.xyz/b2/LICENSE.txt) + +import sys + +def create(t): + t.write('''mockinfo.py''', ''' +from __future__ import print_function +import re +import optparse +import os + +parser = optparse.OptionParser() +parser.add_option('-o', dest="output_file") +parser.add_option('-x', dest="language") +parser.add_option('-c', dest="compile", action="store_true") +parser.add_option('-I', dest="includes", action="append") +parser.add_option('-D', dest="defines", action="append") +parser.add_option('-L', dest="library_path", action="append") +parser.add_option('--dll', dest="dll", action="store_true") +parser.add_option('--archive', dest="archive", action="store_true") +parser.add_option('--static-lib', dest="static_libraries", action="append") +parser.add_option('--shared-lib', dest="shared_libraries", action="append") + +cwd = os.environ["JAM_CWD"] + +class MockInfo(object): + def __init__(self, verbose=False): + self.files = dict() + self.commands = list() + self.verbose = verbose + def source_file(self, name, pattern): + self.files[name] = pattern + def action(self, command, status=0): + if isinstance(command, str): + command = command.split() + self.commands.append((command, status)) + def check(self, command): + print("Testing command", command) + for (raw, status) in self.commands: + if self.matches(raw, command): + return status + def matches(self, raw, command): + (expected_options, expected_args) = parser.parse_args(raw) + options = command[0] + input_files = list(command[1]) + if self.verbose: + print(" - matching against", (expected_options, expected_args)) + if len(expected_args) != len(input_files): + if self.verbose: + print(" argument list sizes differ") + return False + for arg in expected_args: + if arg.startswith('$'): + fileid = arg[1:] + pattern = self.files[fileid] if fileid in self.files else fileid + matching_file = None + for input_file in input_files: + with open(input_file, 'r') as f: + contents = f.read() + if pattern == contents: + matching_file = input_file + break + if matching_file is not None: + input_files.remove(matching_file) + else: + if self.verbose: + print(" Failed to match input file contents: %s" % arg) + return False + else: + if arg in input_files: + input_files.remove(arg) + else: + if self.verbose: + print(" Failed to match input file: %s" % arg) + return False + + if options.language != expected_options.language: + if self.verbose: + print(" Failed to match -c") + return False + + if options.compile != expected_options.compile: + if self.verbose: + print(" Failed to match -x") + return False + + # Normalize a path for comparison purposes + def adjust_path(p): + return os.path.normcase(os.path.normpath(os.path.join(cwd, p))) + + # order matters + if options.includes is None: + options.includes = [] + if expected_options.includes is None: + expected_options.includes = [] + if list(map(adjust_path, options.includes)) != \ + list(map(adjust_path, expected_options.includes)): + if self.verbose: + print(" Failed to match -I ", list(map(adjust_path, options.includes)), \ + " != ", list(map(adjust_path, expected_options.includes))) + return False + + if options.defines is None: + options.defines = [] + if expected_options.defines is None: + expected_options.defines = [] + if options.defines != expected_options.defines: + if self.verbose: + print(" Failed to match -I ", options.defines, \ + " != ", expected_options.defines) + return False + + if options.library_path is None: + options.library_path = [] + if expected_options.library_path is None: + expected_options.library_path = [] + if list(map(adjust_path, options.library_path)) != \ + list(map(adjust_path, expected_options.library_path)): + if self.verbose: + print(" Failed to match -L ", list(map(adjust_path, options.library_path)), \ + " != ", list(map(adjust_path, expected_options.library_path))) + return False + + if options.static_libraries != expected_options.static_libraries: + if self.verbose: + print(" Failed to match --static-lib") + return False + + if options.shared_libraries != expected_options.shared_libraries: + if self.verbose: + print(" Failed to match --shared-lib") + return False + + if options.dll != expected_options.dll: + if self.verbose: + print(" Failed to match --dll") + return False + + if options.archive != expected_options.archive: + if self.verbose: + print(" Failed to match --archive") + return False + + # The output must be handled after everything else + # is validated + if expected_options.output_file is not None: + if options.output_file is not None: + if expected_options.output_file.startswith('$'): + fileid = expected_options.output_file[1:] + if fileid not in self.files: + self.files[fileid] = fileid + else: + assert(self.files[fileid] == fileid) + with open(options.output_file, 'w') as output: + output.write(fileid) + else: + if self.verbose: + print("Failed to match -o") + return False + elif options.output_file is not None: + if self.verbose: + print("Failed to match -o") + return False + + # if we've gotten here, then everything matched + if self.verbose: + print(" Matched") + return True +''') + + t.write('mock.py', ''' +from __future__ import print_function +import mockinfo +import markup +import sys + +status = markup.info.check(mockinfo.parser.parse_args()) +if status is not None: + exit(status) +else: + print("Unrecognized command: " + ' '.join(sys.argv)) + exit(1) +''') + + t.write('mock.jam', ''' +import feature ; +import toolset ; +import path ; +import modules ; +import common ; +import type ; + +.python-cmd = "\"%s\"" ; + +# Behave the same as gcc on Windows, because that's what +# the test system expects +type.set-generated-target-prefix SHARED_LIB : <toolset>mock <target-os>windows : lib ; +type.set-generated-target-suffix STATIC_LIB : <toolset>mock <target-os>windows : a ; + +rule init ( ) +{ + local here = [ path.make [ modules.binding $(__name__) ] ] ; + here = [ path.native [ path.root [ path.parent $(here) ] [ path.pwd ] ] ] ; + .config-cmd = [ common.variable-setting-command JAM_CWD : $(here) ] $(.python-cmd) -B ; +} + +feature.extend toolset : mock ; + +generators.register-c-compiler mock.compile.c++ : CPP : OBJ : <toolset>mock ; +generators.register-c-compiler mock.compile.c : C : OBJ : <toolset>mock ; + +generators.register-linker mock.link : LIB OBJ : EXE : <toolset>mock ; +generators.register-linker mock.link.dll : LIB OBJ : SHARED_LIB : <toolset>mock ; +generators.register-archiver mock.archive : OBJ : STATIC_LIB : <toolset>mock ; + +toolset.flags mock.compile OPTIONS <link>shared : -fPIC ; +toolset.flags mock.compile INCLUDES : <include> ; +toolset.flags mock.compile DEFINES : <define> ; + +actions compile.c +{ + $(.config-cmd) mock.py -c -x c -I"$(INCLUDES)" -D"$(DEFINES)" "$(>)" -o "$(<)" +} + +actions compile.c++ +{ + $(.config-cmd) mock.py -c -x c++ -I"$(INCLUDES)" -D"$(DEFINES)" "$(>)" -o "$(<)" +} + +toolset.flags mock.link USER_OPTIONS <linkflags> ; +toolset.flags mock.link FINDLIBS-STATIC <find-static-library> ; +toolset.flags mock.link FINDLIBS-SHARED <find-shared-library> ; +toolset.flags mock.link LINK_PATH <library-path> ; +toolset.flags mock.link LIBRARIES <library-file> ; + +actions link +{ + $(.config-cmd) mock.py "$(>)" -o "$(<)" $(USER_OPTIONS) -L"$(LINK_PATH)" --static-lib=$(FINDLIBS-STATIC) --shared-lib=$(FINDLIBS-SHARED) +} + +actions archive +{ + $(.config-cmd) mock.py --archive "$(>)" -o "$(<)" $(USER_OPTIONS) +} + +actions link.dll +{ + $(.config-cmd) mock.py --dll "$(>)" -o "$(<)" $(USER_OPTIONS) -L"$(LINK_PATH)" --static-lib=$(FINDLIBS-STATIC) --shared-lib=$(FINDLIBS-SHARED) +} + +''' % sys.executable.replace('\\', '\\\\')) + +def set_expected(t, markup): + verbose = "True" if t.verbose else "False" + t.write('markup.py', ''' +import mockinfo +info = mockinfo.MockInfo(%s) +def source_file(name, contents): + info.source_file(name, contents) +def action(command, status=0): + info.action(command, status) +''' % (verbose) + markup) |