diff options
Diffstat (limited to 'debuginfo-tests/dexter/dex/builder/Builder.py')
-rw-r--r-- | debuginfo-tests/dexter/dex/builder/Builder.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/debuginfo-tests/dexter/dex/builder/Builder.py b/debuginfo-tests/dexter/dex/builder/Builder.py new file mode 100644 index 00000000000..a2bab863568 --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/Builder.py @@ -0,0 +1,117 @@ +# DExTer : Debugging Experience Tester +# ~~~~~~ ~ ~~ ~ ~~ +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +"""Deals with the processing execution of shell or batch build scripts.""" + +import os +import subprocess +import unittest + +from dex.dextIR import BuilderIR +from dex.utils import Timer +from dex.utils.Exceptions import BuildScriptException + + +def _quotify(text): + if '"' in text or ' ' not in text: + return text + return '"{}"'.format(text) + + +def _get_script_environment(source_files, compiler_options, + linker_options, executable_file): + + source_files = [_quotify(f) for f in source_files] + object_files = [ + _quotify('{}.o'.format(os.path.basename(f))) for f in source_files + ] + source_indexes = ['{:02d}'.format(i + 1) for i in range(len(source_files))] + + env_variables = {} + env_variables['SOURCE_INDEXES'] = ' '.join(source_indexes) + env_variables['SOURCE_FILES'] = ' '.join(source_files) + env_variables['OBJECT_FILES'] = ' '.join(object_files) + env_variables['LINKER_OPTIONS'] = linker_options + + for i, _ in enumerate(source_files): + index = source_indexes[i] + env_variables['SOURCE_FILE_{}'.format(index)] = source_files[i] + env_variables['OBJECT_FILE_{}'.format(index)] = object_files[i] + env_variables['COMPILER_OPTIONS_{}'.format(index)] = compiler_options[i] + + env_variables['EXECUTABLE_FILE'] = executable_file + + return env_variables + + +def run_external_build_script(context, script_path, source_files, + compiler_options, linker_options, + executable_file): + """Build an executable using a builder script. + + The executable is saved to `context.working_directory.path`. + + Returns: + ( stdout (str), stderr (str), builder (BuilderIR) ) + """ + + builderIR = BuilderIR( + name=context.options.builder, + cflags=compiler_options, + ldflags=linker_options, + ) + assert len(source_files) == len(compiler_options), (source_files, + compiler_options) + + script_environ = _get_script_environment(source_files, compiler_options, + linker_options, executable_file) + env = dict(os.environ) + env.update(script_environ) + try: + with Timer('running build script'): + process = subprocess.Popen( + [script_path], + cwd=context.working_directory.path, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = process.communicate() + returncode = process.returncode + if returncode != 0: + raise BuildScriptException( + '{}: failed with returncode {}.\nstdout:\n{}\n\nstderr:\n{}\n'. + format(script_path, returncode, out, err), + script_error=err) + return out.decode('utf-8'), err.decode('utf-8'), builderIR + except OSError as e: + raise BuildScriptException('{}: {}'.format(e.strerror, script_path)) + + +class TestBuilder(unittest.TestCase): + def test_get_script_environment(self): + source_files = ['a.a', 'b.b'] + compiler_options = ['-option1 value1', '-option2 value2'] + linker_options = '-optionX valueX' + executable_file = 'exe.exe' + env = _get_script_environment(source_files, compiler_options, + linker_options, executable_file) + + assert env['SOURCE_FILES'] == 'a.a b.b' + assert env['OBJECT_FILES'] == 'a.a.o b.b.o' + + assert env['SOURCE_INDEXES'] == '01 02' + assert env['LINKER_OPTIONS'] == '-optionX valueX' + + assert env['SOURCE_FILE_01'] == 'a.a' + assert env['SOURCE_FILE_02'] == 'b.b' + + assert env['OBJECT_FILE_01'] == 'a.a.o' + assert env['OBJECT_FILE_02'] == 'b.b.o' + + assert env['EXECUTABLE_FILE'] == 'exe.exe' + + assert env['COMPILER_OPTIONS_01'] == '-option1 value1' + assert env['COMPILER_OPTIONS_02'] == '-option2 value2' |