Stephen Tozer 5647f2908d Revert "Reapply "[Dexter] Remove builder from Dexter""
Re-application of the Dexter builder removal reversed due to continued
errors on the green dragon LLDB buildbot:
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/59716/

Cause of the error is unclear, but it looks as though there is some
unexpected non-determinism in the test failures.

This reverts commit 323270451d8db24f2c816f455b3d8f70f434286d.
2023-09-05 15:18:09 +01:00

128 lines
4.1 KiB
Python

# 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
out = out.decode("utf-8")
err = err.decode("utf-8")
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, err, 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"