in tensorflow-sys/build.rs [297:412]
fn build_from_src() {
let dll_suffix = dll_suffix();
let framework_target = FRAMEWORK_TARGET.to_string() + dll_suffix;
let target = TARGET.to_string() + dll_suffix;
let output = PathBuf::from(&get!("OUT_DIR"));
log_var!(output);
let source = PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join(format!("target/source-{}", TAG));
log_var!(source);
let lib_dir = output.join(format!("lib-{}", TAG));
log_var!(lib_dir);
if lib_dir.exists() {
log!("Directory {:?} already exists", lib_dir);
} else {
log!("Creating directory {:?}", lib_dir);
fs::create_dir(lib_dir.clone()).unwrap();
}
let framework_unversioned_library_path = lib_dir.join(format!("lib{}.so", FRAMEWORK_LIBRARY));
let framework_library_path = lib_dir.join(format!("lib{}.so.2", FRAMEWORK_LIBRARY));
log_var!(framework_library_path);
let unversioned_library_path = lib_dir.join(format!("lib{}.so", LIBRARY));
let library_path = lib_dir.join(format!("lib{}.so.2", LIBRARY));
log_var!(library_path);
if library_path.exists() && framework_library_path.exists() {
log!(
"{:?} and {:?} already exist, not building",
library_path,
framework_library_path
);
} else {
if let Err(e) = check_bazel() {
println!(
"cargo:error=Bazel must be installed at version {} or greater. (Error: {})",
MIN_BAZEL, e
);
process::exit(1);
}
let framework_target_path = &format!("{}.2", framework_target.replace(":", "/"));
log_var!(framework_target_path);
let target_path = &format!("{}.so", TARGET.replace(":", "/"));
log_var!(target_path);
if !Path::new(&source.join(".git")).exists() {
run("git", |command| {
command
.arg("clone")
.arg(format!("--branch={}", TAG))
.arg("--recursive")
.arg(REPOSITORY)
.arg(&source)
});
}
// Only configure if not previously configured. Configuring runs a
// `bazel clean`, which we don't want, because we want to be able to
// continue from a cancelled build.
let configure_hint_file_pb = source.join(".rust-configured");
let configure_hint_file = Path::new(&configure_hint_file_pb);
if !configure_hint_file.exists() {
run("bash", |command| {
command
.current_dir(&source)
.env(
"TF_NEED_CUDA",
if cfg!(feature = "tensorflow_gpu") {
"1"
} else {
"0"
},
)
.arg("-c")
.arg("yes ''|./configure")
});
File::create(configure_hint_file).unwrap();
}
// Allows us to pass in --incompatible_load_argument_is_label=false
// to work around https://github.com/tensorflow/tensorflow/issues/15492
let bazel_args_string = if let Ok(args) = env::var("TF_RUST_BAZEL_OPTS") {
args
} else {
"".to_string()
};
run("bazel", |command| {
command
.current_dir(&source)
.arg("build")
.arg(format!("--jobs={}", get!("NUM_JOBS")))
.arg("--compilation_mode=opt")
.arg("--copt=-march=native")
.args(bazel_args_string.split_whitespace())
.arg(&target)
});
let framework_target_bazel_bin = source.join("bazel-bin").join(framework_target_path);
log!(
"Copying {:?} to {:?}",
framework_target_bazel_bin,
framework_library_path
);
if framework_library_path.exists() {
fs::remove_file(&framework_library_path).unwrap();
}
fs::copy(framework_target_bazel_bin, &framework_library_path).unwrap();
let target_bazel_bin = source.join("bazel-bin").join(target_path);
log!("Copying {:?} to {:?}", target_bazel_bin, library_path);
if library_path.exists() {
fs::remove_file(&library_path).unwrap();
}
fs::copy(target_bazel_bin, &library_path).unwrap();
}
symlink(
framework_library_path.file_name().unwrap(),
framework_unversioned_library_path,
);
symlink(library_path.file_name().unwrap(), unversioned_library_path);
println!("cargo:rustc-link-lib=dylib={}", FRAMEWORK_LIBRARY);
println!("cargo:rustc-link-lib=dylib={}", LIBRARY);
println!("cargo:rustc-link-search={}", lib_dir.display());
}