Implement ffi for OutputFile type.

Bug: 528225104
Change-Id: I11e37400058ef9a4939ce761e624a3236a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/23661
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: Matt Stark <msta@google.com>
diff --git a/build/gen.py b/build/gen.py
index 032e74c..ba6f170 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -731,6 +731,7 @@
               'src/gn/escape.cc',
               'src/gn/exec_process.cc',
               'src/gn/ffi/label.cc',
+              'src/gn/ffi/output_file.cc',
               'src/gn/ffi/settings.cc',
               'src/gn/filesystem_utils.cc',
               'src/gn/file_writer.cc',
diff --git a/src/gn/ffi/output_file.cc b/src/gn/ffi/output_file.cc
new file mode 100644
index 0000000..5437eba
--- /dev/null
+++ b/src/gn/ffi/output_file.cc
@@ -0,0 +1,15 @@
+// Copyright 2026 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gn/output_file.h"
+
+#include "cxx.h"
+
+extern "C" {
+
+rust::Str GetOutputFilePath(const OutputFile& file) {
+  return file.value();
+}
+
+}  // extern "C"
diff --git a/src/gn/starlark/crates/ffi/src/lib.rs b/src/gn/starlark/crates/ffi/src/lib.rs
index 7a6ec4a..cfb5f72 100644
--- a/src/gn/starlark/crates/ffi/src/lib.rs
+++ b/src/gn/starlark/crates/ffi/src/lib.rs
@@ -65,7 +65,9 @@
 
 pub mod label;
 pub mod opaque;
+pub mod output_file;
 pub mod settings;
 
 pub use label::{Label, SourceDir};
+pub use output_file::OutputFile;
 pub use settings::Settings;
diff --git a/src/gn/starlark/crates/ffi/src/output_file.rs b/src/gn/starlark/crates/ffi/src/output_file.rs
new file mode 100644
index 0000000..60d2cff
--- /dev/null
+++ b/src/gn/starlark/crates/ffi/src/output_file.rs
@@ -0,0 +1,21 @@
+// Copyright 2026 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use crate::declare_opaque_type;
+
+declare_opaque_type!(pub OutputFile);
+
+impl OutputFile {
+    /// Converts a GN OutputFile to a starlark File.
+    pub fn to_rust(&self) -> types::File {
+        extern "C" {
+            // Returned OutputFile objects will be owned by targets,
+            // which live forever, so &'static is fine.
+            fn GetOutputFilePath(file: &OutputFile) -> &'static str;
+        }
+        // Safety: Just an FFI function.
+        let s = unsafe { GetOutputFilePath(self) };
+        types::File::new(s)
+    }
+}