Skip to content

Commit bcc42c8

Browse files
committed
fix: copy Rust updater library to build output dir for Ninja tracking
The GN action for building the Rust updater via cargo declared only a stamp file as output. The library path referenced by libs[] was in the source tree, so Ninja couldn't map it to any build rule — causing "missing and no known rule to make it" for targets where the pre-built library didn't already exist (e.g. host_debug on macOS). Fix: the build_rust_updater.py script now copies the cargo-built library from the source tree to target_gen_dir, which is declared as an action output. This lets Ninja properly order the link step after the cargo build.
1 parent 4259c50 commit bcc42c8

3 files changed

Lines changed: 36 additions & 8 deletions

File tree

engine/src/flutter/shell/common/shorebird/BUILD.gn

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,30 @@ source_set("snapshots_data_handle") {
1717
}
1818

1919
if (shorebird_updater_supported) {
20+
# The library is copied from cargo's source-tree output into the build
21+
# output dir so GN/Ninja can track it as an action output and properly
22+
# order the link step after the cargo build.
23+
_updater_output_lib = "$target_gen_dir/$shorebird_updater_lib_name"
24+
2025
action("build_rust_updater") {
2126
script = "//flutter/shell/common/shorebird/build_rust_updater.py"
2227

23-
# The stamp file is the declared output for Ninja dependency tracking.
2428
_stamp =
2529
"$target_gen_dir/rust_updater_${shorebird_updater_rust_target}.stamp"
26-
outputs = [ _stamp ]
30+
outputs = [
31+
_stamp,
32+
_updater_output_lib,
33+
]
2734

2835
args = [
2936
"--rust-target",
3037
shorebird_updater_rust_target,
3138
"--manifest-dir",
3239
rebase_path("$shorebird_updater_dir", root_build_dir),
40+
"--cargo-output-lib",
41+
rebase_path("$shorebird_updater_cargo_lib", root_build_dir),
3342
"--output-lib",
34-
rebase_path("$shorebird_updater_output_lib", root_build_dir),
43+
rebase_path("$_updater_output_lib", root_build_dir),
3544
"--stamp",
3645
rebase_path(_stamp, root_build_dir),
3746
]
@@ -73,7 +82,7 @@ source_set("updater") {
7382

7483
if (shorebird_updater_supported) {
7584
deps += [ ":build_rust_updater" ]
76-
libs = [ shorebird_updater_output_lib ]
85+
libs = [ _updater_output_lib ]
7786

7887
if (is_win) {
7988
libs += [ "userenv.lib" ]

engine/src/flutter/shell/common/shorebird/build_rust_updater.gni

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ if (shorebird_updater_supported) {
6060
_updater_lib_name = "libupdater.a"
6161
}
6262

63-
shorebird_updater_output_lib = "$shorebird_updater_dir/target/$shorebird_updater_rust_target/release/$_updater_lib_name"
63+
# Path where cargo produces the library (in the source tree).
64+
shorebird_updater_cargo_lib = "$shorebird_updater_dir/target/$shorebird_updater_rust_target/release/$_updater_lib_name"
65+
66+
# The library filename, used by BUILD.gn to construct the output path
67+
# in target_gen_dir (which is only available inside BUILD.gn targets).
68+
shorebird_updater_lib_name = _updater_lib_name
6469

6570
# Glob all .rs source files so the input list stays in sync automatically.
6671
shorebird_updater_rs_sources =

engine/src/flutter/shell/common/shorebird/build_rust_updater.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,14 @@ def main():
1919
parser.add_argument(
2020
'--manifest-dir', required=True, help='Directory containing the workspace Cargo.toml'
2121
)
22-
parser.add_argument('--output-lib', required=True, help='Expected output library path')
22+
parser.add_argument(
23+
'--cargo-output-lib',
24+
required=True,
25+
help='Path where cargo places the built library (in the source tree)'
26+
)
27+
parser.add_argument(
28+
'--output-lib', required=True, help='Path to copy the library to (in the build output dir)'
29+
)
2330
parser.add_argument('--stamp', required=True, help='Stamp file to write on success')
2431
parser.add_argument('--ndk-path', help='Path to the Android NDK (required for Android targets)')
2532
parser.add_argument(
@@ -45,6 +52,7 @@ def main():
4552
# Ninja runs the action). Resolve them to absolute paths so they work
4653
# regardless of cargo's working directory.
4754
manifest_path = os.path.abspath(os.path.join(args.manifest_dir, 'Cargo.toml'))
55+
cargo_output_lib = os.path.abspath(args.cargo_output_lib)
4856
output_lib = os.path.abspath(args.output_lib)
4957

5058
cmd = [
@@ -65,10 +73,16 @@ def main():
6573
print(f'ERROR: cargo build failed with exit code {result.returncode}', file=sys.stderr)
6674
return result.returncode
6775

68-
if not os.path.exists(output_lib):
69-
print(f'ERROR: Expected output library not found: {output_lib}', file=sys.stderr)
76+
if not os.path.exists(cargo_output_lib):
77+
print(f'ERROR: Cargo output library not found: {cargo_output_lib}', file=sys.stderr)
7078
return 1
7179

80+
# Copy the library from the cargo output (source tree) to the build output
81+
# dir so GN/Ninja can track it as an action output.
82+
import shutil
83+
os.makedirs(os.path.dirname(output_lib), exist_ok=True)
84+
shutil.copy2(cargo_output_lib, output_lib)
85+
7286
# Write stamp file to signal success to Ninja.
7387
with open(args.stamp, 'w') as f:
7488
f.write('')

0 commit comments

Comments
 (0)