From 83337ed14d3ef56194fe54654599b0751a8b63e1 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 19 May 2021 14:55:23 -0700 Subject: Upgrade rust/crates/clang-sys to 1.2.0 Test: make Change-Id: I490b30d1f1bdd43a81e55e6ffb69521526de92d5 --- src/lib.rs | 24 +++++++++++++----------- src/support.rs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 6497715..90f3706 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,20 +14,22 @@ //! Rust bindings for `libclang`. //! -//! ## Documentation +//! ## [Documentation](https://docs.rs/clang-sys) //! -//! There are two versions of the documentation, one for the API exposed when -//! linking dynamically or statically and one for the API exposed when linking -//! at runtime (see the -//! [Dependencies](https://github.com/KyleMayes/clang-sys#dependencies) section -//! of the README for more information on the linking options). +//! Note that the documentation on https://docs.rs for this crate assumes usage +//! of the `runtime` Cargo feature as well as the Cargo feature for the latest +//! supported version of `libclang` (e.g., `clang_11_0`), neither of which are +//! enabled by default. //! -//! The only difference between the APIs exposed is that when linking at runtime -//! a few additional types and functions are exposed to manage the loaded -//! `libclang` shared library. +//! Due to the usage of the `runtime` Cargo feature, this documentation will +//! contain some additional types and functions to manage a dynamically loaded +//! `libclang` instance at runtime. //! -//! * Runtime - [Documentation](https://kylemayes.github.io/clang-sys/runtime/clang_sys) -//! * Dynamic / Static - [Documentation](https://kylemayes.github.io/clang-sys/default/clang_sys) +//! Due to the usage of the Cargo feature for the latest supported version of +//! `libclang`, this documentation will contain constants and functions that are +//! not available in the oldest supported version of `libclang` (3.5). All of +//! these types and functions have a documentation comment which specifies the +//! minimum `libclang` version required to use the item. #![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] #![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))] diff --git a/src/support.rs b/src/support.rs index 8422f59..4e698ff 100644 --- a/src/support.rs +++ b/src/support.rs @@ -74,20 +74,41 @@ impl Clang { /// directory returned by `llvm-config --bindir` is searched. On macOS /// systems, `xcodebuild -find clang` will next be queried. Last, the /// directories in the system's `PATH` are searched. + /// + /// ## Cross-compilation + /// + /// If target arguments are provided (e.g., `-target` followed by a target + /// like `x86_64-unknown-linux-gnu`) then this method will prefer a + /// target-prefixed instance of `clang` (e.g., + /// `x86_64-unknown-linux-gnu-clang` for the above example). pub fn find(path: Option<&Path>, args: &[String]) -> Option { if let Ok(path) = env::var("CLANG_PATH") { return Some(Clang::new(path, args)); } + // Determine the cross-compilation target, if any. + + let mut target = None; + for i in 0..args.len() { + if args[i] == "-target" && i + 1 < args.len() { + target = Some(&args[i + 1]); + } + } + + // Collect the paths to search for a `clang` executable in. + let mut paths = vec![]; + if let Some(path) = path { paths.push(path.into()); } + if let Ok(path) = run_llvm_config(&["--bindir"]) { if let Some(line) = path.lines().next() { paths.push(line.into()); } } + if cfg!(target_os = "macos") { if let Ok((path, _)) = run("xcodebuild", &["-find", "clang"]) { if let Some(line) = path.lines().next() { @@ -95,8 +116,24 @@ impl Clang { } } } + paths.extend(env::split_paths(&env::var("PATH").unwrap())); + // First, look for a target-prefixed `clang` executable. + + if let Some(target) = target { + let default = format!("{}-clang{}", target, env::consts::EXE_SUFFIX); + let versioned = format!("{}-clang-[0-9]*{}", target, env::consts::EXE_SUFFIX); + let patterns = &[&default[..], &versioned[..]]; + for path in &paths { + if let Some(path) = find(&path, patterns) { + return Some(Clang::new(path, args)); + } + } + } + + // Otherwise, look for any other `clang` executable. + let default = format!("clang{}", env::consts::EXE_SUFFIX); let versioned = format!("clang-[0-9]*{}", env::consts::EXE_SUFFIX); let patterns = &[&default[..], &versioned[..]]; -- cgit v1.2.3