mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:50:14 +01:00
This also switches to a more Bazel-based install layout, skipping the FHS-based synthetic layout. The FHS-based layout is still reconstructed explicitly when building an installable tar-ball. The biggest change is to configure the just-built install as a Bazel toolchain, including allowing it to build its own runtime libraries as native Bazel libraries. This removes the need for a monolithic runtimes build, all of that code logic is removed. This should also pave the way to using the just-built toolchain for doing a full 3-stage bootstrap. Building the 2nd stage is included here as it was a particularly effective way to test that the Bazel integration was fully working. Adding a 3rd-stage check for stability is future work, but should be pretty easy. There is a down-side: this uses the busybox to do the runtimes compilation, which means they will be re-built after ~any change to Carbon. However, the integration with Bazel should largely pay for this, and we can continue to factor the tests away from depending on built runtimes in most cases. Now that we're building and testing the runtimes more directly, this surfaced a problem with the layout of runtimes on macOS that is fixed here. All of the Darwin OSes use a custom layout for their resource directory compared to other targets. We now model this in both the C++ built runtimes and the Bazel built runtimes. Assisted-by: Gemini via Antigravity
85 lines
2.8 KiB
Python
Executable File
85 lines
2.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
"""Checks various LLVM tool symlinks behave as expected."""
|
|
|
|
__copyright__ = """
|
|
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
Exceptions. See /LICENSE for license information.
|
|
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import unittest
|
|
from bazel_tools.tools.python.runfiles import runfiles
|
|
from bazel_integration_test.py import test_base
|
|
|
|
|
|
class BazelExampleTest(test_base.TestBase):
|
|
def setUp(self) -> None:
|
|
test_base.TestBase.setUp(self)
|
|
self.runfiles = runfiles.Create()
|
|
self.install_module = self.runfiles.Rlocation(
|
|
"carbon/toolchain/install"
|
|
)
|
|
self.startup_flags = [
|
|
"--ignore_all_rc_files",
|
|
"--batch",
|
|
]
|
|
self.flags = [
|
|
f"--override_module=carbon_toolchain={self.install_module}"
|
|
]
|
|
|
|
def _run_bazel(self, command: list[str]) -> str:
|
|
"""Runs bazel with retry logic for transient errors."""
|
|
for attempt in range(5):
|
|
exit_code, stdout, stderr = self.RunBazel(
|
|
self.startup_flags + command + self.flags
|
|
)
|
|
|
|
# Several error codes are reliably permanent, break immediately.
|
|
# `1` -- The build failed.
|
|
# `2` -- Command line or environment problem.
|
|
# `3` -- Tests failed or timed out, we don't retry at this layer
|
|
# on execution timeout.
|
|
# `4` -- Test command but no tests found.
|
|
# `8` -- Explicitly interrupted build.
|
|
#
|
|
# Note that `36` is documented as "likely permanent", but we retry
|
|
# it as most of our transient failures actually produce that error
|
|
# code.
|
|
perm_error = (1, 2, 3, 4, 8)
|
|
if exit_code in perm_error:
|
|
break
|
|
|
|
for line in stderr:
|
|
print(line, file=sys.stderr)
|
|
|
|
if exit_code == 0:
|
|
return stdout
|
|
|
|
# Retry transient errors with a brief delay.
|
|
print(f"Attempt {attempt + 1} failed with exit code {exit_code}")
|
|
time.sleep(attempt)
|
|
|
|
self.AssertExitCode(exit_code, 0, stderr)
|
|
return stdout
|
|
|
|
def test_compile_lib(self) -> None:
|
|
# TODO: Can remove this in favor of always running `test_run` if we can
|
|
# make linking a binary sufficiently efficient.
|
|
self._run_bazel(["build", "//:example_lib"])
|
|
|
|
@unittest.skipUnless(
|
|
"CARBON_BAZEL_TEST_FULL" in os.environ,
|
|
"Skipping expensive test step for minimal testing",
|
|
)
|
|
def test_run(self) -> None:
|
|
stdout = self._run_bazel(["run", "//:example"])
|
|
self.assertEqual(stdout, ["Hello World!"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|