No bug - Revendor rust dependencies

This commit is contained in:
Servo VCS Sync 2017-05-10 21:23:02 +00:00
parent c421fb27c4
commit fcd2579334
27 changed files with 3223 additions and 3208 deletions

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@ name = "bindgen"
readme = "README.md"
repository = "https://github.com/servo/rust-bindgen"
documentation = "https://docs.rs/bindgen"
version = "0.24.0"
version = "0.25.0"
build = "build.rs"
exclude = [
@ -44,7 +44,7 @@ quasi_codegen = "0.32"
[dependencies]
cexpr = "0.2"
cfg-if = "0.1.0"
clang-sys = { version = "0.16.0", features = ["runtime", "clang_3_9"] }
clang-sys = { version = "0.17.0", features = ["runtime", "clang_3_9"] }
lazy_static = "0.2.1"
syntex_syntax = "0.58"
regex = "0.2"

View File

@ -1465,11 +1465,21 @@ impl CodeGenerator for CompInfo {
let mut generics = aster::AstBuilder::new().generics();
if let Some(ref params) = used_template_params {
for ty in params.iter() {
for (idx, ty) in params.iter().enumerate() {
let param = ctx.resolve_type(*ty);
let name = param.name().unwrap();
let ident = ctx.rust_ident(name);
generics = generics.ty_param_id(ident);
let prefix = ctx.trait_prefix();
let phantom_ty = quote_ty!(
ctx.ext_cx(),
::$prefix::marker::PhantomData<::$prefix::cell::UnsafeCell<$ident>>);
let phantom_field = StructFieldBuilder::named(format!("_phantom_{}", idx))
.pub_()
.build_ty(phantom_ty);
fields.push(phantom_field);
}
}

View File

@ -279,8 +279,7 @@ impl TemplateInstantiation {
/// Does this instantiation have a vtable?
pub fn has_vtable(&self, ctx: &BindgenContext) -> bool {
ctx.resolve_type(self.definition).has_vtable(ctx) ||
self.args.iter().any(|arg| ctx.resolve_type(*arg).has_vtable(ctx))
ctx.resolve_type(self.definition).has_vtable(ctx)
}
/// Does this instantiation have a destructor?

View File

@ -1047,10 +1047,12 @@ impl<'ctx> Bindings<'ctx> {
if !has_target_arg {
// TODO: distinguish C and C++ paths? C++'s should be enough, I
// guess.
for path in clang.cpp_search_paths.into_iter() {
if let Ok(path) = path.into_os_string().into_string() {
options.clang_args.push("-isystem".to_owned());
options.clang_args.push(path);
if let Some(cpp_search_paths) = clang.cpp_search_paths {
for path in cpp_search_paths.into_iter() {
if let Ok(path) = path.into_os_string().into_string() {
options.clang_args.push("-isystem".to_owned());
options.clang_args.push(path);
}
}
}
}

View File

@ -1 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"a9f9f46afd7635a8a47b385e8cb022832fe5e33f629e6f38da39ce19695b5fd5",".travis.yml":"7767a93c49d1762848d6f89dedc8b2e01a8c3795a37b358af8b791b94be42780","CHANGELOG.md":"4e419eab7bb022a75a3b56d20f08d1a6d2d7b334b7c769ddedf119c76e975715","CONTRIBUTING.md":"012c061cd6bc131e2da12a64fb479af1dbd126d754a23e799edbc1e75f1022ba","Cargo.toml":"fa622cdc43562639b210964ff743abeab65d7f5f05759e067bf20e08db2afc43","LICENSE.txt":"3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","README.md":"91a447ed0693ec5b7deb54880c38fd64e4b85b2576a0f6410d28f088478e7791","appveyor.yml":"6c1afedc3368e4a0079c062d95d05f76d822f94d34fa8b513866ceb4271f94b6","build.rs":"80a58cef847798788ea84a51f56f058cc6ae850892a0b1b1c99425beec611d25","ci/before_install.sh":"b190ecd9a1b3df18c544ce4f5a821a0c76504cc7291a5d5f04fe1b75904c3368","ci/install.bat":"47d2da7ae74e2577a126bbde61d286529e1d9082c42e17833e7cfa46226f0b65","ci/script.sh":"52db533df970f1b44c0b2663f3bfac4476f2150e94fc392b2bab4145325f418b","ci/test_script.bat":"901609adc59dab2730e16dd374d0351d6406e7559fe4d86ddd9a857ad9c84d2a","clippy.toml":"fcf54943ba571514b244cc098ce08671b4117167733e8107e799d533a12a2195","src/lib.rs":"96e997af6dc44530437175251884765461511a67bbb14bd3c5a994b5f9a82b47","src/link.rs":"d0e21e29e137c1c20747ad8428dadc6ed1e7cc62c5fd14cc229138daa26b3fb4","src/support.rs":"a1b919bdda41ca6f3be986aa882314fed8a1a27fcd975b796bf961d3a4b701d9","tests/header.h":"1b15a686d1c06561960045a26c25a34d840f26c8246f2f5e630f993b69c7492c","tests/lib.rs":"c258811d230506cd420ddef3c83c91de64d6cbbd4b61d1f6e1816924ab1c7a73"},"package":"5f4f6aa0c4cfa318cd4d2940afae57e48b94d44d3aced603501df24f3c2a414f"}
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"09cd366a44271073e57584376fd326da166664cd8ff303c2839b63a330557c73",".travis.yml":"79d6a139814ae0f06ce0ca85fe22a27316a27d444320b904c471c7f612129889","CHANGELOG.md":"786e019493746e2a1a98fdd069e28103acf146c0093814b74b54f145665c6428","CONTRIBUTING.md":"4e2a45992604f07a37030bb1fc598c6f54a1785747c4f37a15a37481bbdecce8","Cargo.toml":"3c22785a6974cd8a051a0cb87090c480af3cab261df125ab7d408a77644b9cef","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"92dc2a93f6de04e38d305df2d0ee4854269acbacadc665e6ce17b90f90ad29ca","appveyor.yml":"fe7033ab25bb78005136748676f59bfdd8f65b4c5c2910af911cbb9c496bdaef","build.rs":"1c5172ffc51fdf00f35b8366945ab98d644d386bcb12eb773990253adb000c80","ci/before_install.sh":"402f5704cd0163254b056a515a6cdfa16482eb2e28c31eb63a5c226abd26a8b7","ci/install.bat":"d694550679e14b384f8adf8384d475866e5880002cf82d450926f4607dc9077b","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"73462f51aaa9a1c14ce9f55c41dc3672df64faa9789725384ae4f28d8ba3c90b","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"f27371163edaec30a3972667318320b060adff25c03a850a9e807f84c9bc395f","src/link.rs":"b9f76e26fa9b1d690f6abf17e9f898d6545be149e2afe64c7411cd53e3168fcf","src/support.rs":"1e48fcb7dc9e7f4dde06d88079074832a4c2dab337228e05241b7d7e94858734","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"9225ffcaa892a3901c0dce9f8190421db8fb17651499b4de765b87f08daaf5b2"},"package":"33d47b0ea88a529a570490efbb79403e416e89864ce8a96bf23e2a0f23d7e9eb"}

View File

@ -1,3 +1,3 @@
target/
Cargo.lock
target/
Cargo.lock

View File

@ -1,28 +1,28 @@
language: rust
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-5
os:
- linux
- osx
rust: stable
env:
- LLVM_VERSION=3.5 CLANG_VERSION=clang_3_5
- LLVM_VERSION=4.0 CLANG_VERSION=clang_4_0
# FIXME: I have no idea why this build is failing.
matrix:
allow_failures:
- os: osx
env: LLVM_VERSION=4.0 CLANG_VERSION=clang_4_0
before_install: . ./ci/before_install.sh
script: . ./ci/script.sh
language: rust
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-5
os:
- linux
- osx
rust: stable
env:
- LLVM_VERSION=3.5 CLANG_VERSION=clang_3_5
- LLVM_VERSION=4.0 CLANG_VERSION=clang_4_0
# FIXME: I have no idea why this build is failing.
matrix:
allow_failures:
- os: osx
env: LLVM_VERSION=4.0 CLANG_VERSION=clang_4_0
before_install: . ./ci/before_install.sh
script: . ./ci/script.sh

View File

@ -1,213 +1,218 @@
## [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 OS X 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 OS X
## [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 OS X
- Fixed search path parsing on Windows
- Fixed default search path ordering on OS X
## [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 OS X
- 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
## [0.17.0] - 2017-05-08
### Changed
- Change 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 OS X 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 OS X
## [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 OS X
- Fixed search path parsing on Windows
- Fixed default search path ordering on OS X
## [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 OS X
- 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

View File

@ -1,7 +1,7 @@
# Contributing to clang-sys
## Pull Requests
If you are intending to make a pull request, please make your changes in a branch that originated
from the `development` branch, not the `master` branch. Then, make your pull request against the
`development` branch.
# Contributing to clang-sys
## Pull Requests
If you are intending to make a pull request, please make your changes in a branch that originated
from the `development` branch, not the `master` branch. Then, make your pull request against the
`development` branch.

View File

@ -1,49 +1,49 @@
[package]
name = "clang-sys"
authors = ["Kyle Mayes <kyle@mayeses.com>"]
version = "0.16.0"
readme = "README.md"
license = "Apache-2.0"
description = "Rust bindings for libclang."
documentation = "https://kylemayes.github.io/clang-sys/3_5/clang_sys"
repository = "https://github.com/KyleMayes/clang-sys"
build = "build.rs"
[features]
clang_3_5 = []
clang_3_6 = ["gte_clang_3_6"]
clang_3_7 = ["gte_clang_3_6", "gte_clang_3_7"]
clang_3_8 = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8"]
clang_3_9 = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8", "gte_clang_3_9"]
clang_4_0 = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8", "gte_clang_3_9", "gte_clang_4_0"]
gte_clang_3_6 = []
gte_clang_3_7 = []
gte_clang_3_8 = []
gte_clang_3_9 = []
gte_clang_4_0 = []
runtime = ["libloading"]
static = []
[dependencies]
bitflags = "0.8.0"
glob = "0.2.11"
libc = "0.2.14"
libloading = { version = "0.4.0", optional = true }
clippy = { version = "0.0.*", optional = true }
[build-dependencies]
glob = "0.2.11"
clippy = { version = "0.0.*", optional = true }
[package]
name = "clang-sys"
authors = ["Kyle Mayes <kyle@mayeses.com>"]
version = "0.17.0"
readme = "README.md"
license = "Apache-2.0"
description = "Rust bindings for libclang."
documentation = "https://kylemayes.github.io/clang-sys/3_5/clang_sys"
repository = "https://github.com/KyleMayes/clang-sys"
build = "build.rs"
[features]
clang_3_5 = []
clang_3_6 = ["gte_clang_3_6"]
clang_3_7 = ["gte_clang_3_6", "gte_clang_3_7"]
clang_3_8 = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8"]
clang_3_9 = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8", "gte_clang_3_9"]
clang_4_0 = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8", "gte_clang_3_9", "gte_clang_4_0"]
gte_clang_3_6 = []
gte_clang_3_7 = []
gte_clang_3_8 = []
gte_clang_3_9 = []
gte_clang_4_0 = []
runtime = ["libloading"]
static = []
[dependencies]
bitflags = "0.8.0"
glob = "0.2.11"
libc = "0.2.14"
libloading = { version = "0.4.0", optional = true }
clippy = { version = "0.0.*", optional = true }
[build-dependencies]
glob = "0.2.11"
clippy = { version = "0.0.*", optional = true }

View File

@ -1,202 +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.
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.

View File

@ -1,100 +1,100 @@
# clang-sys
[![crates.io](https://img.shields.io/crates/v/clang-sys.svg)](https://crates.io/crates/clang-sys)
[![Travis CI](https://travis-ci.org/KyleMayes/clang-sys.svg?branch=master)](https://travis-ci.org/KyleMayes/clang-sys)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/7tv5mjyg55rof356/branch/master?svg=true)](https://ci.appveyor.com/project/KyleMayes/clang-sys-vtvy5/branch/master)
Rust bindings for `libclang`.
If you are interested in a Rust wrapper for these bindings, see
[clang-rs](https://github.com/KyleMayes/clang-rs).
Supported on the stable, beta, and nightly Rust channels.
Released under the Apache License 2.0.
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on contributing to this repository.
## Supported Versions
To target a version of `libclang`, enable one of the following Cargo features:
* `clang_3_5` - requires `libclang` 3.5 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_5/clang_sys))
* `clang_3_6` - requires `libclang` 3.6 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_6/clang_sys))
* `clang_3_7` - requires `libclang` 3.7 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_7/clang_sys))
* `clang_3_8` - requires `libclang` 3.8 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_8/clang_sys))
* `clang_3_9` - requires `libclang` 3.9 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_9/clang_sys))
* `clang_4_0` - requires `libclang` 4.0 or later
([Documentation](https://kylemayes.github.io/clang-sys/4_0/clang_sys))
If you do not enable one of these features, the API provided by `libclang` 3.5 will be available by
default.
## Dependencies
By default, this crate will attempt to link to `libclang` dynamically. In this case, this crate
depends on the `libclang` shared library (`libclang.so` on Linux, `libclang.dylib` on OS X,
`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:** Installing `libclang` through a package manager might install the `libclang` shared
library as something like `libclang.so.1` instead of `libclang.so`. In this case, you need to make a
symbolic link from the versioned shared library to `libclang.so`.
**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.
## Environment Variables
The following environment variables, if set, are used by this crate to find the required libraries
and executables:
* `LLVM_CONFIG_PATH` **(compile time)** - provides a path to an `llvm-config` executable
* `LIBCLANG_PATH` **(compile time)** - provides a path to a directory containing a `libclang` shared
library
* `LIBCLANG_STATIC_PATH` **(compile time)** - provides a path to a directory containing LLVM and
Clang static libraries
* `CLANG_PATH` **(run time)** - provides a path to a `clang` executable
## Linking
### Dynamic
First, the `libclang` shared library will be searched for in the directory provided by the
`LIBCLANG_PATH` environment variable if it was set. If this fails, the directory returned by
`llvm-config --libdir` will be searched. If neither of these approaches is successful, a list of
likely directories will be searched (e.g., `/usr/local/lib` on Linux).
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 the
shared library is 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.
# clang-sys
[![crates.io](https://img.shields.io/crates/v/clang-sys.svg)](https://crates.io/crates/clang-sys)
[![Travis CI](https://travis-ci.org/KyleMayes/clang-sys.svg?branch=master)](https://travis-ci.org/KyleMayes/clang-sys)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/7tv5mjyg55rof356/branch/master?svg=true)](https://ci.appveyor.com/project/KyleMayes/clang-sys-vtvy5/branch/master)
Rust bindings for `libclang`.
If you are interested in a Rust wrapper for these bindings, see
[clang-rs](https://github.com/KyleMayes/clang-rs).
Supported on the stable, beta, and nightly Rust channels.
Released under the Apache License 2.0.
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on contributing to this repository.
## Supported Versions
To target a version of `libclang`, enable one of the following Cargo features:
* `clang_3_5` - requires `libclang` 3.5 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_5/clang_sys))
* `clang_3_6` - requires `libclang` 3.6 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_6/clang_sys))
* `clang_3_7` - requires `libclang` 3.7 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_7/clang_sys))
* `clang_3_8` - requires `libclang` 3.8 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_8/clang_sys))
* `clang_3_9` - requires `libclang` 3.9 or later
([Documentation](https://kylemayes.github.io/clang-sys/3_9/clang_sys))
* `clang_4_0` - requires `libclang` 4.0 or later
([Documentation](https://kylemayes.github.io/clang-sys/4_0/clang_sys))
If you do not enable one of these features, the API provided by `libclang` 3.5 will be available by
default.
## Dependencies
By default, this crate will attempt to link to `libclang` dynamically. In this case, this crate
depends on the `libclang` shared library (`libclang.so` on Linux, `libclang.dylib` on OS X,
`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:** Installing `libclang` through a package manager might install the `libclang` shared
library as something like `libclang.so.1` instead of `libclang.so`. In this case, you need to make a
symbolic link from the versioned shared library to `libclang.so`.
**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.
## Environment Variables
The following environment variables, if set, are used by this crate to find the required libraries
and executables:
* `LLVM_CONFIG_PATH` **(compile time)** - provides a path to an `llvm-config` executable
* `LIBCLANG_PATH` **(compile time)** - provides a path to a directory containing a `libclang` shared
library
* `LIBCLANG_STATIC_PATH` **(compile time)** - provides a path to a directory containing LLVM and
Clang static libraries
* `CLANG_PATH` **(run time)** - provides a path to a `clang` executable
## Linking
### Dynamic
First, the `libclang` shared library will be searched for in the directory provided by the
`LIBCLANG_PATH` environment variable if it was set. If this fails, the directory returned by
`llvm-config --libdir` will be searched. If neither of these approaches is successful, a list of
likely directories will be searched (e.g., `/usr/local/lib` on Linux).
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 the
shared library is 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.

View File

@ -1,12 +1,12 @@
environment:
matrix:
- LLVM_VERSION: 4.0.0
CLANG_VERSION: clang_4_0
install:
- .\ci\install.bat
build: false
test_script:
- .\ci\test_script.bat
environment:
matrix:
- LLVM_VERSION: 4.0.0
CLANG_VERSION: clang_4_0
install:
- .\ci\install.bat
build: false
test_script:
- .\ci\test_script.bat

View File

@ -1,355 +1,355 @@
// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Finds the required `libclang` libraries and links to them.
//!
//! # Environment Variables
//!
//! This build script can make use of several environment variables to help it find the required
//! static or dynamic libraries.
//!
//! * LLVM_CONFIG_PATH - provides a path to an `llvm-config` executable
//! * LIBCLANG_PATH - provides a path to a directory containing a `libclang` shared library
//! * LIBCLANG_STATIC_PATH - provides a path to a directory containing LLVM and Clang static libraries
#![allow(unused_attributes)]
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(feature="clippy", warn(clippy))]
extern crate glob;
use std::env;
use std::fs::{self, File};
use std::io::{Read};
use std::path::{Path, PathBuf};
use std::process::{Command};
use glob::{MatchOptions};
/// Returns a path to one of the supplied files if such a file can be found in the supplied directory.
fn contains<D: AsRef<Path>>(directory: D, files: &[String]) -> Option<PathBuf> {
files.iter().map(|file| directory.as_ref().join(file)).find(|file| file.exists())
}
/// Runs a console command, returning the output if the command was successfully executed.
fn run(command: &str, arguments: &[&str]) -> Option<String> {
Command::new(command).args(arguments).output().map(|o| {
String::from_utf8_lossy(&o.stdout).into_owned()
}).ok()
}
/// Runs `llvm-config`, returning the output if the command was successfully executed.
fn run_llvm_config(arguments: &[&str]) -> Result<String, String> {
match run(&env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into()), arguments) {
Some(output) => Ok(output),
None => {
let message = format!(
"couldn't execute `llvm-config {}`, set the LLVM_CONFIG_PATH environment variable \
to a path to a valid `llvm-config` executable",
arguments.join(" "),
);
Err(message)
},
}
}
/// Backup search directory globs for FreeBSD and Linux.
const SEARCH_LINUX: &'static [&'static str] = &[
"/usr/lib*",
"/usr/lib*/*",
"/usr/lib*/*/*",
"/usr/local/lib*",
"/usr/local/lib*/*",
"/usr/local/lib*/*/*",
"/usr/local/llvm*/lib",
];
/// Backup search directory globs for OS X.
const SEARCH_OSX: &'static [&'static str] = &[
"/usr/local/opt/llvm*/lib",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
"/Library/Developer/CommandLineTools/usr/lib",
"/usr/local/opt/llvm*/lib/llvm*/lib",
];
/// Backup search directory globs for Windows.
const SEARCH_WINDOWS: &'static [&'static str] = &[
"C:\\LLVM\\lib",
"C:\\Program Files*\\LLVM\\lib",
"C:\\MSYS*\\MinGW*\\lib",
];
/// Indicates the type of library being searched for.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum Library {
Dynamic,
Static,
}
impl Library {
/// Checks whether the supplied file is a valid library for the architecture.
fn check(&self, file: &PathBuf) -> Result<(), String> {
if cfg!(any(target_os="freebsd", target_os="linux")) {
if *self == Library::Static {
return Ok(());
}
let mut file = try!(File::open(file).map_err(|e| e.to_string()));
let mut elf = [0; 5];
try!(file.read_exact(&mut elf).map_err(|e| e.to_string()));
if elf[..4] != [127, 69, 76, 70] {
return Err("invalid ELF header".into());
}
if cfg!(target_pointer_width="32") && elf[4] != 1 {
return Err("invalid ELF class (64-bit)".into());
}
if cfg!(target_pointer_width="64") && elf[4] != 2 {
return Err("invalid ELF class (32-bit)".into());
}
Ok(())
} else {
Ok(())
}
}
}
/// Searches for a library, returning the directory it can be found in if the search was successful.
fn find(library: Library, files: &[String], env: &str) -> Result<PathBuf, String> {
let mut skipped = vec![];
/// Attempts to return the supplied file.
macro_rules! try_file {
($file:expr) => ({
match library.check(&$file) {
Ok(_) => return Ok($file),
Err(message) => skipped.push(format!("({}: {})", $file.display(), message)),
}
});
}
/// Searches the supplied directory and, on Windows, any relevant sibling directories.
macro_rules! search_directory {
($directory:ident) => {
if let Some(file) = contains(&$directory, files) {
try_file!(file);
}
// 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 cfg!(target_os="windows") && $directory.ends_with("lib") {
let sibling = $directory.parent().unwrap().join("bin");
if let Some(file) = contains(&sibling, files) {
try_file!(file);
}
}
}
}
// Search the directory provided by the relevant environment variable if it is set.
if let Ok(directory) = env::var(env).map(|d| Path::new(&d).to_path_buf()) {
search_directory!(directory);
}
// Search the `bin` and `lib` subdirectories in the directory returned by
// `llvm-config --prefix` if `llvm-config` is available.
if let Ok(output) = run_llvm_config(&["--prefix"]) {
let directory = Path::new(output.lines().next().unwrap()).to_path_buf();
let bin = directory.join("bin");
if let Some(file) = contains(&bin, files) {
try_file!(file);
}
let lib = directory.join("lib");
if let Some(file) = contains(&lib, files) {
try_file!(file);
}
}
// Search the backup directories.
let search = if cfg!(any(target_os="freebsd", target_os="linux")) {
SEARCH_LINUX
} else if cfg!(target_os="macos") {
SEARCH_OSX
} else if cfg!(target_os="windows") {
SEARCH_WINDOWS
} else {
&[]
};
for pattern in search {
let mut options = MatchOptions::new();
options.case_sensitive = false;
options.require_literal_separator = true;
if let Ok(paths) = glob::glob_with(pattern, &options) {
for path in paths.filter_map(Result::ok).filter(|p| p.is_dir()) {
search_directory!(path);
}
}
}
let message = format!(
"couldn't find any of [{}], set the {} environment variable to a path where one of these \
files can be found (skipped: [{}])",
files.iter().map(|f| format!("'{}'", f)).collect::<Vec<_>>().join(", "),
env,
skipped.join(", "),
);
Err(message)
}
/// Searches for a `libclang` shared library, returning the path to such a shared library if the
/// search was successful.
pub fn find_shared_library() -> Result<PathBuf, String> {
let mut files = vec![format!("{}clang{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX)];
if cfg!(target_os="linux") {
// Some Linux distributions don't create a `libclang.so` symlink.
//
// FIXME: We should improve our detection and selection of versioned libraries.
files.push("libclang.so.1".into());
}
if cfg!(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(Library::Dynamic, &files, "LIBCLANG_PATH")
}
/// Returns the name of an LLVM or Clang library from a path to such a library.
fn get_library_name(path: &Path) -> Option<String> {
path.file_stem().map(|l| l.to_string_lossy()[3..].into())
}
/// Returns the LLVM libraries required to link to `libclang` statically.
fn get_llvm_libraries() -> Vec<String> {
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 p.starts_with("-l") {
Some(p[2..].into())
} else {
get_library_name(Path::new(p))
}
}).collect()
}
/// Clang libraries required to link to `libclang` 3.5 and later statically.
const CLANG_LIBRARIES: &'static [&'static str] = &[
"clang",
"clangAST",
"clangAnalysis",
"clangBasic",
"clangDriver",
"clangEdit",
"clangFrontend",
"clangIndex",
"clangLex",
"clangParse",
"clangRewrite",
"clangSema",
"clangSerialization",
];
/// Returns the Clang libraries required to link to `libclang` statically.
fn get_clang_libraries<P: AsRef<Path>>(directory: P) -> Vec<String> {
let pattern = directory.as_ref().join("libclang*.a").to_string_lossy().to_string();
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()
}
}
/// Find and link to `libclang` statically.
#[cfg_attr(feature="runtime", allow(dead_code))]
fn link_static() {
let file = find(Library::Static, &["libclang.a".into()], "LIBCLANG_STATIC_PATH").unwrap();
let directory = file.parent().unwrap();
print!("cargo:rustc-flags=");
// Specify required Clang static libraries.
print!("-L {} ", directory.display());
for library in get_clang_libraries(directory) {
print!("-l static={} ", library);
}
// Specify required LLVM static libraries.
print!("-L {} ", run_llvm_config(&["--libdir"]).unwrap().trim_right());
for library in get_llvm_libraries() {
print!("-l static={} ", library);
}
// Specify required system libraries.
if cfg!(target_os="freebsd") {
println!("-l ffi -l ncursesw -l c++ -l z");
} else if cfg!(target_os="linux") {
println!("-l ffi -l ncursesw -l stdc++ -l z");
} else if cfg!(target_os="macos") {
println!("-l ffi -l ncurses -l c++ -l z");
} else {
panic!("unsupported operating system for static linking");
}
}
/// Find and link to `libclang` dynamically.
#[cfg_attr(feature="runtime", allow(dead_code))]
fn link_dynamic() {
let file = find_shared_library().unwrap();
let directory = file.parent().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 libdir = if !directory.ends_with("bin") {
directory.to_owned()
} else {
directory.parent().unwrap().join("lib")
};
if libdir.join("libclang.lib").exists() {
println!("cargo:rustc-link-search={}", libdir.display());
} else if libdir.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(libdir.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 {}",
file.display(),
libdir.display(),
);
}
println!("cargo:rustc-link-lib=dylib=libclang");
} else {
println!("cargo:rustc-link-lib=dylib=clang");
}
}
#[cfg_attr(feature="runtime", allow(dead_code))]
fn main() {
if cfg!(feature="runtime") {
if cfg!(feature="static") {
panic!("`runtime` and `static` features can't be combined");
}
} else if cfg!(feature="static") {
link_static();
} else {
link_dynamic();
}
}
// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Finds the required `libclang` libraries and links to them.
//!
//! # Environment Variables
//!
//! This build script can make use of several environment variables to help it find the required
//! static or dynamic libraries.
//!
//! * `LLVM_CONFIG_PATH` - provides a path to an `llvm-config` executable
//! * `LIBCLANG_PATH` - provides a path to a directory containing a `libclang` shared library
//! * `LIBCLANG_STATIC_PATH` - provides a path to a directory containing LLVM and Clang static libraries
#![allow(unused_attributes)]
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(feature="clippy", warn(clippy))]
extern crate glob;
use std::env;
use std::fs::{self, File};
use std::io::{Read};
use std::path::{Path, PathBuf};
use std::process::{Command};
use glob::{MatchOptions};
/// Returns a path to one of the supplied files if such a file can be found in the supplied directory.
fn contains<D: AsRef<Path>>(directory: D, files: &[String]) -> Option<PathBuf> {
files.iter().map(|file| directory.as_ref().join(file)).find(|file| file.exists())
}
/// Runs a console command, returning the output if the command was successfully executed.
fn run(command: &str, arguments: &[&str]) -> Option<String> {
Command::new(command).args(arguments).output().map(|o| {
String::from_utf8_lossy(&o.stdout).into_owned()
}).ok()
}
/// Runs `llvm-config`, returning the output if the command was successfully executed.
fn run_llvm_config(arguments: &[&str]) -> Result<String, String> {
match run(&env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into()), arguments) {
Some(output) => Ok(output),
None => {
let message = format!(
"couldn't execute `llvm-config {}`, set the LLVM_CONFIG_PATH environment variable \
to a path to a valid `llvm-config` executable",
arguments.join(" "),
);
Err(message)
},
}
}
/// Backup search directory globs for FreeBSD and Linux.
const SEARCH_LINUX: &'static [&'static str] = &[
"/usr/lib*",
"/usr/lib*/*",
"/usr/lib*/*/*",
"/usr/local/lib*",
"/usr/local/lib*/*",
"/usr/local/lib*/*/*",
"/usr/local/llvm*/lib",
];
/// Backup search directory globs for OS X.
const SEARCH_OSX: &'static [&'static str] = &[
"/usr/local/opt/llvm*/lib",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
"/Library/Developer/CommandLineTools/usr/lib",
"/usr/local/opt/llvm*/lib/llvm*/lib",
];
/// Backup search directory globs for Windows.
const SEARCH_WINDOWS: &'static [&'static str] = &[
"C:\\LLVM\\lib",
"C:\\Program Files*\\LLVM\\lib",
"C:\\MSYS*\\MinGW*\\lib",
];
/// Indicates the type of library being searched for.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum Library {
Dynamic,
Static,
}
impl Library {
/// Checks whether the supplied file is a valid library for the architecture.
fn check(&self, file: &PathBuf) -> Result<(), String> {
if cfg!(any(target_os="freebsd", target_os="linux")) {
if *self == Library::Static {
return Ok(());
}
let mut file = try!(File::open(file).map_err(|e| e.to_string()));
let mut elf = [0; 5];
try!(file.read_exact(&mut elf).map_err(|e| e.to_string()));
if elf[..4] != [127, 69, 76, 70] {
return Err("invalid ELF header".into());
}
if cfg!(target_pointer_width="32") && elf[4] != 1 {
return Err("invalid ELF class (64-bit)".into());
}
if cfg!(target_pointer_width="64") && elf[4] != 2 {
return Err("invalid ELF class (32-bit)".into());
}
Ok(())
} else {
Ok(())
}
}
}
/// Searches for a library, returning the directory it can be found in if the search was successful.
fn find(library: Library, files: &[String], env: &str) -> Result<PathBuf, String> {
let mut skipped = vec![];
/// Attempts to return the supplied file.
macro_rules! try_file {
($file:expr) => ({
match library.check(&$file) {
Ok(_) => return Ok($file),
Err(message) => skipped.push(format!("({}: {})", $file.display(), message)),
}
});
}
/// Searches the supplied directory and, on Windows, any relevant sibling directories.
macro_rules! search_directory {
($directory:ident) => {
if let Some(file) = contains(&$directory, files) {
try_file!(file);
}
// 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 cfg!(target_os="windows") && $directory.ends_with("lib") {
let sibling = $directory.parent().unwrap().join("bin");
if let Some(file) = contains(&sibling, files) {
try_file!(file);
}
}
}
}
// Search the directory provided by the relevant environment variable if it is set.
if let Ok(directory) = env::var(env).map(|d| Path::new(&d).to_path_buf()) {
search_directory!(directory);
}
// Search the `bin` and `lib` subdirectories in the directory returned by
// `llvm-config --prefix` if `llvm-config` is available.
if let Ok(output) = run_llvm_config(&["--prefix"]) {
let directory = Path::new(output.lines().next().unwrap()).to_path_buf();
let bin = directory.join("bin");
if let Some(file) = contains(&bin, files) {
try_file!(file);
}
let lib = directory.join("lib");
if let Some(file) = contains(&lib, files) {
try_file!(file);
}
}
// Search the backup directories.
let search = if cfg!(any(target_os="freebsd", target_os="linux")) {
SEARCH_LINUX
} else if cfg!(target_os="macos") {
SEARCH_OSX
} else if cfg!(target_os="windows") {
SEARCH_WINDOWS
} else {
&[]
};
for pattern in search {
let mut options = MatchOptions::new();
options.case_sensitive = false;
options.require_literal_separator = true;
if let Ok(paths) = glob::glob_with(pattern, &options) {
for path in paths.filter_map(Result::ok).filter(|p| p.is_dir()) {
search_directory!(path);
}
}
}
let message = format!(
"couldn't find any of [{}], set the {} environment variable to a path where one of these \
files can be found (skipped: [{}])",
files.iter().map(|f| format!("'{}'", f)).collect::<Vec<_>>().join(", "),
env,
skipped.join(", "),
);
Err(message)
}
/// Searches for a `libclang` shared library, returning the path to such a shared library if the
/// search was successful.
pub fn find_shared_library() -> Result<PathBuf, String> {
let mut files = vec![format!("{}clang{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX)];
if cfg!(target_os="linux") {
// Some Linux distributions don't create a `libclang.so` symlink.
//
// FIXME: We should improve our detection and selection of versioned libraries.
files.push("libclang.so.1".into());
}
if cfg!(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(Library::Dynamic, &files, "LIBCLANG_PATH")
}
/// Returns the name of an LLVM or Clang library from a path to such a library.
fn get_library_name(path: &Path) -> Option<String> {
path.file_stem().map(|l| l.to_string_lossy()[3..].into())
}
/// Returns the LLVM libraries required to link to `libclang` statically.
fn get_llvm_libraries() -> Vec<String> {
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 p.starts_with("-l") {
Some(p[2..].into())
} else {
get_library_name(Path::new(p))
}
}).collect()
}
/// Clang libraries required to link to `libclang` 3.5 and later statically.
const CLANG_LIBRARIES: &'static [&'static str] = &[
"clang",
"clangAST",
"clangAnalysis",
"clangBasic",
"clangDriver",
"clangEdit",
"clangFrontend",
"clangIndex",
"clangLex",
"clangParse",
"clangRewrite",
"clangSema",
"clangSerialization",
];
/// Returns the Clang libraries required to link to `libclang` statically.
fn get_clang_libraries<P: AsRef<Path>>(directory: P) -> Vec<String> {
let pattern = directory.as_ref().join("libclang*.a").to_string_lossy().to_string();
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()
}
}
/// Find and link to `libclang` statically.
#[cfg_attr(feature="runtime", allow(dead_code))]
fn link_static() {
let file = find(Library::Static, &["libclang.a".into()], "LIBCLANG_STATIC_PATH").unwrap();
let directory = file.parent().unwrap();
print!("cargo:rustc-flags=");
// Specify required Clang static libraries.
print!("-L {} ", directory.display());
for library in get_clang_libraries(directory) {
print!("-l static={} ", library);
}
// Specify required LLVM static libraries.
print!("-L {} ", run_llvm_config(&["--libdir"]).unwrap().trim_right());
for library in get_llvm_libraries() {
print!("-l static={} ", library);
}
// Specify required system libraries.
if cfg!(target_os="freebsd") {
println!("-l ffi -l ncursesw -l c++ -l z");
} else if cfg!(target_os="linux") {
println!("-l ffi -l ncursesw -l stdc++ -l z");
} else if cfg!(target_os="macos") {
println!("-l ffi -l ncurses -l c++ -l z");
} else {
panic!("unsupported operating system for static linking");
}
}
/// Find and link to `libclang` dynamically.
#[cfg_attr(feature="runtime", allow(dead_code))]
fn link_dynamic() {
let file = find_shared_library().unwrap();
let directory = file.parent().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 libdir = if !directory.ends_with("bin") {
directory.to_owned()
} else {
directory.parent().unwrap().join("lib")
};
if libdir.join("libclang.lib").exists() {
println!("cargo:rustc-link-search={}", libdir.display());
} else if libdir.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(libdir.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 {}",
file.display(),
libdir.display(),
);
}
println!("cargo:rustc-link-lib=dylib=libclang");
} else {
println!("cargo:rustc-link-lib=dylib=clang");
}
}
#[cfg_attr(feature="runtime", allow(dead_code))]
fn main() {
if cfg!(feature="runtime") {
if cfg!(feature="static") {
panic!("`runtime` and `static` features can't be combined");
}
} else if cfg!(feature="static") {
link_static();
} else {
link_dynamic();
}
}

