magick-rust/build.rs

99 lines
4.2 KiB
Rust
Raw Normal View History

/*
* Copyright 2016 Nathan Fiedler
*
* 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.
*/
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
static HEADER: &'static str = "#include <wand/MagickWand.h>\n";
fn main() {
//
// If the MagickWand bindings are missing, generate them using
// rust-bindgen.
//
let bindings_path = Path::new("src/bindings.rs");
if !bindings_path.exists() {
let bindgen_path = Path::new("rust-bindgen");
if !bindgen_path.exists() {
Command::new("git")
.arg("clone")
.arg("https://github.com/crabtw/rust-bindgen.git")
.status().unwrap();
// Checkout a version of rust-bindgen that is known to work;
// more recent versions produce code that does not compile (the
// commit after 8a51860 changes the way enums are generated).
Command::new("git")
.arg("checkout")
.arg("8a51860")
.current_dir("rust-bindgen")
.status().unwrap();
Command::new("cargo")
.arg("build")
.current_dir("rust-bindgen")
.status().unwrap();
}
// Create the header file that rust-bindgen needs as input.
let mut gen_h = match File::create("gen.h") {
Err(why) => panic!("could not create gen.h file: {}", Error::description(&why)),
Ok(file) => file
};
match gen_h.write_all(HEADER.as_bytes()) {
Err(why) => panic!("could not write to gen.h: {}", Error::description(&why)),
Ok(_) => ()
};
// Get the compiler and linker flags for the MagickWand library.
let mw_cflags_output = Command::new("MagickWand-config")
.arg("--cflags")
.output().unwrap();
let mw_cflags = std::str::from_utf8(&mw_cflags_output.stdout).unwrap().trim();
let mw_cflags_arr: Vec<&str> = mw_cflags.split_whitespace().collect();
let mw_ldflags_output = Command::new("MagickWand-config")
.arg("--ldflags")
.output().unwrap();
let mw_ldflags = std::str::from_utf8(&mw_ldflags_output.stdout).unwrap().trim();
let mw_ldflags_arr: Vec<&str> = mw_ldflags.split_whitespace().collect();
// Combine all of that in the invocation of rust-bindgen.
Command::new("./rust-bindgen/target/debug/bindgen")
// always include this even though it only makes sense on Mac to
// work around https://github.com/crabtw/rust-bindgen/issues/89
.env("DYLD_LIBRARY_PATH", "/Library/Developer/CommandLineTools/usr/lib")
.args(&mw_cflags_arr[..])
.arg("-builtins")
.arg("-o")
.arg("src/bindings.rs")
.args(&mw_ldflags_arr[..])
.arg("gen.h")
.status().unwrap();
// how to get the output of the command...
// let output = Commad::new(...).output().unwrap();
// let out = std::str::from_utf8(&output.stdout).unwrap();
// println!("cargo:output={}", out);
// let err = std::str::from_utf8(&output.stderr).unwrap();
// println!("cargo:error={}", err);
match std::fs::remove_file("gen.h") {
Err(why) => panic!("could not remove gen.h: {}", Error::description(&why)),
Ok(_) => ()
}
}
// For the sake of easily building and testing on Mac, include the path
// to MagickWand. Chances are MagickWand is in /usr/local/lib, or
// somewhere else that rustc can find it.
println!("cargo:rustc-link-search=native=/usr/local/lib");
}