esp-rs / esp-idf-template

A "Hello, world!" template of a Rust binary crate for the ESP-IDF framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`rust-analyzer` unable to build esp-idf-hal

onkoe opened this issue · comments

Bug description

On both macOS and Fedora, when rust-analyzer attempts to do its LSP dirty work, it starts by building the project in the background. However, this work fails due to a build script panicking before it finishes.

This results in degraded IDE features, making the development experience on these boards unsatisfying and a tad difficult.

The complete build script output is as shown below:

rust-analyzer.txt

On the other hand, that leaves the CMakeOutput.log file as a potential cause. It doesn't seem particularly actionable. Still, here's the information it provides:

CMakeOutput.log.txt

  • Would you like to work on a fix? [y/n] I'm happy to take a look if we find a 'real' bug here! :)

To Reproduce

Steps to reproduce the behavior:

  1. Follow the installation instructions from the Rust on ESP Book.
  2. Set up ESP-IDF as mentioned here.
  3. Open up an editor that uses rust-analyzer.
  4. Wait a significant amount of time while it builds on your first-generation Ryzen.
  5. A build script should panic, failing to perform autocompletion and other LSP tasks.

Expected behavior

I love completions in Rust - they make API discovery much easier to grasp! I expect them to be in full operation per the typical Rust project.

Environment

Additional context

<! I'd like you to please add any other context about the problem here. -->

I was rather frustrated with this issue on my MacBook. As such, I assembled a desktop computer from old parts and installed a fresh copy of Fedora. To my dismay, the problem remains!

