Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/clang-sys/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/clang-sys/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"CHANGELOG.md":"7a177945b551a62c30b9183f8edaac38216fbeb3fb7f8760e5f2a69916140086","Cargo.toml":"9d896747d0d657eeb8913dc254439b06f77025399c654026db5d58bf655837f6","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"d75bc7b6e957818c2c9c78107eade13c48bd1e9f6a5eca3b04644b21938b0157","build.rs":"f344874bf25f8ec6f852c55edaf262789fc6b883489afb47fa3d7da83f95ad1c","build/common.rs":"0b23893c737a9b60d8d400b5101bf3bcc632e0833d948590c42d189a1f69aeb0","build/dynamic.rs":"79014d1f9c7a197affb018d60218458e8878ccc80e61fc2e5d61b2f291ebbb4b","build/macros.rs":"eac7bffaac5f70728764065145eb1541b0a133c900356a0bcf55f0d89966c84e","build/static.rs":"b3000f872b139b3f3230f49e98a183d05ac18be661192bb5cada896eca853aca","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"3c0fc0c0e3cabc3b81732b5ac784b36f69dfb72abcecc3bf4e5a08c72d9c8ad0","src/link.rs":"13b236714d68483fbcec9df2ee1ae63db21e87176881c2d53a9157a2b38240eb","src/support.rs":"5398f8c35cceae64ca941b9a26ed28f29d34a1301958399d636e599dcfd0d64f","tests/build.rs":"66ed85f6e1baf9fac5c50e486fa43413e40c3f16ce9f503c9bba53e300682a9a","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"a39e48b2ab3347692f461609e296456850cff870514fa3df8232341318015568"},"package":"67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1"}
|
||||
527
third-party/vendor/clang-sys/CHANGELOG.md
vendored
Normal file
527
third-party/vendor/clang-sys/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,527 @@
|
|||
## [1.7.0] - 2023-12-31
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 17.0.x
|
||||
|
||||
## [1.6.1] - 2023-03-29
|
||||
|
||||
### Fixed
|
||||
- Improved error message when calling a `libclang` function that is not supported by the loaded `libclang` instance (https://github.com/rust-lang/rust-bindgen/issues/2446)
|
||||
|
||||
## [1.6.0] - 2023-02-18
|
||||
|
||||
### 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
|
||||
- The value of an `EntityKind` enum variant
|
||||
(`EntityKind::CXCursor_TranslationUnit`) has been updated for Clang 15.0 and
|
||||
later to match the
|
||||
[breaking change made in `libclang`](https://github.com/llvm/llvm-project/commit/bb83f8e70bd1d56152f02307adacd718cd67e312#diff-674613a0e47f4e66cc19061e28e3296d39be2d124dceefb68237b30b8e241e7c)
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 16.0.x
|
||||
- Added support for `clang` 15.0.x
|
||||
- Added support for `clang` 14.0.x
|
||||
|
||||
## [1.3.3] - 2022-05-28
|
||||
|
||||
### Fixed
|
||||
- Fixed `Clang::find` to check that `CLANG_PATH` is an executable file before
|
||||
selecting it
|
||||
|
||||
## [1.3.2] - 2022-05-18
|
||||
|
||||
### Added
|
||||
- Added support for illumos and derivatives
|
||||
|
||||
## [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
|
||||
- Fixed handling of paths that contain characters that have special meaning in
|
||||
glob patterns (e.g., `[` or `]`)
|
||||
|
||||
## [1.2.1] - 2021-08-24
|
||||
|
||||
### Changed
|
||||
- Updated build script to check the install location used by the
|
||||
[Scoop](https://scoop.sh/) command-line installer on Windows
|
||||
|
||||
### Fixed
|
||||
- Updated build script to support environments where the `PATH` environment
|
||||
variable is not set
|
||||
|
||||
## [1.2.0] - 2021-04-08
|
||||
|
||||
### Changed
|
||||
- Changed `Clang::find` to prefer target-prefixed binaries when a `-target`
|
||||
argument is provided (e.g., if the arguments `-target` and
|
||||
`x86_64-unknown-linux-gnu` are provided, a target-prefixed Clang executable
|
||||
such as `x86_64-unknown-linux-gnu-clang` will be preferred over a non-target
|
||||
prefixed Clang executable)
|
||||
|
||||
### Fixed
|
||||
- Fixed build script to split paths in environment variables (e.g.,
|
||||
`LD_LIBRARY_PATH`) using the appropriate separator for the platform (previously
|
||||
`:` was used as the separator but some platforms such as Windows use `;`)
|
||||
|
||||
## [1.1.1] - 2021-02-19
|
||||
|
||||
### Changed
|
||||
- Bumped `libloading` version to `0.7`
|
||||
|
||||
## [1.1.0] - 2021-02-09
|
||||
|
||||
### Changed
|
||||
- Added Visual Studio LLVM component directory to search paths on Windows
|
||||
([#121](https://github.com/KyleMayes/clang-sys/issues/121))
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 11.0.x
|
||||
|
||||
## [1.0.3] - 2020-11-19
|
||||
|
||||
### Fixed
|
||||
- Fixed `Clang::find` panicking when `llvm-config` or `xcode-build` don't output anything to `stdout`
|
||||
|
||||
## [1.0.2] - 2020-11-17
|
||||
|
||||
### Fixed
|
||||
- Fixed `Clang::find` to properly search directories returned by the
|
||||
`llvm-config --bindir` and `xcodebuild -find clang` commands
|
||||
- Improved version selection algorithm in the case where there are multiple
|
||||
instances of `libclang` with the highest version found; previously the lowest
|
||||
priority instance would be selected instead of the highest priority instance
|
||||
(e.g., the versions found by searching the fallback directories were preferred
|
||||
over the versions found by searching the `llvm-config --prefix` directory)
|
||||
|
||||
## [1.0.1] - 2020-10-01
|
||||
|
||||
### Changed
|
||||
- Improved panic error message when calling an unloaded function
|
||||
|
||||
## [1.0.0] - 2020-07-14
|
||||
|
||||
### Changed
|
||||
- Bumped `libloading` version to `0.6.0`
|
||||
- Updated build script to not print warnings about failures to execute
|
||||
`llvm-config` and `xcode-select` unless an instance of `libclang` is not found
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 10.0.x
|
||||
|
||||
### Removed
|
||||
- Removed `gte_clang_*` Cargo features (these were an implementation detail)
|
||||
|
||||
## [0.29.3] - 2020-03-31
|
||||
|
||||
### Added
|
||||
- Added ability to determine version of runtime-linked instance of `libclang`
|
||||
|
||||
## [0.29.2] - 2020-03-09
|
||||
|
||||
### Added
|
||||
- Revert unnecessary increase of minimum version of `libc` and `libloading`
|
||||
|
||||
## [0.29.2] - 2020-03-09
|
||||
|
||||
### Added
|
||||
- Revert unnecessary increase of minimum version of `libc` and `libloading`
|
||||
|
||||
## [0.29.1] - 2020-03-06
|
||||
|
||||
### Added
|
||||
- Added support for finding instances of `libclang` matching `libclang-*.so.*`
|
||||
|
||||
## [0.29.0] - 2020-02-17
|
||||
|
||||
### Changed
|
||||
- Wrapped function pointer fields in `Option` in the `CXCursorAndRangeVisitor`
|
||||
and `IndexerCallbacks` structs (to permit nullability and to avoid undefined
|
||||
behavior caused by `Default` implementations for these structs which returns a
|
||||
zeroed value)
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 9.0.x
|
||||
- Added missing `CXCallingConv_AArch64VectorCall` variant to `CXCallingConv` enum
|
||||
- Added missing `clang_CompileCommand_getNumMappedSources` function
|
||||
|
||||
## [0.28.1] - 2019-07-28
|
||||
|
||||
### Changed
|
||||
- Bumped `glob` version to `0.3.0`
|
||||
- Improved error message when an invocation of an executable is not successful
|
||||
- Allowed `LIBCLANG_PATH` to refer to a specific `libclang` instance (e.g.,
|
||||
`/usr/local/lib/libclang.so.10`)
|
||||
|
||||
### Fixed
|
||||
- Fixed
|
||||
[`libclang-cpp`](https://github.com/llvm-mirror/clang/commit/90d6722bdcbc2af52306f7e948c556ad6185ac48)
|
||||
being linked instead of `libclang`
|
||||
|
||||
## [0.28.0] - 2019-02-17
|
||||
|
||||
### Changed
|
||||
- Changed `llvm-config` to be first search candidate on macOS
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 8.0.x
|
||||
|
||||
### Removed
|
||||
- Removed `assert-minimum` feature
|
||||
- Removed version detection for libraries without versions embedded in the filename
|
||||
|
||||
## [0.27.0] - 2019-01-10
|
||||
|
||||
### Changed
|
||||
- Added version detection for libraries without versions embedded in the filename
|
||||
|
||||
### Added
|
||||
- Added `assert-minimum` feature (see `README.md` for details)
|
||||
|
||||
## [0.26.4] - 2018-12-29
|
||||
|
||||
### Changed
|
||||
- Added shared library path to `SharedLibrary` struct
|
||||
|
||||
## [0.26.3] - 2018-11-14
|
||||
|
||||
### Changed
|
||||
- Disable default features of `libc` dependency
|
||||
|
||||
## [0.26.2] - 2018-11-03
|
||||
|
||||
### Fixed
|
||||
- Fixed dynamic linking on macOS
|
||||
|
||||
## [0.26.1] - 2018-10-10
|
||||
|
||||
### Fixed
|
||||
- Fixed support for finding libraries in `bin` directories on Windows
|
||||
|
||||
## [0.26.0] - 2018-10-07
|
||||
|
||||
### Changed
|
||||
- Added support for finding libraries with version suffixes on Linux when using runtime linking (e.g., `libclang.so.1`)
|
||||
|
||||
## [0.25.0] - 2018-10-06
|
||||
|
||||
### Changed
|
||||
- Added support for versioned libraries on BSDs
|
||||
|
||||
## [0.24.0] - 2018-09-15
|
||||
|
||||
### Changed
|
||||
- Reworked finding of libraries (see `README.md` for details)
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 7.0.x
|
||||
|
||||
## [0.23.0] - 2018-06-16
|
||||
|
||||
### Changed
|
||||
- Changed `Clang::find` to skip dynamic libraries for an incorrect architecture on Windows
|
||||
|
||||
## [0.22.0] - 2018-03-11
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 6.0.x
|
||||
- Bumped `libc` version to `0.2.39`
|
||||
- Bumped `libloading` version to `0.5.0`
|
||||
|
||||
## [0.21.2] - 2018-02-17
|
||||
|
||||
### Changed
|
||||
- Added original errors to error messages
|
||||
- Added support for searching for libraries in `LD_LIBRARY_PATH` directories
|
||||
|
||||
## [0.21.1] - 2017-11-24
|
||||
|
||||
### Changed
|
||||
- Improved finding of versioned libraries (e.g., `libclang-3.9.so`)
|
||||
|
||||
### Fixed
|
||||
* Fixed compilation failures on the beta and nightly channels caused by a [compiler bug](https://github.com/KyleMayes/clang-sys/pull/69)
|
||||
|
||||
## [0.21.0] - 2017-10-11
|
||||
|
||||
### Changed
|
||||
* Replaced `bitflags` usage with constants which avoids crashes on 32-bit Linux platforms
|
||||
|
||||
## [0.20.1] - 2017-09-16
|
||||
|
||||
### Fixed
|
||||
- Fixed static linking
|
||||
|
||||
## [0.20.0] - 2017-09-14
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 5.0.x
|
||||
- Added `clang` as a link target of this package
|
||||
- Added dummy implementations of `is_loaded` for builds with the `static` Cargo feature enabled
|
||||
|
||||
## [0.19.0] - 2017-07-02
|
||||
|
||||
### Changed
|
||||
- Bumped `bitflags` version to `0.9.1`
|
||||
- Added `args` parameter to `Clang::new` function which passes arguments to the Clang executable
|
||||
|
||||
## [0.18.0] - 2017-05-16
|
||||
|
||||
### Changed
|
||||
- Improved finding of versioned libraries (e.g., `libclang.so.3.9`)
|
||||
|
||||
## [0.17.0] - 2017-05-08
|
||||
|
||||
### Changed
|
||||
- Changed storage type of include search paths from `Vec<PathBuf>` to `Option<Vec<PathBuf>>`
|
||||
|
||||
## [0.16.0] - 2017-05-02
|
||||
|
||||
### Changed
|
||||
- Bumped `libloading` version to `0.4.0`
|
||||
|
||||
## [0.15.2] - 2017-04-28
|
||||
|
||||
### Fixed
|
||||
- Fixed finding of `libclang.so.1` on Linux
|
||||
|
||||
## [0.15.1] - 2017-03-29
|
||||
|
||||
### Fixed
|
||||
- Fixed static linking when libraries are in [different directories](https://github.com/KyleMayes/clang-sys/issues/50)
|
||||
|
||||
## [0.15.0] - 2017-03-13
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 4.0.x
|
||||
|
||||
### Changed
|
||||
- Changed functions in the `Functions` struct to be `unsafe` (`runtime` feature only)
|
||||
- Changed `Clang::find` method to ignore directories and non-executable files
|
||||
- Changed `Clang::find` to skip dynamic libraries for an incorrect architecture on FreeBSD and Linux
|
||||
- Bumped `bitflags` version to `0.7.0`
|
||||
|
||||
## [0.14.0] - 2017-01-30
|
||||
|
||||
### Changed
|
||||
- Changed all enum types from tuple structs to raw integers to avoid
|
||||
[segmentation faults](https://github.com/rust-lang/rust/issues/39394) on some platforms
|
||||
|
||||
## [0.13.0] - 2017-01-29
|
||||
|
||||
### Changed
|
||||
- Changed all opaque pointers types from tuple structs to raw pointers to avoid
|
||||
[segmentation faults](https://github.com/rust-lang/rust/issues/39394) on some platforms
|
||||
|
||||
## [0.12.0] - 2016-12-13
|
||||
|
||||
### Changed
|
||||
- Altered the runtime linking API to allow for testing the presence of functions
|
||||
|
||||
## [0.11.1] - 2016-12-07
|
||||
|
||||
### Added
|
||||
- Added support for linking to Clang on Windows from unofficial LLVM sources such as MSYS and MinGW
|
||||
|
||||
## [0.11.0] - 2016-10-07
|
||||
|
||||
### Changed
|
||||
- Changed all enums from Rust enums to typed constants to avoid
|
||||
[undefined behavior](https://github.com/KyleMayes/clang-sys/issues/42)
|
||||
|
||||
## [0.10.1] - 2016-08-21
|
||||
|
||||
### Changed
|
||||
- Changed static linking on FreeBSD and macOS to link against `libc++` instead of `libstd++`
|
||||
|
||||
## [0.10.0] - 2016-08-01
|
||||
|
||||
### Changed
|
||||
- Added `runtime` Cargo feature that links to `libclang` shared library at runtime
|
||||
- Added `from_raw` method to `CXTypeLayoutError` enum
|
||||
- Added implementations of `Deref` for opaque FFI structs
|
||||
- Changed `Default` implementations for structs to zero out the struct
|
||||
|
||||
## [0.9.0] - 2016-07-21
|
||||
|
||||
### Added
|
||||
- Added documentation bindings
|
||||
|
||||
## [0.8.1] - 2016-07-20
|
||||
|
||||
### Changed
|
||||
- Added `CLANG_PATH` environment variable for providing a path to `clang` executable
|
||||
- Added usage of `llvm-config` to search for `clang`
|
||||
- Added usage of `xcodebuild` to search for `clang` on macOS
|
||||
|
||||
## [0.8.0] - 2016-07-18
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 3.9.x
|
||||
|
||||
### Changed
|
||||
- Bumped `libc` version to `0.2.14`
|
||||
|
||||
### Fixed
|
||||
- Fixed `LIBCLANG_PATH` usage on Windows to search both the `bin` and `lib` directories
|
||||
- Fixed search path parsing on macOS
|
||||
- Fixed search path parsing on Windows
|
||||
- Fixed default search path ordering on macOS
|
||||
|
||||
## [0.7.2] - 2016-06-17
|
||||
|
||||
### Fixed
|
||||
- Fixed finding of `clang` executables when system has executables matching `clang-*`
|
||||
(e.g., `clang-format`)
|
||||
|
||||
## [0.7.1] - 2016-06-10
|
||||
|
||||
### Changed
|
||||
- Bumped `libc` version to `0.2.12`
|
||||
|
||||
### Fixed
|
||||
- Fixed finding of `clang` executables suffixed by their version (e.g., `clang-3.5`)
|
||||
|
||||
## [0.7.0] - 2016-05-31
|
||||
|
||||
### Changed
|
||||
- Changed `Clang` struct `version` field type to `Option<CXVersion>`
|
||||
|
||||
## [0.6.0] - 2016-05-26
|
||||
|
||||
### Added
|
||||
- Added `support` module
|
||||
|
||||
### Fixed
|
||||
- Fixed `libclang` linking on FreeBSD
|
||||
- Fixed `libclang` linking on Windows with the MSVC toolchain
|
||||
- Improved `libclang` static linking
|
||||
|
||||
## [0.5.4] - 20160-5-19
|
||||
|
||||
### Changed
|
||||
- Added implementations of `Default` for FFI structs
|
||||
|
||||
## [0.5.3] - 2016-05-17
|
||||
|
||||
### Changed
|
||||
- Bumped `bitflags` version to `0.7.0`
|
||||
|
||||
## [0.5.2] - 2016-05-12
|
||||
|
||||
### Fixed
|
||||
- Fixed `libclang` static linking
|
||||
|
||||
## [0.5.1] - 2016-05-10
|
||||
|
||||
### Fixed
|
||||
- Fixed `libclang` linking on macOS
|
||||
- Fixed `libclang` linking on Windows
|
||||
|
||||
## [0.5.0] - 2016-05-10
|
||||
|
||||
### Removed
|
||||
- Removed `rustc_version` dependency
|
||||
- Removed support for `LIBCLANG_STATIC` environment variable
|
||||
|
||||
### Changed
|
||||
- Bumped `bitflags` version to `0.6.0`
|
||||
- Bumped `libc` version to `0.2.11`
|
||||
- Improved `libclang` search path
|
||||
- Improved `libclang` static linking
|
||||
|
||||
## [0.4.2] - 2016-04-20
|
||||
|
||||
### Changed
|
||||
- Bumped `libc` version to `0.2.10`
|
||||
|
||||
## [0.4.1] - 2016-04-02
|
||||
|
||||
### Changed
|
||||
- Bumped `libc` version to `0.2.9`
|
||||
- Bumped `rustc_version` version to `0.1.7`
|
||||
|
||||
## [0.4.0] - 2016-03-28
|
||||
|
||||
### Removed
|
||||
- Removed support for `clang` 3.4.x
|
||||
|
||||
## [0.3.1] - 2016-03-21
|
||||
|
||||
### Added
|
||||
- Added support for finding `libclang`
|
||||
|
||||
## [0.3.0] - 2016-03-16
|
||||
|
||||
### Removed
|
||||
- Removed build system types and functions
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 3.4.x
|
||||
|
||||
### Changed
|
||||
- Bumped `bitflags` version to `0.5.0`
|
||||
- Bumped `libc` version to `0.2.8`
|
||||
|
||||
## [0.2.1] - 2016-02-13
|
||||
|
||||
### Changed
|
||||
- Simplified internal usage of conditional compilation
|
||||
- Bumped `bitflags` version to `0.4.0`
|
||||
- Bumped `libc` version to `0.2.7`
|
||||
- Bumped `rustc_version` version to `0.1.6`
|
||||
|
||||
## [0.2.0] - 2016-02-12
|
||||
|
||||
### Added
|
||||
- Added support for `clang` 3.8.x
|
||||
|
||||
## [0.1.2] - 2015-12-29
|
||||
|
||||
### Added
|
||||
- Added derivations of `Debug` for FFI structs
|
||||
|
||||
## [0.1.1] - 2015-12-26
|
||||
|
||||
### Added
|
||||
- Added derivations of `PartialOrd` and `Ord` for FFI enums
|
||||
|
||||
## [0.1.0] - 2015-12-22
|
||||
- Initial release
|
||||
74
third-party/vendor/clang-sys/Cargo.toml
vendored
Normal file
74
third-party/vendor/clang-sys/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.7.0"
|
||||
authors = ["Kyle Mayes <kyle@mayeses.com>"]
|
||||
build = "build.rs"
|
||||
links = "clang"
|
||||
description = "Rust bindings for libclang."
|
||||
documentation = "https://docs.rs/clang-sys"
|
||||
readme = "README.md"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/KyleMayes/clang-sys"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = [
|
||||
"clang_17_0",
|
||||
"runtime",
|
||||
]
|
||||
|
||||
[dependencies.glob]
|
||||
version = "0.3"
|
||||
|
||||
[dependencies.libc]
|
||||
version = "0.2.39"
|
||||
default-features = false
|
||||
|
||||
[dependencies.libloading]
|
||||
version = "0.8"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies.glob]
|
||||
version = "0.3"
|
||||
|
||||
[dev-dependencies.serial_test]
|
||||
version = "1"
|
||||
|
||||
[dev-dependencies.tempfile]
|
||||
version = "3"
|
||||
|
||||
[build-dependencies.glob]
|
||||
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_14_0 = ["clang_13_0"]
|
||||
clang_15_0 = ["clang_14_0"]
|
||||
clang_16_0 = ["clang_15_0"]
|
||||
clang_17_0 = ["clang_16_0"]
|
||||
clang_3_5 = []
|
||||
clang_3_6 = ["clang_3_5"]
|
||||
clang_3_7 = ["clang_3_6"]
|
||||
clang_3_8 = ["clang_3_7"]
|
||||
clang_3_9 = ["clang_3_8"]
|
||||
clang_4_0 = ["clang_3_9"]
|
||||
clang_5_0 = ["clang_4_0"]
|
||||
clang_6_0 = ["clang_5_0"]
|
||||
clang_7_0 = ["clang_6_0"]
|
||||
clang_8_0 = ["clang_7_0"]
|
||||
clang_9_0 = ["clang_8_0"]
|
||||
runtime = ["libloading"]
|
||||
static = []
|
||||
202
third-party/vendor/clang-sys/LICENSE.txt
vendored
Normal file
202
third-party/vendor/clang-sys/LICENSE.txt
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
89
third-party/vendor/clang-sys/README.md
vendored
Normal file
89
third-party/vendor/clang-sys/README.md
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# clang-sys
|
||||
|
||||
[](https://crates.io/crates/clang-sys)
|
||||
[](https://docs.rs/clang-sys)
|
||||
[](https://github.com/KyleMayes/clang-sys/actions?query=workflow%3ACI)
|
||||

|
||||
|
||||
Rust bindings for `libclang`.
|
||||
|
||||
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_16_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 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 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
|
||||
* etc...
|
||||
* `clang_15_0` - requires `libclang` 15.0 or later
|
||||
* `clang_16_0` - requires `libclang` 16.0 or later
|
||||
|
||||
If you do not enable one of these features, the API provided by `libclang` 3.5 will be available by default.
|
||||
|
||||
**Note:** If you are using Clang 15.0 or later, you should enable the `clang_15_0` feature or a more recent version feature. Clang 15.0 introduced [a breaking change to the `EntityKind` enum](https://github.com/llvm/llvm-project/commit/bb83f8e70bd1d56152f02307adacd718cd67e312#diff-674613a0e47f4e66cc19061e28e3296d39be2d124dceefb68237b30b8e241e7c) which resulted in a mismatch between the values returned by `libclang` and the values for `EntityKind` defined by this crate in previous versions.
|
||||
|
||||
## 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.
|
||||
|
||||
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.
|
||||
|
||||
### 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:
|
||||
|
||||
1. `libclang-4.0.so`
|
||||
2. `libclang-4.so`
|
||||
3. `libclang-3.9.so`
|
||||
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 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:
|
||||
|
||||
* `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
|
||||
|
||||
### Dynamic
|
||||
|
||||
`libclang` shared libraries will be searched for in the following directories:
|
||||
|
||||
* the directory provided by the `LIBCLANG_PATH` environment variable
|
||||
* the `bin` and `lib` directories in the directory provided by `llvm-config --libdir`
|
||||
* the directories provided by `LD_LIBRARY_PATH` environment variable
|
||||
* 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 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.
|
||||
|
||||
### 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.
|
||||
79
third-party/vendor/clang-sys/build.rs
vendored
Normal file
79
third-party/vendor/clang-sys/build.rs
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//! 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 shared libraries.
|
||||
//!
|
||||
//! * `LLVM_CONFIG_PATH` - provides a path to an `llvm-config` executable
|
||||
//! * `LIBCLANG_PATH` - provides a path to a directory containing a `libclang`
|
||||
//! shared library or a path to a specific `libclang` shared library
|
||||
//! * `LIBCLANG_STATIC_PATH` - provides a path to a directory containing LLVM
|
||||
//! and Clang static libraries
|
||||
|
||||
#![allow(unused_attributes)]
|
||||
|
||||
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"]
|
||||
pub mod dynamic;
|
||||
#[path = "build/static.rs"]
|
||||
pub mod r#static;
|
||||
|
||||
/// Copies a file.
|
||||
#[cfg(feature = "runtime")]
|
||||
fn copy(source: &str, destination: &Path) {
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
let mut string = String::new();
|
||||
File::open(source)
|
||||
.unwrap()
|
||||
.read_to_string(&mut string)
|
||||
.unwrap();
|
||||
File::create(destination)
|
||||
.unwrap()
|
||||
.write_all(string.as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
if cfg!(feature = "static") {
|
||||
panic!("`runtime` and `static` features can't be combined");
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
/// Finds and links to the required libraries dynamically or statically.
|
||||
#[cfg(not(feature = "runtime"))]
|
||||
fn main() {
|
||||
if cfg!(feature = "static") {
|
||||
r#static::link();
|
||||
} else {
|
||||
dynamic::link();
|
||||
}
|
||||
|
||||
if let Some(output) = common::run_llvm_config(&["--includedir"]) {
|
||||
let directory = Path::new(output.trim_end());
|
||||
println!("cargo:include={}", directory.display());
|
||||
}
|
||||
}
|
||||
355
third-party/vendor/clang-sys/build/common.rs
vendored
Normal file
355
third-party/vendor/clang-sys/build/common.rs
vendored
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
extern crate glob;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use glob::{MatchOptions, Pattern};
|
||||
|
||||
//================================================
|
||||
// Commands
|
||||
//================================================
|
||||
|
||||
thread_local! {
|
||||
/// The errors encountered by the build script while executing commands.
|
||||
static COMMAND_ERRORS: RefCell<HashMap<String, Vec<String>>> = RefCell::default();
|
||||
}
|
||||
|
||||
/// 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,
|
||||
))
|
||||
});
|
||||
}
|
||||
|
||||
/// 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,
|
||||
}
|
||||
|
||||
impl CommandErrorPrinter {
|
||||
pub fn discard(mut self) {
|
||||
self.discard = true;
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for CommandErrorPrinter {
|
||||
fn drop(&mut self) {
|
||||
if self.discard {
|
||||
return;
|
||||
}
|
||||
|
||||
let errors = COMMAND_ERRORS.with(|e| e.borrow().clone());
|
||||
|
||||
if let Some(errors) = errors.get("llvm-config") {
|
||||
println!(
|
||||
"cargo:warning=could not execute `llvm-config` one or more \
|
||||
times, if the LLVM_CONFIG_PATH environment variable is set to \
|
||||
a full path to valid `llvm-config` executable it will be used \
|
||||
to try to find an instance of `libclang` on your system: {}",
|
||||
errors
|
||||
.iter()
|
||||
.map(|e| format!("\"{}\"", e))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n "),
|
||||
)
|
||||
}
|
||||
|
||||
if let Some(errors) = errors.get("xcode-select") {
|
||||
println!(
|
||||
"cargo:warning=could not execute `xcode-select` one or more \
|
||||
times, if a valid instance of this executable is on your PATH \
|
||||
it will be used to try to find an instance of `libclang` on \
|
||||
your system: {}",
|
||||
errors
|
||||
.iter()
|
||||
.map(|e| format!("\"{}\"", e))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n "),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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) => {
|
||||
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
|
||||
//================================================
|
||||
// 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/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/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/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.
|
||||
///
|
||||
/// 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\\**\\lib", true),
|
||||
];
|
||||
|
||||
/// `libclang` directory patterns for illumos
|
||||
const DIRECTORIES_ILLUMOS: &[&str] = &[
|
||||
"/opt/ooce/llvm-*/lib",
|
||||
"/opt/ooce/clang-*/lib",
|
||||
];
|
||||
|
||||
//================================================
|
||||
// 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 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 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 to ensure that the search
|
||||
// is limited to the specified directory.
|
||||
let mut options = MatchOptions::new();
|
||||
options.require_literal_separator = true;
|
||||
|
||||
paths
|
||||
.map(|p| glob::glob_with(&p, options))
|
||||
.filter_map(Result::ok)
|
||||
.flatten()
|
||||
.filter_map(|p| {
|
||||
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.,
|
||||
// `libclang-cpp.so.10`) to be matched by patterns looking for
|
||||
// instances of `libclang`.
|
||||
if filename.contains("-cpp.") {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((directory.to_owned(), filename.into()))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
/// 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);
|
||||
|
||||
// On Windows, `libclang.dll` is usually found in the LLVM `bin` directory
|
||||
// while `libclang.lib` is usually found in the LLVM `lib` directory. To
|
||||
// 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 target_os!("windows") && directory.ends_with("lib") {
|
||||
let sibling = directory.parent().unwrap().join("bin");
|
||||
results.extend(search_directory(&sibling, filenames).into_iter());
|
||||
}
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
/// 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 a matching file.
|
||||
if let Some(parent) = path.parent() {
|
||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||
let libraries = search_directories(parent, filenames);
|
||||
if libraries.iter().any(|(_, f)| f == filename) {
|
||||
return vec![(parent.into(), filename.into())];
|
||||
}
|
||||
}
|
||||
|
||||
// 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 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"), filenames));
|
||||
found.extend(search_directories(&directory.join("lib"), filenames));
|
||||
found.extend(search_directories(&directory.join("lib64"), filenames));
|
||||
}
|
||||
|
||||
// Search the toolchain directory in the directory returned by
|
||||
// `xcode-select --print-path`.
|
||||
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");
|
||||
found.extend(search_directories(&directory, filenames));
|
||||
}
|
||||
}
|
||||
|
||||
// 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, filenames));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the `libclang` directory patterns.
|
||||
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
|
||||
.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
|
||||
};
|
||||
|
||||
// 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() {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found
|
||||
}
|
||||
257
third-party/vendor/clang-sys/build/dynamic.rs
vendored
Normal file
257
third-party/vendor/clang-sys/build/dynamic.rs
vendored
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Error, ErrorKind, Read, Seek, SeekFrom};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::common;
|
||||
|
||||
//================================================
|
||||
// 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];
|
||||
file.read_exact(&mut buffer)?;
|
||||
if buffer[..4] == [127, 69, 76, 70] {
|
||||
Ok(buffer[4])
|
||||
} else {
|
||||
Err(Error::new(ErrorKind::InvalidData, "invalid ELF header"))
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)?;
|
||||
|
||||
// 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);
|
||||
|
||||
// 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"));
|
||||
}
|
||||
|
||||
// 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))
|
||||
}
|
||||
|
||||
/// Checks that a `libclang` shared library matches the target platform.
|
||||
fn validate_library(path: &Path) -> Result<(), String> {
|
||||
if target_os!("linux") || target_os!("freebsd") {
|
||||
let class = parse_elf_header(path).map_err(|e| e.to_string())?;
|
||||
|
||||
if target_pointer_width!("32") && class != 1 {
|
||||
return Err("invalid ELF class (64-bit)".into());
|
||||
}
|
||||
|
||||
if target_pointer_width!("64") && class != 2 {
|
||||
return Err("invalid ELF class (32-bit)".into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else if target_os!("windows") {
|
||||
let magic = parse_pe_header(path).map_err(|e| e.to_string())?;
|
||||
|
||||
if target_pointer_width!("32") && magic != 267 {
|
||||
return Err("invalid DLL (64-bit)".into());
|
||||
}
|
||||
|
||||
if target_pointer_width!("64") && magic != 523 {
|
||||
return Err("invalid DLL (32-bit)".into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// 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
|
||||
} else if filename.starts_with("libclang-") {
|
||||
&filename[9..filename.len() - 3]
|
||||
} else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
version.split('.').map(|s| s.parse().unwrap_or(0)).collect()
|
||||
}
|
||||
|
||||
/// 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{}",
|
||||
env::consts::DLL_PREFIX,
|
||||
env::consts::DLL_SUFFIX
|
||||
)];
|
||||
|
||||
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());
|
||||
|
||||
// Some Linux distributions don't create a `libclang.so` symlink and
|
||||
// don't have versioned files as described above, so we need to look for
|
||||
// suffix versioned files (e.g., `libclang.so.1`). However, `ld` cannot
|
||||
// link to these files, so this will only be included when linking at
|
||||
// runtime.
|
||||
if runtime {
|
||||
files.push("libclang.so.*".into());
|
||||
files.push("libclang-*.so.*".into());
|
||||
}
|
||||
}
|
||||
|
||||
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 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());
|
||||
}
|
||||
|
||||
// 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_library(&path) {
|
||||
Ok(()) => {
|
||||
let version = parse_version(&filename);
|
||||
valid.push((directory, filename, version))
|
||||
}
|
||||
Err(message) => invalid.push(format!("({}: {})", path.display(), message)),
|
||||
}
|
||||
}
|
||||
|
||||
if !valid.is_empty() {
|
||||
return Ok(valid);
|
||||
}
|
||||
|
||||
let message = format!(
|
||||
"couldn't find any valid shared libraries matching: [{}], set the \
|
||||
`LIBCLANG_PATH` environment variable to a path where one of these files \
|
||||
can be found (invalid: [{}])",
|
||||
files
|
||||
.iter()
|
||||
.map(|f| format!("'{}'", f))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
invalid.join(", "),
|
||||
);
|
||||
|
||||
Err(message)
|
||||
}
|
||||
|
||||
/// 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()
|
||||
// We want to find the `libclang` shared library with the highest
|
||||
// version number, hence `max_by_key` below.
|
||||
//
|
||||
// However, in the case where there are multiple such `libclang` shared
|
||||
// libraries, we want to use the order in which they appeared in the
|
||||
// list returned by `search_libclang_directories` as a tiebreaker since
|
||||
// that function returns `libclang` shared libraries in descending order
|
||||
// of preference by how they were found.
|
||||
//
|
||||
// `max_by_key`, perhaps surprisingly, returns the *last* item with the
|
||||
// maximum key rather than the first which results in the opposite of
|
||||
// the tiebreaking behavior we want. This is easily fixed by reversing
|
||||
// the list first.
|
||||
.rev()
|
||||
.max_by_key(|f| &f.2)
|
||||
.cloned()
|
||||
.map(|(path, filename, _)| (path, filename))
|
||||
.ok_or_else(|| "unreachable".into())
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Linking
|
||||
//================================================
|
||||
|
||||
/// Finds and links to a `libclang` shared library.
|
||||
#[cfg(not(feature = "runtime"))]
|
||||
pub fn link() {
|
||||
let cep = common::CommandErrorPrinter::default();
|
||||
|
||||
use std::fs;
|
||||
|
||||
let (directory, filename) = find(false).unwrap();
|
||||
println!("cargo:rustc-link-search={}", directory.display());
|
||||
|
||||
if cfg!(all(target_os = "windows", target_env = "msvc")) {
|
||||
// Find the `libclang` stub static library required for the MSVC
|
||||
// toolchain.
|
||||
let lib = if !directory.ends_with("bin") {
|
||||
directory
|
||||
} else {
|
||||
directory.parent().unwrap().join("lib")
|
||||
};
|
||||
|
||||
if lib.join("libclang.lib").exists() {
|
||||
println!("cargo:rustc-link-search={}", lib.display());
|
||||
} else if lib.join("libclang.dll.a").exists() {
|
||||
// MSYS and MinGW use `libclang.dll.a` instead of `libclang.lib`.
|
||||
// It is linkable with the MSVC linker, but Rust doesn't recognize
|
||||
// the `.a` suffix, so we need to copy it with a different name.
|
||||
//
|
||||
// FIXME: Maybe we can just hardlink or symlink it?
|
||||
let out = env::var("OUT_DIR").unwrap();
|
||||
fs::copy(
|
||||
lib.join("libclang.dll.a"),
|
||||
Path::new(&out).join("libclang.lib"),
|
||||
)
|
||||
.unwrap();
|
||||
println!("cargo:rustc-link-search=native={}", out);
|
||||
} else {
|
||||
panic!(
|
||||
"using '{}', so 'libclang.lib' or 'libclang.dll.a' must be \
|
||||
available in {}",
|
||||
filename,
|
||||
lib.display(),
|
||||
);
|
||||
}
|
||||
|
||||
println!("cargo:rustc-link-lib=dylib=libclang");
|
||||
} else {
|
||||
let name = filename.trim_start_matches("lib");
|
||||
|
||||
// Strip extensions and trailing version numbers (e.g., the `.so.7.0` in
|
||||
// `libclang.so.7.0`).
|
||||
let name = match name.find(".dylib").or_else(|| name.find(".so")) {
|
||||
Some(index) => &name[0..index],
|
||||
None => name,
|
||||
};
|
||||
|
||||
println!("cargo:rustc-link-lib=dylib={}", name);
|
||||
}
|
||||
|
||||
cep.discard();
|
||||
}
|
||||
38
third-party/vendor/clang-sys/build/macros.rs
vendored
Normal file
38
third-party/vendor/clang-sys/build/macros.rs
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
};
|
||||
}
|
||||
140
third-party/vendor/clang-sys/build/static.rs
vendored
Normal file
140
third-party/vendor/clang-sys/build/static.rs
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
extern crate glob;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use glob::Pattern;
|
||||
|
||||
use super::common;
|
||||
|
||||
//================================================
|
||||
// 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();
|
||||
if let Some(name) = string.strip_prefix("lib") {
|
||||
name.to_owned()
|
||||
} else {
|
||||
string.to_string()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets the LLVM static libraries required to link to `libclang`.
|
||||
fn get_llvm_libraries() -> Vec<String> {
|
||||
common::run_llvm_config(&["--libs"])
|
||||
.unwrap()
|
||||
.split_whitespace()
|
||||
.filter_map(|p| {
|
||||
// Depending on the version of `llvm-config` in use, listed
|
||||
// libraries may be in one of two forms, a full path to the library
|
||||
// or simply prefixed with `-l`.
|
||||
if let Some(path) = p.strip_prefix("-l") {
|
||||
Some(path.into())
|
||||
} else {
|
||||
get_library_name(Path::new(p))
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// 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 `]`).
|
||||
let directory = Pattern::escape(directory.as_ref().to_str().unwrap());
|
||||
let directory = Path::new(&directory);
|
||||
|
||||
let pattern = directory.join("libclang*.a").to_str().unwrap().to_owned();
|
||||
if let Ok(libraries) = glob::glob(&pattern) {
|
||||
libraries
|
||||
.filter_map(|l| l.ok().and_then(|l| get_library_name(&l)))
|
||||
.collect()
|
||||
} else {
|
||||
CLANG_LIBRARIES.iter().map(|l| (*l).to_string()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds a directory containing LLVM and Clang static libraries and returns the
|
||||
/// path to that directory.
|
||||
fn find() -> PathBuf {
|
||||
let name = if target_os!("windows") {
|
||||
"libclang.lib"
|
||||
} else {
|
||||
"libclang.a"
|
||||
};
|
||||
|
||||
let files = common::search_libclang_directories(&[name.into()], "LIBCLANG_STATIC_PATH");
|
||||
if let Some((directory, _)) = files.into_iter().next() {
|
||||
directory
|
||||
} else {
|
||||
panic!("could not find any static libraries");
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Linking
|
||||
//================================================
|
||||
|
||||
/// Finds and links to `libclang` static libraries.
|
||||
pub fn link() {
|
||||
let cep = common::CommandErrorPrinter::default();
|
||||
|
||||
let directory = find();
|
||||
|
||||
// Specify required Clang static libraries.
|
||||
println!("cargo:rustc-link-search=native={}", directory.display());
|
||||
for library in get_clang_libraries(directory) {
|
||||
println!("cargo:rustc-link-lib=static={}", library);
|
||||
}
|
||||
|
||||
// Determine the shared mode used by LLVM.
|
||||
let mode = common::run_llvm_config(&["--shared-mode"]).map(|m| m.trim().to_owned());
|
||||
let prefix = if mode.map_or(false, |m| m == "static") {
|
||||
"static="
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
// Specify required LLVM static libraries.
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
common::run_llvm_config(&["--libdir"]).unwrap().trim_end()
|
||||
);
|
||||
for library in get_llvm_libraries() {
|
||||
println!("cargo:rustc-link-lib={}{}", prefix, library);
|
||||
}
|
||||
|
||||
// Specify required system libraries.
|
||||
// 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!(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");
|
||||
}
|
||||
|
||||
cep.discard();
|
||||
}
|
||||
1
third-party/vendor/clang-sys/clippy.toml
vendored
Normal file
1
third-party/vendor/clang-sys/clippy.toml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
doc-valid-idents = ["FreeBSD"]
|
||||
2434
third-party/vendor/clang-sys/src/lib.rs
vendored
Normal file
2434
third-party/vendor/clang-sys/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
323
third-party/vendor/clang-sys/src/link.rs
vendored
Normal file
323
third-party/vendor/clang-sys/src/link.rs
vendored
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//================================================
|
||||
// Macros
|
||||
//================================================
|
||||
|
||||
#[cfg(feature = "runtime")]
|
||||
macro_rules! link {
|
||||
(
|
||||
@LOAD:
|
||||
$(#[doc=$doc:expr])*
|
||||
#[cfg($cfg:meta)]
|
||||
fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*
|
||||
) => (
|
||||
$(#[doc=$doc])*
|
||||
#[cfg($cfg)]
|
||||
pub fn $name(library: &mut super::SharedLibrary) {
|
||||
let symbol = unsafe { library.library.get(stringify!($name).as_bytes()) }.ok();
|
||||
library.functions.$name = match symbol {
|
||||
Some(s) => *s,
|
||||
None => None,
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not($cfg))]
|
||||
pub fn $name(_: &mut super::SharedLibrary) {}
|
||||
);
|
||||
|
||||
(
|
||||
@LOAD:
|
||||
fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*
|
||||
) => (
|
||||
link!(@LOAD: #[cfg(feature = "runtime")] fn $name($($pname: $pty), *) $(-> $ret)*);
|
||||
);
|
||||
|
||||
(
|
||||
$(
|
||||
$(#[doc=$doc:expr] #[cfg($cfg:meta)])*
|
||||
pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*;
|
||||
)+
|
||||
) => (
|
||||
use std::cell::{RefCell};
|
||||
use std::fmt;
|
||||
use std::sync::{Arc};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// The (minimum) version of a `libclang` shared library.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum Version {
|
||||
V3_5 = 35,
|
||||
V3_6 = 36,
|
||||
V3_7 = 37,
|
||||
V3_8 = 38,
|
||||
V3_9 = 39,
|
||||
V4_0 = 40,
|
||||
V5_0 = 50,
|
||||
V6_0 = 60,
|
||||
V7_0 = 70,
|
||||
V8_0 = 80,
|
||||
V9_0 = 90,
|
||||
V11_0 = 110,
|
||||
V12_0 = 120,
|
||||
V16_0 = 160,
|
||||
V17_0 = 170,
|
||||
}
|
||||
|
||||
impl fmt::Display for Version {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use Version::*;
|
||||
match self {
|
||||
V3_5 => write!(f, "3.5.x"),
|
||||
V3_6 => write!(f, "3.6.x"),
|
||||
V3_7 => write!(f, "3.7.x"),
|
||||
V3_8 => write!(f, "3.8.x"),
|
||||
V3_9 => write!(f, "3.9.x"),
|
||||
V4_0 => write!(f, "4.0.x"),
|
||||
V5_0 => write!(f, "5.0.x"),
|
||||
V6_0 => write!(f, "6.0.x"),
|
||||
V7_0 => write!(f, "7.0.x"),
|
||||
V8_0 => write!(f, "8.0.x"),
|
||||
V9_0 => write!(f, "9.0.x - 10.0.x"),
|
||||
V11_0 => write!(f, "11.0.x"),
|
||||
V12_0 => write!(f, "12.0.x - 15.0.x"),
|
||||
V16_0 => write!(f, "16.0.x"),
|
||||
V17_0 => write!(f, "17.0.x or later"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The set of functions loaded dynamically.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Functions {
|
||||
$(
|
||||
$(#[doc=$doc] #[cfg($cfg)])*
|
||||
pub $name: Option<unsafe extern fn($($pname: $pty), *) $(-> $ret)*>,
|
||||
)+
|
||||
}
|
||||
|
||||
/// A dynamically loaded instance of the `libclang` library.
|
||||
#[derive(Debug)]
|
||||
pub struct SharedLibrary {
|
||||
library: libloading::Library,
|
||||
path: PathBuf,
|
||||
pub functions: Functions,
|
||||
}
|
||||
|
||||
impl SharedLibrary {
|
||||
fn new(library: libloading::Library, path: PathBuf) -> Self {
|
||||
Self { library, path, functions: Functions::default() }
|
||||
}
|
||||
|
||||
/// Returns the path to this `libclang` shared library.
|
||||
pub fn path(&self) -> &Path {
|
||||
&self.path
|
||||
}
|
||||
|
||||
/// Returns the (minimum) version of this `libclang` shared library.
|
||||
///
|
||||
/// If this returns `None`, it indicates that the version is too old
|
||||
/// to be supported by this crate (i.e., `3.4` or earlier). If the
|
||||
/// version of this shared library is more recent than that fully
|
||||
/// supported by this crate, the most recent fully supported version
|
||||
/// will be returned.
|
||||
pub fn version(&self) -> Option<Version> {
|
||||
macro_rules! check {
|
||||
($fn:expr, $version:ident) => {
|
||||
if self.library.get::<unsafe extern fn()>($fn).is_ok() {
|
||||
return Some(Version::$version);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
unsafe {
|
||||
check!(b"clang_CXXMethod_isExplicit", V17_0);
|
||||
check!(b"clang_CXXMethod_isCopyAssignmentOperator", V16_0);
|
||||
check!(b"clang_Cursor_getVarDeclInitializer", V12_0);
|
||||
check!(b"clang_Type_getValueType", V11_0);
|
||||
check!(b"clang_Cursor_isAnonymousRecordDecl", V9_0);
|
||||
check!(b"clang_Cursor_getObjCPropertyGetterName", V8_0);
|
||||
check!(b"clang_File_tryGetRealPathName", V7_0);
|
||||
check!(b"clang_CXIndex_setInvocationEmissionPathOption", V6_0);
|
||||
check!(b"clang_Cursor_isExternalSymbol", V5_0);
|
||||
check!(b"clang_EvalResult_getAsLongLong", V4_0);
|
||||
check!(b"clang_CXXConstructor_isConvertingConstructor", V3_9);
|
||||
check!(b"clang_CXXField_isMutable", V3_8);
|
||||
check!(b"clang_Cursor_getOffsetOfField", V3_7);
|
||||
check!(b"clang_Cursor_getStorageClass", V3_6);
|
||||
check!(b"clang_Type_getNumTemplateArguments", V3_5);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
thread_local!(static LIBRARY: RefCell<Option<Arc<SharedLibrary>>> = RefCell::new(None));
|
||||
|
||||
/// Returns whether a `libclang` shared library is loaded on this thread.
|
||||
pub fn is_loaded() -> bool {
|
||||
LIBRARY.with(|l| l.borrow().is_some())
|
||||
}
|
||||
|
||||
fn with_library<T, F>(f: F) -> Option<T> where F: FnOnce(&SharedLibrary) -> T {
|
||||
LIBRARY.with(|l| {
|
||||
match l.borrow().as_ref() {
|
||||
Some(library) => Some(f(&library)),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
$(
|
||||
#[cfg_attr(feature="cargo-clippy", allow(clippy::missing_safety_doc))]
|
||||
#[cfg_attr(feature="cargo-clippy", allow(clippy::too_many_arguments))]
|
||||
$(#[doc=$doc] #[cfg($cfg)])*
|
||||
pub unsafe fn $name($($pname: $pty), *) $(-> $ret)* {
|
||||
let f = with_library(|library| {
|
||||
if let Some(function) = library.functions.$name {
|
||||
function
|
||||
} else {
|
||||
panic!(
|
||||
r#"
|
||||
A `libclang` function was called that is not supported by the loaded `libclang` instance.
|
||||
|
||||
called function = `{0}`
|
||||
loaded `libclang` instance = {1}
|
||||
|
||||
This crate only supports `libclang` 3.5 and later.
|
||||
The minimum `libclang` requirement for this particular function can be found here:
|
||||
https://docs.rs/clang-sys/latest/clang_sys/{0}/index.html
|
||||
|
||||
Instructions for installing `libclang` can be found here:
|
||||
https://rust-lang.github.io/rust-bindgen/requirements.html
|
||||
"#,
|
||||
stringify!($name),
|
||||
library
|
||||
.version()
|
||||
.map(|v| format!("{}", v))
|
||||
.unwrap_or_else(|| "unsupported version".into()),
|
||||
);
|
||||
}
|
||||
}).expect("a `libclang` shared library is not loaded on this thread");
|
||||
f($($pname), *)
|
||||
}
|
||||
|
||||
$(#[doc=$doc] #[cfg($cfg)])*
|
||||
pub mod $name {
|
||||
pub fn is_loaded() -> bool {
|
||||
super::with_library(|l| l.functions.$name.is_some()).unwrap_or(false)
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
||||
mod load {
|
||||
$(link!(@LOAD: $(#[cfg($cfg)])* fn $name($($pname: $pty), *) $(-> $ret)*);)+
|
||||
}
|
||||
|
||||
/// Loads a `libclang` shared library and returns the library instance.
|
||||
///
|
||||
/// This function does not attempt to load any functions from the shared library. The caller
|
||||
/// is responsible for loading the functions they require.
|
||||
///
|
||||
/// # Failures
|
||||
///
|
||||
/// * 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")); }
|
||||
}
|
||||
|
||||
let (directory, filename) = build::dynamic::find(true)?;
|
||||
let path = directory.join(filename);
|
||||
|
||||
unsafe {
|
||||
let library = libloading::Library::new(&path).map_err(|e| {
|
||||
format!(
|
||||
"the `libclang` shared library at {} could not be opened: {}",
|
||||
path.display(),
|
||||
e,
|
||||
)
|
||||
});
|
||||
|
||||
let mut library = SharedLibrary::new(library?, path);
|
||||
$(load::$name(&mut library);)+
|
||||
Ok(library)
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads a `libclang` shared library for use in the current thread.
|
||||
///
|
||||
/// This functions attempts to load all the functions in the shared library. Whether a
|
||||
/// function has been loaded can be tested by calling the `is_loaded` function on the
|
||||
/// module with the same name as the function (e.g., `clang_createIndex::is_loaded()` for
|
||||
/// the `clang_createIndex` function).
|
||||
///
|
||||
/// # Failures
|
||||
///
|
||||
/// * a `libclang` shared library could not be found
|
||||
/// * the `libclang` shared library could not be opened
|
||||
#[allow(dead_code)]
|
||||
pub fn load() -> Result<(), String> {
|
||||
let library = Arc::new(load_manually()?);
|
||||
LIBRARY.with(|l| *l.borrow_mut() = Some(library));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Unloads the `libclang` shared library in use in the current thread.
|
||||
///
|
||||
/// # Failures
|
||||
///
|
||||
/// * a `libclang` shared library is not in use in the current thread
|
||||
pub fn unload() -> Result<(), String> {
|
||||
let library = set_library(None);
|
||||
if library.is_some() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("a `libclang` shared library is not in use in the current thread".into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the library instance stored in TLS.
|
||||
///
|
||||
/// This functions allows for sharing library instances between threads.
|
||||
pub fn get_library() -> Option<Arc<SharedLibrary>> {
|
||||
LIBRARY.with(|l| l.borrow_mut().clone())
|
||||
}
|
||||
|
||||
/// Sets the library instance stored in TLS and returns the previous library.
|
||||
///
|
||||
/// This functions allows for sharing library instances between threads.
|
||||
pub fn set_library(library: Option<Arc<SharedLibrary>>) -> Option<Arc<SharedLibrary>> {
|
||||
LIBRARY.with(|l| mem::replace(&mut *l.borrow_mut(), library))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "runtime"))]
|
||||
macro_rules! link {
|
||||
(
|
||||
$(
|
||||
$(#[doc=$doc:expr] #[cfg($cfg:meta)])*
|
||||
pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*;
|
||||
)+
|
||||
) => (
|
||||
extern {
|
||||
$(
|
||||
$(#[doc=$doc] #[cfg($cfg)])*
|
||||
pub fn $name($($pname: $pty), *) $(-> $ret)*;
|
||||
)+
|
||||
}
|
||||
|
||||
$(
|
||||
$(#[doc=$doc] #[cfg($cfg)])*
|
||||
pub mod $name {
|
||||
pub fn is_loaded() -> bool { true }
|
||||
}
|
||||
)+
|
||||
)
|
||||
}
|
||||
236
third-party/vendor/clang-sys/src/support.rs
vendored
Normal file
236
third-party/vendor/clang-sys/src/support.rs
vendored
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//! Provides helper functionality.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::{env, io};
|
||||
|
||||
use glob::{self, Pattern};
|
||||
|
||||
use libc::c_int;
|
||||
|
||||
use super::CXVersion;
|
||||
|
||||
//================================================
|
||||
// Structs
|
||||
//================================================
|
||||
|
||||
/// A `clang` executable.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Clang {
|
||||
/// The path to this `clang` executable.
|
||||
pub path: PathBuf,
|
||||
/// The version of this `clang` executable if it could be parsed.
|
||||
pub version: Option<CXVersion>,
|
||||
/// The directories searched by this `clang` executable for C headers if
|
||||
/// they could be parsed.
|
||||
pub c_search_paths: Option<Vec<PathBuf>>,
|
||||
/// The directories searched by this `clang` executable for C++ headers if
|
||||
/// they could be parsed.
|
||||
pub cpp_search_paths: Option<Vec<PathBuf>>,
|
||||
}
|
||||
|
||||
impl Clang {
|
||||
fn new(path: impl AsRef<Path>, args: &[String]) -> Self {
|
||||
Self {
|
||||
path: path.as_ref().into(),
|
||||
version: parse_version(path.as_ref()),
|
||||
c_search_paths: parse_search_paths(path.as_ref(), "c", args),
|
||||
cpp_search_paths: parse_search_paths(path.as_ref(), "c++", args),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a `clang` executable if one can be found.
|
||||
///
|
||||
/// If the `CLANG_PATH` environment variable is set, that is the instance of
|
||||
/// `clang` used. Otherwise, a series of directories are searched. First, if
|
||||
/// a path is supplied, that is the first directory searched. Then, the
|
||||
/// 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<Clang> {
|
||||
if let Ok(path) = env::var("CLANG_PATH") {
|
||||
let p = Path::new(&path);
|
||||
if p.is_file() && is_executable(p).unwrap_or(false) {
|
||||
return Some(Clang::new(p, 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() {
|
||||
paths.push(line.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(path) = env::var("PATH") {
|
||||
paths.extend(env::split_paths(&path));
|
||||
}
|
||||
|
||||
// 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[..]];
|
||||
for path in paths {
|
||||
if let Some(path) = find(&path, patterns) {
|
||||
return Some(Clang::new(path, args));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Functions
|
||||
//================================================
|
||||
|
||||
/// Returns the first match to the supplied glob patterns in the supplied
|
||||
/// directory if there are any matches.
|
||||
fn find(directory: &Path, patterns: &[&str]) -> Option<PathBuf> {
|
||||
// Escape the directory in case it contains characters that have special
|
||||
// meaning in glob patterns (e.g., `[` or `]`).
|
||||
let directory = if let Some(directory) = directory.to_str() {
|
||||
Path::new(&Pattern::escape(directory)).to_owned()
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
for pattern in patterns {
|
||||
let pattern = directory.join(pattern).to_string_lossy().into_owned();
|
||||
if let Some(path) = glob::glob(&pattern).ok()?.filter_map(|p| p.ok()).next() {
|
||||
if path.is_file() && is_executable(&path).unwrap_or(false) {
|
||||
return Some(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn is_executable(path: &Path) -> io::Result<bool> {
|
||||
use std::ffi::CString;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let path = CString::new(path.as_os_str().as_bytes())?;
|
||||
unsafe { Ok(libc::access(path.as_ptr(), libc::X_OK) == 0) }
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn is_executable(_: &Path) -> io::Result<bool> {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// Attempts to run an executable, returning the `stdout` and `stderr` output if
|
||||
/// successful.
|
||||
fn run(executable: &str, arguments: &[&str]) -> Result<(String, String), String> {
|
||||
Command::new(executable)
|
||||
.args(arguments)
|
||||
.output()
|
||||
.map(|o| {
|
||||
let stdout = String::from_utf8_lossy(&o.stdout).into_owned();
|
||||
let stderr = String::from_utf8_lossy(&o.stderr).into_owned();
|
||||
(stdout, stderr)
|
||||
})
|
||||
.map_err(|e| format!("could not run executable `{}`: {}", executable, e))
|
||||
}
|
||||
|
||||
/// Runs `clang`, returning the `stdout` and `stderr` output.
|
||||
fn run_clang(path: &Path, arguments: &[&str]) -> (String, String) {
|
||||
run(&path.to_string_lossy(), arguments).unwrap()
|
||||
}
|
||||
|
||||
/// Runs `llvm-config`, returning the `stdout` output if successful.
|
||||
fn run_llvm_config(arguments: &[&str]) -> Result<String, String> {
|
||||
let config = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".to_string());
|
||||
run(&config, arguments).map(|(o, _)| o)
|
||||
}
|
||||
|
||||
/// Parses a version number if possible, ignoring trailing non-digit characters.
|
||||
fn parse_version_number(number: &str) -> Option<c_int> {
|
||||
number
|
||||
.chars()
|
||||
.take_while(|c| c.is_ascii_digit())
|
||||
.collect::<String>()
|
||||
.parse()
|
||||
.ok()
|
||||
}
|
||||
|
||||
/// Parses the version from the output of a `clang` executable if possible.
|
||||
fn parse_version(path: &Path) -> Option<CXVersion> {
|
||||
let output = run_clang(path, &["--version"]).0;
|
||||
let start = output.find("version ")? + 8;
|
||||
let mut numbers = output[start..].split_whitespace().next()?.split('.');
|
||||
let major = numbers.next().and_then(parse_version_number)?;
|
||||
let minor = numbers.next().and_then(parse_version_number)?;
|
||||
let subminor = numbers.next().and_then(parse_version_number).unwrap_or(0);
|
||||
Some(CXVersion {
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
Subminor: subminor,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses the search paths from the output of a `clang` executable if possible.
|
||||
fn parse_search_paths(path: &Path, language: &str, args: &[String]) -> Option<Vec<PathBuf>> {
|
||||
let mut clang_args = vec!["-E", "-x", language, "-", "-v"];
|
||||
clang_args.extend(args.iter().map(|s| &**s));
|
||||
let output = run_clang(path, &clang_args).1;
|
||||
let start = output.find("#include <...> search starts here:")? + 34;
|
||||
let end = output.find("End of search list.")?;
|
||||
let paths = output[start..end].replace("(framework directory)", "");
|
||||
Some(
|
||||
paths
|
||||
.lines()
|
||||
.filter(|l| !l.is_empty())
|
||||
.map(|l| Path::new(l.trim()).into())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
281
third-party/vendor/clang-sys/tests/build.rs
vendored
Normal file
281
third-party/vendor/clang-sys/tests/build.rs
vendored
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
extern crate glob;
|
||||
extern crate serial_test;
|
||||
extern crate tempfile;
|
||||
|
||||
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 tempfile::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: tempfile::Builder::new().prefix("clang_sys_test").tempdir().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())),
|
||||
);
|
||||
}
|
||||
6
third-party/vendor/clang-sys/tests/header.h
vendored
Normal file
6
third-party/vendor/clang-sys/tests/header.h
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef HEADER_H_
|
||||
#define HEADER_H_
|
||||
|
||||
int add(int a, int b);
|
||||
|
||||
#endif
|
||||
55
third-party/vendor/clang-sys/tests/lib.rs
vendored
Normal file
55
third-party/vendor/clang-sys/tests/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
extern crate clang_sys;
|
||||
extern crate libc;
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use clang_sys::*;
|
||||
|
||||
use libc::c_char;
|
||||
|
||||
fn parse() {
|
||||
unsafe {
|
||||
let index = clang_createIndex(0, 0);
|
||||
assert!(!index.is_null());
|
||||
|
||||
let tu = clang_parseTranslationUnit(
|
||||
index,
|
||||
"tests/header.h\0".as_ptr() as *const c_char,
|
||||
ptr::null_mut(),
|
||||
0,
|
||||
ptr::null_mut(),
|
||||
0,
|
||||
0,
|
||||
);
|
||||
assert!(!tu.is_null());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime")]
|
||||
#[test]
|
||||
fn test() {
|
||||
load().unwrap();
|
||||
let library = get_library().unwrap();
|
||||
println!("{:?} ({:?})", library.version(), library.path());
|
||||
parse();
|
||||
unload().unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "runtime"))]
|
||||
#[test]
|
||||
fn test() {
|
||||
parse();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_support() {
|
||||
let clang = support::Clang::find(None, &[]).unwrap();
|
||||
println!("{:?}", clang);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_support_target() {
|
||||
let args = &["-target".into(), "x86_64-unknown-linux-gnu".into()];
|
||||
let clang = support::Clang::find(None, args).unwrap();
|
||||
println!("{:?}", clang);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue