summaryrefslogtreecommitdiffstats
path: root/third_party/rust/clang-sys/tests/build.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/clang-sys/tests/build.rs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/clang-sys/tests/build.rs')
-rw-r--r--third_party/rust/clang-sys/tests/build.rs281
1 files changed, 281 insertions, 0 deletions
diff --git a/third_party/rust/clang-sys/tests/build.rs b/third_party/rust/clang-sys/tests/build.rs
new file mode 100644
index 0000000000..224421b221
--- /dev/null
+++ b/third_party/rust/clang-sys/tests/build.rs
@@ -0,0 +1,281 @@
+#![allow(dead_code)]
+
+extern crate glob;
+extern crate serial_test;
+extern crate tempdir;
+
+use std::collections::HashMap;
+use std::env;
+use std::fs;
+use std::path::PathBuf;
+use std::sync::Arc;
+use std::sync::Mutex;
+
+use serial_test::serial;
+use tempdir::TempDir;
+
+#[macro_use]
+#[path = "../build/macros.rs"]
+mod macros;
+
+#[path = "../build/common.rs"]
+mod common;
+#[path = "../build/dynamic.rs"]
+mod dynamic;
+#[path = "../build/static.rs"]
+mod r#static;
+
+#[derive(Debug, Default)]
+struct RunCommandMock {
+ invocations: Vec<(String, String, Vec<String>)>,
+ responses: HashMap<Vec<String>, String>,
+}
+
+#[derive(Debug)]
+struct Env {
+ os: String,
+ pointer_width: String,
+ env: Option<String>,
+ vars: HashMap<String, (Option<String>, Option<String>)>,
+ cwd: PathBuf,
+ tmp: TempDir,
+ files: Vec<String>,
+ commands: Arc<Mutex<RunCommandMock>>,
+}
+
+impl Env {
+ fn new(os: &str, pointer_width: &str) -> Self {
+ Env {
+ os: os.into(),
+ pointer_width: pointer_width.into(),
+ env: None,
+ vars: HashMap::new(),
+ cwd: env::current_dir().unwrap(),
+ tmp: TempDir::new("clang_sys_test").unwrap(),
+ files: vec![],
+ commands: Default::default(),
+ }
+ .var("CLANG_PATH", None)
+ .var("LD_LIBRARY_PATH", None)
+ .var("LIBCLANG_PATH", None)
+ .var("LIBCLANG_STATIC_PATH", None)
+ .var("LLVM_CONFIG_PATH", None)
+ .var("PATH", None)
+ }
+
+ fn env(mut self, env: &str) -> Self {
+ self.env = Some(env.into());
+ self
+ }
+
+ fn var(mut self, name: &str, value: Option<&str>) -> Self {
+ let previous = env::var(name).ok();
+ self.vars.insert(name.into(), (value.map(|v| v.into()), previous));
+ self
+ }
+
+ fn dir(mut self, path: &str) -> Self {
+ self.files.push(path.into());
+ let path = self.tmp.path().join(path);
+ fs::create_dir_all(path).unwrap();
+ self
+ }
+
+ fn file(mut self, path: &str, contents: &[u8]) -> Self {
+ self.files.push(path.into());
+ let path = self.tmp.path().join(path);
+ fs::create_dir_all(path.parent().unwrap()).unwrap();
+ fs::write(self.tmp.path().join(path), contents).unwrap();
+ self
+ }
+
+ fn dll(self, path: &str, pointer_width: &str) -> Self {
+ // PE header.
+ let mut contents = [0; 64];
+ contents[0x3C..0x3C + 4].copy_from_slice(&i32::to_le_bytes(10));
+ contents[10..14].copy_from_slice(&[b'P', b'E', 0, 0]);
+ let magic = if pointer_width == "64" { 523 } else { 267 };
+ contents[34..36].copy_from_slice(&u16::to_le_bytes(magic));
+
+ self.file(path, &contents)
+ }
+
+ fn so(self, path: &str, pointer_width: &str) -> Self {
+ // ELF header.
+ let class = if pointer_width == "64" { 2 } else { 1 };
+ let contents = [127, 69, 76, 70, class];
+
+ self.file(path, &contents)
+ }
+
+ fn command(self, command: &str, args: &[&str], response: &str) -> Self {
+ let command = command.to_string();
+ let args = args.iter().map(|a| a.to_string()).collect::<Vec<_>>();
+
+ let mut key = vec![command];
+ key.extend(args);
+ self.commands.lock().unwrap().responses.insert(key, response.into());
+
+ self
+ }
+
+ fn enable(self) -> Self {
+ env::set_var("_CLANG_SYS_TEST", "yep");
+ env::set_var("_CLANG_SYS_TEST_OS", &self.os);
+ env::set_var("_CLANG_SYS_TEST_POINTER_WIDTH", &self.pointer_width);
+ if let Some(env) = &self.env {
+ env::set_var("_CLANG_SYS_TEST_ENV", env);
+ }
+
+ for (name, (value, _)) in &self.vars {
+ if let Some(value) = value {
+ env::set_var(name, value);
+ } else {
+ env::remove_var(name);
+ }
+ }
+
+ env::set_current_dir(&self.tmp).unwrap();
+
+ let commands = self.commands.clone();
+ let mock = &mut *common::RUN_COMMAND_MOCK.lock().unwrap();
+ *mock = Some(Box::new(move |command, path, args| {
+ let command = command.to_string();
+ let path = path.to_string();
+ let args = args.iter().map(|a| a.to_string()).collect::<Vec<_>>();
+
+ let mut commands = commands.lock().unwrap();
+ commands.invocations.push((command.clone(), path, args.clone()));
+
+ let mut key = vec![command];
+ key.extend(args);
+ commands.responses.get(&key).cloned()
+ }));
+
+ self
+ }
+}
+
+impl Drop for Env {
+ fn drop(&mut self) {
+ env::remove_var("_CLANG_SYS_TEST");
+ env::remove_var("_CLANG_SYS_TEST_OS");
+ env::remove_var("_CLANG_SYS_TEST_POINTER_WIDTH");
+ env::remove_var("_CLANG_SYS_TEST_ENV");
+
+ for (name, (_, previous)) in &self.vars {
+ if let Some(previous) = previous {
+ env::set_var(name, previous);
+ } else {
+ env::remove_var(name);
+ }
+ }
+
+ if let Err(error) = env::set_current_dir(&self.cwd) {
+ println!("Failed to reset working directory: {:?}", error);
+ }
+ }
+}
+
+//================================================
+// Dynamic
+//================================================
+
+// Linux -----------------------------------------
+
+#[test]
+#[serial]
+fn test_linux_directory_preference() {
+ let _env = Env::new("linux", "64")
+ .so("usr/lib/libclang.so.1", "64")
+ .so("usr/local/lib/libclang.so.1", "64")
+ .enable();
+
+ assert_eq!(
+ dynamic::find(true),
+ Ok(("usr/local/lib".into(), "libclang.so.1".into())),
+ );
+}
+
+#[test]
+#[serial]
+fn test_linux_version_preference() {
+ let _env = Env::new("linux", "64")
+ .so("usr/lib/libclang-3.so", "64")
+ .so("usr/lib/libclang-3.5.so", "64")
+ .so("usr/lib/libclang-3.5.0.so", "64")
+ .enable();
+
+ assert_eq!(
+ dynamic::find(true),
+ Ok(("usr/lib".into(), "libclang-3.5.0.so".into())),
+ );
+}
+
+#[test]
+#[serial]
+fn test_linux_directory_and_version_preference() {
+ let _env = Env::new("linux", "64")
+ .so("usr/local/llvm/lib/libclang-3.so", "64")
+ .so("usr/local/lib/libclang-3.5.so", "64")
+ .so("usr/lib/libclang-3.5.0.so", "64")
+ .enable();
+
+ assert_eq!(
+ dynamic::find(true),
+ Ok(("usr/lib".into(), "libclang-3.5.0.so".into())),
+ );
+}
+
+// Windows ---------------------------------------
+
+#[cfg(target_os = "windows")]
+#[test]
+#[serial]
+fn test_windows_bin_sibling() {
+ let _env = Env::new("windows", "64")
+ .dir("Program Files\\LLVM\\lib")
+ .dll("Program Files\\LLVM\\bin\\libclang.dll", "64")
+ .enable();
+
+ assert_eq!(
+ dynamic::find(true),
+ Ok(("Program Files\\LLVM\\bin".into(), "libclang.dll".into())),
+ );
+}
+
+#[cfg(target_os = "windows")]
+#[test]
+#[serial]
+fn test_windows_mingw_gnu() {
+ let _env = Env::new("windows", "64")
+ .env("gnu")
+ .dir("MSYS\\MinGW\\lib")
+ .dll("MSYS\\MinGW\\bin\\clang.dll", "64")
+ .dir("Program Files\\LLVM\\lib")
+ .dll("Program Files\\LLVM\\bin\\libclang.dll", "64")
+ .enable();
+
+ assert_eq!(
+ dynamic::find(true),
+ Ok(("MSYS\\MinGW\\bin".into(), "clang.dll".into())),
+ );
+}
+
+#[cfg(target_os = "windows")]
+#[test]
+#[serial]
+fn test_windows_mingw_msvc() {
+ let _env = Env::new("windows", "64")
+ .env("msvc")
+ .dir("MSYS\\MinGW\\lib")
+ .dll("MSYS\\MinGW\\bin\\clang.dll", "64")
+ .dir("Program Files\\LLVM\\lib")
+ .dll("Program Files\\LLVM\\bin\\libclang.dll", "64")
+ .enable();
+
+ assert_eq!(
+ dynamic::find(true),
+ Ok(("Program Files\\LLVM\\bin".into(), "libclang.dll".into())),
+ );
+}