diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-03-06 00:05:04 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-03-06 00:05:04 +0000 |
commit | fadd84edaced229bd1aa3761c7a93d2ab23afb6a (patch) | |
tree | c3fd3925071bf0cdbbe66bf20942023e9d495622 | |
parent | 4af0f42278cc2ef1d715d1e55d7c777cce324700 (diff) | |
parent | ab7b7e07212fe5caa833a44a1c7d2b8bc876a7d4 (diff) | |
download | clang-sys-android13-platform-release.tar.gz |
Snap for 8261343 from ab7b7e07212fe5caa833a44a1c7d2b8bc876a7d4 to tm-releaseandroid-vts-13.0_r8android-vts-13.0_r7android-vts-13.0_r6android-vts-13.0_r5android-vts-13.0_r4android-vts-13.0_r3android-vts-13.0_r2android-vts-13.0_r1android-security-13.0.0_r9android-security-13.0.0_r8android-security-13.0.0_r7android-security-13.0.0_r6android-security-13.0.0_r5android-security-13.0.0_r4android-security-13.0.0_r3android-security-13.0.0_r2android-security-13.0.0_r17android-security-13.0.0_r16android-security-13.0.0_r15android-security-13.0.0_r14android-security-13.0.0_r13android-security-13.0.0_r12android-security-13.0.0_r11android-security-13.0.0_r10android-security-13.0.0_r1android-platform-13.0.0_r9android-platform-13.0.0_r8android-platform-13.0.0_r7android-platform-13.0.0_r6android-platform-13.0.0_r5android-platform-13.0.0_r4android-platform-13.0.0_r3android-platform-13.0.0_r2android-platform-13.0.0_r19android-platform-13.0.0_r18android-platform-13.0.0_r17android-platform-13.0.0_r16android-platform-13.0.0_r15android-platform-13.0.0_r14android-platform-13.0.0_r13android-platform-13.0.0_r12android-platform-13.0.0_r11android-platform-13.0.0_r10android-platform-13.0.0_r1android-cts-13.0_r8android-cts-13.0_r7android-cts-13.0_r6android-cts-13.0_r5android-cts-13.0_r4android-cts-13.0_r3android-cts-13.0_r2android-cts-13.0_r1android-13.0.0_r8android-13.0.0_r7android-13.0.0_r6android-13.0.0_r5android-13.0.0_r4android-13.0.0_r31android-13.0.0_r3android-13.0.0_r2android-13.0.0_r12android-13.0.0_r1android13-tests-releaseandroid13-security-releaseandroid13-s3-releaseandroid13-s2-releaseandroid13-s1-releaseandroid13-releaseandroid13-platform-releaseandroid13-gsi
Change-Id: I6e26632b701bbd5f27778fb9c24a7f041b9f4147
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 5 | ||||
-rw-r--r-- | .github/workflows/ssh.yml | 40 | ||||
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | CHANGELOG.md | 12 | ||||
-rw-r--r-- | Cargo.toml | 15 | ||||
-rw-r--r-- | Cargo.toml.orig | 6 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | README.md | 91 | ||||
-rw-r--r-- | build.rs | 29 | ||||
-rw-r--r-- | build/common.rs | 272 | ||||
-rw-r--r-- | build/dynamic.rs | 64 | ||||
-rw-r--r-- | build/static.rs | 69 | ||||
-rw-r--r-- | out/common.rs | 272 | ||||
-rw-r--r-- | out/dynamic.rs | 64 | ||||
-rw-r--r-- | src/lib.rs | 90 | ||||
-rw-r--r-- | src/link.rs | 14 | ||||
-rw-r--r-- | src/support.rs | 14 |
18 files changed, 561 insertions, 515 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 859474d..ac25bc0 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "fa181dee9b829be68d581ec02583c0568576bbed" - } -} + "sha1": "8090d6853624a04b859e8ab2e467bae88a8d4ef6" + }, + "path_in_vcs": "" +}
\ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 103c19e..5bd0a2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: [macos-latest, ubuntu-latest, windows-latest] - clang: [["11.0", "clang_11_0"]] + clang: [["13.0", "clang_13_0"]] rust: ["1.40.0"] steps: - name: Checkout Repository @@ -39,9 +39,6 @@ jobs: args: --verbose --features ${{ matrix.clang[1] }} -- --nocapture - name: Cargo Test (Runtime) uses: actions-rs/cargo@v1 - env: - # Needed to not find MinGW when loading at runtime - LIBCLANG_PATH: ${{ runner.temp }}/llvm-${{ matrix.clang[0] }}/lib with: command: test args: --verbose --features "${{ matrix.clang[1] }} runtime" -- --nocapture diff --git a/.github/workflows/ssh.yml b/.github/workflows/ssh.yml new file mode 100644 index 0000000..5dfc251 --- /dev/null +++ b/.github/workflows/ssh.yml @@ -0,0 +1,40 @@ +name: SSH + +on: + workflow_dispatch: + inputs: + os: + description: "Operating System" + required: true + default: "ubuntu-latest" + +jobs: + ssh: + name: SSH + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + clang: [["13.0", "clang_13_0"]] + rust: ["1.40.0"] + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + if: github.event.inputs.os == matrix.os + # LLVM and Clang + - name: Install LLVM and Clang + uses: KyleMayes/install-llvm-action@v1 + if: github.event.inputs.os == matrix.os + with: + version: ${{ matrix.clang[0] }} + directory: ${{ runner.temp }}/llvm-${{ matrix.clang[0] }} + # Rust + - name: Install Rust + uses: actions-rs/toolchain@v1 + if: github.event.inputs.os == matrix.os + with: + toolchain: ${{ matrix.rust }} + # SSH + - name: Enable SSH + uses: mxschmitt/action-tmate@v3 + if: github.event.inputs.os == matrix.os @@ -32,7 +32,7 @@ rust_library_host { name: "libclang_sys", crate_name: "clang_sys", cargo_env_compat: true, - cargo_pkg_version: "1.2.2", + cargo_pkg_version: "1.3.1", srcs: [ "src/lib.rs", ":copy_clang-sys_build_out", diff --git a/CHANGELOG.md b/CHANGELOG.md index dd5d8a3..681cde4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [1.3.1] - 2022-02-03 + +### Added +- Added missing `clang_getToken` function + +## [1.3.0] - 2021-10-31 + +### Added +- Added support for `clang` 13.0.x +- Added support for `clang` 12.0.x +- Added support for the Haiku operating system + ## [1.2.2] - 2021-09-02 ### Fixed @@ -3,16 +3,15 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] name = "clang-sys" -version = "1.2.2" +version = "1.3.1" authors = ["Kyle Mayes <kyle@mayeses.com>"] build = "build.rs" links = "clang" @@ -22,7 +21,7 @@ readme = "README.md" license = "Apache-2.0" repository = "https://github.com/KyleMayes/clang-sys" [package.metadata.docs.rs] -features = ["clang_11_0", "runtime"] +features = ["clang_13_0", "runtime"] [dependencies.glob] version = "0.3" @@ -39,6 +38,8 @@ version = "0.3" [features] clang_10_0 = ["clang_9_0"] clang_11_0 = ["clang_10_0"] +clang_12_0 = ["clang_11_0"] +clang_13_0 = ["clang_12_0"] clang_3_5 = [] clang_3_6 = ["clang_3_5"] clang_3_7 = ["clang_3_6"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index e04a103..a78a106 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -3,7 +3,7 @@ name = "clang-sys" authors = ["Kyle Mayes <kyle@mayeses.com>"] -version = "1.2.2" +version = "1.3.1" readme = "README.md" license = "Apache-2.0" @@ -31,6 +31,8 @@ clang_8_0 = ["clang_7_0"] clang_9_0 = ["clang_8_0"] clang_10_0 = ["clang_9_0"] clang_11_0 = ["clang_10_0"] +clang_12_0 = ["clang_11_0"] +clang_13_0 = ["clang_12_0"] runtime = ["libloading"] static = [] @@ -47,4 +49,4 @@ glob = "0.3" [package.metadata.docs.rs] -features = ["clang_11_0", "runtime"] +features = ["clang_13_0", "runtime"] @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/clang-sys/clang-sys-1.2.2.crate" + value: "https://static.crates.io/crates/clang-sys/clang-sys-1.3.1.crate" } - version: "1.2.2" + version: "1.3.1" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 9 - day: 22 + year: 2022 + month: 3 + day: 1 } } @@ -2,70 +2,46 @@ [![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://github.com/KyleMayes/clang-sys/workflows/CI/badge.svg?branch=master)](https://github.com/KyleMayes/clang-sys/actions?query=workflow%3ACI) +[![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) Rust bindings for `libclang`. -If you are interested in a Rust wrapper for these bindings, see -[clang-rs](https://github.com/KyleMayes/clang-rs). - -Supported on the stable, beta, and nightly Rust channels.<br/> -Minimum supported Rust version: **1.40.0** +If you are interested in a somewhat idiomatic Rust wrapper for these bindings, see [`clang-rs`](https://github.com/KyleMayes/clang-rs). Released under the Apache License 2.0. ## [Documentation](https://docs.rs/clang-sys) -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. +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_13_0`), neither of which are enabled by default. -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. +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. 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. ## Supported Versions -To target a version of `libclang`, enable one of the following Cargo features: +To target a version of `libclang`, enable a Cargo features such as one of the following: * `clang_3_5` - requires `libclang` 3.5 or later * `clang_3_6` - requires `libclang` 3.6 or later -* `clang_3_7` - requires `libclang` 3.7 or later -* `clang_3_8` - requires `libclang` 3.8 or later -* `clang_3_9` - requires `libclang` 3.9 or later -* `clang_4_0` - requires `libclang` 4.0 or later -* `clang_5_0` - requires `libclang` 5.0 or later -* `clang_6_0` - requires `libclang` 6.0 or later -* `clang_7_0` - requires `libclang` 7.0 or later -* `clang_8_0` - requires `libclang` 8.0 or later -* `clang_9_0` - requires `libclang` 9.0 or later -* `clang_10_0` - requires `libclang` 10.0 or later -* `clang_11_0` - requires `libclang` 11.0 or later - -If you do not enable one of these features, the API provided by `libclang` 3.5 will be available by -default. +* etc... +* `clang_12_0` - requires `libclang` 12.0 or later +* `clang_13_0` - requires `libclang` 13.0 or later + +If you do not enable one of these features, the API provided by `libclang` 3.5 will be available by default. ## Dependencies -By default, this crate will attempt to link to `libclang` dynamically. In this case, this crate -depends on the `libclang` shared library (`libclang.so` on Linux, `libclang.dylib` on macOS, -`libclang.dll` on Windows). If you want to link to `libclang` statically instead, enable the -`static` Cargo feature. In this case, this crate depends on the LLVM and Clang static libraries. If -you don't want to link to `libclang` at compiletime but instead want to load it at runtime, enable -the `runtime` Cargo feature. +By default, this crate will attempt to link to `libclang` dynamically. In this case, this crate depends on the `libclang` shared library (`libclang.so` on Linux, `libclang.dylib` on macOS, `libclang.dll` on Windows). If you want to link to `libclang` statically instead, enable the `static` Cargo feature. In this case, this crate depends on the LLVM and Clang static libraries. If you don't want to link to `libclang` at compiletime but instead want to load it at runtime, enable the `runtime` Cargo feature. -These libraries can be either be installed as a part of Clang or downloaded -[here](http://llvm.org/releases/download.html). +These libraries can be either be installed as a part of Clang or downloaded [here](http://llvm.org/releases/download.html). -**Note:** The downloads for LLVM and Clang 3.8 and later do not include the `libclang.a` static -library. This means you cannot link to any of these versions of `libclang` statically unless you -build it from source. +**Note:** The downloads for LLVM and Clang 3.8 and later do not include the `libclang.a` static library. This means you cannot link to any of these versions of `libclang` statically unless you build it from source. ### Versioned Dependencies -This crate supports finding versioned instances of `libclang.so` (e.g.,`libclang-3.9.so`). -In the case where there are multiple instances to choose from, this crate will prefer instances with -higher versions. For example, the following instances of `libclang.so` are listed in descending -order of preference: +This crate supports finding versioned instances of `libclang.so` (e.g.,`libclang-3.9.so`). In the case where there are multiple instances to choose from, this crate will prefer instances with higher versions. For example, the following instances of `libclang.so` are listed in descending order of preference: 1. `libclang-4.0.so` 2. `libclang-4.so` @@ -73,23 +49,17 @@ order of preference: 4. `libclang-3.so` 5. `libclang.so` -**Note:** On BSD distributions, versioned instances of `libclang.so` matching the pattern -`libclang.so.*` (e.g., `libclang.so.7.0`) are also included. +**Note:** On BSD distributions, versioned instances of `libclang.so` matching the pattern `libclang.so.*` (e.g., `libclang.so.7.0`) are also included. -**Note:** On Linux distributions when the `runtime` features is enabled, versioned instances of -`libclang.so` matching the pattern `libclang.so.*` (e.g., `libclang.so.1`) are also included. +**Note:** On Linux distributions when the `runtime` features is enabled, versioned instances of `libclang.so` matching the pattern `libclang.so.*` (e.g., `libclang.so.1`) are also included. ## Environment Variables -The following environment variables, if set, are used by this crate to find the required libraries -and executables: +The following environment variables, if set, are used by this crate to find the required libraries and executables: -* `LLVM_CONFIG_PATH` **(compiletime)** - provides a full path to an `llvm-config` executable - (including the executable itself [i.e., `/usr/local/bin/llvm-config-8.0`]) -* `LIBCLANG_PATH` **(compiletime)** - provides a path to a directory containing a `libclang` shared - library or a full path to a specific `libclang` shared library -* `LIBCLANG_STATIC_PATH` **(compiletime)** - provides a path to a directory containing LLVM and - Clang static libraries +* `LLVM_CONFIG_PATH` **(compiletime)** - provides a full path to an `llvm-config` executable (including the executable itself [i.e., `/usr/local/bin/llvm-config-8.0`]) +* `LIBCLANG_PATH` **(compiletime)** - provides a path to a directory containing a `libclang` shared library or a full path to a specific `libclang` shared library +* `LIBCLANG_STATIC_PATH` **(compiletime)** - provides a path to a directory containing LLVM and Clang static libraries * `CLANG_PATH` **(runtime)** - provides a path to a `clang` executable ## Linking @@ -104,25 +74,14 @@ and executables: * a list of likely directories for the target platform (e.g., `/usr/local/lib` on Linux) * **macOS only:** the toolchain directory in the directory provided by `xcode-select --print-path` -On Linux, running an executable that has been dynamically linked to `libclang` may require you to -add a path to `libclang.so` to the `LD_LIBRARY_PATH` environment variable. The same is true on OS -X, except the `DYLD_LIBRARY_PATH` environment variable is used instead. +On Linux, running an executable that has been dynamically linked to `libclang` may require you to add a path to `libclang.so` to the `LD_LIBRARY_PATH` environment variable. The same is true on OS X, except the `DYLD_LIBRARY_PATH` environment variable is used instead. -On Windows, running an executable that has been dynamically linked to `libclang` requires that -`libclang.dll` can be found by the executable at runtime. See -[here](https://msdn.microsoft.com/en-us/library/7d83bc18.aspx) for more information. +On Windows, running an executable that has been dynamically linked to `libclang` requires that `libclang.dll` can be found by the executable at runtime. See [here](https://msdn.microsoft.com/en-us/library/7d83bc18.aspx) for more information. ### Static -The availability of `llvm-config` is not optional for static linking. Ensure that an instance of -this executable can be found on your system's path or set the `LLVM_CONFIG_PATH` environment -variable. The required LLVM and Clang static libraries will be searched for in the same way as -shared libraries are searched for, except the `LIBCLANG_STATIC_PATH` environment variable is used in -place of the `LIBCLANG_PATH` environment variable. +The availability of `llvm-config` is not optional for static linking. Ensure that an instance of this executable can be found on your system's path or set the `LLVM_CONFIG_PATH` environment variable. The required LLVM and Clang static libraries will be searched for in the same way as shared libraries are searched for, except the `LIBCLANG_STATIC_PATH` environment variable is used in place of the `LIBCLANG_PATH` environment variable. ### Runtime -The `clang_sys::load` function is used to load a `libclang` shared library for use in the thread in -which it is called. The `clang_sys::unload` function will unload the `libclang` shared library. -`clang_sys::load` searches for a `libclang` shared library in the same way one is searched for when -linking to `libclang` dynamically at compiletime. +The `clang_sys::load` function is used to load a `libclang` shared library for use in the thread in which it is called. The `clang_sys::unload` function will unload the `libclang` shared library. `clang_sys::load` searches for a `libclang` shared library in the same way one is searched for when linking to `libclang` dynamically at compiletime. @@ -1,23 +1,11 @@ -// Copyright 2016 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 -//! Finds `libclang` static or dynamic libraries and links to them. +//! Finds `libclang` static or shared libraries and links to them. //! //! # Environment Variables //! //! This build script can make use of several environment variables to help it -//! find the required static or dynamic libraries. +//! find the required static or shared libraries. //! //! * `LLVM_CONFIG_PATH` - provides a path to an `llvm-config` executable //! * `LIBCLANG_PATH` - provides a path to a directory containing a `libclang` @@ -36,9 +24,9 @@ pub mod common; #[path = "build/dynamic.rs"] pub mod dynamic; #[path = "build/static.rs"] -pub mod static_; +pub mod r#static; -/// Copy the file from the supplied source to the supplied destination. +/// Copies a file. #[cfg(feature = "runtime")] fn copy(source: &str, destination: &Path) { use std::fs::File; @@ -55,7 +43,8 @@ fn copy(source: &str, destination: &Path) { .unwrap(); } -/// Generates the finding and linking code so that it may be used at runtime. +/// Copies the code used to find and link to `libclang` shared libraries into +/// the build output directory so that it may be used when linking at runtime. #[cfg(feature = "runtime")] fn main() { use std::env; @@ -69,11 +58,11 @@ fn main() { copy("build/dynamic.rs", &Path::new(&out).join("dynamic.rs")); } -/// Finds and links to the required libraries. +/// Finds and links to the required libraries dynamically or statically. #[cfg(not(feature = "runtime"))] fn main() { if cfg!(feature = "static") { - static_::link(); + r#static::link(); } else { dynamic::link(); } diff --git a/build/common.rs b/build/common.rs index 56480df..bc720ca 100644 --- a/build/common.rs +++ b/build/common.rs @@ -1,16 +1,4 @@ -// Copyright 2018 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 extern crate glob; @@ -22,87 +10,38 @@ use std::process::Command; use glob::{MatchOptions, Pattern}; -/// `libclang` directory patterns for FreeBSD and Linux. -const DIRECTORIES_LINUX: &[&str] = &[ - "/usr/lib*", - "/usr/lib*/*", - "/usr/lib*/*/*", - "/usr/local/lib*", - "/usr/local/lib*/*", - "/usr/local/lib*/*/*", - "/usr/local/llvm*/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", -]; - -/// `libclang` directory patterns for Windows. -const DIRECTORIES_WINDOWS: &[&str] = &[ - "C:\\LLVM\\lib", - "C:\\Program Files*\\LLVM\\lib", - "C:\\MSYS*\\MinGW*\\lib", - // 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", - // Scoop user installation https://scoop.sh/. - // Chocolatey, WinGet and other installers use to the system wide dir listed above - "C:\\Users\\*\\scoop\\apps\\llvm\\current\\bin", -]; +//================================================ +// Commands +//================================================ thread_local! { - /// The errors encountered when attempting to execute console commands. + /// The errors encountered by the build script while executing commands. static COMMAND_ERRORS: RefCell<HashMap<String, Vec<String>>> = RefCell::default(); } -/// Executes the supplied console command, returning the `stdout` output if the -/// command was successfully executed. -fn run_command(name: &str, command: &str, arguments: &[&str]) -> Option<String> { - macro_rules! error { - ($error:expr) => {{ - COMMAND_ERRORS.with(|e| { - e.borrow_mut() - .entry(name.into()) - .or_insert_with(Vec::new) - .push(format!( - "couldn't execute `{} {}` ({})", - command, - arguments.join(" "), - $error, - )) - }); - }}; - } - - let output = match Command::new(command).args(arguments).output() { - Ok(output) => output, - Err(error) => { - error!(format!("error: {}", error)); - return None; - } - }; - - if !output.status.success() { - error!(format!("exit code: {}", output.status)); - return None; - } - - Some(String::from_utf8_lossy(&output.stdout).into_owned()) +/// Adds an error encountered by the build script while executing a command. +fn add_command_error(name: &str, path: &str, arguments: &[&str], message: String) { + COMMAND_ERRORS.with(|e| { + e.borrow_mut() + .entry(name.into()) + .or_insert_with(Vec::new) + .push(format!( + "couldn't execute `{} {}` (path={}) ({})", + name, + arguments.join(" "), + path, + message, + )) + }); } -/// Executes `llvm-config`, returning the `stdout` output if the command was -/// successfully executed. -pub fn run_llvm_config(arguments: &[&str]) -> Option<String> { - let path = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into()); - run_command("llvm-config", &path, arguments) -} - -/// A struct that prints errors encountered when attempting to execute console -/// commands on drop if not discarded. +/// A struct that prints the errors encountered by the build script while +/// executing commands when dropped (unless explictly discarded). +/// +/// This is handy because we only want to print these errors when the build +/// script fails to link to an instance of `libclang`. For example, if +/// `llvm-config` couldn't be executed but an instance of `libclang` was found +/// anyway we don't want to pollute the build output with irrelevant errors. #[derive(Default)] pub struct CommandErrorPrinter { discard: bool, @@ -152,33 +91,117 @@ impl Drop for CommandErrorPrinter { } } -/// Returns the paths to and the filenames of the files matching the supplied -/// filename patterns in the supplied directory. +/// 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> { + let output = match Command::new(path).args(arguments).output() { + Ok(output) => output, + Err(error) => { + let message = format!("error: {}", error); + add_command_error(name, path, arguments, message); + return None; + } + }; + + if output.status.success() { + Some(String::from_utf8_lossy(&output.stdout).into_owned()) + } else { + let message = format!("exit code: {}", output.status); + add_command_error(name, path, arguments, message); + None + } +} + +/// Executes the `llvm-config` command and returns the `stdout` output if the +/// command was successfully executed (errors are added to `COMMAND_ERRORS`). +pub fn run_llvm_config(arguments: &[&str]) -> Option<String> { + let path = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into()); + run_command("llvm-config", &path, arguments) +} + +/// Executes the `xcode-select` command and returns the `stdout` output if the +/// command was successfully executed (errors are added to `COMMAND_ERRORS`). +pub fn run_xcode_select(arguments: &[&str]) -> Option<String> { + run_command("xcode-select", "xcode-select", arguments) +} + +//================================================ +// Search Directories +//================================================ + +/// `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", +]; + +/// `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*", +]; + +/// `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", +]; + +/// `libclang` directory patterns for Windows. +const DIRECTORIES_WINDOWS: &[&str] = &[ + "C:\\LLVM\\lib", + "C:\\Program Files*\\LLVM\\lib", + "C:\\MSYS*\\MinGW*\\lib", + // 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", +]; + +//================================================ +// Searching +//================================================ + +/// Finds the files in a directory that match one or more filename glob patterns +/// and returns the paths to and filenames of those files. fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> { - // Escape the directory in case it contains characters that have special - // meaning in glob patterns (e.g., `[` or `]`). + // Escape the specified directory in case it contains characters that have + // special meaning in glob patterns (e.g., `[` or `]`). let directory = Pattern::escape(directory.to_str().unwrap()); let directory = Path::new(&directory); - // Join the directory to the filename patterns to obtain the path patterns. + // Join the escaped directory to the filename glob patterns to obtain + // complete glob patterns for the files being searched for. let paths = filenames .iter() .map(|f| directory.join(f).to_str().unwrap().to_owned()); - // Prevent wildcards from matching path separators. + // Prevent wildcards from matching path separators to ensure that the search + // is limited to the specified directory. let mut options = MatchOptions::new(); options.require_literal_separator = true; paths - .flat_map(|p| { - if let Ok(paths) = glob::glob_with(&p, options) { - paths.filter_map(Result::ok).collect() - } else { - vec![] - } - }) + .map(|p| glob::glob_with(&p, options)) + .filter_map(Result::ok) + .flatten() .filter_map(|p| { - let filename = p.file_name()?.to_str().unwrap(); + let path = p.ok()?; + let filename = path.file_name()?.to_str().unwrap(); // The `libclang_shared` library has been renamed to `libclang-cpp` // in Clang 10. This can cause instances of this library (e.g., @@ -193,9 +216,9 @@ fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, Str .collect::<Vec<_>>() } -/// Returns the paths to and the filenames of the files matching the supplied -/// filename patterns in the supplied directory, checking any relevant sibling -/// directories. +/// Finds the files in a directory (and any relevant sibling directories) that +/// match one or more filename glob patterns and returns the paths to and +/// filenames of those files. fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> { let mut results = search_directory(directory, filenames); @@ -212,54 +235,57 @@ fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, S results } -/// Returns the paths to and the filenames of the `libclang` static or dynamic -/// libraries matching the supplied filename patterns. -pub fn search_libclang_directories(files: &[String], variable: &str) -> Vec<(PathBuf, String)> { - // Use the path provided by the relevant environment variable. +/// Finds the `libclang` static or dynamic libraries matching one or more +/// filename glob patterns and returns the paths to and filenames of those files. +pub fn search_libclang_directories(filenames: &[String], variable: &str) -> Vec<(PathBuf, String)> { + // Search only the path indicated by the relevant environment variable + // (e.g., `LIBCLANG_PATH`) if it is set. if let Ok(path) = env::var(variable).map(|d| Path::new(&d).to_path_buf()) { - // Check if the path is referring to a matching file already. + // Check if the path is a matching file. if let Some(parent) = path.parent() { let filename = path.file_name().unwrap().to_str().unwrap(); - let libraries = search_directories(parent, files); + let libraries = search_directories(parent, filenames); if libraries.iter().any(|(_, f)| f == filename) { return vec![(parent.into(), filename.into())]; } } - return search_directories(&path, files); + // Check if the path is directory containing a matching file. + return search_directories(&path, filenames); } let mut found = vec![]; - // Search the `bin` and `lib` directories in directory provided by + // Search the `bin` and `lib` directories in the directory returned by // `llvm-config --prefix`. if let Some(output) = run_llvm_config(&["--prefix"]) { let directory = Path::new(output.lines().next().unwrap()).to_path_buf(); - found.extend(search_directories(&directory.join("bin"), files)); - found.extend(search_directories(&directory.join("lib"), files)); - found.extend(search_directories(&directory.join("lib64"), files)); + found.extend(search_directories(&directory.join("bin"), filenames)); + found.extend(search_directories(&directory.join("lib"), filenames)); + found.extend(search_directories(&directory.join("lib64"), filenames)); } - // Search the toolchain directory in the directory provided by + // Search the toolchain directory in the directory returned by // `xcode-select --print-path`. if cfg!(target_os = "macos") { - if let Some(output) = run_command("xcode-select", "xcode-select", &["--print-path"]) { + 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"); - found.extend(search_directories(&directory, files)); + found.extend(search_directories(&directory, filenames)); } } - // Search the directories provided by the `LD_LIBRARY_PATH` environment - // variable. + // Search the directories in the `LD_LIBRARY_PATH` environment variable. if let Ok(path) = env::var("LD_LIBRARY_PATH") { for directory in env::split_paths(&path) { - found.extend(search_directories(&directory, files)); + found.extend(search_directories(&directory, filenames)); } } // Determine the `libclang` directory patterns. - let directories = if cfg!(any(target_os = "freebsd", target_os = "linux")) { + 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 @@ -276,7 +302,7 @@ pub fn search_libclang_directories(files: &[String], variable: &str) -> Vec<(Pat for directory in directories.iter().rev() { 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, files)); + found.extend(search_directories(&directory, filenames)); } } } diff --git a/build/dynamic.rs b/build/dynamic.rs index 156afe4..39247c8 100644 --- a/build/dynamic.rs +++ b/build/dynamic.rs @@ -1,16 +1,4 @@ -// Copyright 2018 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 use std::env; use std::fs::File; @@ -19,7 +7,11 @@ use std::path::{Path, PathBuf}; use super::common; -/// Returns the ELF class from the ELF header in the supplied file. +//================================================ +// Validation +//================================================ + +/// Extracts the ELF class from the ELF header in a shared library. fn parse_elf_header(path: &Path) -> io::Result<u8> { let mut file = File::open(path)?; let mut buffer = [0; 5]; @@ -31,34 +23,34 @@ fn parse_elf_header(path: &Path) -> io::Result<u8> { } } -/// Returns the magic number from the PE header in the supplied file. +/// Extracts the magic number from the PE header in a shared library. fn parse_pe_header(path: &Path) -> io::Result<u16> { let mut file = File::open(path)?; - // Determine the header offset. + // Extract the header offset. let mut buffer = [0; 4]; let start = SeekFrom::Start(0x3C); file.seek(start)?; file.read_exact(&mut buffer)?; let offset = i32::from_le_bytes(buffer); - // Determine the validity of the header. + // Check the validity of the header. file.seek(SeekFrom::Start(offset as u64))?; file.read_exact(&mut buffer)?; if buffer != [80, 69, 0, 0] { return Err(Error::new(ErrorKind::InvalidData, "invalid PE header")); } - // Find the magic number. + // Extract the magic number. let mut buffer = [0; 2]; file.seek(SeekFrom::Current(20))?; file.read_exact(&mut buffer)?; Ok(u16::from_le_bytes(buffer)) } -/// Validates the header for the supplied `libclang` shared library. -fn validate_header(path: &Path) -> Result<(), String> { - if cfg!(any(target_os = "freebsd", target_os = "linux")) { +/// 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")) { let class = parse_elf_header(path).map_err(|e| e.to_string())?; if cfg!(target_pointer_width = "32") && class != 1 { @@ -87,8 +79,11 @@ fn validate_header(path: &Path) -> Result<(), String> { } } -/// Returns the components of the version in the supplied `libclang` shared -// library filename. +//================================================ +// Searching +//================================================ + +/// Extracts the version components in a `libclang` shared library filename. fn parse_version(filename: &str) -> Vec<u32> { let version = if let Some(version) = filename.strip_prefix("libclang.so.") { version @@ -101,8 +96,8 @@ fn parse_version(filename: &str) -> Vec<u32> { version.split('.').map(|s| s.parse().unwrap_or(0)).collect() } -/// Returns the paths to, the filenames, and the versions of the `libclang` -// shared libraries. +/// Finds `libclang` shared libraries and returns the paths to, filenames of, +/// and versions of those shared libraries. fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Vec<u32>)>, String> { let mut files = vec![format!( "{}clang{}", @@ -127,9 +122,10 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve } if cfg!(any( - target_os = "openbsd", target_os = "freebsd", - target_os = "netbsd" + 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., @@ -143,12 +139,12 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve files.push("libclang.dll".into()); } - // Validate the `libclang` shared libraries and collect the versions. + // Find and validate `libclang` shared libraries and collect the versions. let mut valid = vec![]; let mut invalid = vec![]; for (directory, filename) in common::search_libclang_directories(&files, "LIBCLANG_PATH") { let path = directory.join(&filename); - match validate_header(&path) { + match validate_library(&path) { Ok(()) => { let version = parse_version(&filename); valid.push((directory, filename, version)) @@ -176,8 +172,8 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve Err(message) } -/// Returns the directory and filename of the "best" available `libclang` shared -/// library. +/// Finds the "best" `libclang` shared library and returns the directory and +/// filename of that library. pub fn find(runtime: bool) -> Result<(PathBuf, String), String> { search_libclang_directories(runtime)? .iter() @@ -201,7 +197,11 @@ pub fn find(runtime: bool) -> Result<(PathBuf, String), String> { .ok_or_else(|| "unreachable".into()) } -/// Find and link to `libclang` dynamically. +//================================================ +// Linking +//================================================ + +/// Finds and links to a `libclang` shared library. #[cfg(not(feature = "runtime"))] pub fn link() { let cep = common::CommandErrorPrinter::default(); diff --git a/build/static.rs b/build/static.rs index 66da274..6af914f 100644 --- a/build/static.rs +++ b/build/static.rs @@ -1,16 +1,4 @@ -// Copyright 2018 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 extern crate glob; @@ -20,7 +8,28 @@ use glob::Pattern; use common; -/// Returns the name of an LLVM or Clang library from a path to such a library. +//================================================ +// Searching +//================================================ + +/// Clang static libraries required to link to `libclang` 3.5 and later. +const CLANG_LIBRARIES: &[&str] = &[ + "clang", + "clangAST", + "clangAnalysis", + "clangBasic", + "clangDriver", + "clangEdit", + "clangFrontend", + "clangIndex", + "clangLex", + "clangParse", + "clangRewrite", + "clangSema", + "clangSerialization", +]; + +/// Gets the name of an LLVM or Clang static library from a path. fn get_library_name(path: &Path) -> Option<String> { path.file_stem().map(|p| { let string = p.to_string_lossy(); @@ -32,7 +41,7 @@ fn get_library_name(path: &Path) -> Option<String> { }) } -/// Returns the LLVM libraries required to link to `libclang` statically. +/// Gets the LLVM static libraries required to link to `libclang`. fn get_llvm_libraries() -> Vec<String> { common::run_llvm_config(&["--libs"]) .unwrap() @@ -50,24 +59,7 @@ fn get_llvm_libraries() -> Vec<String> { .collect() } -/// Clang libraries required to link to `libclang` 3.5 and later statically. -const CLANG_LIBRARIES: &[&str] = &[ - "clang", - "clangAST", - "clangAnalysis", - "clangBasic", - "clangDriver", - "clangEdit", - "clangFrontend", - "clangIndex", - "clangLex", - "clangParse", - "clangRewrite", - "clangSema", - "clangSerialization", -]; - -/// Returns the Clang libraries required to link to `libclang` statically. +/// Gets the Clang static libraries required to link to `libclang`. fn get_clang_libraries<P: AsRef<Path>>(directory: P) -> Vec<String> { // Escape the directory in case it contains characters that have special // meaning in glob patterns (e.g., `[` or `]`). @@ -84,7 +76,8 @@ fn get_clang_libraries<P: AsRef<Path>>(directory: P) -> Vec<String> { } } -/// Returns a directory containing `libclang` static libraries. +/// 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") { "libclang.lib" @@ -100,7 +93,11 @@ fn find() -> PathBuf { } } -/// Find and link to `libclang` statically. +//================================================ +// Linking +//================================================ + +/// Finds and links to `libclang` static libraries. pub fn link() { let cep = common::CommandErrorPrinter::default(); @@ -133,7 +130,7 @@ pub fn link() { // MSVC doesn't need this, as it tracks dependencies inside `.lib` files. if cfg!(target_os = "freebsd") { println!("cargo:rustc-flags=-l ffi -l ncursesw -l c++ -l z"); - } else if cfg!(target_os = "linux") { + } else if cfg!(any(target_os = "haiku", target_os = "linux")) { println!("cargo:rustc-flags=-l ffi -l ncursesw -l stdc++ -l z"); } else if cfg!(target_os = "macos") { println!("cargo:rustc-flags=-l ffi -l ncurses -l c++ -l z"); diff --git a/out/common.rs b/out/common.rs index 56480df..bc720ca 100644 --- a/out/common.rs +++ b/out/common.rs @@ -1,16 +1,4 @@ -// Copyright 2018 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 extern crate glob; @@ -22,87 +10,38 @@ use std::process::Command; use glob::{MatchOptions, Pattern}; -/// `libclang` directory patterns for FreeBSD and Linux. -const DIRECTORIES_LINUX: &[&str] = &[ - "/usr/lib*", - "/usr/lib*/*", - "/usr/lib*/*/*", - "/usr/local/lib*", - "/usr/local/lib*/*", - "/usr/local/lib*/*/*", - "/usr/local/llvm*/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", -]; - -/// `libclang` directory patterns for Windows. -const DIRECTORIES_WINDOWS: &[&str] = &[ - "C:\\LLVM\\lib", - "C:\\Program Files*\\LLVM\\lib", - "C:\\MSYS*\\MinGW*\\lib", - // 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", - // Scoop user installation https://scoop.sh/. - // Chocolatey, WinGet and other installers use to the system wide dir listed above - "C:\\Users\\*\\scoop\\apps\\llvm\\current\\bin", -]; +//================================================ +// Commands +//================================================ thread_local! { - /// The errors encountered when attempting to execute console commands. + /// The errors encountered by the build script while executing commands. static COMMAND_ERRORS: RefCell<HashMap<String, Vec<String>>> = RefCell::default(); } -/// Executes the supplied console command, returning the `stdout` output if the -/// command was successfully executed. -fn run_command(name: &str, command: &str, arguments: &[&str]) -> Option<String> { - macro_rules! error { - ($error:expr) => {{ - COMMAND_ERRORS.with(|e| { - e.borrow_mut() - .entry(name.into()) - .or_insert_with(Vec::new) - .push(format!( - "couldn't execute `{} {}` ({})", - command, - arguments.join(" "), - $error, - )) - }); - }}; - } - - let output = match Command::new(command).args(arguments).output() { - Ok(output) => output, - Err(error) => { - error!(format!("error: {}", error)); - return None; - } - }; - - if !output.status.success() { - error!(format!("exit code: {}", output.status)); - return None; - } - - Some(String::from_utf8_lossy(&output.stdout).into_owned()) +/// Adds an error encountered by the build script while executing a command. +fn add_command_error(name: &str, path: &str, arguments: &[&str], message: String) { + COMMAND_ERRORS.with(|e| { + e.borrow_mut() + .entry(name.into()) + .or_insert_with(Vec::new) + .push(format!( + "couldn't execute `{} {}` (path={}) ({})", + name, + arguments.join(" "), + path, + message, + )) + }); } -/// Executes `llvm-config`, returning the `stdout` output if the command was -/// successfully executed. -pub fn run_llvm_config(arguments: &[&str]) -> Option<String> { - let path = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into()); - run_command("llvm-config", &path, arguments) -} - -/// A struct that prints errors encountered when attempting to execute console -/// commands on drop if not discarded. +/// A struct that prints the errors encountered by the build script while +/// executing commands when dropped (unless explictly discarded). +/// +/// This is handy because we only want to print these errors when the build +/// script fails to link to an instance of `libclang`. For example, if +/// `llvm-config` couldn't be executed but an instance of `libclang` was found +/// anyway we don't want to pollute the build output with irrelevant errors. #[derive(Default)] pub struct CommandErrorPrinter { discard: bool, @@ -152,33 +91,117 @@ impl Drop for CommandErrorPrinter { } } -/// Returns the paths to and the filenames of the files matching the supplied -/// filename patterns in the supplied directory. +/// 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> { + let output = match Command::new(path).args(arguments).output() { + Ok(output) => output, + Err(error) => { + let message = format!("error: {}", error); + add_command_error(name, path, arguments, message); + return None; + } + }; + + if output.status.success() { + Some(String::from_utf8_lossy(&output.stdout).into_owned()) + } else { + let message = format!("exit code: {}", output.status); + add_command_error(name, path, arguments, message); + None + } +} + +/// Executes the `llvm-config` command and returns the `stdout` output if the +/// command was successfully executed (errors are added to `COMMAND_ERRORS`). +pub fn run_llvm_config(arguments: &[&str]) -> Option<String> { + let path = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into()); + run_command("llvm-config", &path, arguments) +} + +/// Executes the `xcode-select` command and returns the `stdout` output if the +/// command was successfully executed (errors are added to `COMMAND_ERRORS`). +pub fn run_xcode_select(arguments: &[&str]) -> Option<String> { + run_command("xcode-select", "xcode-select", arguments) +} + +//================================================ +// Search Directories +//================================================ + +/// `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", +]; + +/// `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*", +]; + +/// `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", +]; + +/// `libclang` directory patterns for Windows. +const DIRECTORIES_WINDOWS: &[&str] = &[ + "C:\\LLVM\\lib", + "C:\\Program Files*\\LLVM\\lib", + "C:\\MSYS*\\MinGW*\\lib", + // 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", +]; + +//================================================ +// Searching +//================================================ + +/// Finds the files in a directory that match one or more filename glob patterns +/// and returns the paths to and filenames of those files. fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> { - // Escape the directory in case it contains characters that have special - // meaning in glob patterns (e.g., `[` or `]`). + // Escape the specified directory in case it contains characters that have + // special meaning in glob patterns (e.g., `[` or `]`). let directory = Pattern::escape(directory.to_str().unwrap()); let directory = Path::new(&directory); - // Join the directory to the filename patterns to obtain the path patterns. + // Join the escaped directory to the filename glob patterns to obtain + // complete glob patterns for the files being searched for. let paths = filenames .iter() .map(|f| directory.join(f).to_str().unwrap().to_owned()); - // Prevent wildcards from matching path separators. + // Prevent wildcards from matching path separators to ensure that the search + // is limited to the specified directory. let mut options = MatchOptions::new(); options.require_literal_separator = true; paths - .flat_map(|p| { - if let Ok(paths) = glob::glob_with(&p, options) { - paths.filter_map(Result::ok).collect() - } else { - vec![] - } - }) + .map(|p| glob::glob_with(&p, options)) + .filter_map(Result::ok) + .flatten() .filter_map(|p| { - let filename = p.file_name()?.to_str().unwrap(); + let path = p.ok()?; + let filename = path.file_name()?.to_str().unwrap(); // The `libclang_shared` library has been renamed to `libclang-cpp` // in Clang 10. This can cause instances of this library (e.g., @@ -193,9 +216,9 @@ fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, Str .collect::<Vec<_>>() } -/// Returns the paths to and the filenames of the files matching the supplied -/// filename patterns in the supplied directory, checking any relevant sibling -/// directories. +/// Finds the files in a directory (and any relevant sibling directories) that +/// match one or more filename glob patterns and returns the paths to and +/// filenames of those files. fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> { let mut results = search_directory(directory, filenames); @@ -212,54 +235,57 @@ fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, S results } -/// Returns the paths to and the filenames of the `libclang` static or dynamic -/// libraries matching the supplied filename patterns. -pub fn search_libclang_directories(files: &[String], variable: &str) -> Vec<(PathBuf, String)> { - // Use the path provided by the relevant environment variable. +/// Finds the `libclang` static or dynamic libraries matching one or more +/// filename glob patterns and returns the paths to and filenames of those files. +pub fn search_libclang_directories(filenames: &[String], variable: &str) -> Vec<(PathBuf, String)> { + // Search only the path indicated by the relevant environment variable + // (e.g., `LIBCLANG_PATH`) if it is set. if let Ok(path) = env::var(variable).map(|d| Path::new(&d).to_path_buf()) { - // Check if the path is referring to a matching file already. + // Check if the path is a matching file. if let Some(parent) = path.parent() { let filename = path.file_name().unwrap().to_str().unwrap(); - let libraries = search_directories(parent, files); + let libraries = search_directories(parent, filenames); if libraries.iter().any(|(_, f)| f == filename) { return vec![(parent.into(), filename.into())]; } } - return search_directories(&path, files); + // Check if the path is directory containing a matching file. + return search_directories(&path, filenames); } let mut found = vec![]; - // Search the `bin` and `lib` directories in directory provided by + // Search the `bin` and `lib` directories in the directory returned by // `llvm-config --prefix`. if let Some(output) = run_llvm_config(&["--prefix"]) { let directory = Path::new(output.lines().next().unwrap()).to_path_buf(); - found.extend(search_directories(&directory.join("bin"), files)); - found.extend(search_directories(&directory.join("lib"), files)); - found.extend(search_directories(&directory.join("lib64"), files)); + found.extend(search_directories(&directory.join("bin"), filenames)); + found.extend(search_directories(&directory.join("lib"), filenames)); + found.extend(search_directories(&directory.join("lib64"), filenames)); } - // Search the toolchain directory in the directory provided by + // Search the toolchain directory in the directory returned by // `xcode-select --print-path`. if cfg!(target_os = "macos") { - if let Some(output) = run_command("xcode-select", "xcode-select", &["--print-path"]) { + 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"); - found.extend(search_directories(&directory, files)); + found.extend(search_directories(&directory, filenames)); } } - // Search the directories provided by the `LD_LIBRARY_PATH` environment - // variable. + // Search the directories in the `LD_LIBRARY_PATH` environment variable. if let Ok(path) = env::var("LD_LIBRARY_PATH") { for directory in env::split_paths(&path) { - found.extend(search_directories(&directory, files)); + found.extend(search_directories(&directory, filenames)); } } // Determine the `libclang` directory patterns. - let directories = if cfg!(any(target_os = "freebsd", target_os = "linux")) { + 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 @@ -276,7 +302,7 @@ pub fn search_libclang_directories(files: &[String], variable: &str) -> Vec<(Pat for directory in directories.iter().rev() { 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, files)); + found.extend(search_directories(&directory, filenames)); } } } diff --git a/out/dynamic.rs b/out/dynamic.rs index 156afe4..39247c8 100644 --- a/out/dynamic.rs +++ b/out/dynamic.rs @@ -1,16 +1,4 @@ -// Copyright 2018 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 use std::env; use std::fs::File; @@ -19,7 +7,11 @@ use std::path::{Path, PathBuf}; use super::common; -/// Returns the ELF class from the ELF header in the supplied file. +//================================================ +// Validation +//================================================ + +/// Extracts the ELF class from the ELF header in a shared library. fn parse_elf_header(path: &Path) -> io::Result<u8> { let mut file = File::open(path)?; let mut buffer = [0; 5]; @@ -31,34 +23,34 @@ fn parse_elf_header(path: &Path) -> io::Result<u8> { } } -/// Returns the magic number from the PE header in the supplied file. +/// Extracts the magic number from the PE header in a shared library. fn parse_pe_header(path: &Path) -> io::Result<u16> { let mut file = File::open(path)?; - // Determine the header offset. + // Extract the header offset. let mut buffer = [0; 4]; let start = SeekFrom::Start(0x3C); file.seek(start)?; file.read_exact(&mut buffer)?; let offset = i32::from_le_bytes(buffer); - // Determine the validity of the header. + // Check the validity of the header. file.seek(SeekFrom::Start(offset as u64))?; file.read_exact(&mut buffer)?; if buffer != [80, 69, 0, 0] { return Err(Error::new(ErrorKind::InvalidData, "invalid PE header")); } - // Find the magic number. + // Extract the magic number. let mut buffer = [0; 2]; file.seek(SeekFrom::Current(20))?; file.read_exact(&mut buffer)?; Ok(u16::from_le_bytes(buffer)) } -/// Validates the header for the supplied `libclang` shared library. -fn validate_header(path: &Path) -> Result<(), String> { - if cfg!(any(target_os = "freebsd", target_os = "linux")) { +/// 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")) { let class = parse_elf_header(path).map_err(|e| e.to_string())?; if cfg!(target_pointer_width = "32") && class != 1 { @@ -87,8 +79,11 @@ fn validate_header(path: &Path) -> Result<(), String> { } } -/// Returns the components of the version in the supplied `libclang` shared -// library filename. +//================================================ +// Searching +//================================================ + +/// Extracts the version components in a `libclang` shared library filename. fn parse_version(filename: &str) -> Vec<u32> { let version = if let Some(version) = filename.strip_prefix("libclang.so.") { version @@ -101,8 +96,8 @@ fn parse_version(filename: &str) -> Vec<u32> { version.split('.').map(|s| s.parse().unwrap_or(0)).collect() } -/// Returns the paths to, the filenames, and the versions of the `libclang` -// shared libraries. +/// Finds `libclang` shared libraries and returns the paths to, filenames of, +/// and versions of those shared libraries. fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Vec<u32>)>, String> { let mut files = vec![format!( "{}clang{}", @@ -127,9 +122,10 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve } if cfg!(any( - target_os = "openbsd", target_os = "freebsd", - target_os = "netbsd" + 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., @@ -143,12 +139,12 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve files.push("libclang.dll".into()); } - // Validate the `libclang` shared libraries and collect the versions. + // Find and validate `libclang` shared libraries and collect the versions. let mut valid = vec![]; let mut invalid = vec![]; for (directory, filename) in common::search_libclang_directories(&files, "LIBCLANG_PATH") { let path = directory.join(&filename); - match validate_header(&path) { + match validate_library(&path) { Ok(()) => { let version = parse_version(&filename); valid.push((directory, filename, version)) @@ -176,8 +172,8 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve Err(message) } -/// Returns the directory and filename of the "best" available `libclang` shared -/// library. +/// Finds the "best" `libclang` shared library and returns the directory and +/// filename of that library. pub fn find(runtime: bool) -> Result<(PathBuf, String), String> { search_libclang_directories(runtime)? .iter() @@ -201,7 +197,11 @@ pub fn find(runtime: bool) -> Result<(PathBuf, String), String> { .ok_or_else(|| "unreachable".into()) } -/// Find and link to `libclang` dynamically. +//================================================ +// Linking +//================================================ + +/// Finds and links to a `libclang` shared library. #[cfg(not(feature = "runtime"))] pub fn link() { let cep = common::CommandErrorPrinter::default(); @@ -1,16 +1,4 @@ -// Copyright 2016 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 //! Rust bindings for `libclang`. //! @@ -137,6 +125,8 @@ cenum! { const CXCallingConv_AArch64VectorCall = 16, const CXCallingConv_Invalid = 100, const CXCallingConv_Unexposed = 200, + /// Only produced by `libclang` 13.0 and later. + const CXCallingConv_SwiftAsync = 17, } } @@ -325,6 +315,12 @@ cenum! { const CXCursor_ObjCAvailabilityCheckExpr = 148, /// Only produced by `libclang` 7.0 and later. const CXCursor_FixedPointLiteral = 149, + /// Only produced by `libclang` 12.0 and later. + const CXCursor_OMPArrayShapingExpr = 150, + /// Only produced by `libclang` 12.0 and later. + const CXCursor_OMPIteratorExpr = 151, + /// Only produced by `libclang` 12.0 and later. + const CXCursor_CXXAddrspaceCastExpr = 152, const CXCursor_UnexposedStmt = 200, const CXCursor_LabelStmt = 201, const CXCursor_CompoundStmt = 202, @@ -454,6 +450,18 @@ cenum! { const CXCursor_OMPDepobjDirective = 286, /// Only produced by `libclang` 11.0 and later. const CXCursor_OMPScanDirective = 287, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPTileDirective = 288, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPCanonicalLoop = 289, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPInteropDirective = 290, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPDispatchDirective = 291, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPMaskedDirective = 292, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPUnrollDirective = 293, const CXCursor_TranslationUnit = 300, const CXCursor_UnexposedAttr = 400, const CXCursor_IBActionAttr = 401, @@ -1033,6 +1041,8 @@ cenum! { const CXTypeNullability_Nullable = 1, const CXTypeNullability_Unspecified = 2, const CXTypeNullability_Invalid = 3, + /// Only produced by `libclang` 12.0 and later. + const CXTypeNullability_NullableResult = 4, } } @@ -1764,12 +1774,6 @@ link! { /// Only available on `libclang` 3.7 and later. #[cfg(feature = "clang_3_7")] pub fn clang_Cursor_getOffsetOfField(cursor: CXCursor) -> c_longlong; - /// Only available on `libclang` 9.0 and later. - #[cfg(feature = "clang_9_0")] - pub fn clang_Cursor_isAnonymousRecordDecl(cursor: CXCursor) -> c_uint; - /// Only available on `libclang` 9.0 and later. - #[cfg(feature = "clang_9_0")] - pub fn clang_Cursor_isInlineNamespace(cursor: CXCursor) -> c_uint; pub fn clang_Cursor_getRawCommentText(cursor: CXCursor) -> CXString; pub fn clang_Cursor_getReceiverType(cursor: CXCursor) -> CXType; pub fn clang_Cursor_getSpellingNameRange(cursor: CXCursor, index: c_uint, reserved: c_uint) -> CXSourceRange; @@ -1789,12 +1793,24 @@ link! { #[cfg(feature = "clang_3_6")] pub fn clang_Cursor_getTemplateArgumentValue(cursor: CXCursor, index: c_uint) -> c_longlong; pub fn clang_Cursor_getTranslationUnit(cursor: CXCursor) -> CXTranslationUnit; + /// Only available on `libclang` 12.0 and later. + #[cfg(feature = "clang_12_0")] + pub fn clang_Cursor_getVarDeclInitializer(cursor: CXCursor) -> CXCursor; /// Only available on `libclang` 3.9 and later. #[cfg(feature = "clang_3_9")] pub fn clang_Cursor_hasAttrs(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 12.0 and later. + #[cfg(feature = "clang_12_0")] + pub fn clang_Cursor_hasVarDeclGlobalStorage(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 12.0 and later. + #[cfg(feature = "clang_12_0")] + pub fn clang_Cursor_hasVarDeclExternalStorage(cursor: CXCursor) -> c_uint; /// Only available on `libclang` 3.7 and later. #[cfg(feature = "clang_3_7")] pub fn clang_Cursor_isAnonymous(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 9.0 and later. + #[cfg(feature = "clang_9_0")] + pub fn clang_Cursor_isAnonymousRecordDecl(cursor: CXCursor) -> c_uint; pub fn clang_Cursor_isBitField(cursor: CXCursor) -> c_uint; pub fn clang_Cursor_isDynamicCall(cursor: CXCursor) -> c_int; /// Only available on `libclang` 5.0 and later. @@ -1803,6 +1819,9 @@ link! { /// Only available on `libclang` 3.9 and later. #[cfg(feature = "clang_3_9")] pub fn clang_Cursor_isFunctionInlined(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 9.0 and later. + #[cfg(feature = "clang_9_0")] + pub fn clang_Cursor_isInlineNamespace(cursor: CXCursor) -> c_uint; /// Only available on `libclang` 3.9 and later. #[cfg(feature = "clang_3_9")] pub fn clang_Cursor_isMacroBuiltin(cursor: CXCursor) -> c_uint; @@ -1878,35 +1897,35 @@ link! { pub fn clang_Type_getAlignOf(type_: CXType) -> c_longlong; pub fn clang_Type_getCXXRefQualifier(type_: CXType) -> CXRefQualifierKind; pub fn clang_Type_getClassType(type_: CXType) -> CXType; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getModifiedType(type_: CXType) -> CXType; /// Only available on `libclang` 3.9 and later. #[cfg(feature = "clang_3_9")] pub fn clang_Type_getNamedType(type_: CXType) -> CXType; - pub fn clang_Type_getNumTemplateArguments(type_: CXType) -> c_int; /// Only available on `libclang` 8.0 and later. #[cfg(feature = "clang_8_0")] - pub fn clang_Type_getObjCObjectBaseType(type_: CXType) -> CXType; + pub fn clang_Type_getNullability(type_: CXType) -> CXTypeNullabilityKind; /// Only available on `libclang` 8.0 and later. #[cfg(feature = "clang_8_0")] pub fn clang_Type_getNumObjCProtocolRefs(type_: CXType) -> c_uint; /// Only available on `libclang` 8.0 and later. #[cfg(feature = "clang_8_0")] - pub fn clang_Type_getObjCProtocolDecl(type_: CXType, index: c_uint) -> CXCursor; - /// Only available on `libclang` 8.0 and later. - #[cfg(feature = "clang_8_0")] pub fn clang_Type_getNumObjCTypeArgs(type_: CXType) -> c_uint; - /// Only available on `libclang` 8.0 and later. - #[cfg(feature = "clang_8_0")] - pub fn clang_Type_getObjCTypeArg(type_: CXType, index: c_uint) -> CXType; + pub fn clang_Type_getNumTemplateArguments(type_: CXType) -> c_int; /// Only available on `libclang` 3.9 and later. #[cfg(feature = "clang_3_9")] pub fn clang_Type_getObjCEncoding(type_: CXType) -> CXString; - pub fn clang_Type_getOffsetOf(type_: CXType, field: *const c_char) -> c_longlong; /// Only available on `libclang` 8.0 and later. #[cfg(feature = "clang_8_0")] - pub fn clang_Type_getModifiedType(type_: CXType) -> CXType; + pub fn clang_Type_getObjCObjectBaseType(type_: CXType) -> CXType; /// Only available on `libclang` 8.0 and later. #[cfg(feature = "clang_8_0")] - pub fn clang_Type_getNullability(type_: CXType) -> CXTypeNullabilityKind; + pub fn clang_Type_getObjCProtocolDecl(type_: CXType, index: c_uint) -> CXCursor; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getObjCTypeArg(type_: CXType, index: c_uint) -> CXType; + pub fn clang_Type_getOffsetOf(type_: CXType, field: *const c_char) -> c_longlong; pub fn clang_Type_getSizeOf(type_: CXType) -> c_longlong; pub fn clang_Type_getTemplateArgumentAsType(type_: CXType, index: c_uint) -> CXType; /// Only available on `libclang` 11.0 and later. @@ -2099,16 +2118,17 @@ link! { pub fn clang_getSpecializedCursorTemplate(cursor: CXCursor) -> CXCursor; pub fn clang_getSpellingLocation(location: CXSourceLocation, file: *mut CXFile, line: *mut c_uint, column: *mut c_uint, offset: *mut c_uint); pub fn clang_getTUResourceUsageName(kind: CXTUResourceUsageKind) -> *const c_char; - /// Only available on `libclang` 5.0 and later. - #[cfg(feature = "clang_5_0")] - pub fn clang_getTranslationUnitTargetInfo(tu: CXTranslationUnit) -> CXTargetInfo; pub fn clang_getTemplateCursorKind(cursor: CXCursor) -> CXCursorKind; + pub fn clang_getToken(tu: CXTranslationUnit, location: CXSourceLocation) -> *mut CXToken; pub fn clang_getTokenExtent(tu: CXTranslationUnit, token: CXToken) -> CXSourceRange; pub fn clang_getTokenKind(token: CXToken) -> CXTokenKind; pub fn clang_getTokenLocation(tu: CXTranslationUnit, token: CXToken) -> CXSourceLocation; pub fn clang_getTokenSpelling(tu: CXTranslationUnit, token: CXToken) -> CXString; pub fn clang_getTranslationUnitCursor(tu: CXTranslationUnit) -> CXCursor; pub fn clang_getTranslationUnitSpelling(tu: CXTranslationUnit) -> CXString; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_getTranslationUnitTargetInfo(tu: CXTranslationUnit) -> CXTargetInfo; pub fn clang_getTypeDeclaration(type_: CXType) -> CXCursor; pub fn clang_getTypeKindSpelling(type_: CXTypeKind) -> CXString; pub fn clang_getTypeSpelling(type_: CXType) -> CXString; @@ -2187,10 +2207,10 @@ link! { pub fn clang_Cursor_getParsedComment(C: CXCursor) -> CXComment; pub fn clang_FullComment_getAsHTML(comment: CXComment) -> CXString; pub fn clang_FullComment_getAsXML(comment: CXComment) -> CXString; - pub fn clang_HTMLStartTagComment_isSelfClosing(comment: CXComment) -> c_uint; pub fn clang_HTMLStartTag_getAttrName(comment: CXComment, index: c_uint) -> CXString; pub fn clang_HTMLStartTag_getAttrValue(comment: CXComment, index: c_uint) -> CXString; pub fn clang_HTMLStartTag_getNumAttrs(comment: CXComment) -> c_uint; + pub fn clang_HTMLStartTagComment_isSelfClosing(comment: CXComment) -> c_uint; pub fn clang_HTMLTagComment_getAsString(comment: CXComment) -> CXString; pub fn clang_HTMLTagComment_getTagName(comment: CXComment) -> CXString; pub fn clang_InlineCommandComment_getArgText(comment: CXComment, index: c_uint) -> CXString; @@ -2203,11 +2223,11 @@ link! { pub fn clang_ParamCommandComment_getParamName(comment: CXComment) -> CXString; pub fn clang_ParamCommandComment_isDirectionExplicit(comment: CXComment) -> c_uint; pub fn clang_ParamCommandComment_isParamIndexValid(comment: CXComment) -> c_uint; + pub fn clang_TextComment_getText(comment: CXComment) -> CXString; pub fn clang_TParamCommandComment_getDepth(comment: CXComment) -> c_uint; pub fn clang_TParamCommandComment_getIndex(comment: CXComment, depth: c_uint) -> c_uint; pub fn clang_TParamCommandComment_getParamName(comment: CXComment) -> CXString; pub fn clang_TParamCommandComment_isParamPositionValid(comment: CXComment) -> c_uint; - pub fn clang_TextComment_getText(comment: CXComment) -> CXString; pub fn clang_VerbatimBlockLineComment_getText(comment: CXComment) -> CXString; pub fn clang_VerbatimLineComment_getText(comment: CXComment) -> CXString; } diff --git a/src/link.rs b/src/link.rs index 64a3528..c3b0830 100644 --- a/src/link.rs +++ b/src/link.rs @@ -1,16 +1,4 @@ -// Copyright 2016 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 //================================================ // Macros diff --git a/src/support.rs b/src/support.rs index 48bae28..ff38d39 100644 --- a/src/support.rs +++ b/src/support.rs @@ -1,16 +1,4 @@ -// Copyright 2016 Kyle Mayes -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: Apache-2.0 //! Provides helper functionality. |