ビルドルール演習

Chromium のビルドで、//ui/base/BUILD.gn に新しい Rust ターゲットを追加し、以下を含めてください。

#![allow(unused)]
fn main() {
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0

// SAFETY: この名前の他のグローバル関数はありません。
#[unsafe(no_mangle)]
pub extern "C" fn hello_from_rust() {
    println!("Hello from Rust!")
}
}

重要: ここでの no_mangle は Rust コンパイラによって一種の unsafe と見なされるため、gn ターゲットで unsafe コードを許可する必要があります。

この新しい Rust ターゲットを //ui/base:base の依存関係として追加してください。この関数を ui/base/resource/resource_bundle.cc の先頭で宣言してください(後で、これをバインディング生成ツールで自動化する方法を見ていきます)。

extern "C" void hello_from_rust();

この関数を ui/base/resource/resource_bundle.cc 内のどこかから呼び出してください。ResourceBundle::MaybeMangleLocalizedString の先頭がおすすめです。Chromium をビルドして実行し、“Hello from Rust!” が何度も出力されることを確認してください。

VSCode を使っている場合は、このタイミングで VSCode で Rust がうまく動作するように設定してください。これは以降の演習で役立ちます。成功していれば、println! に対して右クリックの「Go to definition」を使えるようになります。

参考情報

学生がこれを動かせるようにすることは本当に重要です。以降の演習はこれを土台にして進めるためです。

この例が少し珍しいのは、最終的に最小公分母の相互運用言語である C に行き着くためです。C++ と Rust はどちらも C ABI 関数をネイティブに宣言して呼び出せます。コースの後半では、C++ を Rust に直接接続します。

allow_unsafe = true がここで必要なのは、#[unsafe(no_mangle)] によって Rust が同じ名前の関数を 2 つ生成できてしまう可能性があり、Rust がどちらの関数が正しく呼び出されるかを保証できなくなるためです。

純粋な Rust の実行ファイルが必要な場合は、rust_executable gn テンプレートを使ってそれを行うこともできます。