From 34a13c2e52d15aa62d7314dfd9e307c8910c0aae Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Sat, 28 Sep 2024 13:09:48 +0100 Subject: [PATCH] building/suggested: Add instructions for Emacs & Helix (#2080) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> --- src/building/suggested.md | 309 +++++++++++++++++++++----------------- 1 file changed, 171 insertions(+), 138 deletions(-) diff --git a/src/building/suggested.md b/src/building/suggested.md index 667c9fc8a..f532bfd7e 100644 --- a/src/building/suggested.md +++ b/src/building/suggested.md @@ -1,46 +1,53 @@ # Suggested Workflows -The full bootstrapping process takes quite a while. Here are some suggestions -to make your life easier. +The full bootstrapping process takes quite a while. Here are some suggestions to +make your life easier. ## Installing a pre-push hook -CI will automatically fail your build if it doesn't pass `tidy`, our -internal tool for ensuring code quality. If you'd like, you can install a -[Git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) -that will automatically run `./x test tidy` on each push, to ensure -your code is up to par. If the hook fails then run `./x test tidy --bless` -and commit the changes. If you decide later that the pre-push behavior is -undesirable, you can delete the `pre-push` file in `.git/hooks`. +CI will automatically fail your build if it doesn't pass `tidy`, our internal +tool for ensuring code quality. If you'd like, you can install a [Git +hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) that will +automatically run `./x test tidy` on each push, to ensure your code is up to +par. If the hook fails then run `./x test tidy --bless` and commit the changes. +If you decide later that the pre-push behavior is undesirable, you can delete +the `pre-push` file in `.git/hooks`. -A prebuilt git hook lives at [`src/etc/pre-push.sh`](https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh) which can be copied into your `.git/hooks` folder as `pre-push` (without the `.sh` extension!). +A prebuilt git hook lives at +[`src/etc/pre-push.sh`](https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh) +which can be copied into your `.git/hooks` folder as `pre-push` (without the +`.sh` extension!). You can also install the hook as a step of running `./x setup`! ## Configuring `rust-analyzer` for `rustc` +### Project-local rust-analyzer setup + +`rust-analyzer` can help you check and format your code whenever you save a +file. By default, `rust-analyzer` runs the `cargo check` and `rustfmt` commands, +but you can override these commands to use more adapted versions of these tools +when hacking on `rustc`. With custom setup, `rust-analyzer` can use `./x check` +to check the sources, and the stage 0 rustfmt to format them. + +The default `rust-analyzer.check.overrideCommand` 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 `x check compiler --json-output` to only check the compiler part. +You can run `x check --help --verbose` to see the available parts. + +If you have enough free disk space and you would like to be able to run `x` +commands while rust-analyzer runs in the background, you can also add +`--build-dir build-rust-analyzer` to the `overrideCommand` to avoid x locking. + ### Visual Studio Code -`rust-analyzer` can help you check and format your code whenever you save -a file. By default, `rust-analyzer` runs the `cargo check` and `rustfmt` -commands, but you can override these commands to use more adapted versions -of these tools when hacking on `rustc`. For example, `x setup vscode` will prompt -you to create a `.vscode/settings.json` file which will configure Visual Studio code. -This will ask `rust-analyzer` to use `./x check` to check the sources, and the -stage 0 rustfmt to format them. -The recommended `rust-analyzer` settings live at [`src/etc/rust_analyzer_settings.json`]. - -The default `rust-analyzer.check.overrideCommand` 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 `x check compiler --json-output` to only -check the compiler part. You can run `x check --help --verbose` to see the available parts. - -If you have enough free disk space and you would like to be able to run `x` commands while -rust-analyzer runs in the background, you can also add `--build-dir build-rust-analyzer` to the -`overrideCommand` to avoid x locking. +Running `./x setup vscode` will prompt you to create a `.vscode/settings.json` +file which will configure Visual Studio code. The recommended `rust-analyzer` +settings live at [`src/etc/rust_analyzer_settings.json`]. If running `./x check` on save is inconvenient, in VS Code you can use a [Build Task] instead: @@ -67,62 +74,87 @@ Task] instead: ### Neovim -For Neovim users there are several options for configuring for rustc. The easiest way is by using -[neoconf.nvim](https://github.com/folke/neoconf.nvim/), 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 [found here](https://rust-analyzer.github.io/manual.html#nvim-lsp). - -1. First install the plugin. This can be done by following the steps in the README. -2. Run `x setup`, which will have a prompt for it to create a `.vscode/settings.json` file. - `neoconf` is able to read and update rust-analyzer settings automatically when the project is - opened when this file is detected. - -If you're running `coc.nvim`, -you can use `:CocLocalConfig` to create a `.vim/coc-settings.json`, -and copy the settings from [`src/etc/rust_analyzer_settings.json`]. - -Another way is without a plugin, and creating your own logic in your configuration. To do this you -must translate the JSON to Lua yourself. The translation is 1:1 and fairly straight-forward. It -must be put in the `["rust-analyzer"]` key of the setup table, which is -[shown here](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#rust_analyzer). - -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 -[overseer.nvim](https://github.com/stevearc/overseer.nvim) that can [read VSCode's `task.json` -files](https://github.com/stevearc/overseer.nvim/blob/master/doc/guides.md#vs-code-tasks), and -follow the same instructions as above. +For Neovim users there are several options for configuring for rustc. The +easiest way is by using [neoconf.nvim](https://github.com/folke/neoconf.nvim/), +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 [found +here](https://rust-analyzer.github.io/manual.html#nvim-lsp). + +1. First install the plugin. This can be done by following the steps in the + README. +2. Run `x setup`, which will have a prompt for it to create a + `.vscode/settings.json` file. `neoconf` is able to read and update + rust-analyzer settings automatically when the project is opened when this + file is detected. + +If you're running `coc.nvim`, you can use `:CocLocalConfig` to create a +`.vim/coc-settings.json`, and copy the settings from +[`src/etc/rust_analyzer_settings.json`]. + +Another way is without a plugin, and creating your own logic in your +configuration. To do this you must translate the JSON to Lua yourself. The +translation is 1:1 and fairly straight-forward. It must be put in the +`["rust-analyzer"]` key of the setup table, which is [shown +here](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#rust_analyzer). + +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 +[overseer.nvim](https://github.com/stevearc/overseer.nvim) that can [read +VSCode's `task.json` +files](https://github.com/stevearc/overseer.nvim/blob/master/doc/guides.md#vs-code-tasks), +and follow the same instructions as above. + +### Emacs + +Emacs provides support for rust-analyzer with project-local configuration +through [Eglot](https://www.gnu.org/software/emacs/manual/html_node/eglot/). +Steps for setting up Eglot with rust-analyzer can be [found +here](https://rust-analyzer.github.io/manual.html#eglot). +Having set up Emacs & Eglot for Rust development in general, you can use the +configuration for rustc provided in [`src/etc/rust_analyzer_eglot.el`]. +Simply copy the provided file to `.dir-locals.el` in the project root directory. +For more information on project-specific Eglot configuration, consult [the +manual](https://www.gnu.org/software/emacs/manual/html_node/eglot/Project_002dspecific-configuration.html). + +### Helix + +Helix comes with built-in LSP and rust-analyzer support. +It can be configured through `languages.toml`, as described +[here](https://docs.helix-editor.com/languages.html). +You can use the configuration for rustc provided in +[`src/etc/rust_analyzer_helix.toml`]. +Simply copy the provided file to `.helix/languages.toml` in the project root +directory. ## Check, check, and check again When doing simple refactorings, it can be useful to run `./x check` -continuously. If you set up `rust-analyzer` as described above, this will -be done for you every time you save a file. Here you are just checking that -the compiler can **build**, but often that is all you need (e.g., when renaming a -method). You can then run `./x build` when you actually need to -run tests. - -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 `git bisect` to track down **precisely** 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. +continuously. If you set up `rust-analyzer` as described above, this will be +done for you every time you save a file. Here you are just checking that the +compiler can **build**, but often that is all you need (e.g., when renaming a +method). You can then run `./x build` when you actually need to run tests. + +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 `git bisect` to track down +**precisely** 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. ## `x suggest` The `x suggest` subcommand suggests (and runs) a subset of the extensive -`rust-lang/rust` tests based on files you have changed. This is especially useful -for new contributors who have not mastered the arcane `x` flags yet and more -experienced contributors as a shorthand for reducing mental effort. In all cases -it is useful not to run the full tests (which can take on the order of tens of -minutes) and just run a subset which are relevant to your changes. For example, -running `tidy` and `linkchecker` is useful when editing Markdown files, whereas UI -tests are much less likely to be helpful. While `x suggest` is a useful tool, it -does not guarantee perfect coverage (just as PR CI isn't a substitute for bors). -See the [dedicated chapter](../tests/suggest-tests.md) for more information and -contribution instructions. +`rust-lang/rust` tests based on files you have changed. This is especially +useful for new contributors who have not mastered the arcane `x` flags yet and +more experienced contributors as a shorthand for reducing mental effort. In all +cases it is useful not to run the full tests (which can take on the order of +tens of minutes) and just run a subset which are relevant to your changes. For +example, running `tidy` and `linkchecker` is useful when editing Markdown files, +whereas UI tests are much less likely to be helpful. While `x suggest` is a +useful tool, it does not guarantee perfect coverage (just as PR CI isn't a +substitute for bors). See the [dedicated chapter](../tests/suggest-tests.md) for +more information and contribution instructions. Please note that `x suggest` is in a beta state currently and the tests that it will suggest are limited. @@ -137,12 +169,14 @@ cd rustup override set nightly ``` -after [installing a nightly toolchain] with `rustup`. Don't forget to do this for all -directories you have [setup a worktree for]. You may need to use the pinned -nightly version from `src/stage0`, but often the normal `nightly` channel will work. +after [installing a nightly toolchain] with `rustup`. Don't forget to do this +for all directories you have [setup a worktree for]. You may need to use the +pinned nightly version from `src/stage0`, but often the normal `nightly` channel +will work. -**Note** see [the section on vscode] for how to configure it with this real rustfmt `x` uses, -and [the section on rustup] for how to setup `rustup` toolchain for your bootstrapped compiler +**Note** see [the section on vscode] for how to configure it with this real +rustfmt `x` uses, and [the section on rustup] for how to setup `rustup` +toolchain for your bootstrapped compiler **Note** This does _not_ allow you to build `rustc` with cargo directly. You still have to use `x` to work on the compiler or standard library, this just @@ -155,42 +189,38 @@ lets you use `cargo fmt`. ## Faster builds with `--keep-stage`. -Sometimes just checking -whether the compiler builds is not enough. A common example is that -you need to add a `debug!` statement to inspect the value of some -state or better understand the problem. In that case, you don't really need +Sometimes just checking whether the compiler builds is not enough. A common +example is that you need to add a `debug!` statement to inspect the value of +some state or better understand the problem. In that case, you don't really need a full build. By bypassing bootstrap's cache invalidation, you can often get -these builds to complete very fast (e.g., around 30 seconds). The only -catch is this requires a bit of fudging and may produce compilers that -don't work (but that is easily detected and fixed). +these builds to complete very fast (e.g., around 30 seconds). The only catch is +this requires a bit of fudging and may produce compilers that don't work (but +that is easily detected and fixed). The sequence of commands you want is as follows: - Initial build: `./x build library` - - As [documented previously], this will build a functional - stage1 compiler as part of running all stage0 commands (which include - building a `std` compatible with the stage1 compiler) as well as the - first few steps of the "stage 1 actions" up to "stage1 (sysroot stage1) - builds std". + - As [documented previously], this will build a functional stage1 compiler as + part of running all stage0 commands (which include building a `std` + compatible with the stage1 compiler) as well as the first few steps of the + "stage 1 actions" up to "stage1 (sysroot stage1) builds std". - Subsequent builds: `./x build library --keep-stage 1` - Note that we added the `--keep-stage 1` flag here [documented previously]: ./how-to-build-and-run.md#building-the-compiler As mentioned, the effect of `--keep-stage 1` is that we just _assume_ that the -old standard library can be re-used. If you are editing the compiler, this -is almost always true: you haven't changed the standard library, after -all. But sometimes, it's not true: for example, if you are editing -the "metadata" part of the compiler, which controls how the compiler -encodes types and other states into the `rlib` files, or if you are -editing things that wind up in the metadata (such as the definition of -the MIR). - -**The TL;DR is that you might get weird behavior from a compile when -using `--keep-stage 1`** -- for example, strange -[ICEs](../appendix/glossary.html#ice) or other panics. In that case, you -should simply remove the `--keep-stage 1` from the command and -rebuild. That ought to fix the problem. +old standard library can be re-used. If you are editing the compiler, this is +almost always true: you haven't changed the standard library, after all. But +sometimes, it's not true: for example, if you are editing the "metadata" part of +the compiler, which controls how the compiler encodes types and other states +into the `rlib` files, or if you are editing things that wind up in the metadata +(such as the definition of the MIR). + +**The TL;DR is that you might get weird behavior from a compile when using +`--keep-stage 1`** -- for example, strange [ICEs](../appendix/glossary.html#ice) +or other panics. In that case, you should simply remove the `--keep-stage 1` +from the command and rebuild. That ought to fix the problem. You can also use `--keep-stage 1` when running tests. Something like this: @@ -199,24 +229,24 @@ You can also use `--keep-stage 1` when running tests. Something like this: ## Using incremental compilation -You can further enable the `--incremental` flag to save additional -time in subsequent rebuilds: +You can further enable the `--incremental` flag to save additional time in +subsequent rebuilds: ```bash ./x test tests/ui --incremental --test-args issue-1234 ``` -If you don't want to include the flag with every command, you can -enable it in the `config.toml`: +If you don't want to include the flag with every command, you can enable it in +the `config.toml`: ```toml [rust] incremental = true ``` -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 `build` directory from time to time. +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 `build` +directory from time to time. ## Fine-tuning optimizations @@ -238,23 +268,23 @@ opt-level = 0 ## Working on multiple branches at the same time 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. - -Fortunately, Git has a better solution called [worktrees]. 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. +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. + +Fortunately, Git has a better solution called [worktrees]. 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. [worktrees]: https://git-scm.com/docs/git-worktree -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: +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: ```bash git worktree add ../rust2 @@ -266,8 +296,8 @@ Creating a new worktree for a new branch based on `master` looks like: git worktree add -b my-feature ../rust2 master ``` -You can then use that rust2 folder as a separate workspace for modifying -and building `rustc`! +You can then use that rust2 folder as a separate workspace for modifying and +building `rustc`! ## Using nix-shell @@ -293,9 +323,9 @@ pkgs.mkShell { ``` Note that when using nix on a not-NixOS distribution, it may be necessary to set -**`patch-binaries-for-nix = true` in `config.toml`**. -Bootstrap tries to detect whether it's running in nix and enable patching automatically, -but this detection can have false negatives. +**`patch-binaries-for-nix = true` in `config.toml`**. Bootstrap tries to detect +whether it's running in nix and enable patching automatically, but this +detection can have false negatives. You can also use your nix shell to manage `config.toml`: @@ -313,12 +343,15 @@ pkgs.mkShell { ## Shell Completions -If you use Bash, Fish or PowerShell, you can find automatically-generated shell completion scripts for `x.py` in [`src/etc/completions`](https://github.com/rust-lang/rust/tree/master/src/etc/completions). -Zsh support will also be included once issues with [`clap_complete`](https://crates.io/crates/clap_complete) have been resolved. +If you use Bash, Fish or PowerShell, you can find automatically-generated shell +completion scripts for `x.py` in +[`src/etc/completions`](https://github.com/rust-lang/rust/tree/master/src/etc/completions). +Zsh support will also be included once issues with +[`clap_complete`](https://crates.io/crates/clap_complete) have been resolved. -You can use `source ./src/etc/completions/x.py.` -to load completions for your shell of choice, -or `& .\src\etc\completions\x.py.ps1` for PowerShell. -Adding this to your shell's startup script (e.g. `.bashrc`) will automatically load this completion. +You can use `source ./src/etc/completions/x.py.` to load completions +for your shell of choice, or `& .\src\etc\completions\x.py.ps1` for PowerShell. +Adding this to your shell's startup script (e.g. `.bashrc`) will automatically +load this completion. [`src/etc/rust_analyzer_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json