Skip to content

Commit

Permalink
Revert "Improve version detection and selection"
Browse files Browse the repository at this point in the history
This reverts commit 63e64a7.
  • Loading branch information
KyleMayes committed Feb 17, 2019
1 parent b33e2cf commit 6ca7d06
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 62 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Removed
- Removed `assert-minimum` feature
- Removed version detection for libraries without versions embedded in the filename

## [0.27.0] - 2019-01-10

Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,3 @@ libloading = { version = "0.5.0", optional = true }
[build-dependencies]

glob = "0.2.11"
libloading = "0.5.0"
38 changes: 14 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,34 +55,24 @@ These libraries can be either be installed as a part of Clang or downloaded
library. This means you cannot link to any of these versions of `libclang` statically unless you
build it from source.

### Dynamic

#### Versions

This crate supports finding instances of the `libclang` shared library that have versions embedded
in the filename when attempting to link to `libclang` dynamically. The following filename patterns
are included in the search:

* Linux distributions:<br>
`libclang-*.so` (e.g., `libclang-4.0.so`)
* BSD distributions:<br>
`libclang.so.*` (e.g., `libclang.so.4.0`)
* Linux distributions with the `runtime` feature enabled:<br>
`libclang.so.*` (e.g., `libclang.so.1`)
### Versioned Dependencies

#### Selection
This crate supports finding versioned instances of `libclang.so` (e.g.,`libclang-3.9.so`).
In the case where there are multiple instances to choose from, this crate will prefer instances with
higher versions. For example, the following instances of `libclang.so` are listed in descending
order of preference:

In the case where there are multiple instances of `libclang.so` to choose from, this crate will
prefer the instance with the highest version. The version of an instance of `libclang.so` is
determined by loading the instance and inspecting it.
1. `libclang-4.0.so`
2. `libclang-4.so`
3. `libclang-3.9.so`
4. `libclang-3.so`
5. `libclang.so`

For example, the following list displays a list of candidate instances listed in descending order of
preference.
**Note:** On BSD distributions, versioned instances of `libclang.so` matching the pattern
`libclang.so.*` (e.g., `libclang.so.7.0`) are also included.

1. `libclang.so.1` (version determined as 6.0)
2. `libclang.so` (version determined as 5.0)
3. `libclang-3.9.so` (version determined as 3.9)
4. `libclang-3.so` (version determined as 3.8)
**Note:** On Linux distributions when the `runtime` features is enabled, versioned instances of
`libclang.so` matching the pattern `libclang.so.*` (e.g., `libclang.so.1`) are also included.

## Environment Variables

Expand Down
52 changes: 15 additions & 37 deletions build/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate libloading;

use std::env;
use std::fs::{File};
use std::io::{Read, Seek, SeekFrom};
use std::path::{Path, PathBuf};

use self::libloading::{Library};

use super::common;

/// Returns the ELF class from the ELF header in the supplied file.
Expand Down Expand Up @@ -87,38 +83,17 @@ fn validate_header(path: &Path) -> Result<(), String> {
}
}

/// Determines the version of the supplied `libclang` shared library by loading functions only
/// available on certain versions.
fn determine_version(path: &Path) -> Result<Vec<u32>, String> {
let library = Library::new(&path).map_err(|e| {
format!(
"the `libclang` shared library at {} could not be opened: {}",
path.display(),
e,
)
})?;

macro_rules! test {
($fn:expr, $version:expr) => {
if library.get::<unsafe extern fn()>($fn).is_ok() {
return Ok($version);
}
};
}

unsafe {
test!(b"clang_File_tryGetRealPathName", vec![7, 0]);
test!(b"clang_CXIndex_setInvocationEmissionPathOption", vec![6, 0]);
test!(b"clang_Cursor_isExternalSymbol", vec![5, 0]);
test!(b"clang_EvalResult_getAsLongLong", vec![4, 0]);
test!(b"clang_CXXConstructor_isConvertingConstructor", vec![3, 9]);
test!(b"clang_CXXField_isMutable", vec![3, 8]);
test!(b"clang_Cursor_getOffsetOfField", vec![3, 7]);
test!(b"clang_Cursor_getStorageClass", vec![3, 6]);
test!(b"clang_Type_getNumTemplateArguments", vec![3, 5]);
}
/// Returns the components of the version in the supplied `libclang` shared library filename.
fn parse_version(filename: &str) -> Vec<u32> {
let version = if filename.starts_with("libclang.so.") {
&filename[12..]
} else if filename.starts_with("libclang-") {
&filename[9..filename.len() - 3]
} else {
return vec![];
};

Ok(vec![])
version.split('.').map(|s| s.parse().unwrap_or(0)).collect()
}

/// Returns the paths to, the filenames, and the versions of the `libclang` shared libraries.
Expand Down Expand Up @@ -156,8 +131,11 @@ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Ve
let mut invalid = vec![];
for (directory, filename) in common::search_libclang_directories(&files, "LIBCLANG_PATH") {
let path = directory.join(&filename);
match validate_header(&path).and_then(|_| determine_version(&path)) {
Ok(version) => valid.push((directory, filename, version)),
match validate_header(&path) {
Ok(()) => {
let version = parse_version(&filename);
valid.push((directory, filename, version))
},
Err(message) => invalid.push(format!("({}: {})", path.display(), message)),
}
}
Expand Down

0 comments on commit 6ca7d06

Please sign in to comment.