| <!DOCTYPE HTML> |
| <html lang="en" class="light sidebar-visible" dir="ltr"> |
| <head> |
| <!-- Book generated using mdBook --> |
| <meta charset="UTF-8"> |
| <title>Suggested workflows - 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/building/suggested.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="suggested-workflows"><a class="header" href="#suggested-workflows">Suggested workflows</a></h1> |
| <p>The full bootstrapping process takes quite a while. Here are some suggestions to |
| make your life easier.</p> |
| <h2 id="installing-a-pre-push-hook"><a class="header" href="#installing-a-pre-push-hook">Installing a pre-push hook</a></h2> |
| <p>CI will automatically fail your build if it doesn't pass <code>tidy</code>, our internal |
| tool for ensuring code quality. If you'd like, you can install a <a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">Git |
| hook</a> that will |
| automatically run <code>./x test tidy</code> on each push, to ensure your code is up to |
| par. If the hook fails then run <code>./x test tidy --bless</code> and commit the changes. |
| If you decide later that the pre-push behavior is undesirable, you can delete |
| the <code>pre-push</code> file in <code>.git/hooks</code>.</p> |
| <p>A prebuilt git hook lives at <a href="https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh"><code>src/etc/pre-push.sh</code></a>. It can be copied into |
| your <code>.git/hooks</code> folder as <code>pre-push</code> (without the <code>.sh</code> extension!).</p> |
| <p>You can also install the hook as a step of running <code>./x setup</code>!</p> |
| <h2 id="config-extensions"><a class="header" href="#config-extensions">Config extensions</a></h2> |
| <p>When working on different tasks, you might need to switch between different bootstrap configurations. |
| Sometimes you may want to keep an old configuration for future use. But saving raw config values in |
| random files and manually copying and pasting them can quickly become messy, especially if you have a |
| long history of different configurations.</p> |
| <p>To simplify managing multiple configurations, you can create config extensions.</p> |
| <p>For example, you can create a simple config file named <code>cross.toml</code>:</p> |
| <pre><code class="language-toml">[build] |
| build = "x86_64-unknown-linux-gnu" |
| host = ["i686-unknown-linux-gnu"] |
| target = ["i686-unknown-linux-gnu"] |
| |
| |
| [llvm] |
| download-ci-llvm = false |
| |
| [target.x86_64-unknown-linux-gnu] |
| llvm-config = "/path/to/llvm-19/bin/llvm-config" |
| </code></pre> |
| <p>Then, include this in your <code>bootstrap.toml</code>:</p> |
| <pre><code class="language-toml">include = ["cross.toml"] |
| </code></pre> |
| <p>You can also include extensions within extensions recursively.</p> |
| <p><strong>Note:</strong> In the <code>include</code> field, the overriding logic follows a right-to-left order. For example, |
| in <code>include = ["a.toml", "b.toml"]</code>, extension <code>b.toml</code> overrides <code>a.toml</code>. Also, parent extensions |
| always overrides the inner ones.</p> |
| <h2 id="configuring-rust-analyzer-for-rustc"><a class="header" href="#configuring-rust-analyzer-for-rustc">Configuring <code>rust-analyzer</code> for <code>rustc</code></a></h2> |
| <h3 id="checking-the-library-tree"><a class="header" href="#checking-the-library-tree">Checking the "library" tree</a></h3> |
| <p>Checking the "library" tree requires a stage1 compiler, which can be a heavy process on some computers. |
| For this reason, bootstrap has a flag called <code>--skip-std-check-if-no-download-rustc</code> that skips checking the |
| "library" tree if <code>rust.download-rustc</code> isn't available. If you want to avoid putting a heavy load on your computer |
| with <code>rust-analyzer</code>, you can add the <code>--skip-std-check-if-no-download-rustc</code> flag to your <code>./x check</code> command in |
| the <code>rust-analyzer</code> configuration.</p> |
| <h3 id="project-local-rust-analyzer-setup"><a class="header" href="#project-local-rust-analyzer-setup">Project-local rust-analyzer setup</a></h3> |
| <p><code>rust-analyzer</code> can help you check and format your code whenever you save a |
| file. By default, <code>rust-analyzer</code> runs the <code>cargo check</code> and <code>rustfmt</code> commands, |
| but you can override these commands to use more adapted versions of these tools |
| when hacking on <code>rustc</code>. With custom setup, <code>rust-analyzer</code> can use <code>./x check</code> |
| to check the sources, and the stage 0 rustfmt to format them.</p> |
| <p>The default <code>rust-analyzer.check.overrideCommand</code> command line will check all |
| the crates and tools in the repository. If you are working on a specific part, |
| you can override the command to only check the part you are working on to save |
| checking time. For example, if you are working on the compiler, you can override |
| the command to <code>x check compiler --json-output</code> to only check the compiler part. |
| You can run <code>x check --help --verbose</code> to see the available parts.</p> |
| <p>Running <code>./x setup editor</code> will prompt you to create a project-local LSP config |
| file for one of the supported editors. You can also create the config file as a |
| step of running <code>./x setup</code>.</p> |
| <h3 id="using-a-separate-build-directory-for-rust-analyzer"><a class="header" href="#using-a-separate-build-directory-for-rust-analyzer">Using a separate build directory for rust-analyzer</a></h3> |
| <p>By default, when rust-analyzer runs a check or format command, it will share |
| the same build directory as manual command-line builds. This can be inconvenient |
| for two reasons:</p> |
| <ul> |
| <li>Each build will lock the build directory and force the other to wait, so it |
| becomes impossible to run command-line builds while rust-analyzer is running |
| commands in the background.</li> |
| <li>There is an increased risk of one of the builds deleting previously-built |
| artifacts due to conflicting compiler flags or other settings, forcing |
| additional rebuilds in some cases.</li> |
| </ul> |
| <p>To avoid these problems:</p> |
| <ul> |
| <li>Add <code>--build-dir=build/rust-analyzer</code> to all of the custom <code>x</code> commands in |
| your editor's rust-analyzer configuration. |
| (Feel free to choose a different directory name if desired.)</li> |
| <li>Modify the <code>rust-analyzer.rustfmt.overrideCommand</code> setting so that it points |
| to the copy of <code>rustfmt</code> in that other build directory.</li> |
| <li>Modify the <code>rust-analyzer.procMacro.server</code> setting so that it points to the |
| copy of <code>rust-analyzer-proc-macro-srv</code> in that other build directory.</li> |
| </ul> |
| <p>Using separate build directories for command-line builds and rust-analyzer |
| requires extra disk space.</p> |
| <h3 id="visual-studio-code"><a class="header" href="#visual-studio-code">Visual Studio Code</a></h3> |
| <p>Selecting <code>vscode</code> in <code>./x setup editor</code> will prompt you to create a |
| <code>.vscode/settings.json</code> file which will configure Visual Studio code. The |
| recommended <code>rust-analyzer</code> settings live at |
| <a href="https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json"><code>src/etc/rust_analyzer_settings.json</code></a>.</p> |
| <p>If running <code>./x check</code> on save is inconvenient, in VS Code you can use a <a href="https://code.visualstudio.com/docs/editor/tasks">Build |
| Task</a> instead:</p> |
| <pre><code class="language-JSON">// .vscode/tasks.json |
| { |
| "version": "2.0.0", |
| "tasks": [ |
| { |
| "label": "./x check", |
| "command": "./x check", |
| "type": "shell", |
| "problemMatcher": "$rustc", |
| "presentation": { "clear": true }, |
| "group": { "kind": "build", "isDefault": true } |
| } |
| ] |
| } |
| </code></pre> |
| <h3 id="neovim"><a class="header" href="#neovim">Neovim</a></h3> |
| <p>For Neovim users, there are a few options. The |
| easiest way is by using <a href="https://github.com/folke/neoconf.nvim/">neoconf.nvim</a>, |
| which allows for project-local configuration files with the native LSP. The |
| steps for how to use it are below. Note that they require rust-analyzer to |
| already be configured with Neovim. Steps for this can be <a href="https://rust-analyzer.github.io/manual.html#nvim-lsp">found |
| here</a>.</p> |
| <ol> |
| <li>First install the plugin. This can be done by following the steps in the |
| README.</li> |
| <li>Run <code>./x setup editor</code>, and select <code>vscode</code> to create a |
| <code>.vscode/settings.json</code> file. <code>neoconf</code> is able to read and update |
| rust-analyzer settings automatically when the project is opened when this |
| file is detected.</li> |
| </ol> |
| <p>If you're using <code>coc.nvim</code>, you can run <code>./x setup editor</code> and select <code>vim</code> to |
| create a <code>.vim/coc-settings.json</code>. The settings can be edited with |
| <code>:CocLocalConfig</code>. The recommended settings live at |
| <a href="https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json"><code>src/etc/rust_analyzer_settings.json</code></a>.</p> |
| <p>Another way is without a plugin, and creating your own logic in your |
| configuration. The following code will work for any checkout of rust-lang/rust (newer than February 2025):</p> |
| <pre><code class="language-lua">local function expand_config_variables(option) |
| local var_placeholders = { |
| ['${workspaceFolder}'] = function(_) |
| return vim.lsp.buf.list_workspace_folders()[1] |
| end, |
| } |
| |
| if type(option) == "table" then |
| local mt = getmetatable(option) |
| local result = {} |
| for k, v in pairs(option) do |
| result[expand_config_variables(k)] = expand_config_variables(v) |
| end |
| return setmetatable(result, mt) |
| end |
| if type(option) ~= "string" then |
| return option |
| end |
| local ret = option |
| for key, fn in pairs(var_placeholders) do |
| ret = ret:gsub(key, fn) |
| end |
| return ret |
| end |
| lspconfig.rust_analyzer.setup { |
| root_dir = function() |
| local default = lspconfig.rust_analyzer.config_def.default_config.root_dir() |
| -- the default root detection uses the cargo workspace root. |
| -- but for rust-lang/rust, the standard library is in its own workspace. |
| -- use the git root instead. |
| local compiler_config = vim.fs.joinpath(default, "../src/bootstrap/defaults/config.compiler.toml") |
| if vim.fs.basename(default) == "library" and vim.uv.fs_stat(compiler_config) then |
| return vim.fs.dirname(default) |
| end |
| return default |
| end, |
| on_init = function(client) |
| local path = client.workspace_folders[1].name |
| local config = vim.fs.joinpath(path, "src/etc/rust_analyzer_zed.json") |
| if vim.uv.fs_stat(config) then |
| -- load rust-lang/rust settings |
| local file = io.open(config) |
| local json = vim.json.decode(file:read("*a")) |
| client.config.settings["rust-analyzer"] = expand_config_variables(json.lsp["rust-analyzer"].initialization_options) |
| client.notify("workspace/didChangeConfiguration", { settings = client.config.settings }) |
| end |
| return true |
| end |
| } |
| </code></pre> |
| <p>If you would like to use the build task that is described above, you may either |
| make your own command in your config, or you can install a plugin such as |
| <a href="https://github.com/stevearc/overseer.nvim">overseer.nvim</a> that can <a href="https://github.com/stevearc/overseer.nvim/blob/master/doc/guides.md#vs-code-tasks">read |
| VSCode's <code>task.json</code> |
| files</a>, |
| and follow the same instructions as above.</p> |
| <h3 id="emacs"><a class="header" href="#emacs">Emacs</a></h3> |
| <p>Emacs provides support for rust-analyzer with project-local configuration |
| through <a href="https://www.gnu.org/software/emacs/manual/html_node/eglot/">Eglot</a>. |
| Steps for setting up Eglot with rust-analyzer can be <a href="https://rust-analyzer.github.io/manual.html#eglot">found |
| here</a>. |
| Having set up Emacs & Eglot for Rust development in general, you can run |
| <code>./x setup editor</code> and select <code>emacs</code>, which will prompt you to create |
| <code>.dir-locals.el</code> with the recommended configuration for Eglot. |
| The recommended settings live at <a href="https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_eglot.el"><code>src/etc/rust_analyzer_eglot.el</code></a>. |
| For more information on project-specific Eglot configuration, consult <a href="https://www.gnu.org/software/emacs/manual/html_node/eglot/Project_002dspecific-configuration.html">the |
| manual</a>.</p> |
| <h3 id="helix"><a class="header" href="#helix">Helix</a></h3> |
| <p>Helix comes with built-in LSP and rust-analyzer support. |
| It can be configured through <code>languages.toml</code>, as described |
| <a href="https://docs.helix-editor.com/languages.html">here</a>. |
| You can run <code>./x setup editor</code> and select <code>helix</code>, which will prompt you to |
| create <code>languages.toml</code> with the recommended configuration for Helix. The |
| recommended settings live at <a href="https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_helix.toml"><code>src/etc/rust_analyzer_helix.toml</code></a>.</p> |
| <h3 id="zed"><a class="header" href="#zed">Zed</a></h3> |
| <p>Zed comes with built-in LSP and rust-analyzer support. |
| It can be configured through <code>.zed/settings.json</code>, as described |
| <a href="https://zed.dev/docs/configuring-languages">here</a>. Selecting <code>zed</code> |
| in <code>./x setup editor</code> will prompt you to create a <code>.zed/settings.json</code> |
| file which will configure Zed with the recommended configuration. The |
| recommended <code>rust-analyzer</code> settings live |
| at <a href="https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_zed.json"><code>src/etc/rust_analyzer_zed.json</code></a>.</p> |
| <h2 id="check-check-and-check-again"><a class="header" href="#check-check-and-check-again">Check, check, and check again</a></h2> |
| <p>When doing simple refactoring, it can be useful to run <code>./x check</code> |
| continuously. If you set up <code>rust-analyzer</code> as described above, this will be |
| done for you every time you save a file. Here you are just checking that the |
| compiler can <strong>build</strong>, but often that is all you need (e.g., when renaming a |
| method). You can then run <code>./x build</code> when you actually need to run tests.</p> |
| <p>In fact, it is sometimes useful to put off tests even when you are not 100% sure |
| the code will work. You can then keep building up refactoring commits and only |
| run the tests at some later time. You can then use <code>git bisect</code> to track down |
| <strong>precisely</strong> which commit caused the problem. A nice side-effect of this style |
| is that you are left with a fairly fine-grained set of commits at the end, all |
| of which build and pass tests. This often helps reviewing.</p> |
| <h2 id="configuring-rustup-to-use-nightly"><a class="header" href="#configuring-rustup-to-use-nightly">Configuring <code>rustup</code> to use nightly</a></h2> |
| <p>Some parts of the bootstrap process uses pinned, nightly versions of tools like |
| rustfmt. To make things like <code>cargo fmt</code> work correctly in your repo, run</p> |
| <pre><code class="language-console">cd <path to rustc repo> |
| rustup override set nightly |
| </code></pre> |
| <p>after <a href="https://rust-lang.github.io/rustup/concepts/channels.html?highlight=nightl#working-with-nightly-rust">installing a nightly toolchain</a> with <code>rustup</code>. Don't forget to do this |
| for all directories you have <a href="./suggested.html#working-on-multiple-branches-at-the-same-time">setup a worktree for</a>. You may need to use the |
| pinned nightly version from <code>src/stage0</code>, but often the normal <code>nightly</code> channel |
| will work.</p> |
| <p><strong>Note</strong> see <a href="suggested.html#configuring-rust-analyzer-for-rustc">the section on vscode</a> for how to configure it with this real |
| rustfmt <code>x</code> uses, and <a href="how-to-build-and-run.html">the section on rustup</a> for how to setup <code>rustup</code> |
| toolchain for your bootstrapped compiler</p> |
| <p><strong>Note</strong> This does <em>not</em> allow you to build <code>rustc</code> with cargo directly. You |
| still have to use <code>x</code> to work on the compiler or standard library, this just |
| lets you use <code>cargo fmt</code>.</p> |
| <h2 id="faster-builds-with-ci-rustc"><a class="header" href="#faster-builds-with-ci-rustc">Faster Builds with CI-rustc</a></h2> |
| <p>If you are not working on the compiler, you often don't need to build the compiler tree. |
| For example, you can skip building the compiler and only build the <code>library</code> tree or the |
| tools under <code>src/tools</code>. To achieve that, you have to enable this by setting the <code>download-rustc</code> |
| option in your configuration. This tells bootstrap to use the latest nightly compiler for <code>stage > 0</code> |
| steps, meaning it will have two precompiled compilers: stage0 compiler and <code>download-rustc</code> compiler |
| for <code>stage > 0</code> steps. This way, it will never need to build the in-tree compiler. As a result, your |
| build time will be significantly reduced by not building the in-tree compiler.</p> |
| <h2 id="using-incremental-compilation"><a class="header" href="#using-incremental-compilation">Using incremental compilation</a></h2> |
| <p>You can further enable the <code>--incremental</code> flag to save additional time in |
| subsequent rebuilds:</p> |
| <pre><code class="language-bash">./x test tests/ui --incremental --test-args issue-1234 |
| </code></pre> |
| <p>If you don't want to include the flag with every command, you can enable it in |
| the <code>bootstrap.toml</code>:</p> |
| <pre><code class="language-toml">[rust] |
| incremental = true |
| </code></pre> |
| <p>Note that incremental compilation will use more disk space than usual. If disk |
| space is a concern for you, you might want to check the size of the <code>build</code> |
| directory from time to time.</p> |
| <h2 id="fine-tuning-optimizations"><a class="header" href="#fine-tuning-optimizations">Fine-tuning optimizations</a></h2> |
| <p>Setting <code>optimize = false</code> makes the compiler too slow for tests. However, to |
| improve the test cycle, you can disable optimizations selectively only for the |
| crates you'll have to rebuild |
| (<a href="https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/incremental.20compilation.20question/near/202712165">source</a>). |
| For example, when working on <code>rustc_mir_build</code>, the <code>rustc_mir_build</code> and |
| <code>rustc_driver</code> crates take the most time to incrementally rebuild. You could |
| therefore set the following in the root <code>Cargo.toml</code>:</p> |
| <pre><code class="language-toml">[profile.release.package.rustc_mir_build] |
| opt-level = 0 |
| [profile.release.package.rustc_driver] |
| opt-level = 0 |
| </code></pre> |
| <h2 id="working-on-multiple-branches-at-the-same-time"><a class="header" href="#working-on-multiple-branches-at-the-same-time">Working on multiple branches at the same time</a></h2> |
| <p>Working on multiple branches in parallel can be a little annoying, since |
| building the compiler on one branch will cause the old build and the incremental |
| compilation cache to be overwritten. One solution would be to have multiple |
| clones of the repository, but that would mean storing the Git metadata multiple |
| times, and having to update each clone individually.</p> |
| <p>Fortunately, Git has a better solution called <a href="https://git-scm.com/docs/git-worktree">worktrees</a>. This lets you create |
| multiple "working trees", which all share the same Git database. Moreover, |
| because all of the worktrees share the same object database, if you update a |
| branch (e.g. master) in any of them, you can use the new commits from any of the |
| worktrees. One caveat, though, is that submodules do not get shared. They will |
| still be cloned multiple times.</p> |
| <p>Given you are inside the root directory for your Rust repository, you can create |
| a "linked working tree" in a new "rust2" directory by running the following |
| command:</p> |
| <pre><code class="language-bash">git worktree add ../rust2 |
| </code></pre> |
| <p>Creating a new worktree for a new branch based on <code>master</code> looks like:</p> |
| <pre><code class="language-bash">git worktree add -b my-feature ../rust2 master |
| </code></pre> |
| <p>You can then use that rust2 folder as a separate workspace for modifying and |
| building <code>rustc</code>!</p> |
| <h2 id="working-with-nix"><a class="header" href="#working-with-nix">Working with nix</a></h2> |
| <p>Several nix configurations are defined in <code>src/tools/nix-dev-shell</code>.</p> |
| <p>If you're using direnv, you can create a symbol link to <code>src/tools/nix-dev-shell/envrc-flake</code> or <code>src/tools/nix-dev-shell/envrc-shell</code></p> |
| <pre><code class="language-bash">ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc # Use flake |
| </code></pre> |
| <p>or</p> |
| <pre><code class="language-bash">ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc # Use nix-shell |
| </code></pre> |
| <h3 id="note"><a class="header" href="#note">Note</a></h3> |
| <p>Note that when using nix on a not-NixOS distribution, it may be necessary to set |
| <strong><code>patch-binaries-for-nix = true</code> in <code>bootstrap.toml</code></strong>. Bootstrap tries to detect |
| whether it's running in nix and enable patching automatically, but this |
| detection can have false negatives.</p> |
| <p>You can also use your nix shell to manage <code>bootstrap.toml</code>:</p> |
| <pre><code class="language-nix">let |
| config = pkgs.writeText "rustc-config" '' |
| # Your bootstrap.toml content goes here |
| '' |
| pkgs.mkShell { |
| /* ... */ |
| # This environment variable tells bootstrap where our bootstrap.toml is. |
| RUST_BOOTSTRAP_CONFIG = config; |
| } |
| </code></pre> |
| <h2 id="shell-completions"><a class="header" href="#shell-completions">Shell Completions</a></h2> |
| <p>If you use Bash, Zsh, Fish or PowerShell, you can find automatically-generated shell |
| completion scripts for <code>x.py</code> in |
| <a href="https://github.com/rust-lang/rust/tree/master/src/etc/completions"><code>src/etc/completions</code></a>.</p> |
| <p>You can use <code>source ./src/etc/completions/x.py.<extension></code> to load completions |
| for your shell of choice, or <code>& .\src\etc\completions\x.py.ps1</code> for PowerShell. |
| Adding this to your shell's startup script (e.g. <code>.bashrc</code>) will automatically |
| load this completion.</p> |
| |
| </main> |
| |
| <nav class="nav-wrapper" aria-label="Page navigation"> |
| <!-- Mobile navigation buttons --> |
| <a rel="prev" href="../building/prerequisites.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="../building/build-install-distribution-artifacts.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="../building/prerequisites.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="../building/build-install-distribution-artifacts.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> |