cargo_build_script_runner: parse cargo::metadata key/value pairs (#3877)

## Summary
Fix `cargo::metadata=KEY=VALUE` handling in `cargo_build_script_runner`
so metadata keys are propagated in Cargo-compatible form.

Before:
- `cargo::metadata=version_1_10_0=1`
- produced `DEP_<links>_METADATA=version_1_10_0=1`

After:
- same input produces `DEP_<links>_VERSION_1_10_0=1`

## Changes
- Add a `"metadata"` parser branch in `BuildScriptOutput::new`.
- Split metadata payload on first `=` and emit
`DepEnv("<KEY>=<VALUE>")`.
- Preserve fallback behavior for malformed metadata payloads.
- Add unit test: `metadata_directive_maps_to_dep_env_key_value`.

## Motivation
Downstream `links` users (for example `hdf5-metno`) expect specific
`DEP_*` metadata keys (`DEP_HDF5_VERSION_*`, `DEP_HDF5_HAVE_*`).

## Testing
- `bazel --batch test //cargo/private/cargo_build_script_runner:test
--remote_executor= --remote_cache= --bes_backend= --noshow_progress
--color=no --curses=no`

`bazel test //test/cargo_build_script/metadata_dep_env:all` are end to
end integration tests

Closes #3876.
diff --git a/cargo/private/cargo_build_script_runner/lib.rs b/cargo/private/cargo_build_script_runner/lib.rs
index de7c468..d2f0461 100644
--- a/cargo/private/cargo_build_script_runner/lib.rs
+++ b/cargo/private/cargo_build_script_runner/lib.rs
@@ -86,6 +86,20 @@
                 eprint!("Build Script Warning: {}", split[1]);
                 None
             }
+            "metadata" => {
+                // cargo::metadata=KEY=VALUE is forwarded to dependents as
+                // DEP_<links>_<KEY>=<VALUE> by Cargo.
+                if let Some((key, value)) = param.split_once('=') {
+                    Some(BuildScriptOutput::DepEnv(format!(
+                        "{}={}",
+                        key.to_uppercase().replace('-', "_"),
+                        value.trim()
+                    )))
+                } else {
+                    // Keep legacy behavior for malformed metadata payloads.
+                    Some(BuildScriptOutput::DepEnv(format!("METADATA={}", param)))
+                }
+            }
             "rustc-cdylib-link-arg" | "rustc-link-arg-bin" | "rustc-link-arg-bins" => {
                 // cargo::rustc-cdylib-link-arg=FLAG — Passes custom flags to a linker for cdylib crates.
                 // cargo::rustc-link-arg-bin=BIN=FLAG – Passes custom flags to a linker for the binary BIN.
@@ -375,4 +389,14 @@
             "valid1=1\nvalid2=2"
         );
     }
+
+    #[test]
+    fn metadata_directive_maps_to_dep_env_key_value() {
+        let reader = BufReader::new(Cursor::new("cargo::metadata=version_1_10_0=1\n"));
+        let result = BuildScriptOutput::outputs_from_reader(reader);
+        assert_eq!(
+            result,
+            vec![BuildScriptOutput::DepEnv("VERSION_1_10_0=1".to_owned())]
+        );
+    }
 }
