about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs24
-rw-r--r--src/bootstrap/src/core/builder/tests.rs111
2 files changed, 132 insertions, 3 deletions
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 46b98a8e7ba..5ea74350445 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -54,6 +54,14 @@ impl LlvmBuildStatus {
             LlvmBuildStatus::ShouldBuild(_) => true,
         }
     }
+
+    #[cfg(test)]
+    pub fn llvm_result(&self) -> &LlvmResult {
+        match self {
+            LlvmBuildStatus::AlreadyBuilt(res) => res,
+            LlvmBuildStatus::ShouldBuild(meta) => &meta.res,
+        }
+    }
 }
 
 /// Linker flags to pass to LLVM's CMake invocation.
@@ -120,9 +128,19 @@ pub fn prebuilt_llvm_config(
     let root = "src/llvm-project/llvm";
     let out_dir = builder.llvm_out(target);
 
-    let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
-    llvm_config_ret_dir.push("bin");
-    let build_llvm_config = llvm_config_ret_dir.join(exe("llvm-config", builder.config.build));
+    let build_llvm_config = if let Some(build_llvm_config) = builder
+        .config
+        .target_config
+        .get(&builder.config.build)
+        .and_then(|config| config.llvm_config.clone())
+    {
+        build_llvm_config
+    } else {
+        let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
+        llvm_config_ret_dir.push("bin");
+        llvm_config_ret_dir.join(exe("llvm-config", builder.config.build))
+    };
+
     let llvm_cmake_dir = out_dir.join("lib/cmake/llvm");
     let res = LlvmResult { llvm_config: build_llvm_config, llvm_cmake_dir };
 
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 74e1ed5c637..994975ed5a8 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1,5 +1,7 @@
 use std::thread;
 
+use llvm::prebuilt_llvm_config;
+
 use super::*;
 use crate::Flags;
 use crate::core::build_steps::doc::DocumentationFormat;
@@ -954,3 +956,112 @@ fn test_test_coverage() {
         assert_eq!(modes, expected);
     }
 }
+
+#[test]
+fn test_prebuilt_llvm_config_path_resolution() {
+    fn configure(config: &str) -> Config {
+        Config::parse_inner(
+            Flags::parse(&[
+                "build".to_string(),
+                "--dry-run".to_string(),
+                "--config=/does/not/exist".to_string(),
+            ]),
+            |&_| toml::from_str(&config),
+        )
+    }
+
+    // Removes Windows disk prefix if present
+    fn drop_win_disk_prefix_if_present(path: PathBuf) -> PathBuf {
+        let path_str = path.to_str().unwrap();
+        if let Some((_, without_prefix)) = path_str.split_once(":/") {
+            return PathBuf::from(format!("/{}", without_prefix));
+        }
+
+        path
+    }
+
+    let config = configure(
+        r#"
+            [llvm]
+            download-ci-llvm = false
+
+            [build]
+            build = "x86_64-unknown-linux-gnu"
+            host = ["arm-unknown-linux-gnueabihf"]
+            target = ["arm-unknown-linux-gnueabihf"]
+
+            [target.x86_64-unknown-linux-gnu]
+            llvm-config = "/some/path/to/llvm-config"
+
+            [target.arm-unknown-linux-gnueabihf]
+            cc = "arm-linux-gnueabihf-gcc"
+            cxx = "arm-linux-gnueabihf-g++"
+        "#,
+    );
+
+    let build = Build::new(config);
+    let builder = Builder::new(&build);
+
+    let expected = PathBuf::from("/some/path/to/llvm-config");
+
+    let actual = prebuilt_llvm_config(
+        &builder,
+        TargetSelection::from_user("arm-unknown-linux-gnueabihf"),
+        false,
+    )
+    .llvm_result()
+    .llvm_config
+    .clone();
+    let actual = drop_win_disk_prefix_if_present(actual);
+    assert_eq!(expected, actual);
+
+    let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+        .llvm_result()
+        .llvm_config
+        .clone();
+    let actual = drop_win_disk_prefix_if_present(actual);
+    assert_eq!(expected, actual);
+    assert_eq!(expected, actual);
+
+    let config = configure(
+        r#"
+            [llvm]
+            download-ci-llvm = false
+        "#,
+    );
+
+    let build = Build::new(config.clone());
+    let builder = Builder::new(&build);
+
+    let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+        .llvm_result()
+        .llvm_config
+        .clone();
+    let expected = builder
+        .out
+        .join(builder.config.build)
+        .join("llvm/bin")
+        .join(exe("llvm-config", builder.config.build));
+    assert_eq!(expected, actual);
+
+    let config = configure(
+        r#"
+            [llvm]
+            download-ci-llvm = true
+        "#,
+    );
+
+    let build = Build::new(config.clone());
+    let builder = Builder::new(&build);
+
+    let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+        .llvm_result()
+        .llvm_config
+        .clone();
+    let expected = builder
+        .out
+        .join(builder.config.build)
+        .join("ci-llvm/bin")
+        .join(exe("llvm-config", builder.config.build));
+    assert_eq!(expected, actual);
+}