1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 use std::process::Command;
21 
22 macro_rules! mf_dir {
23     ($p:literal) => {
24         concat!(env!("CARGO_MANIFEST_DIR"), $p)
25     };
26 }
27 
main()28 fn main() {
29     let out_dir = std::env::var("OUT_DIR").unwrap();
30 
31     let build_output = Command::new(mf_dir!("/src/build_model.py"))
32         .arg(&out_dir)
33         .env(
34             "PYTHONPATH",
35             concat!(
36                 mf_dir!("/../../python"),
37                 ":",
38                 mf_dir!("/../../nnvm/python")
39             ),
40         )
41         .output()
42         .expect("Failed to build model");
43     assert!(
44         ["model.o", "graph.json", "params.bin"]
45             .iter()
46             .all(|f| { std::path::Path::new(&format!("{}/{}", out_dir, f)).exists() }),
47         "Could not build tvm lib: STDOUT:\n\n{}\n\nSTDERR\n\n{}",
48         String::from_utf8(build_output.stdout).unwrap().trim(),
49         String::from_utf8(build_output.stderr).unwrap().trim()
50     );
51 
52     let sysroot_output = Command::new("rustc")
53         .args(&["--print", "sysroot"])
54         .output()
55         .expect("Failed to get sysroot");
56     let sysroot = String::from_utf8(sysroot_output.stdout).unwrap();
57     let sysroot = sysroot.trim();
58     let mut llvm_tools_path = std::path::PathBuf::from(&sysroot);
59     llvm_tools_path.push("lib/rustlib/x86_64-unknown-linux-gnu/bin");
60 
61     Command::new("rustup")
62         .args(&["component", "add", "llvm-tools-preview"])
63         .output()
64         .expect("failed to install llvm tools");
65 
66     std::process::Command::new(llvm_tools_path.join("llvm-objcopy"))
67         .arg("--globalize-symbol=__tvm_module_startup")
68         .arg("--remove-section=.ctors")
69         .arg(&format!("{}/model.o", out_dir))
70         .output()
71         .expect("gould not gloablize startup function");
72 
73     std::process::Command::new(llvm_tools_path.join("llvm-ar"))
74         .arg("rcs")
75         .arg(&format!("{}/libmodel.a", out_dir))
76         .arg(&format!("{}/model.o", out_dir))
77         .output()
78         .expect("failed to package model archive");
79 
80     println!("cargo:rustc-link-lib=static=model");
81     println!("cargo:rustc-link-search=native={}", out_dir);
82 }
83