• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::env;
6 use std::path::Path;
7 use std::path::PathBuf;
8 use std::process::Command;
9 
10 use anyhow::bail;
11 use anyhow::Result;
12 
13 /// Returns the target triplet prefix for gcc commands. No prefix is required
14 /// for native builds.
get_cross_compile_prefix() -> String15 fn get_cross_compile_prefix() -> String {
16     let target = env::var("TARGET").unwrap();
17 
18     if env::var("HOST").unwrap() == target {
19         return String::from("");
20     }
21 
22     let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
23     let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
24     let env = if target.ends_with("-gnueabihf") {
25         String::from("gnueabihf")
26     } else {
27         env::var("CARGO_CFG_TARGET_ENV").unwrap()
28     };
29     format!("{}-{}-{}-", arch, os, env)
30 }
31 
build_libtpm2(out_dir: &Path) -> Result<()>32 fn build_libtpm2(out_dir: &Path) -> Result<()> {
33     let lib_path = out_dir.join("libtpm2.a");
34     if lib_path.exists() {
35         return Ok(());
36     }
37 
38     if !Path::new("libtpm2/.git").exists() {
39         bail!(
40             "tpm2-sys/libtpm2 source does not exist, did you forget to \
41             `git submodule update --init`?"
42         );
43     }
44 
45     let make_flags = env::var("CARGO_MAKEFLAGS").unwrap();
46     let prefix = get_cross_compile_prefix();
47     let status = Command::new("make")
48         .env("MAKEFLAGS", make_flags)
49         .arg(format!("AR={}ar", prefix))
50         .arg(format!("CC={}gcc", prefix))
51         .arg(format!("OBJCOPY={}objcopy", prefix))
52         .arg("CFLAGS=-Wno-error")
53         .arg(format!("obj={}", out_dir.display()))
54         .current_dir("libtpm2")
55         .status()?;
56     if !status.success() {
57         bail!("make failed with status: {}", status);
58     }
59     Ok(())
60 }
61 
main() -> Result<()>62 fn main() -> Result<()> {
63     // Skip installing dependencies when generating documents.
64     if std::env::var("CARGO_DOC").is_ok() {
65         return Ok(());
66     }
67 
68     // libtpm2 is unix only
69     if std::env::var("CARGO_CFG_UNIX").is_err() {
70         return Ok(());
71     }
72 
73     // Use tpm2 package from the standard system location if available.
74     if pkg_config::Config::new()
75         .statik(true)
76         .probe("libtpm2")
77         .is_ok()
78     {
79         return Ok(());
80     }
81 
82     // Otherwise build from source
83     let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
84     build_libtpm2(&out_dir)?;
85 
86     println!("cargo:rustc-link-search={}", out_dir.display());
87     println!("cargo:rustc-link-lib=static=tpm2");
88     println!("cargo:rustc-link-lib=ssl");
89     println!("cargo:rustc-link-lib=crypto");
90     Ok(())
91 }
92