diff --git a/scripts/ada_d_eh_matrix.py b/scripts/ada_d_eh_matrix.py index 4f795ae..0d9877d 100644 --- a/scripts/ada_d_eh_matrix.py +++ b/scripts/ada_d_eh_matrix.py @@ -249,14 +249,16 @@ def compiler_flags( ) -> tuple[str, ...]: mapped = f"-ffile-prefix-map={checkout_prefix}=/testbins" if cell.toolchain == "gnat": + # -cargs is a one-way door: gnatmake hands every later argv token to + # gcc, including the source file and -o if they follow it. return ( "-q", "-gnat2022", + f"-O{variant.optimization[-1]}", "-cargs", "-fexceptions", "-g0", mapped, - f"-O{variant.optimization[-1]}", ) if cell.toolchain == "gdc": return ( diff --git a/scripts/build_language_eh_corpus.py b/scripts/build_language_eh_corpus.py index 4010392..5297d8d 100644 --- a/scripts/build_language_eh_corpus.py +++ b/scripts/build_language_eh_corpus.py @@ -100,6 +100,16 @@ def runner_image() -> str: return f"local-{platform.system().lower()}-{platform.machine().lower()}" +def gnatmake_command( + compiler: str, flags: list[str], source: str, output: str +) -> list[str]: + """Keep the source and -o on gnatmake's side of -cargs.""" + if "-cargs" in flags: + index = flags.index("-cargs") + return [compiler, *flags[:index], source, "-o", output, *flags[index:]] + return [compiler, *flags, source, "-o", output] + + def build_artifact( cell: matrix.MatrixCell, variant: matrix.Variant, @@ -114,7 +124,7 @@ def build_artifact( if cell.toolchain == "gnat": with tempfile.TemporaryDirectory(prefix="ada-eh-") as temporary: - command = [compiler, *flags, str(source), "-o", str(output)] + command = gnatmake_command(compiler, flags, str(source), str(output)) run(command, cwd=Path(temporary), environment=environment) elif cell.toolchain == "gdc": command = [compiler, *flags, cell.source_path, "-o", str(output)] diff --git a/scripts/tests/test_ada_d_eh_matrix.py b/scripts/tests/test_ada_d_eh_matrix.py index 3b76859..66dbf67 100644 --- a/scripts/tests/test_ada_d_eh_matrix.py +++ b/scripts/tests/test_ada_d_eh_matrix.py @@ -123,7 +123,16 @@ def test_gnat_passes_gcc_flags_through_cargs(self) -> None: self.assertEqual(flags[0], "-q") self.assertIn("-cargs", flags) self.assertGreater(flags.index("-cargs"), flags.index("-gnat2022")) - self.assertGreater(flags.index("-fexceptions"), flags.index("-cargs")) + self.assertGreater(flags.index("-cargs"), flags.index("-O0")) + self.assertEqual( + flags[flags.index("-cargs") :], + ( + "-cargs", + "-fexceptions", + "-g0", + "-ffile-prefix-map=/checkout=/testbins", + ), + ) class CommandTests(unittest.TestCase): diff --git a/scripts/tests/test_build_language_eh_corpus.py b/scripts/tests/test_build_language_eh_corpus.py index a30099d..e3eb650 100644 --- a/scripts/tests/test_build_language_eh_corpus.py +++ b/scripts/tests/test_build_language_eh_corpus.py @@ -12,6 +12,7 @@ sys.path.insert(0, str(SCRIPTS_ROOT)) import ada_d_eh_matrix as matrix # noqa: E402 +import build_language_eh_corpus as builder # noqa: E402 BUILD_SCRIPT = SCRIPTS_ROOT / "build_language_eh_corpus.py" @@ -64,5 +65,27 @@ def test_each_cell_describes_exactly_the_contract_the_matrix_defines(self) -> No self.assertEqual(entry["neverd"], matrix.neverd_contract(cell)) +class GnatmakeCommandTests(unittest.TestCase): + def test_places_source_and_output_before_cargs(self) -> None: + cell = matrix.validate_cell("gnat", "x86_64-linux-gnu") + flags = list( + matrix.compiler_flags(cell, matrix.validate_variant("o0"), "/checkout") + ) + command = builder.gnatmake_command( + "gnatmake-13", + flags, + "/checkout/sources/ada-d-eh/ada_eh_probe.adb", + "/out/ada_eh_probe", + ) + + self.assertLess( + command.index("/checkout/sources/ada-d-eh/ada_eh_probe.adb"), + command.index("-cargs"), + ) + self.assertLess(command.index("-o"), command.index("-cargs")) + self.assertLess(command.index("/out/ada_eh_probe"), command.index("-cargs")) + self.assertEqual(command[command.index("-cargs") + 1], "-fexceptions") + + if __name__ == "__main__": unittest.main()