72
third_party/rust/clang-sys/ci/before_install.sh vendored Normal file → Executable file
View File

@ -1,36 +1,36 @@
set -e
function llvm_version_triple() {
if [ "$1" == "3.5" ]; then
echo "3.5.2"
elif [ "$1" == "3.6" ]; then
echo "3.6.2"
elif [ "$1" == "3.7" ]; then
echo "3.7.1"
elif [ "$1" == "3.8" ]; then
echo "3.8.1"
elif [ "$1" == "3.9" ]; then
echo "3.9.0"
elif [ "$1" == "4.0" ]; then
echo "4.0.0"
fi
}
function llvm_download() {
export LLVM_VERSION_TRIPLE=`llvm_version_triple ${LLVM_VERSION}`
export LLVM=clang+llvm-${LLVM_VERSION_TRIPLE}-x86_64-$1
wget http://llvm.org/releases/${LLVM_VERSION_TRIPLE}/${LLVM}.tar.xz
mkdir llvm
tar xf ${LLVM}.tar.xz -C llvm --strip-components=1
export LLVM_CONFIG_PATH=`pwd`/llvm/bin/llvm-config
}
if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
llvm_download linux-gnu-ubuntu-14.04
export LD_LIBRARY_PATH=`pwd`/llvm/lib:$LD_LIBRARY_PATH
else
llvm_download apple-darwin
export DYLD_LIBRARY_PATH=`pwd`/llvm/lib:$DYLD_LIBRARY_PATH
fi
set -e
function llvm_version_triple() {
if [ "$1" == "3.5" ]; then
echo "3.5.2"
elif [ "$1" == "3.6" ]; then
echo "3.6.2"
elif [ "$1" == "3.7" ]; then
echo "3.7.1"
elif [ "$1" == "3.8" ]; then
echo "3.8.1"
elif [ "$1" == "3.9" ]; then
echo "3.9.0"
elif [ "$1" == "4.0" ]; then
echo "4.0.0"
fi
}
function llvm_download() {
export LLVM_VERSION_TRIPLE=`llvm_version_triple ${LLVM_VERSION}`
export LLVM=clang+llvm-${LLVM_VERSION_TRIPLE}-x86_64-$1
wget http://llvm.org/releases/${LLVM_VERSION_TRIPLE}/${LLVM}.tar.xz
mkdir llvm
tar xf ${LLVM}.tar.xz -C llvm --strip-components=1
export LLVM_CONFIG_PATH=`pwd`/llvm/bin/llvm-config
}
if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
llvm_download linux-gnu-ubuntu-14.04
export LD_LIBRARY_PATH=`pwd`/llvm/lib:$LD_LIBRARY_PATH
else
llvm_download apple-darwin
export DYLD_LIBRARY_PATH=`pwd`/llvm/lib:$DYLD_LIBRARY_PATH
fi