That said, I can still build/flash the project just fine. Instead of relying on my editor, I can use cargo watch -x "clippy"` - which works okay! Still, it's not fantastic, and I don't think it should be an issue in the first place.

p.s. the issue "troubleshooting section" link is broken in the bug report issue template! 🫣️

Have you configured rust-analyzer as described here? Look at the "UPDATE" section in the bug description.

Some more details:

I was rather frustrated with this issue on my MacBook. As such, I assembled a desktop computer from old parts and installed a fresh copy of Fedora. To my dismay, the problem remains!

There is nothing Linux-specific in the build setup, and it should work out of the box on Mac and Windows (on Windows, with short project path name, but that's all there is to it).

I'm sorry to hear that you have put so much effort into assembling an alternative environment. Perhaps you can join the Matrix room and ask around before taking such drastic measures. Or build a VM first? Anyway, all of this should be completely unnecessary - see below.

The complete build script output is as shown below:

rust-analyzer.txt

The build output seems to suggest that you are using the pio build. While there is nothing wrong with that - and it should work too, I have suspicions that's by mistake or by misconfiguration, as almost nobody uses the PlatformIO-based build these days, as it is much less flexible compared to the native build of esp-idf-sys. So let's start by switching you to the native build first. This is anyway the build type that is generated by esp-idf-template so that's why I'm suspicious here.

Would you please share the contents of your .cargo/config.toml file that you should be having in your binary crate?

Also, and very important would you share the build command used by your rust-analyzer? See again bug esp-rs/esp-idf-sys#113 for details why this is important.

  1. Wait a significant amount of time while it builds on your first-generation Ryzen.

I get the sarcasm here, but it is a bit unfounded. The build - during first time build only - downloads ALL of ESP IDF and ALL of the build toolchain executables which are necessary for the particular ESP IDF you are using. Afterwards these are cached, and once the rust-analyzer build issues are addressed, the build becomes incremental. The alternative would have been to ask YOU - as the user - to install all of this circus, which surely would've been much less convenient. :)

Woah, thanks for the detailed reply! ☺️

To address your first response, I don't use the esp toolchain, as the ESP32-C6 is officially supported! If it could help fix the problem, I'm happy to try it.

Anyway, there's no need to apologize for the quick computer build! It was fun, and I prefer Linux for this kind of debugging anyway. In my experience, any virtual machine on the M1 will have some jank, and Asahi Linux can't get around the page size issue. I'm used to macOS causing great pain during development - it's nothing new. ;)

Here's the generated .cargo/config.toml you requested! Please let me know if you need any more information about it.

[build]
target = "riscv32imac-esp-espidf"

[target.riscv32imac-esp-espidf]
linker = "ldproxy"
# runner = "espflash --monitor" # Select this runner for espflash v1.x.x
runner = "espflash flash --monitor" # Select this runner for espflash v2.x.x
rustflags = ["--cfg", "espidf_time64", "-C", "default-linker-libraries"]

[unstable]
build-std = ["std", "panic_abort"]

[env]
MCU="esp32c6"
# Note: this variable is not used by the pio builder (`cargo build --features pio`)
ESP_IDF_VERSION = "v5.1.1"

On the other hand, I have utterly failed for the past hour to get rust-analyzer to emit any helpful information about what build script command it's using. The 'default' command is just cargo check --quiet --workspace --message-format=json --all-targets - but that's not too useful. That's mentioned in the other issue, so it's not applicable, either.

If you have any suggestions on getting meaningful output from r-a without instantly filling the OUTPUT tab (that doesn't have configurable scrollback) or crashing VSCode, I'd love to try them out! I tried a few options, including recording slow-motion video on my phone. Still, it wipes the output nearly instantaneously, and there's no external logging option, according to the documentation. Whew!

I may end up trying other editors in the morning.

Finally, I completely agree that the whole automatic build thing is incredible! However, I've had some trouble with it. The first time took nearly 30 minutes, though that may be my internet. Subsequent builds have been significantly faster.

Thank you for the assistance so far - I hope we can get to the bottom of this! 😌️

Often rust-analyzer does not pick up the configuration environment correctly, with respect to files like .cargo/config.toml or rust-toolchain.toml . In vscode you can create custom configs for your rust-analyzer to manually tell it all that configs.

For example it can look like the following

  "rust-analyzer.cargo.target": "riscv32imc-esp-espidf",
    "rust-analyzer.cargo.extraEnv": {
        "ESP_IDF_VERSION": "v5.1.2",
        "MCU": "esp32c3",
        "RUSTFLAGS": "--cfg espidf_time64 -C default-linker-libraries",
    },
    "rust-analyzer.cargo.extraArgs": [
        "-Zbuild-std=std,panic_abort",
        "-Zbuild-std-features=panic_immediate_abort"
    ],
    "rust-analyzer.check.targets": "riscv32imc-esp-espidf",
    "rust-analyzer.check.extraArgs": [
        "-Zbuild-std=std,panic_abort",
        "-Zbuild-std-features=panic_immediate_abort"
    ],
    "rust-analyzer.check.extraEnv": {
        "ESP_IDF_VERSION": "v5.1.2",
        "MCU": "esp32c3",
        "RUSTFLAGS": "--cfg espidf_time64 -C default-linker-libraries",
    },

sometimes you also need to sprinkle in the LIBCLANG_PATH as an env variable it depends. In general ra will complain about such things :D

Before going with what @Vollbrecht suggested, which might be the heavy gun, let's try to fix your conf somehow.

rustflags = ["--cfg", "espidf_time64", "-C", "default-linker-libraries"]

Remove "-C", "default-linker-libraries". There is an opened pinned issue that we should not do this with ESP IDF 5+ anymore. In fact, I'm very surprised that it works for you in the presence of this flag! How recent is your nightly Rust? I suggest you update to latest nightly anyway.

On the other hand, I have utterly failed for the past hour to get rust-analyzer to emit any helpful information about what build script command it's using. The 'default' command is just cargo check --quiet --workspace --message-format=json --all-targets - but that's not too useful. That's mentioned in the other issue, so it's not applicable, either.

I think you can and should remove --all-targets at the very least. I would also enforce nightly, as if stable is your default, the build will fail for sure. So something like:
cargo +nightly check --quiet --workspace --message-format=json should be OK.

Can you also paste your Config.toml? It is very weird that the thing is trying to do a pio build. It should do a native build instead...

If you have any suggestions on getting meaningful output from r-a without instantly filling the OUTPUT tab (that doesn't have configurable scrollback) or crashing VSCode, I'd love to try them out! I tried a few options, including recording slow-motion video on my phone. Still, it wipes the output nearly instantaneously, and there's no external logging option, according to the documentation. Whew!

Hmmm. No gazillions of ideas. Maybe you can try to play with the above r-a command by making it wrong first on purpose, and then looking at the r-a logs if at least it is picking up your command?

I may end up trying other editors in the morning.

Not worth it, and in the end, they all rely on r-a anyway, so I suggest you stick to vscode (or code-server) and playing with r-a until it works.

(BTW - this is vscode - right - as you don't mention this explicitly anywhere?)

Finally, I completely agree that the whole automatic build thing is incredible! However, I've had some trouble with it. The first time took nearly 30 minutes, though that may be my internet. Subsequent builds have been significantly faster.

Your internet it is. The build initially downloads gigabytes of stuff (look at the .embuild folder inside your binary crate). Afterwards, it just uses this folder. Changing the ESP IDF version which is in use, or wiping out that folder will set you back into a 30 minutes initial build.

Also make sure that this setting does not contain "all" and in fact does not contain anything. If it is set to "all" that would explain why r-a tries to trigger a pio build in addition to a native one, and then it fails:

"rust-analyzer.cargo.features": []

(You can find the setting in the r-a configuration screen.)

Thanks for all the information! You were right that only minor modifications to the build command resulted in the correct output! :)

For example, this project_root/.vscode/settings.json fixed the problem:

{
    "rust-analyzer.cargo.buildScripts.overrideCommand": [
        "cargo",
        "+nightly",
        "check",
        "--quiet",
        "--workspace",
        "--message-format=json",
    ],
    "rust-analyzer.check.overrideCommand": [
        "cargo",
        "+nightly",
        "clippy",
        "--workspace",
        "--message-format=json",
    ],
    "rust-analyzer.cargo.features": [],
}

I also overrode the check command to use Clippy and apply the same optimizations we did for build scripts. Beforehand, clippy would work by default - however, it'd take 8 seconds to lint! ☺️

You also suggested modifying project_root/.cargo/config.toml to avoid the "-C", "default-linker-libraries" flags. Removing these doesn't affect building and linting - both work fine!

If there are any other changes you'd like me to test, I'm happy to do so! Otherwise, thank you so much for your help. I'm so excited to have this resolved! 😄️

No, that's it. I'll close the issue now. I think the culprit was that you were probably having "rust-analyzer.cargo.features": ["all"] which was triggering the PIO build. I'll open an issue for that in esp-idf-sys because ideally, the build should work even if all features are enabled.