cognitive-engineering-lab / rustc_plugin

A framework for writing plugins that integrate with the Rust compiler
MIT License
135 stars 16 forks source link

Working with Nixos #26

Open StealthyKamereon opened 4 months ago

StealthyKamereon commented 4 months ago

Hello,

I would like to make a plugin on Nixos but I'm facing problems. I get the following error: unresolved extern crate on:

extern crate rustc_driver;
extern crate rustc_interface;
extern crate rustc_middle;
extern crate rustc_session;

However, if I cargo check everything compiles fine.

I have poured tens of hours trying to understand what's wrong. I would greatly appreciate if someone see's something I'm missing.

I hope this could serve as a documentation for other people using Nixos.

My environment is the following

shell.nix

{ nixpkgs ? import <nixpkgs> { }}:

let
  rustOverlay = builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz";
  pinnedPkgs = nixpkgs.fetchFromGitHub {
    owner  = "NixOS";
    repo   = "nixpkgs";
    rev    = "b3fcfcfabd01b947a1e4f36622bbffa3985bdac6";
    sha256 = "0va68ddkrqb6j349rsbkjhdq7m243kg9njcqhnx9p2sbrcl2g5l8";
  };
  pkgs = import pinnedPkgs {
    overlays = [ (import rustOverlay) ];
  };
  rust_pkg = pkgs.rust-bin.nightly."2024-05-20".default.override {
    extensions = ["rust-src" "rustc" "rustc-dev" "llvm-tools" "rust-analyzer" "cargo"];
  };
in
  pkgs.mkShell {
    buildInputs = with pkgs; [
      (
        rust_pkg
      )
      openssl
      pkg-config
      eza
      fd
    ];

    RUST_BACKTRACE = 1;
    RUST_SRC_PATH = "${rust_pkg}/lib/rustlib/src/rust/library";
  }

This allows to build all the required components.

Code

I have cloned the crates/rustc_plugin/examples/print-all-items example. I made some tweaks that I feel relevant. In Cargo.toml:

[dependencies]
- rustc_plugin = { path = "../.." }
+ rustc_plugin = "=0.10.0-nightly-2024-05-20"
env_logger = "0.10"

I also set the following setting in rust-analyzer's config:

rust_analyzer = {
  cargo = {
    features = "all",
  },
  rustc = { source = "discover" },
},

Thanks in advance

StealthyKamereon commented 3 months ago

For those who can't wait a fix, I found a dirty workaround. Make a directory in your project and create a auxiliary nix store by copying the rust package :

# Set the RUST_PKG with the shell.nix. For example, my RUST_PKG contains the following:
export RUST_PKG=/nix/store/v0769idpz76l6b3xff8ps98bcsy5ymjb-rust-default-1.80.0-nightly-2024-05-20

nix copy --to /<project-dir>/local-store $RUST_PKG --no-check-sigs

This will take care of copying all the necessary packages.

Then simply enable writing in the local store:

chmod u+w -R /<project-dir>/local-store

You then need to tell your lsp where your sysroot is. For example, I have these settings for vscode:

{
    "rust-analyzer.server.path": "/<project-dir>/local-store/nix/store/v0769idpz76l6b3xff8ps98bcsy5ymjb-rust-default-1.80.0-nightly-2024-05-20/bin/rust-analyzer",
    "rust-analyzer.cargo.sysroot": "/<project-dir>/local-store/nix/store/v0769idpz76l6b3xff8ps98bcsy5ymjb-rust-default-1.80.0-nightly-2024-05-20/",
    "rust-analyzer.rustc.source": "discover"
}
willcrichton commented 3 months ago

HI @StealthyKamereon, thanks for letting me know. I know nothing about Nix so I can't be of any help, but I'm glad you've found some workarounds. @gavinleroy lmk if you have any ideas.

gavinleroy commented 3 months ago

Hi @StealthyKamereon 👋 I haven't run into the issue that you've described. I recently started using Nix (read, everything I do could be slightly broken) and you may find the shell env for my current project useful. It's located here, I use flakes, but I don't see any major differences between the two configurations on first glance.

Edit, the main difference is how I load the toolchain from a rust-toolchain.toml, but I don't think that should make a difference.