View File

@ -1,8 +1,8 @@
curl -sSf https://static.rust-lang.org/dist/rust-1.10.0-i686-pc-windows-msvc.exe -o rust.exe
rust.exe /VERYSILENT /NORESTART /DIR="C:\Rust"
set PATH=%PATH%;C:\Rust\bin
curl -sSf http://releases.llvm.org/%LLVM_VERSION%/LLVM-%LLVM_VERSION%-win32.exe -o LLVM.exe
7z x LLVM.exe -oC:\LLVM
set PATH=%PATH%;C:\LLVM\bin
set LIBCLANG_PATH=C:\LLVM\bin
curl -sSf https://static.rust-lang.org/dist/rust-1.10.0-i686-pc-windows-msvc.exe -o rust.exe
rust.exe /VERYSILENT /NORESTART /DIR="C:\Rust"
set PATH=%PATH%;C:\Rust\bin
curl -sSf http://releases.llvm.org/%LLVM_VERSION%/LLVM-%LLVM_VERSION%-win32.exe -o LLVM.exe
7z x LLVM.exe -oC:\LLVM
set PATH=%PATH%;C:\LLVM\bin
set LIBCLANG_PATH=C:\LLVM\bin

26
third_party/rust/clang-sys/ci/script.sh vendored Normal file → Executable file
View File

