| // Copyright 2019 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use anyhow::{bail, Result}; |
| use std::env; |
| use std::path::Path; |
| use std::path::PathBuf; |
| use std::process::Command; |
| |
| /// Returns the target triplet prefix for gcc commands. No prefix is required |
| /// for native builds. |
| fn get_cross_compile_prefix() -> String { |
| let target = env::var("TARGET").unwrap(); |
| |
| if env::var("HOST").unwrap() == target { |
| return String::from(""); |
| } |
| |
| let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); |
| let os = env::var("CARGO_CFG_TARGET_OS").unwrap(); |
| let env = if target.ends_with("-gnueabihf") { |
| String::from("gnueabihf") |
| } else { |
| env::var("CARGO_CFG_TARGET_ENV").unwrap() |
| }; |
| return format!("{}-{}-{}-", arch, os, env); |
| } |
| |
| fn build_libtpm2(out_dir: &Path) -> Result<()> { |
| let lib_path = out_dir.join("libtpm2.a"); |
| if lib_path.exists() { |
| return Ok(()); |
| } |
| |
| if !Path::new("libtpm2/.git").exists() { |
| bail!( |
| "tpm2-sys/libtpm2 source does not exist, did you forget to \ |
| `git submodule update --init`?" |
| ); |
| } |
| |
| let make_flags = env::var("CARGO_MAKEFLAGS").unwrap(); |
| let prefix = get_cross_compile_prefix(); |
| let status = Command::new("make") |
| .env("MAKEFLAGS", make_flags) |
| .arg(format!("AR={}ar", prefix)) |
| .arg(format!("CC={}gcc", prefix)) |
| .arg(format!("OBJCOPY={}objcopy", prefix)) |
| .arg(format!("obj={}", out_dir.display())) |
| .current_dir("libtpm2") |
| .status()?; |
| if !status.success() { |
| bail!("make failed with status: {}", status); |
| } |
| Ok(()) |
| } |
| |
| fn main() -> Result<()> { |
| // Use tpm2 package from the standard system location if available. |
| if pkg_config::Config::new() |
| .statik(true) |
| .probe("libtpm2") |
| .is_ok() |
| { |
| return Ok(()); |
| } |
| |
| // Otherwise build from source |
| let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| build_libtpm2(&out_dir)?; |
| |
| println!("cargo:rustc-link-search={}", out_dir.display()); |
| println!("cargo:rustc-link-lib=static=tpm2"); |
| println!("cargo:rustc-link-lib=ssl"); |
| println!("cargo:rustc-link-lib=crypto"); |
| Ok(()) |
| } |