зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1817900 - Update clang-sys to 1.6.0. r=emilio,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D170430
This commit is contained in:
Родитель
54d876838f
Коммит
1c963ddd1d
|
@ -772,9 +772,9 @@ checksum = "bb7bdea464ae038f09197b82430b921c53619fc8d2bcaf7b151013b3ca008017"
|
|||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.4.0"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
|
||||
checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
|
|
|
@ -316,6 +316,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
|||
criteria = "safe-to-deploy"
|
||||
delta = "1.3.3 -> 1.4.0"
|
||||
|
||||
[[audits.clang-sys]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "1.4.0 -> 1.6.0"
|
||||
|
||||
[[audits.clap_lex]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"e213b234e1e64fca8c4fc26cc194d3e4c7d3de1f30eaab5fe2a001b5decf461d","Cargo.toml":"6c398894882867cf488387a5adc927336ae6e31d4a413c7918655f934b617d0c","LICENSE.txt":"3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","README.md":"00ea4c69bb97f07cc29ee68d673666252c35b94593e3eb26b4f7a838a4ce1d08","build.rs":"fbcd7eb0494a38be9e3fda648f91e4be05cad53a4c9faaf4fb8c7be270b1305d","build/common.rs":"7a38220e50c7c208057cb0b5ac13d54152aa4f6bebaea2160b0391adaf518e68","build/dynamic.rs":"84bc5a004dd7fa72a176cf9564db58a517c09870bac9ae6f5169411e1ed7f548","build/static.rs":"15e680b3896d1a83720210de7b72cc2fd2791626721e480c89902595d876eba7","clippy.toml":"fcf54943ba571514b244cc098ce08671b4117167733e8107e799d533a12a2195","src/lib.rs":"31cbacb197fc75dc13719d162666602f1a373d910f7947bebe2c5236f5a547d4","src/link.rs":"2fd772f679752a215566460671b159c01324504e7a36b642751fa3e1eca8d42f","src/support.rs":"da7e4e08a5fce844f563943588fca5de3b72972fc61db96c5158b1246737e006","tests/header.h":"1b15a686d1c06561960045a26c25a34d840f26c8246f2f5e630f993b69c7492c","tests/lib.rs":"81a459e9f48e6d384b3fd61e7942e685f7ea39af6574bc2b382a0fbe7820ff65"},"package":"fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"}
|
||||
{"files":{"CHANGELOG.md":"0d30b4166abd35d7a300478c089a4f0ade53cb81ce3333876b1461151810bd69","Cargo.toml":"0a419871f05f413d27701e336c3c8e9253b980243025be0adf47a6c101d69430","LICENSE.txt":"3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","README.md":"0970fc9c7d9933e1900a465d95b9300bd68435ef56436a665b998108bf1b0abd","build.rs":"da53087156a235fe65cab1ee34e12d97b6c3e540e2c8e3ae9b2aeac71efcf1ce","build/common.rs":"52fcb086e5cf1f47a528bdc4474206a2299b6d54e536f164e288344904cdd7ed","build/dynamic.rs":"2754e488d48920681351c32b89ead0ebd03a83705b55b36f32eed54e68fa8f73","build/macros.rs":"cdd7553864bf1e5565ea3eb71561718f1485d75f277020ed37af4c272d97b5c8","build/static.rs":"b8b2654504fe509f42091b658b323214030161beb7850bbdb45924959bccc0c2","clippy.toml":"fcf54943ba571514b244cc098ce08671b4117167733e8107e799d533a12a2195","src/lib.rs":"d70eee9a78304b3daaf090471a2ae93b8007ffa181aab654b5631f53eb14475e","src/link.rs":"4d257be78d4fd654133102ec26e855cce9d9376143cff0ba0aea7c2e5b4216f8","src/support.rs":"da7e4e08a5fce844f563943588fca5de3b72972fc61db96c5158b1246737e006","tests/build.rs":"db3df3417906a77aafc8f8b4bf936dbd2cf89f2f6a7b728f14ff967897597f58","tests/header.h":"1b15a686d1c06561960045a26c25a34d840f26c8246f2f5e630f993b69c7492c","tests/lib.rs":"81a459e9f48e6d384b3fd61e7942e685f7ea39af6574bc2b382a0fbe7820ff65"},"package":"77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a"}
|
|
@ -1,3 +1,30 @@
|
|||
## [1.6.0] - 2023-02-18
|
||||
w
|
||||
### Changed
|
||||
- MinGW directories are not searched for `libclang` instances on Windows when
|
||||
compiling for an MSVC target
|
||||
- Bumped minimum supported Rust version (MSRV) to 1.51.0
|
||||
- Changed Windows search directory preferences (`libclang` instances from
|
||||
Visual Studio installs are now the lowest priority rather than the second
|
||||
highest)
|
||||
|
||||
## ~~[1.5.1] - 2023-02-05~~ (YANKED)
|
||||
|
||||
### Changed
|
||||
- MinGW directories are not searched for `libclang` instances on Windows when
|
||||
compiling for an MSVC target
|
||||
|
||||
## ~~[1.5.0] - 2023-02-05~~ (YANKED)
|
||||
|
||||
### Changed
|
||||
- Bumped minimum supported Rust version (MSRV) to 1.51.0
|
||||
- Changed Windows search directory preferences (`libclang` instances from
|
||||
Visual Studio installs are now the lowest priority rather than the second
|
||||
highest)
|
||||
|
||||
### Added
|
||||
- Added additional support for `clang` 16.0.x
|
||||
|
||||
## [1.4.0] - 2022-09-22
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
[package]
|
||||
name = "clang-sys"
|
||||
version = "1.4.0"
|
||||
version = "1.6.0"
|
||||
authors = ["Kyle Mayes <kyle@mayeses.com>"]
|
||||
build = "build.rs"
|
||||
links = "clang"
|
||||
|
@ -38,6 +38,15 @@ default-features = false
|
|||
version = "0.7"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies.glob]
|
||||
version = "0.3"
|
||||
|
||||
[dev-dependencies.serial_test]
|
||||
version = "1"
|
||||
|
||||
[dev-dependencies.tempdir]
|
||||
version = "0.3"
|
||||
|
||||
[build-dependencies.glob]
|
||||
version = "0.3"
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
[![Crate](https://img.shields.io/crates/v/clang-sys.svg)](https://crates.io/crates/clang-sys)
|
||||
[![Documentation](https://docs.rs/clang-sys/badge.svg)](https://docs.rs/clang-sys)
|
||||
[![CI](https://img.shields.io/github/workflow/status/KyleMayes/clang-sys/CI/master)](https://github.com/KyleMayes/vulkanalia/actions?query=workflow%3ACI)
|
||||
![MSRV](https://img.shields.io/badge/MSRV-1.40.0-blue)
|
||||
[![CI](https://img.shields.io/github/actions/workflow/status/KyleMayes/clang-sys/ci.yml?branch=master)](https://github.com/KyleMayes/clang-sys/actions?query=workflow%3ACI)
|
||||
![MSRV](https://img.shields.io/badge/MSRV-1.51.0-blue)
|
||||
|
||||
Rust bindings for `libclang`.
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ extern crate glob;
|
|||
|
||||
use std::path::Path;
|
||||
|
||||
#[macro_use]
|
||||
#[path = "build/macros.rs"]
|
||||
pub mod macros;
|
||||
|
||||
#[path = "build/common.rs"]
|
||||
pub mod common;
|
||||
#[path = "build/dynamic.rs"]
|
||||
|
@ -54,6 +58,7 @@ fn main() {
|
|||
}
|
||||
|
||||
let out = env::var("OUT_DIR").unwrap();
|
||||
copy("build/macros.rs", &Path::new(&out).join("macros.rs"));
|
||||
copy("build/common.rs", &Path::new(&out).join("common.rs"));
|
||||
copy("build/dynamic.rs", &Path::new(&out).join("dynamic.rs"));
|
||||
}
|
||||
|
|
|
@ -91,9 +91,19 @@ impl Drop for CommandErrorPrinter {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub static RUN_COMMAND_MOCK: std::sync::Mutex<
|
||||
Option<Box<dyn Fn(&str, &str, &[&str]) -> Option<String> + Send + Sync + 'static>>,
|
||||
> = std::sync::Mutex::new(None);
|
||||
|
||||
/// Executes a command and returns the `stdout` output if the command was
|
||||
/// successfully executed (errors are added to `COMMAND_ERRORS`).
|
||||
fn run_command(name: &str, path: &str, arguments: &[&str]) -> Option<String> {
|
||||
#[cfg(test)]
|
||||
if let Some(command) = &*RUN_COMMAND_MOCK.lock().unwrap() {
|
||||
return command(name, path, arguments);
|
||||
}
|
||||
|
||||
let output = match Command::new(path).args(arguments).output() {
|
||||
Ok(output) => output,
|
||||
Err(error) => {
|
||||
|
@ -128,54 +138,64 @@ pub fn run_xcode_select(arguments: &[&str]) -> Option<String> {
|
|||
//================================================
|
||||
// Search Directories
|
||||
//================================================
|
||||
// These search directories are listed in order of
|
||||
// preference, so if multiple `libclang` instances
|
||||
// are found when searching matching directories,
|
||||
// the `libclang` instances from earlier
|
||||
// directories will be preferred (though version
|
||||
// takes precedence over location).
|
||||
//================================================
|
||||
|
||||
/// `libclang` directory patterns for Haiku.
|
||||
const DIRECTORIES_HAIKU: &[&str] = &[
|
||||
"/boot/system/lib",
|
||||
"/boot/system/develop/lib",
|
||||
"/boot/system/non-packaged/lib",
|
||||
"/boot/system/non-packaged/develop/lib",
|
||||
"/boot/home/config/non-packaged/lib",
|
||||
"/boot/home/config/non-packaged/develop/lib",
|
||||
"/boot/home/config/non-packaged/lib",
|
||||
"/boot/system/non-packaged/develop/lib",
|
||||
"/boot/system/non-packaged/lib",
|
||||
"/boot/system/develop/lib",
|
||||
"/boot/system/lib",
|
||||
];
|
||||
|
||||
/// `libclang` directory patterns for Linux (and FreeBSD).
|
||||
const DIRECTORIES_LINUX: &[&str] = &[
|
||||
"/usr/lib*",
|
||||
"/usr/lib*/*",
|
||||
"/usr/lib*/*/*",
|
||||
"/usr/local/lib*",
|
||||
"/usr/local/lib*/*",
|
||||
"/usr/local/lib*/*/*",
|
||||
"/usr/local/llvm*/lib*",
|
||||
"/usr/local/lib*/*/*",
|
||||
"/usr/local/lib*/*",
|
||||
"/usr/local/lib*",
|
||||
"/usr/lib*/*/*",
|
||||
"/usr/lib*/*",
|
||||
"/usr/lib*",
|
||||
];
|
||||
|
||||
/// `libclang` directory patterns for macOS.
|
||||
const DIRECTORIES_MACOS: &[&str] = &[
|
||||
"/usr/local/opt/llvm*/lib",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
|
||||
"/Library/Developer/CommandLineTools/usr/lib",
|
||||
"/usr/local/opt/llvm*/lib/llvm*/lib",
|
||||
"/Library/Developer/CommandLineTools/usr/lib",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
|
||||
"/usr/local/opt/llvm*/lib",
|
||||
];
|
||||
|
||||
/// `libclang` directory patterns for Windows.
|
||||
const DIRECTORIES_WINDOWS: &[&str] = &[
|
||||
"C:\\LLVM\\lib",
|
||||
"C:\\Program Files*\\LLVM\\lib",
|
||||
"C:\\MSYS*\\MinGW*\\lib",
|
||||
///
|
||||
/// The boolean indicates whether the directory pattern should be used when
|
||||
/// compiling for an MSVC target environment.
|
||||
const DIRECTORIES_WINDOWS: &[(&str, bool)] = &[
|
||||
// LLVM + Clang can be installed using Scoop (https://scoop.sh).
|
||||
// Other Windows package managers install LLVM + Clang to other listed
|
||||
// system-wide directories.
|
||||
("C:\\Users\\*\\scoop\\apps\\llvm\\current\\lib", true),
|
||||
("C:\\MSYS*\\MinGW*\\lib", false),
|
||||
("C:\\Program Files*\\LLVM\\lib", true),
|
||||
("C:\\LLVM\\lib", true),
|
||||
// LLVM + Clang can be installed as a component of Visual Studio.
|
||||
// https://github.com/KyleMayes/clang-sys/issues/121
|
||||
"C:\\Program Files*\\Microsoft Visual Studio\\*\\BuildTools\\VC\\Tools\\Llvm\\**\\bin",
|
||||
// LLVM + Clang can be installed using Scoop (https://scoop.sh).
|
||||
// Other Windows package managers install LLVM + Clang to previously listed
|
||||
// system-wide directories.
|
||||
"C:\\Users\\*\\scoop\\apps\\llvm\\current\\bin",
|
||||
("C:\\Program Files*\\Microsoft Visual Studio\\*\\BuildTools\\VC\\Tools\\Llvm\\**\\lib", true),
|
||||
];
|
||||
|
||||
/// `libclang` directory patterns for illumos
|
||||
const DIRECTORIES_ILLUMOS: &[&str] = &[
|
||||
"/opt/ooce/clang-*/lib",
|
||||
"/opt/ooce/llvm-*/lib",
|
||||
"/opt/ooce/clang-*/lib",
|
||||
];
|
||||
|
||||
//================================================
|
||||
|
@ -233,7 +253,7 @@ fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, S
|
|||
// keep things consistent with other platforms, only LLVM `lib` directories
|
||||
// are included in the backup search directory globs so we need to search
|
||||
// the LLVM `bin` directory here.
|
||||
if cfg!(target_os = "windows") && directory.ends_with("lib") {
|
||||
if target_os!("windows") && directory.ends_with("lib") {
|
||||
let sibling = directory.parent().unwrap().join("bin");
|
||||
results.extend(search_directory(&sibling, filenames).into_iter());
|
||||
}
|
||||
|
@ -273,7 +293,7 @@ pub fn search_libclang_directories(filenames: &[String], variable: &str) -> Vec<
|
|||
|
||||
// Search the toolchain directory in the directory returned by
|
||||
// `xcode-select --print-path`.
|
||||
if cfg!(target_os = "macos") {
|
||||
if target_os!("macos") {
|
||||
if let Some(output) = run_xcode_select(&["--print-path"]) {
|
||||
let directory = Path::new(output.lines().next().unwrap()).to_path_buf();
|
||||
let directory = directory.join("Toolchains/XcodeDefault.xctoolchain/usr/lib");
|
||||
|
@ -289,25 +309,41 @@ pub fn search_libclang_directories(filenames: &[String], variable: &str) -> Vec<
|
|||
}
|
||||
|
||||
// Determine the `libclang` directory patterns.
|
||||
let directories = if cfg!(target_os = "haiku") {
|
||||
DIRECTORIES_HAIKU
|
||||
} else if cfg!(any(target_os = "linux", target_os = "freebsd")) {
|
||||
DIRECTORIES_LINUX
|
||||
} else if cfg!(target_os = "macos") {
|
||||
DIRECTORIES_MACOS
|
||||
} else if cfg!(target_os = "windows") {
|
||||
let directories: Vec<&str> = if target_os!("haiku") {
|
||||
DIRECTORIES_HAIKU.into()
|
||||
} else if target_os!("linux") || target_os!("freebsd") {
|
||||
DIRECTORIES_LINUX.into()
|
||||
} else if target_os!("macos") {
|
||||
DIRECTORIES_MACOS.into()
|
||||
} else if target_os!("windows") {
|
||||
let msvc = target_env!("msvc");
|
||||
DIRECTORIES_WINDOWS
|
||||
} else if cfg!(target_os = "illumos") {
|
||||
DIRECTORIES_ILLUMOS
|
||||
.iter()
|
||||
.filter(|d| d.1 || !msvc)
|
||||
.map(|d| d.0)
|
||||
.collect()
|
||||
} else if target_os!("illumos") {
|
||||
DIRECTORIES_ILLUMOS.into()
|
||||
} else {
|
||||
&[]
|
||||
vec![]
|
||||
};
|
||||
|
||||
// We use temporary directories when testing the build script so we'll
|
||||
// remove the prefixes that make the directories absolute.
|
||||
let directories = if test!() {
|
||||
directories
|
||||
.iter()
|
||||
.map(|d| d.strip_prefix('/').or_else(|| d.strip_prefix("C:\\")).unwrap_or(d))
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
directories.into()
|
||||
};
|
||||
|
||||
// Search the directories provided by the `libclang` directory patterns.
|
||||
let mut options = MatchOptions::new();
|
||||
options.case_sensitive = false;
|
||||
options.require_literal_separator = true;
|
||||
for directory in directories.iter().rev() {
|
||||
for directory in directories.iter() {
|
||||
if let Ok(directories) = glob::glob_with(directory, options) {
|
||||
for directory in directories.filter_map(Result::ok).filter(|p| p.is_dir()) {
|
||||
found.extend(search_directories(&directory, filenames));
|
||||
|
|
|
@ -50,26 +50,26 @@ fn parse_pe_header(path: &Path) -> io::Result<u16> {
|
|||
|
||||
/// Checks that a `libclang` shared library matches the target platform.
|
||||
fn validate_library(path: &Path) -> Result<(), String> {
|
||||
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
|
||||
if target_os!("linux") || target_os!("freebsd") {
|
||||
let class = parse_elf_header(path).map_err(|e| e.to_string())?;
|
||||
|
||||
if cfg!(target_pointer_width = "32") && class != 1 {
|
||||
if target_pointer_width!("32") && class != 1 {
|
||||
return Err("invalid ELF class (64-bit)".into());
|
||||
}
|
||||
|
||||
if cfg!(target_pointer_width = "64") && class != 2 {
|
||||
if target_pointer_width!("64") && class != 2 {
|
||||
return Err("invalid ELF class (32-bit)".into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else if cfg!(target_os = "windows") {
|
||||
} else if target_os!("windows") {
|
||||
let magic = parse_pe_header(path).map_err(|e| e.to_string())?;
|
||||
|
||||
if cfg!(target_pointer_width = "32") && magic != 267 {
|
||||
if target_pointer_width!("32") && magic != 267 {
|
||||
return Err("invalid DLL (64-bit)".into());
|
||||
}
|
||||
|
||||
if cfg!(target_pointer_width = "64") && magic != 523 {
|
||||
if target_pointer_width!("64") && magic != 523 {
|
||||
return Err("invalid DLL (32-bit)".into());
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve
|
|||
env::consts::DLL_SUFFIX
|
||||
)];
|
||||
|
||||
if cfg!(target_os = "linux") {
|
||||
if target_os!("linux") {
|
||||
// Some Linux distributions don't create a `libclang.so` symlink, so we
|
||||
// need to look for versioned files (e.g., `libclang-3.9.so`).
|
||||
files.push("libclang-*.so".into());
|
||||
|
@ -121,19 +121,14 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve
|
|||
}
|
||||
}
|
||||
|
||||
if cfg!(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "haiku",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
)) {
|
||||
if target_os!("freebsd") || target_os!("haiku") || target_os!("netbsd") || target_os!("openbsd") {
|
||||
// Some BSD distributions don't create a `libclang.so` symlink either,
|
||||
// but use a different naming scheme for versioned files (e.g.,
|
||||
// `libclang.so.7.0`).
|
||||
files.push("libclang.so.*".into());
|
||||
}
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
if target_os!("windows") {
|
||||
// The official LLVM build uses `libclang.dll` on Windows instead of
|
||||
// `clang.dll`. However, unofficial builds such as MinGW use `clang.dll`.
|
||||
files.push("libclang.dll".into());
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
macro_rules! test {
|
||||
() => (cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok());
|
||||
}
|
||||
|
||||
macro_rules! target_os {
|
||||
($os:expr) => {
|
||||
if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() {
|
||||
let var = ::std::env::var("_CLANG_SYS_TEST_OS");
|
||||
var.map_or(false, |v| v == $os)
|
||||
} else {
|
||||
cfg!(target_os = $os)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! target_pointer_width {
|
||||
($pointer_width:expr) => {
|
||||
if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() {
|
||||
let var = ::std::env::var("_CLANG_SYS_TEST_POINTER_WIDTH");
|
||||
var.map_or(false, |v| v == $pointer_width)
|
||||
} else {
|
||||
cfg!(target_pointer_width = $pointer_width)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! target_env {
|
||||
($env:expr) => {
|
||||
if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() {
|
||||
let var = ::std::env::var("_CLANG_SYS_TEST_ENV");
|
||||
var.map_or(false, |v| v == $env)
|
||||
} else {
|
||||
cfg!(target_env = $env)
|
||||
}
|
||||
};
|
||||
}
|
|
@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use glob::Pattern;
|
||||
|
||||
use common;
|
||||
use super::common;
|
||||
|
||||
//================================================
|
||||
// Searching
|
||||
|
@ -79,7 +79,7 @@ fn get_clang_libraries<P: AsRef<Path>>(directory: P) -> Vec<String> {
|
|||
/// Finds a directory containing LLVM and Clang static libraries and returns the
|
||||
/// path to that directory.
|
||||
fn find() -> PathBuf {
|
||||
let name = if cfg!(target_os = "windows") {
|
||||
let name = if target_os!("windows") {
|
||||
"libclang.lib"
|
||||
} else {
|
||||
"libclang.a"
|
||||
|
|
|
@ -327,6 +327,8 @@ cenum! {
|
|||
const CXCursor_ConceptSpecializationExpr = 153,
|
||||
/// Only produced by `libclang` 15.0 and later.
|
||||
const CXCursor_RequiresExpr = 154,
|
||||
/// Only produced by `libclang` 16.0 and later.
|
||||
const CXCursor_CXXParenListInitExpr = 155,
|
||||
const CXCursor_UnexposedStmt = 200,
|
||||
const CXCursor_LabelStmt = 201,
|
||||
const CXCursor_CompoundStmt = 202,
|
||||
|
@ -490,6 +492,8 @@ cenum! {
|
|||
const CXCursor_OMPParallelMaskedTaskLoopDirective = 303,
|
||||
/// Only produced by `libclang` 15.0 and later.
|
||||
const CXCursor_OMPParallelMaskedTaskLoopSimdDirective = 304,
|
||||
/// Only produced by `libclang` 16.0 and later.
|
||||
const CXCursor_OMPErrorDirective = 305,
|
||||
#[cfg(not(feature="clang_15_0"))]
|
||||
const CXCursor_TranslationUnit = 300,
|
||||
#[cfg(feature="clang_15_0")]
|
||||
|
@ -1752,9 +1756,18 @@ link! {
|
|||
#[cfg(feature = "clang_3_8")]
|
||||
pub fn clang_CXXField_isMutable(cursor: CXCursor) -> c_uint;
|
||||
pub fn clang_CXXMethod_isConst(cursor: CXCursor) -> c_uint;
|
||||
/// Only available on `libclang` 16.0 and later.
|
||||
#[cfg(feature = "clang_16_0")]
|
||||
pub fn clang_CXXMethod_isCopyAssignmentOperator(cursor: CXCursor) -> c_uint;
|
||||
/// Only available on `libclang` 3.9 and later.
|
||||
#[cfg(feature = "clang_3_9")]
|
||||
pub fn clang_CXXMethod_isDefaulted(cursor: CXCursor) -> c_uint;
|
||||
/// Only available on `libclang` 16.0 and later.
|
||||
#[cfg(feature = "clang_16_0")]
|
||||
pub fn clang_CXXMethod_isDeleted(cursor: CXCursor) -> c_uint;
|
||||
/// Only available on `libclang` 16.0 and later.
|
||||
#[cfg(feature = "clang_16_0")]
|
||||
pub fn clang_CXXMethod_isMoveAssignmentOperator(cursor: CXCursor) -> c_uint;
|
||||
pub fn clang_CXXMethod_isPureVirtual(cursor: CXCursor) -> c_uint;
|
||||
pub fn clang_CXXMethod_isStatic(cursor: CXCursor) -> c_uint;
|
||||
pub fn clang_CXXMethod_isVirtual(cursor: CXCursor) -> c_uint;
|
||||
|
@ -2134,6 +2147,9 @@ link! {
|
|||
pub fn clang_getLocation(tu: CXTranslationUnit, file: CXFile, line: c_uint, column: c_uint) -> CXSourceLocation;
|
||||
pub fn clang_getLocationForOffset(tu: CXTranslationUnit, file: CXFile, offset: c_uint) -> CXSourceLocation;
|
||||
pub fn clang_getModuleForFile(tu: CXTranslationUnit, file: CXFile) -> CXModule;
|
||||
/// Only available on `libclang` 16.0 and later.
|
||||
#[cfg(feature = "clang_16_0")]
|
||||
pub fn clang_getNonReferenceType(type_: CXType) -> CXType;
|
||||
pub fn clang_getNullCursor() -> CXCursor;
|
||||
pub fn clang_getNullLocation() -> CXSourceLocation;
|
||||
pub fn clang_getNullRange() -> CXSourceRange;
|
||||
|
@ -2171,9 +2187,6 @@ link! {
|
|||
/// Only available on `libclang` 16.0 and later.
|
||||
#[cfg(feature = "clang_16_0")]
|
||||
pub fn clang_getUnqualifiedType(type_: CXType) -> CXType;
|
||||
/// Only available on `libclang` 16.0 and later.
|
||||
#[cfg(feature = "clang_16_0")]
|
||||
pub fn clang_getNonReferenceType(type_: CXType) -> CXType;
|
||||
pub fn clang_getTypeDeclaration(type_: CXType) -> CXCursor;
|
||||
pub fn clang_getTypeKindSpelling(type_: CXTypeKind) -> CXString;
|
||||
pub fn clang_getTypeSpelling(type_: CXType) -> CXString;
|
||||
|
|
|
@ -175,7 +175,9 @@ macro_rules! link {
|
|||
/// * a `libclang` shared library could not be found
|
||||
/// * the `libclang` shared library could not be opened
|
||||
pub fn load_manually() -> Result<SharedLibrary, String> {
|
||||
#[allow(dead_code)]
|
||||
mod build {
|
||||
include!(concat!(env!("OUT_DIR"), "/macros.rs"));
|
||||
pub mod common { include!(concat!(env!("OUT_DIR"), "/common.rs")); }
|
||||
pub mod dynamic { include!(concat!(env!("OUT_DIR"), "/dynamic.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())),
|
||||
);
|
||||
}
|
Загрузка…
Ссылка в новой задаче