@ -1,13 +1,13 @@
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
rvm get head || true
fi
set -e
RUST_BACKTRACE=1 cargo test --verbose --features $CLANG_VERSION -- --nocapture
if [ "${CLANG_VERSION}" \< "clang_3_7" ]; then
RUST_BACKTRACE=1 cargo test --verbose --features "$CLANG_VERSION static" -- --nocapture
fi
RUST_BACKTRACE=1 cargo test --verbose --features "$CLANG_VERSION runtime" -- --nocapture
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
rvm get head || true
fi
set -e
RUST_BACKTRACE=1 cargo test --verbose --features $CLANG_VERSION -- --nocapture
if [ "${CLANG_VERSION}" \< "clang_3_7" ]; then
RUST_BACKTRACE=1 cargo test --verbose --features "$CLANG_VERSION static" -- --nocapture
fi
RUST_BACKTRACE=1 cargo test --verbose --features "$CLANG_VERSION runtime" -- --nocapture

View File

@ -1,2 +1,2 @@
set RUST_BACKTRACE=1
cargo test --verbose --features %CLANG_VERSION% -- --nocapture
set RUST_BACKTRACE=1
cargo test --verbose --features %CLANG_VERSION% -- --nocapture

View File

@ -1 +1 @@
doc-valid-idents = ["FreeBSD"]
doc-valid-idents = ["FreeBSD"]

