about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-13 22:53:31 +0000
committerbors <bors@rust-lang.org>2022-04-13 22:53:31 +0000
commit15844bf48ce6bd4aaba7c26fa3df76415903aec1 (patch)
tree8be1a2f07997f5011df0fb55f5f64f3f44470902
parent8ab26f6abcf3d2617b229813846f9a72264e83b6 (diff)
parent73a033e77c830ef793a1c302a4794bf73a8c61c4 (diff)
downloadrust-15844bf48ce6bd4aaba7c26fa3df76415903aec1.tar.gz
rust-15844bf48ce6bd4aaba7c26fa3df76415903aec1.zip
Auto merge of #11956 - fee1-dead:master, r=flodiebold
feat: allow customizing the command for running build scripts

I have tested this locally and it fixed #9201 with some small changes on the compiler side with suggestions from https://github.com/rust-analyzer/rust-analyzer/issues/9201#issuecomment-1019554086.

I have also added an environment variable `IS_RA_BUILDSCRIPT_CHECK` for crates to detect that it is a check for buildscripts, and allows defaulting to bogus values for expected environment variables.
-rw-r--r--crates/project_model/src/build_scripts.rs43
-rw-r--r--crates/project_model/src/cargo_workspace.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs5
-rw-r--r--docs/user/generated_config.adoc7
-rw-r--r--editors/code/package.json11
5 files changed, 53 insertions, 15 deletions
diff --git a/crates/project_model/src/build_scripts.rs b/crates/project_model/src/build_scripts.rs
index 6b601c34a24..d96c135ba5e 100644
--- a/crates/project_model/src/build_scripts.rs
+++ b/crates/project_model/src/build_scripts.rs
@@ -42,22 +42,15 @@ pub(crate) struct BuildScriptOutput {
 }
 
 impl WorkspaceBuildScripts {
-    pub(crate) fn run(
-        config: &CargoConfig,
-        workspace: &CargoWorkspace,
-        progress: &dyn Fn(String),
-    ) -> Result<WorkspaceBuildScripts> {
+    fn build_command(config: &CargoConfig) -> Command {
+        if let Some([program, args @ ..]) = config.run_build_script_command.as_deref() {
+            let mut cmd = Command::new(program);
+            cmd.args(args);
+            return cmd;
+        }
+
         let mut cmd = Command::new(toolchain::cargo());
 
-        if config.wrap_rustc_in_build_scripts {
-            // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
-            // that to compile only proc macros and build scripts during the initial
-            // `cargo check`.
-            let myself = std::env::current_exe()?;
-            cmd.env("RUSTC_WRAPPER", myself);
-            cmd.env("RA_RUSTC_WRAPPER", "1");
-        }
-        cmd.current_dir(workspace.workspace_root());
         cmd.args(&["check", "--quiet", "--workspace", "--message-format=json"]);
 
         // --all-targets includes tests, benches and examples in addition to the
@@ -81,6 +74,26 @@ impl WorkspaceBuildScripts {
             }
         }
 
+        cmd
+    }
+    pub(crate) fn run(
+        config: &CargoConfig,
+        workspace: &CargoWorkspace,
+        progress: &dyn Fn(String),
+    ) -> Result<WorkspaceBuildScripts> {
+        let mut cmd = Self::build_command(config);
+
+        if config.wrap_rustc_in_build_scripts {
+            // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
+            // that to compile only proc macros and build scripts during the initial
+            // `cargo check`.
+            let myself = std::env::current_exe()?;
+            cmd.env("RUSTC_WRAPPER", myself);
+            cmd.env("RA_RUSTC_WRAPPER", "1");
+        }
+
+        cmd.current_dir(workspace.workspace_root());
+
         cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null());
 
         let mut res = WorkspaceBuildScripts::default();
@@ -104,7 +117,7 @@ impl WorkspaceBuildScripts {
                 }
 
                 // Copy-pasted from existing cargo_metadata. It seems like we
-                // should be using sered_stacker here?
+                // should be using serde_stacker here?
                 let mut deserializer = serde_json::Deserializer::from_str(line);
                 deserializer.disable_recursion_limit();
                 let message = Message::deserialize(&mut deserializer)
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs
index 48051e4b5e8..76ef44e1471 100644
--- a/crates/project_model/src/cargo_workspace.rs
+++ b/crates/project_model/src/cargo_workspace.rs
@@ -96,6 +96,8 @@ pub struct CargoConfig {
     pub unset_test_crates: UnsetTestCrates,
 
     pub wrap_rustc_in_build_scripts: bool,
+
+    pub run_build_script_command: Option<Vec<String>>,
 }
 
 impl CargoConfig {
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index ab9ad4a5431..64b60a23a6e 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -78,6 +78,10 @@ config_data! {
         /// Run build scripts (`build.rs`) for more precise code analysis.
         cargo_runBuildScripts |
         cargo_loadOutDirsFromCheck: bool = "true",
+        /// Advanced option, fully override the command rust-analyzer uses to
+        /// run build scripts and build procedural macros. The command should
+        /// include `--message-format=json` or a similar option.
+        cargo_runBuildScriptsCommand: Option<Vec<String>> = "null",
         /// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
         /// avoid compiling unnecessary things.
         cargo_useRustcWrapperForBuildScripts: bool = "true",
@@ -834,6 +838,7 @@ impl Config {
             rustc_source,
             unset_test_crates: UnsetTestCrates::Only(self.data.cargo_unsetTest.clone()),
             wrap_rustc_in_build_scripts: self.data.cargo_useRustcWrapperForBuildScripts,
+            run_build_script_command: self.data.cargo_runBuildScriptsCommand.clone(),
         }
     }
 
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index d552982768b..ace74f8e08a 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -64,6 +64,13 @@ List of features to activate.
 --
 Run build scripts (`build.rs`) for more precise code analysis.
 --
+[[rust-analyzer.cargo.runBuildScriptsCommand]]rust-analyzer.cargo.runBuildScriptsCommand (default: `null`)::
++
+--
+Advanced option, fully override the command rust-analyzer uses to
+run build scripts and build procedural macros. The command should
+include `--message-format=json` or a similar option.
+--
 [[rust-analyzer.cargo.useRustcWrapperForBuildScripts]]rust-analyzer.cargo.useRustcWrapperForBuildScripts (default: `true`)::
 +
 --
diff --git a/editors/code/package.json b/editors/code/package.json
index bbc7feef7ec..7860d18758a 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -476,6 +476,17 @@
                     "default": true,
                     "type": "boolean"
                 },
+                "rust-analyzer.cargo.runBuildScriptsCommand": {
+                    "markdownDescription": "Advanced option, fully override the command rust-analyzer uses to\nrun build scripts and build procedural macros. The command should\ninclude `--message-format=json` or a similar option.",
+                    "default": null,
+                    "type": [
+                        "null",
+                        "array"
+                    ],
+                    "items": {
+                        "type": "string"
+                    }
+                },
                 "rust-analyzer.cargo.useRustcWrapperForBuildScripts": {
                     "markdownDescription": "Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to\navoid compiling unnecessary things.",
                     "default": true,