diff --git a/test/cargo_build_script/metadata_dep_env/BUILD.bazel b/test/cargo_build_script/metadata_dep_env/BUILD.bazel
new file mode 100644
index 0000000..340fd93
--- /dev/null
+++ b/test/cargo_build_script/metadata_dep_env/BUILD.bazel
@@ -0,0 +1,37 @@
+load("//cargo:defs.bzl", "cargo_build_script")
+load("//rust:defs.bzl", "rust_library", "rust_test")
+
+cargo_build_script(
+    name = "producer_build_rs",
+    srcs = ["producer_build.rs"],
+    edition = "2021",
+    links = "producer",
+)
+
+rust_library(
+    name = "producer_lib",
+    srcs = ["producer_lib.rs"],
+    edition = "2021",
+    deps = [":producer_build_rs"],
+)
+
+cargo_build_script(
+    name = "consumer_build_rs",
+    srcs = ["consumer_build.rs"],
+    edition = "2021",
+    link_deps = [":producer_lib"],
+)
+
+rust_test(
+    name = "metadata_dep_env_modern_test",
+    srcs = ["modern_test.rs"],
+    edition = "2021",
+    deps = [":consumer_build_rs"],
+)
+
+rust_test(
+    name = "metadata_dep_env_legacy_test",
+    srcs = ["legacy_test.rs"],
+    edition = "2021",
+    deps = [":consumer_build_rs"],
+)
diff --git a/test/cargo_build_script/metadata_dep_env/README.md b/test/cargo_build_script/metadata_dep_env/README.md
new file mode 100644
index 0000000..978d708
--- /dev/null
+++ b/test/cargo_build_script/metadata_dep_env/README.md
@@ -0,0 +1,27 @@
+# metadata_dep_env test
+
+This package contains end-to-end tests for metadata forwarding through `cargo_build_script`
+for both syntax forms:
+- modern syntax: `cargo::metadata=KEY=VALUE`
+- legacy syntax: `cargo:KEY=VALUE`
+
+## What it verifies
+
+1. `producer_build_rs` emits both:
+   - `cargo::metadata=modern_version_1_10_0=1`
+   - `cargo:legacy_version_1_10_0=2`
+2. `rules_rust` converts that to a dependent build-script env var:
+   - `DEP_PRODUCER_MODERN_VERSION_1_10_0=1`
+   - `DEP_PRODUCER_LEGACY_VERSION_1_10_0=1`
+3. `consumer_build_rs` reads both and exports:
+   - `cargo:rustc-env=METADATA_MODERN_VALUE=1`
+   - `cargo:rustc-env=METADATA_LEGACY_VALUE=2`
+4. Two `rust_test` targets assert each value independently:
+   - `metadata_dep_env_modern_test`: `env!("METADATA_MODERN_VALUE") == "1"`
+   - `metadata_dep_env_legacy_test`: `env!("METADATA_LEGACY_VALUE") == "2"`
+
+## Why `producer_lib.rs` exists
+
+`cargo_build_script` targets cannot directly depend on other `cargo_build_script` targets.
+To model a realistic dependency edge, we attach `producer_build_rs` to a tiny Rust library (`producer_lib`),
+and the consumer build script depends on that library via `link_deps`.
diff --git a/test/cargo_build_script/metadata_dep_env/consumer_build.rs b/test/cargo_build_script/metadata_dep_env/consumer_build.rs
new file mode 100644
index 0000000..1db03cd
--- /dev/null
+++ b/test/cargo_build_script/metadata_dep_env/consumer_build.rs
@@ -0,0 +1,18 @@
+fn main() {
+    let modern = std::env::var("DEP_PRODUCER_MODERN_VERSION_1_10_0")
+        .expect("DEP_PRODUCER_MODERN_VERSION_1_10_0 should be set by producer build script");
+    assert_eq!(
+        modern, "1",
+        "unexpected DEP_PRODUCER_MODERN_VERSION_1_10_0 value"
+    );
+
+    let legacy = std::env::var("DEP_PRODUCER_LEGACY_VERSION_1_10_0")
+        .expect("DEP_PRODUCER_LEGACY_VERSION_1_10_0 should be set by producer build script");
+    assert_eq!(
+        legacy, "2",
+        "unexpected DEP_PRODUCER_LEGACY_VERSION_1_10_0 value"
+    );
+
+    println!("cargo:rustc-env=METADATA_MODERN_VALUE={modern}");
+    println!("cargo:rustc-env=METADATA_LEGACY_VALUE={legacy}");
+}
diff --git a/test/cargo_build_script/metadata_dep_env/legacy_test.rs b/test/cargo_build_script/metadata_dep_env/legacy_test.rs
new file mode 100644
index 0000000..c46dfa4
--- /dev/null
+++ b/test/cargo_build_script/metadata_dep_env/legacy_test.rs
@@ -0,0 +1,4 @@
+#[test]
+fn legacy_metadata_dep_env_is_forwarded() {
+    assert_eq!(env!("METADATA_LEGACY_VALUE"), "2");
+}
diff --git a/test/cargo_build_script/metadata_dep_env/modern_test.rs b/test/cargo_build_script/metadata_dep_env/modern_test.rs
new file mode 100644
index 0000000..733fb1f
--- /dev/null
+++ b/test/cargo_build_script/metadata_dep_env/modern_test.rs
@@ -0,0 +1,4 @@
+#[test]
+fn modern_metadata_dep_env_is_forwarded() {
+    assert_eq!(env!("METADATA_MODERN_VALUE"), "1");
+}
diff --git a/test/cargo_build_script/metadata_dep_env/producer_build.rs b/test/cargo_build_script/metadata_dep_env/producer_build.rs
new file mode 100644
index 0000000..8207a07
--- /dev/null
+++ b/test/cargo_build_script/metadata_dep_env/producer_build.rs
@@ -0,0 +1,5 @@
+fn main() {
+    println!("cargo::metadata=modern_version_1_10_0=1");
+    // Legacy (pre-1.77-compatible) syntax where unknown cargo:KEY is treated as metadata.
+    println!("cargo:legacy_version_1_10_0=2");
+}
diff --git a/test/cargo_build_script/metadata_dep_env/producer_lib.rs b/test/cargo_build_script/metadata_dep_env/producer_lib.rs
new file mode 100644
index 0000000..837e925
--- /dev/null
+++ b/test/cargo_build_script/metadata_dep_env/producer_lib.rs
@@ -0,0 +1,6 @@
+// Dummy Rust crate used to carry DepInfo from `producer_build_rs`.
+// `cargo_build_script` cannot depend directly on another build script target,
+// so the consumer build script uses this library in `link_deps` instead.
+pub fn marker() -> u8 {
+    1
+}