diff options
Diffstat (limited to 'debuginfo-tests/dexter/dex/builder')
7 files changed, 255 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' diff --git a/debuginfo-tests/dexter/dex/builder/ParserOptions.py b/debuginfo-tests/dexter/dex/builder/ParserOptions.py new file mode 100644 index 00000000000..b6677aac549 --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/ParserOptions.py @@ -0,0 +1,56 @@ +# 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 +"""Command line options for subtools that use the builder component.""" + +import os + +from dex.tools import Context +from dex.utils import is_native_windows + + +def _find_build_scripts(): + """Finds build scripts in the 'scripts' subdirectory. + + Returns: + { script_name (str): directory (str) } + """ + try: + return _find_build_scripts.cached + except AttributeError: + scripts_directory = os.path.join(os.path.dirname(__file__), 'scripts') + if is_native_windows(): + scripts_directory = os.path.join(scripts_directory, 'windows') + else: + scripts_directory = os.path.join(scripts_directory, 'posix') + assert os.path.isdir(scripts_directory), scripts_directory + results = {} + + for f in os.listdir(scripts_directory): + results[os.path.splitext(f)[0]] = os.path.abspath( + os.path.join(scripts_directory, f)) + + _find_build_scripts.cached = results + return results + + +def add_builder_tool_arguments(parser): + parser.add_argument('--binary', + metavar="<file>", + help='provide binary file to override --builder') + + parser.add_argument( + '--builder', + type=str, + choices=sorted(_find_build_scripts().keys()), + help='test builder to use') + parser.add_argument( + '--cflags', type=str, default='', help='compiler flags') + parser.add_argument('--ldflags', type=str, default='', help='linker flags') + + +def handle_builder_tool_options(context: Context) -> str: + return _find_build_scripts()[context.options.builder] diff --git a/debuginfo-tests/dexter/dex/builder/__init__.py b/debuginfo-tests/dexter/dex/builder/__init__.py new file mode 100644 index 00000000000..3bf0ca40f5c --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/__init__.py @@ -0,0 +1,10 @@ +# 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 + +from dex.builder.Builder import run_external_build_script +from dex.builder.ParserOptions import add_builder_tool_arguments +from dex.builder.ParserOptions import handle_builder_tool_options diff --git a/debuginfo-tests/dexter/dex/builder/scripts/posix/clang-c.sh b/debuginfo-tests/dexter/dex/builder/scripts/posix/clang-c.sh new file mode 100755 index 00000000000..f69f51cd86a --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/scripts/posix/clang-c.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -e + +if test -z "$PATHTOCLANG"; then + PATHTOCLANG=clang +fi + +for INDEX in $SOURCE_INDEXES +do + CFLAGS=$(eval echo "\$COMPILER_OPTIONS_$INDEX") + SRCFILE=$(eval echo "\$SOURCE_FILE_$INDEX") + OBJFILE=$(eval echo "\$OBJECT_FILE_$INDEX") + $PATHTOCLANG -std=gnu11 -c $CFLAGS $SRCFILE -o $OBJFILE +done + +$PATHTOCLANG $LINKER_OPTIONS $OBJECT_FILES -o $EXECUTABLE_FILE diff --git a/debuginfo-tests/dexter/dex/builder/scripts/posix/clang.sh b/debuginfo-tests/dexter/dex/builder/scripts/posix/clang.sh new file mode 100755 index 00000000000..9cf4cdd65f7 --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/scripts/posix/clang.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -e + +if test -z "$PATHTOCLANGPP"; then + PATHTOCLANGPP=clang++ +fi + +for INDEX in $SOURCE_INDEXES +do + CFLAGS=$(eval echo "\$COMPILER_OPTIONS_$INDEX") + SRCFILE=$(eval echo "\$SOURCE_FILE_$INDEX") + OBJFILE=$(eval echo "\$OBJECT_FILE_$INDEX") + $PATHTOCLANGPP -std=gnu++11 -c $CFLAGS $SRCFILE -o $OBJFILE +done + +$PATHTOCLANGPP $LINKER_OPTIONS $OBJECT_FILES -o $EXECUTABLE_FILE diff --git a/debuginfo-tests/dexter/dex/builder/scripts/windows/clang-cl_vs2015.bat b/debuginfo-tests/dexter/dex/builder/scripts/windows/clang-cl_vs2015.bat new file mode 100644 index 00000000000..ea0d4414d26 --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/scripts/windows/clang-cl_vs2015.bat @@ -0,0 +1,23 @@ +@echo OFF +setlocal EnableDelayedExpansion + +call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat" + +@echo OFF +setlocal EnableDelayedExpansion + +for %%I in (%SOURCE_INDEXES%) do ( + %PATHTOCLANGCL% /c !COMPILER_OPTIONS_%%I! !SOURCE_FILE_%%I! /Fo!OBJECT_FILE_%%I! + if errorlevel 1 goto :FAIL +) + +%PATHTOCLANGCL% %LINKER_OPTIONS% %OBJECT_FILES% /Fe%EXECUTABLE_FILE% +if errorlevel 1 goto :FAIL +goto :END + +:FAIL +echo FAILED +exit /B 1 + +:END +exit /B 0 diff --git a/debuginfo-tests/dexter/dex/builder/scripts/windows/clang.bat b/debuginfo-tests/dexter/dex/builder/scripts/windows/clang.bat new file mode 100644 index 00000000000..a83e4d4c1bb --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/scripts/windows/clang.bat @@ -0,0 +1,17 @@ +setlocal EnableDelayedExpansion + +for %%I in (%SOURCE_INDEXES%) do ( + %PATHTOCLANGPP% -fuse-ld=lld -c !COMPILER_OPTIONS_%%I! !SOURCE_FILE_%%I! -o !OBJECT_FILE_%%I! + if errorlevel 1 goto :FAIL +) + +%PATHTOCLANGPP% -fuse-ld=lld %LINKER_OPTIONS% %OBJECT_FILES% -o %EXECUTABLE_FILE% +if errorlevel 1 goto :FAIL +goto :END + +:FAIL +echo FAILED +exit /B 1 + +:END +exit /B 0 |