File diff suppressed because it is too large Load Diff

View File

@ -1,185 +1,185 @@
// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//================================================
// Macros
//================================================
// link! _________________________________________
#[cfg(feature="runtime")]
macro_rules! link {
(@LOAD: #[cfg($cfg:meta)] fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*) => (
#[cfg($cfg)]
pub fn $name(library: &mut super::SharedLibrary) {
let symbol = unsafe { library.library.get(stringify!($name).as_bytes()) }.ok();
library.functions.$name = symbol.map(|s| *s);
}
#[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)*);
);
($($(#[cfg($cfg:meta)])* pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*;)+) => (
use std::cell::{RefCell};
use std::sync::{Arc};
/// The set of functions loaded dynamically.
#[derive(Debug)]
pub struct Functions {
$($(#[cfg($cfg)])* pub $name: Option<unsafe extern fn($($pname: $pty), *) $(-> $ret)*>,)+
}
impl Default for Functions {
fn default() -> Functions {
unsafe { std::mem::zeroed() }
}
}
/// A dynamically loaded instance of the `libclang` library.
#[derive(Debug)]
pub struct SharedLibrary {
library: libloading::Library,
pub functions: Functions,
}
impl SharedLibrary {
//- Constructors -----------------------------
fn new(library: libloading::Library) -> SharedLibrary {
SharedLibrary { library: library, functions: Functions::default() }
}
}
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="clippy", allow(too_many_arguments))]
$(#[cfg($cfg)])*
pub unsafe fn $name($($pname: $pty), *) $(-> $ret)* {
let f = with_library(|l| {
match l.functions.$name {
Some(f) => f,
_ => panic!(concat!("function not loaded: ", stringify!($name))),
}
}).expect("a `libclang` shared library is not loaded on this thread");
f($($pname), *)
}
$(#[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> {
#[path="../build.rs"]
mod build;
let file = try!(build::find_shared_library());
let library = libloading::Library::new(&file).map_err(|_| {
format!("the `libclang` shared library could not be opened: {}", file.display())
});
let mut library = SharedLibrary::new(try!(library));
$(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(try!(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 {
($($(#[cfg($cfg:meta)])* pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*;)+) => (
extern { $($(#[cfg($cfg)])* pub fn $name($($pname: $pty), *) $(-> $ret)*;)+ }
)
}
// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//================================================
// Macros
//================================================
// link! _________________________________________
#[cfg(feature="runtime")]
macro_rules! link {
(@LOAD: #[cfg($cfg:meta)] fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*) => (
#[cfg($cfg)]
pub fn $name(library: &mut super::SharedLibrary) {
let symbol = unsafe { library.library.get(stringify!($name).as_bytes()) }.ok();
library.functions.$name = symbol.map(|s| *s);
}
#[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)*);
);
($($(#[cfg($cfg:meta)])* pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*;)+) => (
use std::cell::{RefCell};
use std::sync::{Arc};
/// The set of functions loaded dynamically.
#[derive(Debug)]
pub struct Functions {
$($(#[cfg($cfg)])* pub $name: Option<unsafe extern fn($($pname: $pty), *) $(-> $ret)*>,)+
}
impl Default for Functions {
fn default() -> Functions {
unsafe { std::mem::zeroed() }
}
}
/// A dynamically loaded instance of the `libclang` library.
#[derive(Debug)]
pub struct SharedLibrary {
library: libloading::Library,
pub functions: Functions,
}
impl SharedLibrary {
//- Constructors -----------------------------
fn new(library: libloading::Library) -> SharedLibrary {
SharedLibrary { library: library, functions: Functions::default() }
}
}
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="clippy", allow(too_many_arguments))]
$(#[cfg($cfg)])*
pub unsafe fn $name($($pname: $pty), *) $(-> $ret)* {
let f = with_library(|l| {
match l.functions.$name {
Some(f) => f,
_ => panic!(concat!("function not loaded: ", stringify!($name))),
}
}).expect("a `libclang` shared library is not loaded on this thread");
f($($pname), *)
}
$(#[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> {
#[path="../build.rs"]
mod build;
let file = try!(build::find_shared_library());
let library = libloading::Library::new(&file).map_err(|_| {
format!("the `libclang` shared library could not be opened: {}", file.display())
});
let mut library = SharedLibrary::new(try!(library));
$(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(try!(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 {
($($(#[cfg($cfg:meta)])* pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*;)+) => (
extern { $($(#[cfg($cfg)])* pub fn $name($($pname: $pty), *) $(-> $ret)*;)+ }
)
}

View File

@ -1,189 +1,188 @@
// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Provides helper functionality.
use std::{io, env};
use std::process::{Command};
use std::path::{Path, PathBuf};
use glob;
use libc::{c_int};
use super::{CXVersion};
//================================================
// Macros
//================================================
// try_opt! ______________________________________
macro_rules! try_opt {
($option:expr) => ({
match $option {
Some(some) => some,
None => return None,
}
});
}
//================================================
// 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.
pub c_search_paths: Vec<PathBuf>,
/// The directories searched by this `clang` executable for C++ headers.
pub cpp_search_paths: Vec<PathBuf>,
}
impl Clang {
//- Constructors -----------------------------
fn new(path: PathBuf) -> Clang {
let version = parse_version(&path);
let c_search_paths = parse_search_paths(&path, "c");
let cpp_search_paths = parse_search_paths(&path, "c++");
Clang {
path: path,
version: version,
c_search_paths: c_search_paths,
cpp_search_paths: cpp_search_paths,
}
}
/// 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 OS X systems, `xcodebuild -find clang` will next be queried. Last, the
/// directories in the system's `PATH` are searched.
pub fn find(path: Option<&Path>) -> Option<Clang> {
if let Ok(path) = env::var("CLANG_PATH") {
return Some(Clang::new(path.into()));
}
let mut paths = vec![];
if let Some(path) = path {
paths.push(path.into());
}
if let Ok(path) = run_llvm_config(&["--bindir"]) {
paths.push(path.into());
}
if cfg!(target_os="macos") {
if let Ok((path, _)) = run("xcodebuild", &["-find", "clang"]) {
paths.push(path.into());
}
}
paths.extend(env::split_paths(&env::var("PATH").unwrap()));
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));
}
}
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> {
for pattern in patterns {
let pattern = directory.join(pattern).to_string_lossy().into_owned();
if let Some(path) = try_opt!(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 libc;
use std::ffi::CString;
use std::os::unix::ffi::OsStrExt;
let cpath = CString::new(path.as_os_str().as_bytes())?;
let res = unsafe { libc::access(cpath.as_ptr(), libc::X_OK) };
Ok(res == 0)
}
#[cfg(not(unix))]
fn is_executable(path: &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(|_| format!("could not run executable: `{}`", executable))
}
/// Runs `clang`, returning the `stdout` and `stderr` output.
fn run_clang(path: &Path, arguments: &[&str]) -> (String, String) {
run(&path.to_string_lossy().into_owned(), 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_digit(10)).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 = try_opt!(output.find("version ")) + 8;
let mut numbers = try_opt!(output[start..].split_whitespace().nth(0)).split('.');
let major = try_opt!(numbers.next().and_then(parse_version_number));
let minor = try_opt!(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.
fn parse_search_paths(path: &Path, language: &str) -> Vec<PathBuf> {
let output = run_clang(path, &["-E", "-x", language, "-", "-v"]).1;
let include_start = "#include <...> search starts here:";
let start = output.find(include_start).expect(include_start) + include_start.len();
let end = output.find("End of search list.").expect("End of search list");
let paths = output[start..end].replace("(framework directory)", "");
paths.lines().filter(|l| !l.is_empty()).map(|l| Path::new(l.trim()).into()).collect()
}
// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Provides helper functionality.
use std::{io, env};
use std::process::{Command};
use std::path::{Path, PathBuf};
use glob;
use libc::{c_int};
use super::{CXVersion};
//================================================
// Macros
//================================================
// try_opt! ______________________________________
macro_rules! try_opt {
($option:expr) => ({
match $option {
Some(some) => some,
None => return None,
}
});
}
//================================================
// 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 {
//- Constructors -----------------------------
fn new(path: PathBuf) -> Clang {
let version = parse_version(&path);
let c_search_paths = parse_search_paths(&path, "c");
let cpp_search_paths = parse_search_paths(&path, "c++");
Clang {
path: path,
version: version,
c_search_paths: c_search_paths,
cpp_search_paths: cpp_search_paths,
}
}
/// 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 OS X systems, `xcodebuild -find clang` will next be queried. Last, the
/// directories in the system's `PATH` are searched.
pub fn find(path: Option<&Path>) -> Option<Clang> {
if let Ok(path) = env::var("CLANG_PATH") {
return Some(Clang::new(path.into()));
}
let mut paths = vec![];
if let Some(path) = path {
paths.push(path.into());
}
if let Ok(path) = run_llvm_config(&["--bindir"]) {
paths.push(path.into());
}
if cfg!(target_os="macos") {
if let Ok((path, _)) = run("xcodebuild", &["-find", "clang"]) {
paths.push(path.into());
}
}
paths.extend(env::split_paths(&env::var("PATH").unwrap()));
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));
}
}
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> {
for pattern in patterns {
let pattern = directory.join(pattern).to_string_lossy().into_owned();
if let Some(path) = try_opt!(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 libc;
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: &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(|_| format!("could not run executable: `{}`", executable))
}
/// Runs `clang`, returning the `stdout` and `stderr` output.
fn run_clang(path: &Path, arguments: &[&str]) -> (String, String) {
run(&path.to_string_lossy().into_owned(), 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_digit(10)).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 = try_opt!(output.find("version ")) + 8;
let mut numbers = try_opt!(output[start..].split_whitespace().nth(0)).split('.');
let major = try_opt!(numbers.next().and_then(parse_version_number));
let minor = try_opt!(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) -> Option<Vec<PathBuf>> {
let output = run_clang(path, &["-E", "-x", language, "-", "-v"]).1;
let start = try_opt!(output.find("#include <...> search starts here:")) + 34;
let end = try_opt!(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())
}

View File

@ -1,6 +1,6 @@
#ifndef HEADER_H_
#define HEADER_H_
int add(int a, int b);
#endif
#ifndef HEADER_H_
#define HEADER_H_
int add(int a, int b);
#endif

View File

@ -1,46 +1,46 @@
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,
CXTranslationUnit_Flags::empty(),
);
assert!(!tu.is_null());
}
}
#[cfg(feature="runtime")]
#[test]
fn test() {
load().unwrap();
parse();
unload().unwrap();
}
#[cfg(not(feature="runtime"))]
#[test]
fn test() {
parse();
}
#[test]
fn test_support() {
let clang = support::Clang::find(None).unwrap();
println!("{:?}", clang);
}
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,
CXTranslationUnit_Flags::empty(),
);
assert!(!tu.is_null());
}
}
#[cfg(feature="runtime")]
#[test]
fn test() {
load().unwrap();
parse();
unload().unwrap();
}
#[cfg(not(feature="runtime"))]
#[test]
fn test() {
parse();
}
#[test]
fn test_support() {
let clang = support::Clang::find(None).unwrap();
println!("{:?}", clang);
}

View File

@ -61,13 +61,13 @@ dependencies = [
[[package]]
name = "bindgen"
version = "0.24.0"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -126,7 +126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clang-sys"
version = "0.16.0"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -775,7 +775,7 @@ version = "0.0.1"
dependencies = [
"app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1083,7 +1083,7 @@ dependencies = [
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
"checksum binary-space-partition 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "df65281d9b2b5c332f5bfbd9bb5e5f2e62f627c259cf9dc9cd10fecb758be33d"
"checksum bincode 1.0.0-alpha6 (registry+https://github.com/rust-lang/crates.io-index)" = "fb0cdeac1c5d567fdb487ae5853c024e4acf1ea85ba6a6552fe084e0805fea5d"
"checksum bindgen 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "21a1de90068c1e58dd31b71daab70e1a1e54212b43cc6c4714e7c8acefb28992"
"checksum bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ccaf8958532d7e570e905266ee2dc1094c3e5c3c3cfc2c299368747a30a5e654"
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
"checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
@ -1092,7 +1092,7 @@ dependencies = [
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
"checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
"checksum clang-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f4f6aa0c4cfa318cd4d2940afae57e48b94d44d3aced603501df24f3c2a414f"
"checksum clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33d47b0ea88a529a570490efbb79403e416e89864ce8a96bf23e2a0f23d7e9eb"
"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
"checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
"checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"

View File

@ -59,13 +59,13 @@ dependencies = [
[[package]]
name = "bindgen"
version = "0.24.0"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -124,7 +124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clang-sys"
version = "0.16.0"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -762,7 +762,7 @@ version = "0.0.1"
dependencies = [
"app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1070,7 +1070,7 @@ dependencies = [
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
"checksum binary-space-partition 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "df65281d9b2b5c332f5bfbd9bb5e5f2e62f627c259cf9dc9cd10fecb758be33d"
"checksum bincode 1.0.0-alpha6 (registry+https://github.com/rust-lang/crates.io-index)" = "fb0cdeac1c5d567fdb487ae5853c024e4acf1ea85ba6a6552fe084e0805fea5d"
"checksum bindgen 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "21a1de90068c1e58dd31b71daab70e1a1e54212b43cc6c4714e7c8acefb28992"
"checksum bindgen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ccaf8958532d7e570e905266ee2dc1094c3e5c3c3cfc2c299368747a30a5e654"
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
"checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
@ -1079,7 +1079,7 @@ dependencies = [
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
"checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
"checksum clang-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f4f6aa0c4cfa318cd4d2940afae57e48b94d44d3aced603501df24f3c2a414f"
"checksum clang-sys 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33d47b0ea88a529a570490efbb79403e416e89864ce8a96bf23e2a0f23d7e9eb"
"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
"checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
"checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"