-
Notifications
You must be signed in to change notification settings - Fork 12
Complete bindings with Bindgen #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
language: rust | ||
rust: | ||
- stable | ||
- beta | ||
- nightly | ||
matrix: | ||
allow_failures: | ||
- rust: nightly |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,14 @@ | ||
# capstone-sys | ||
libcapstone3 system bindings for Rust | ||
|
||
Low-level, unsafe Rust bindings for the `capstone` disassembly library. | ||
|
||
|
||
## Features | ||
|
||
`capstone-sys` will build differently based on [features](http://doc.crates.io/manifest.html#the-features-section) that are specified in `Cargo.toml`. | ||
|
||
`capstone-sys` supports the following features: | ||
|
||
* `use_system_capstone`: use the system capstone instead of the bundled copy of the `capstone` library. | ||
* `build_capstone_cmake`: if using the bundled `capstone` library, then build `capstone` using `cmake`. | ||
* `use_bundled_capstone_bindings`: instead of using [`bindgen`](https://github.com/rust-lang-nursery/rust-bindgen), use the pre-generated capstone bindings (if available for the current platform). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,204 @@ | ||
//! The following environment variables affect the build: | ||
//! | ||
//! * `UPDATE_CAPSTONE_BINDINGS`: setting indicates that the pre-generated `capstone.rs` should be | ||
//! updated with the output bindgen | ||
//! * `CAPSTONE_BUILD_DEBUG`: write debug output to file | ||
|
||
extern crate bindgen; | ||
extern crate gcc; | ||
extern crate pkg_config; | ||
#[cfg(feature="build_src_cmake")] | ||
|
||
#[cfg(feature = "build_src_cmake")] | ||
extern crate cmake; | ||
|
||
use std::path::{Path}; | ||
#[macro_use] | ||
extern crate lazy_static; | ||
|
||
use std::fs::{File, copy}; | ||
use std::path::PathBuf; | ||
use std::process::Command; | ||
use std::env; | ||
use std::io::Write; | ||
use std::sync::Mutex; | ||
|
||
include!("common.rs"); | ||
|
||
/// Indicates how capstone library should be linked | ||
enum LinkType { | ||
Dynamic, | ||
Static, | ||
} | ||
|
||
static DEBUG_FILE_ENV_VAR: &'static str = "CAPSTONE_BUILD_DEBUG"; | ||
|
||
// Open/truncate debug file once at the beginning of execution | ||
lazy_static! { | ||
static ref BUILD_DEBUG_LOG_FILE: Mutex<Option<File>> = Mutex::new( | ||
match env::var(DEBUG_FILE_ENV_VAR) { | ||
Err(_) => None, | ||
Ok(filename) => { | ||
let file = File::create(&filename) | ||
.expect(&format!("Could not open debug log \"{}\"", filename)); | ||
Some(file) | ||
} | ||
} | ||
); | ||
} | ||
|
||
/// Log to debug file | ||
macro_rules! debug_println( | ||
($($arg:tt)*) => { { | ||
if let Some(ref mut file) = *BUILD_DEBUG_LOG_FILE.lock().unwrap() { | ||
writeln!(file, $($arg)*) | ||
.expect("failed printing to stderr"); | ||
} | ||
} } | ||
); | ||
|
||
#[cfg(feature = "build_src_cmake")] | ||
fn cmake() { | ||
debug_println!("Building capstone with cmake"); | ||
let mut cfg = cmake::Config::new("capstone"); | ||
let dst = cfg.build(); | ||
println!("cargo:rustc-link-search=native={}/lib", dst.display()); | ||
} | ||
|
||
/// Search for header in search paths | ||
fn find_capstone_header(header_search_paths: &Vec<PathBuf>, name: &str) -> Option<PathBuf> { | ||
for search_path in header_search_paths.iter() { | ||
let potential_file = search_path.join(name); | ||
if potential_file.is_file() { | ||
return Some(potential_file); | ||
} | ||
} | ||
None | ||
} | ||
|
||
/// Create bindings using bindgen | ||
fn write_bindgen_bindings(header_search_paths: &Vec<PathBuf>, update_pregenerated_bindings: bool) { | ||
debug_println!( | ||
"Writing bindgen bindings with search paths {:?}", | ||
header_search_paths | ||
); | ||
|
||
|
||
let mut builder = bindgen::Builder::default() | ||
.unstable_rust(false) | ||
.header( | ||
find_capstone_header(header_search_paths, "capstone.h") | ||
.expect("Could not find header") | ||
.to_str() | ||
.unwrap(), | ||
) | ||
.disable_name_namespacing() | ||
.prepend_enum_name(false) | ||
.generate_comments(true) | ||
.constified_enum_module("[^_]+_reg$"); // Some registers have aliases | ||
|
||
|
||
// Whitelist cs_.* functions and types | ||
let pattern = String::from("cs_.*"); | ||
builder = builder | ||
.whitelisted_function(pattern.clone()) | ||
.whitelisted_type(pattern.clone()); | ||
|
||
// Whitelist types with architectures | ||
for arch in ARCH_INCLUDES { | ||
let pattern = format!(".*(^|_){}(_|$).*", arch.cs_name); | ||
builder = builder.whitelisted_type(pattern); | ||
} | ||
|
||
let bindings = builder.generate().expect("Unable to generate bindings"); | ||
|
||
// Write bindings to $OUT_DIR/bindings.rs | ||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join(BINDINGS_FILE); | ||
bindings.write_to_file(out_path.clone()).expect( | ||
"Unable to write bindings", | ||
); | ||
|
||
if update_pregenerated_bindings { | ||
debug_println!("Updating pre-generated capstone bindings"); | ||
let stored_bindgen_header: PathBuf = | ||
[ | ||
env::var("CARGO_MANIFEST_DIR").expect("Could not find cargo environment variable"), | ||
"pre_generated".into(), | ||
BINDINGS_FILE.into(), | ||
].iter() | ||
.collect(); | ||
debug_println!( | ||
"Updating capstone bindings at \"{}\"", | ||
stored_bindgen_header.to_str().unwrap() | ||
); | ||
copy(out_path, stored_bindgen_header).expect("Unable to update capstone bindings"); | ||
} | ||
} | ||
|
||
fn main() { | ||
if !cfg!(feature = "build_src") && pkg_config::find_library("capstone").is_ok() { | ||
let link_type: Option<LinkType>; | ||
|
||
// C header search paths | ||
let mut header_search_paths: Vec<PathBuf> = Vec::new(); | ||
|
||
if cfg!(feature = "use_system_capstone") { | ||
debug_println!("Using system capstone library"); | ||
|
||
assert!( | ||
!cfg!(feature = "build_capstone_cmake"), | ||
"build_capstone_cmake feature is only valid when using bundled cmake" | ||
); | ||
|
||
let capstone_lib = | ||
pkg_config::find_library("capstone").expect("Could not find system capstone"); | ||
header_search_paths.append(&mut capstone_lib.include_paths.clone()); | ||
link_type = Some(LinkType::Dynamic); | ||
} else { | ||
if !Path::new("capstone/.git").exists() { | ||
let _ = Command::new("git").args(&["submodule", "update", "--init", "--depth", "5"]) | ||
.status(); | ||
} | ||
if cfg!(feature = "build_src_cmake") { | ||
debug_println!("Using bundled capstone library"); | ||
|
||
if cfg!(feature = "build_capstone_cmake") { | ||
#[cfg(feature = "build_src_cmake")] | ||
cmake(); | ||
} else { | ||
//let target = env::var("TARGET").unwrap(); | ||
//let windows = target.contains("windows"); | ||
// TODO: need to add this argument for windows 64-bit, msvc, dunno, read the COMPILE_MSVC.txt | ||
// file cygwin-mingw64 | ||
// TODO: need to add this argument for windows 64-bit, msvc, dunno, read | ||
// COMPILE_MSVC.txt file cygwin-mingw64 | ||
let out_dir = env::var("OUT_DIR").unwrap(); | ||
let _ = Command::new("./make.sh").current_dir("capstone").status(); | ||
let _ = Command::new("./make.sh") | ||
.current_dir("capstone") | ||
.status(); | ||
let capstone = "libcapstone.a"; | ||
let _ = Command::new("cp").current_dir("capstone").arg(&capstone).arg(&out_dir).status(); | ||
let _ = Command::new("cp") | ||
.current_dir("capstone") | ||
.arg(&capstone) | ||
.arg(&out_dir) | ||
.status(); | ||
println!("cargo:rustc-link-search=native={}", out_dir); | ||
} | ||
header_search_paths.push(PathBuf::from("capstone/include")); | ||
link_type = Some(LinkType::Static); | ||
} | ||
println!("cargo:rustc-link-lib=static=capstone"); | ||
|
||
match link_type.expect("Must specify link type") { | ||
LinkType::Dynamic => { | ||
println!("cargo:rustc-link-lib=dylib=capstone"); | ||
} | ||
LinkType::Static => { | ||
println!("cargo:rustc-link-lib=static=capstone"); | ||
} | ||
} | ||
|
||
// If UPDATE_CAPSTONE_BINDINGS is set, then updated the pre-generated capstone bindings | ||
let update_pregenerated_bindings = env::var("UPDATE_CAPSTONE_BINDINGS").is_ok(); | ||
if update_pregenerated_bindings { | ||
assert!( | ||
!cfg!(feature = "use_bundled_capstone_bindings"), | ||
concat!( | ||
"Setting UPDATE_CAPSTONE_BINDINGS only makes ", | ||
"sense when NOT enabling feature use_bundled_capstone_bindings" | ||
) | ||
); | ||
} | ||
|
||
debug_println!("Creating capstone bindings with bindgen"); | ||
write_bindgen_bindings(&header_search_paths, update_pregenerated_bindings); | ||
} |
Submodule capstone
deleted from
8308ac
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
version: 3.0.4-{build} | ||
|
||
os: | ||
- Visual Studio 2015 | ||
|
||
before_build: | ||
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 | ||
|
||
build_script: | ||
- mkdir build | ||
- cd build | ||
- cmake -DCMAKE_BUILD_TYPE=RELEASE -G "NMake Makefiles" .. | ||
- nmake | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Object files | ||
*.o | ||
*.ko | ||
|
||
# Gcc dependency-tracking files | ||
*.d | ||
|
||
# Libraries | ||
*.lib | ||
*.a | ||
|
||
# Shared objects (inc. Windows DLLs) | ||
*.dll | ||
*.so | ||
*.so.* | ||
*.dylib | ||
|
||
# Executables | ||
*.exe | ||
*.out | ||
*.app | ||
|
||
# python | ||
bindings/python/build/ | ||
bindings/python/capstone.egg-info/ | ||
*.pyc | ||
|
||
# java | ||
bindings/java/capstone.jar | ||
|
||
# ocaml | ||
bindings/ocaml/*.cmi | ||
bindings/ocaml/*.cmx | ||
bindings/ocaml/*.cmxa | ||
bindings/ocaml/*.mli | ||
bindings/ocaml/test | ||
bindings/ocaml/test_arm | ||
bindings/ocaml/test_arm64 | ||
bindings/ocaml/test_mips | ||
bindings/ocaml/test_x86 | ||
bindings/ocaml/test_detail | ||
bindings/ocaml/test_ppc | ||
bindings/ocaml/test_sparc | ||
bindings/ocaml/test_systemz | ||
bindings/ocaml/test_xcore | ||
|
||
|
||
# test binaries | ||
tests/test | ||
tests/test_detail | ||
tests/test_iter | ||
tests/test_arm | ||
tests/test_arm64 | ||
tests/test_mips | ||
tests/test_x86 | ||
tests/test_ppc | ||
tests/test_skipdata | ||
tests/test_sparc | ||
tests/test_systemz | ||
tests/test_xcore | ||
tests/*.static | ||
tests/test_basic | ||
tests/test_customized_mnem | ||
|
||
|
||
# regress binaries | ||
suite/regress/invalid_read_in_print_operand | ||
|
||
|
||
# vim tmp file | ||
*.swp | ||
*~ | ||
|
||
capstone.pc | ||
|
||
# local files | ||
_* | ||
|
||
# freebsd ports: generated file with "make makesum" command | ||
packages/freebsd/ports/devel/capstone/distinfo | ||
|
||
# VisualStudio | ||
ProjectUpgradeLog.log | ||
Debug/ | ||
Release/ | ||
ipch/ | ||
*.sdf | ||
*.opensdf | ||
*.suo | ||
*.user | ||
*.backup | ||
*.VC.db | ||
*.VC.opendb | ||
|
||
# CMake build directories | ||
build*/ | ||
|
||
# Xcode | ||
xcode/Capstone.xcodeproj/xcuserdata | ||
xcode/Capstone.xcodeproj/project.xcworkspace/xcuserdata | ||
|
||
# suite/ | ||
test_arm_regression | ||
test_arm_regression.o | ||
fuzz_harness | ||
test_iter_benchmark | ||
|
||
|
||
*.s | ||
.DS_Store | ||
|
||
cstool/cstool |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be optional with undeleted bindings; just need to add a feature flag on the bindings and reexport iiuc