blob: 36948c5029a3b366064b74d9f8c4dcd4020a349a [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Fuchsia - Rust Compiler Development Guide</title>
<!-- Custom HTML head -->
<meta name="description" content="A guide to developing the Rust compiler (rustc)">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../../favicon.svg">
<link rel="shortcut icon" href="../../favicon.png">
<link rel="stylesheet" href="../../css/variables.css">
<link rel="stylesheet" href="../../css/general.css">
<link rel="stylesheet" href="../../css/chrome.css">
<link rel="stylesheet" href="../../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="highlight-css" href="../../highlight.css">
<link rel="stylesheet" id="tomorrow-night-css" href="../../tomorrow-night.css">
<link rel="stylesheet" id="ayu-highlight-css" href="../../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../../pagetoc.css">
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "../../";
const default_light_theme = "light";
const default_dark_theme = "navy";
window.path_to_searchindex_js = "../../searchindex.js";
</script>
<!-- Start loading toc.js asap -->
<script src="../../toc.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
sidebar_toggle.checked = false;
}
if (sidebar === 'visible') {
sidebar_toggle.checked = true;
} else {
html.classList.remove('sidebar-visible');
}
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Rust Compiler Development Guide</h1>
<div class="right-buttons">
<a href="../../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide/edit/master/src/tests/ecosystem-test-jobs/fuchsia.md" title="Suggest an edit" aria-label="Suggest an edit" rel="edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<div class="search-wrapper">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="fuchsia-integration-tests"><a class="header" href="#fuchsia-integration-tests">Fuchsia integration tests</a></h1>
<p><a href="https://fuchsia.dev">Fuchsia</a> is an open-source operating system with about 2
million lines of Rust code.<sup class="footnote-reference" id="fr-loc-1"><a href="#footnote-loc">1</a></sup> It has caught a large number of <a href="https://gist.github.com/tmandry/7103eba4bd6a6fb0c439b5a90ae355fa">regressions</a>
in the past and was subsequently included in CI.</p>
<h2 id="what-to-do-if-the-fuchsia-job-breaks"><a class="header" href="#what-to-do-if-the-fuchsia-job-breaks">What to do if the Fuchsia job breaks?</a></h2>
<p>Please contact the <a href="../../notification-groups/fuchsia.html">fuchsia</a> ping group and ask them for help.</p>
<pre><code class="language-text">@rustbot ping fuchsia
</code></pre>
<h2 id="building-fuchsia-in-ci"><a class="header" href="#building-fuchsia-in-ci">Building Fuchsia in CI</a></h2>
<p>Fuchsia builds as part of the suite of bors tests that run before a pull request
is merged.</p>
<p>If you are worried that a pull request might break the Fuchsia builder and want
to test it out before submitting it to the bors queue, simply ask bors to run
the try job that builds the Fuchsia integration: <code>@bors try jobs=x86_64-fuchsia</code>.</p>
<h2 id="building-fuchsia-locally"><a class="header" href="#building-fuchsia-locally">Building Fuchsia locally</a></h2>
<p>Because Fuchsia uses languages other than Rust, it does not use Cargo as a build
system. It also requires the toolchain build to be configured in a <a href="https://fuchsia.dev/fuchsia-src/development/build/rust_toolchain">certain
way</a>.</p>
<p>The recommended way to build Fuchsia is to use the Docker scripts that check out
and run a Fuchsia build for you. If you've run Docker tests before, you can
simply run this command from your Rust checkout to download and build Fuchsia
using your local Rust toolchain.</p>
<pre><code>src/ci/docker/run.sh x86_64-fuchsia
</code></pre>
<p>See the <a href="../docker.html">Testing with Docker</a> chapter for more details on how to run
and debug jobs with Docker.</p>
<p>Note that a Fuchsia checkout is <em>large</em> – as of this writing, a checkout and
build takes 46G of space – and as you might imagine, it takes a while to
complete.</p>
<h3 id="modifying-the-fuchsia-checkout"><a class="header" href="#modifying-the-fuchsia-checkout">Modifying the Fuchsia checkout</a></h3>
<p>The main reason you would want to build Fuchsia locally is because you need to
investigate a regression. After running a Docker build, you'll find the Fuchsia
checkout inside the <code>obj/fuchsia</code> directory of your Rust checkout. If you
modify the <code>KEEP_CHECKOUT</code> line in the <a href="https://github.com/rust-lang/rust/blob/221e2741c39515a5de6da42d8c76ee1e132c2c74/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh">build-fuchsia.sh</a> script to
<code>KEEP_CHECKOUT=1</code>, you can change the checkout as needed and rerun the build
command above. This will reuse all the build results from before.</p>
<p>You can find more options to customize the Fuchsia checkout in the
<a href="https://github.com/rust-lang/rust/blob/221e2741c39515a5de6da42d8c76ee1e132c2c74/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh">build-fuchsia.sh</a> script.</p>
<h3 id="customizing-the-fuchsia-build"><a class="header" href="#customizing-the-fuchsia-build">Customizing the Fuchsia build</a></h3>
<p>You can find more info about the options used to build Fuchsia in Rust CI in the
<a href="https://cs.opensource.google/fuchsia/fuchsia/+/main:scripts/rust/build_fuchsia_from_rust_ci.sh?q=build_fuchsia_from_rust_ci&amp;ss=fuchsia">build_fuchsia_from_rust_ci.sh</a> script invoked by <a href="https://github.com/rust-lang/rust/blob/221e2741c39515a5de6da42d8c76ee1e132c2c74/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh">build-fuchsia.sh</a>.</p>
<p>The Fuchsia build system uses <a href="https://gn.googlesource.com/gn/+/main#gn">GN</a>, a metabuild system that generates <a href="https://ninja-build.org/">Ninja</a>
files and then hands off the work of running the build to Ninja.</p>
<p>Fuchsia developers use <code>fx</code> to run builds and perform other development tasks.
This tool is located in <code>.jiri_root/bin</code> of the Fuchsia checkout; you may need
to add this to your <code>$PATH</code> for some workflows.</p>
<p>There are a few <code>fx</code> subcommands that are relevant, including:</p>
<ul>
<li><code>fx set</code> accepts build arguments, writes them to <code>out/default/args.gn</code>, and
runs GN.</li>
<li><code>fx build</code> builds the Fuchsia project using Ninja. It will automatically pick
up changes to build arguments and rerun GN. By default it builds everything,
but it also accepts target paths to build specific targets (see below).</li>
<li><code>fx clippy</code> runs Clippy on specific Rust targets (or all of them). We use this
in the Rust CI build to avoid running codegen on most Rust targets. Underneath
it invokes Ninja, just like <code>fx build</code>. The clippy results are saved in json
files inside the build output directory before being printed.</li>
</ul>
<h4 id="target-paths"><a class="header" href="#target-paths">Target paths</a></h4>
<p>GN uses paths like the following to identify build targets:</p>
<pre><code>//src/starnix/kernel:starnix_core
</code></pre>
<p>The initial <code>//</code> means the root of the checkout, and the remaining slashes are
directory names. The string after <code>:</code> is the <em>target name</em> of a target defined
in the <code>BUILD.gn</code> file of that directory.</p>
<p>The target name can be omitted if it is the same as the directory name. In other
words, <code>//src/starnix/kernel</code> is the same as <code>//src/starnix/kernel:kernel</code>.</p>
<p>These target paths are used inside <code>BUILD.gn</code> files to reference dependencies,
and can also be used in <code>fx build</code>.</p>
<h4 id="modifying-compiler-flags"><a class="header" href="#modifying-compiler-flags">Modifying compiler flags</a></h4>
<p>You can put custom compiler flags inside a GN <code>config</code> that is added to a
target. As a simple example:</p>
<pre><code>config("everybody_loops") {
rustflags = [ "-Zeverybody-loops" ]
}
rustc_binary("example") {
crate_root = "src/bin.rs"
# ...existing keys here...
configs += [ ":everybody_loops" ]
}
</code></pre>
<p>This will add the flag <code>-Zeverybody-loops</code> to rustc when building the <code>example</code>
target. Note that you can also use <a href="https://gn.googlesource.com/gn/+/main/docs/reference.md#var_public_configs"><code>public_configs</code></a> for a config to be added
to every target that depends on that target.</p>
<p>If you want to add a flag to every Rust target in the build, you can add
rustflags to the <a href="https://cs.opensource.google/fuchsia/fuchsia/+/main:build/config/BUILD.gn;l=121;drc=c26c473bef93b33117ae417893118907a026fec7"><code>//build/config:compiler</code></a> config or to the OS-specific
configs referenced in that file. Note that <code>cflags</code> and <code>ldflags</code> are ignored on
Rust targets.</p>
<h4 id="running-ninja-and-rustc-commands-directly"><a class="header" href="#running-ninja-and-rustc-commands-directly">Running ninja and rustc commands directly</a></h4>
<p>Going down one layer, <code>fx build</code> invokes <code>ninja</code>, which in turn eventually
invokes <code>rustc</code>. All build actions are run inside the out directory, which is
usually <code>out/default</code> inside the Fuchsia checkout.</p>
<p>You can get ninja to print the actual command it invokes by forcing that command
to fail, e.g. by adding a syntax error to one of the source files of the target.
Once you have the command, you can run it from inside the output directory.</p>
<p>After changing the toolchain itself, the build setting <code>rustc_version_string</code> in
<code>out/default/args.gn</code> needs to be changed so that <code>fx build</code> or <code>ninja</code> will
rebuild all the Rust targets. This can be done in a text editor and the contents
of the string do not matter, as long as it changes from one build to the next.
<a href="https://cs.opensource.google/fuchsia/fuchsia/+/main:scripts/rust/build_fuchsia_from_rust_ci.sh?q=build_fuchsia_from_rust_ci&amp;ss=fuchsia">build_fuchsia_from_rust_ci.sh</a> does this for you by hashing the toolchain
directory.</p>
<p>The Fuchsia website has more detailed documentation of the <a href="https://fuchsia.dev/fuchsia-src/development/build/build_system">build system</a>.</p>
<h4 id="other-tips-and-tricks"><a class="header" href="#other-tips-and-tricks">Other tips and tricks</a></h4>
<p>When using <code>build_fuchsia_from_rust_ci.sh</code> you can comment out the <code>fx set</code>
command after the initial run so it won't rerun GN each time. If you do this you
can also comment out the version_string line to save a couple seconds.</p>
<p><code>export NINJA_PERSISTENT_MODE=1</code> to get faster ninja startup times after the
initial build.</p>
<h2 id="fuchsia-target-support"><a class="header" href="#fuchsia-target-support">Fuchsia target support</a></h2>
<p>To learn more about Fuchsia target support, see the Fuchsia chapter in <a href="https://doc.rust-lang.org/nightly/rustc/platform-support/fuchsia.html">the
rustc book</a>.</p>
<hr>
<ol class="footnote-definition"><li id="footnote-loc">
<p>As of June 2024, Fuchsia had about 2 million lines of first-party Rust
code and a roughly equal amount of third-party code, as counted by tokei
(excluding comments and blanks). <a href="#fr-loc-1"></a></p>
</li>
</ol>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../../tests/crater.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../../tests/ecosystem-test-jobs/rust-for-linux.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../../tests/crater.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../../tests/ecosystem-test-jobs/rust-for-linux.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../../elasticlunr.min.js"></script>
<script src="../../mark.min.js"></script>
<script src="../../searcher.js"></script>
<script src="../../clipboard.min.js"></script>
<script src="../../highlight.js"></script>
<script src="../../book.js"></script>
<!-- Custom JS scripts -->
<script src="../../mermaid.min.js"></script>
<script src="../../mermaid-init.js"></script>
<script src="../../pagetoc.js"></script>
</div>
</body>
</html>