From 19efec93be6385db1a561fe0781eb6e5834ba7c4 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Thu, 9 Apr 2026 14:49:19 -0700 Subject: [PATCH] Fix missing runtimes file in the installation (#7044) Fixes #7031 Also switches the previous symlinks test to be a more full integration test. While a bit slow, it does seem worthwhile to have something that tests things end-to-end, both with the prebuilt runtimes and the on-demand runtimes. This test is already reasonably well separated from the rest of the toolchain so incremental development shouldn't be negatively impacted. And since we turned off ASan by default, it isn't completely infeasibly expensive. Assisted-by: Antigravity with Gemini --- toolchain/install/BUILD | 8 +- ...{llvm_symlinks_test.py => install_test.py} | 94 ++++++++++++++++++- 2 files changed, 97 insertions(+), 5 deletions(-) rename toolchain/install/{llvm_symlinks_test.py => install_test.py} (58%) diff --git a/toolchain/install/BUILD b/toolchain/install/BUILD index 0ad5e615b481..419c0e32d033 100644 --- a/toolchain/install/BUILD +++ b/toolchain/install/BUILD @@ -342,6 +342,7 @@ filegroup( ":libcxx_hdrs", ":libcxxabi_hdrs", ":libcxxabi_srcs", + ":libcxxabi_textual_srcs", ":libunwind_hdrs", ":libunwind_srcs", ], @@ -728,11 +729,12 @@ filegroup( ) py_test( - name = "llvm_symlinks_test", - size = "small", - srcs = ["llvm_symlinks_test.py"], + name = "install_test", + size = "large", + srcs = ["install_test.py"], data = [ ":built_runtimes", + ":carbon-busybox", ":install_data", ], deps = ["@bazel_tools//tools/python/runfiles"], diff --git a/toolchain/install/llvm_symlinks_test.py b/toolchain/install/install_test.py similarity index 58% rename from toolchain/install/llvm_symlinks_test.py rename to toolchain/install/install_test.py index dd94beae56ec..d7d1e562a7b4 100644 --- a/toolchain/install/llvm_symlinks_test.py +++ b/toolchain/install/install_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -"""Checks various LLVM tool symlinks behave as expected.""" +"""Integration tests for the Carbon toolchain installation.""" __copyright__ = """ Part of the Carbon Language project, under the Apache License v2.0 with LLVM @@ -13,11 +13,12 @@ import subprocess import os import platform import sys +import textwrap import unittest from bazel_tools.tools.python.runfiles import runfiles -class LLVMSymlinksTest(unittest.TestCase): +class InstallTest(unittest.TestCase): def setUp(self) -> None: # The install root is adjacent to the test script self.install_root = Path(sys.argv[0]).parent @@ -118,6 +119,95 @@ class LLVMSymlinksTest(unittest.TestCase): self.assertEqual(run.stderr, "") self.assertRegex(run.stdout, r"(^|\n)SUCCESS\n") + def run_carbon_test( + self, name: str, source: str, use_prebuilt: bool, expected_output: str + ) -> None: + src_file = self.tmpdir / f"{name}.carbon" + src_file.write_text(textwrap.dedent(source).lstrip()) + + output_bin = self.tmpdir / name + + carbon = self.runfiles.Rlocation( + "carbon/toolchain/install/carbon-busybox" + ) + + try: + obj_file = self.tmpdir / f"{name}.o" + subprocess.run( + [carbon, "compile", f"--output={obj_file}", src_file], + check=True, + capture_output=True, + text=True, + ) + + link_cmd = [carbon] + if use_prebuilt: + link_cmd.append(f"--prebuilt-runtimes={self.prebuilt_runtimes}") + link_cmd.extend(["link", f"--output={output_bin}", obj_file]) + subprocess.run(link_cmd, check=True, capture_output=True, text=True) + except subprocess.CalledProcessError as err: + self.fail(f"Subprocess failed: {err.stderr}") + + run = subprocess.run( + [output_bin], check=True, capture_output=True, text=True + ) + self.assertEqual(run.returncode, 0) + self.assertEqual(run.stdout.strip(), expected_output) + + def run_cpp_test( + self, name: str, source: str, use_prebuilt: bool, expected_output: str + ) -> None: + src_file = self.tmpdir / f"{name}.cpp" + src_file.write_text(textwrap.dedent(source).lstrip()) + + output_bin = self.tmpdir / name + + clang = self.install_root / "llvm/bin/clang++" + + try: + cmd = [clang, f"-o{output_bin}", src_file] + if use_prebuilt: + cmd.append( + f"-Xcarbon=--prebuilt-runtimes={self.prebuilt_runtimes}" + ) + subprocess.run(cmd, check=True, capture_output=True, text=True) + except subprocess.CalledProcessError as err: + self.fail(f"Subprocess failed: {err.stderr}") + + run = subprocess.run( + [output_bin], check=True, capture_output=True, text=True + ) + self.assertEqual(run.returncode, 0) + self.assertEqual(run.stdout.strip(), expected_output) + + def test_carbon_end_to_end(self) -> None: + source = r""" + import Cpp library ""; + fn Run() -> i32 { + Cpp.std.cout << "Hello from Carbon\n"; + return 0; + } + """ + for use_prebuilt in [True, False]: + with self.subTest(use_prebuilt=use_prebuilt): + self.run_carbon_test( + "simple_carbon", source, use_prebuilt, "Hello from Carbon" + ) + + def test_cpp_end_to_end(self) -> None: + source = r""" + #include + int main() { + std::cout << "Hello from C++" << std::endl; + return 0; + } + """ + for use_prebuilt in [True, False]: + with self.subTest(use_prebuilt=use_prebuilt): + self.run_cpp_test( + "simple_cpp", source, use_prebuilt, "Hello from C++" + ) + if __name__ == "__main__": unittest.main()