1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
extern crate bindgen;
use std::env;
use std::fs;
use std::path::PathBuf;
use bindgen::CargoCallbacks;
fn main() {
/*
idea: let the build script figure out, from where it is invoked
*/
println!("enter BUILD-SCRIPT");
let dir = env::current_dir().unwrap();
println!( "DIR: {:?}" ,dir );
// let mut prj_dir = env::var("PROJECT_DIR").or( Ok( String::from(dir.to_str().unwrap()) ) );
/* let path_to_lib: PathBuf = match env::var("PROJECT_DIR") {
Ok(p) =>{
PathBuf::from(p).join("/rust/src")
},
Err(e)=>{
dir.join("/src")
}
};
*/
let mut out_dir = env::var("OUT_DIR").unwrap();
let out = env::var("OUTER_OUT_DIR");
match out
{
Ok(o)=>{
// CargoBuild
println!("cargo-build: {}", o);
// out_dir = o;
},
Err(e)=>{
// CMakeBuild
println!("cmake-build");
}
}
match std::process::Command::new("mkdir").arg("tmp").output() {
Ok(o) => {
print!("mkdir output: {:?}\n", o);
}
Err(e) => {
panic!("mkdir failed: {}", e);
}
}
// This is the directory where the `c` library is located.
let libdir_path = PathBuf::from("./tmp")
// Canonicalize the path as `rustc-link-search` requires an absolute
// path.
.canonicalize()
.expect("cannot canonicalize path");
println!("libdir_path: {}", libdir_path.display());
// This is the path to the `c` headers file.
let headers_path_str = "../include/pan/go_handle.hpp"; // headers_path.to_str().expect("Path is not a valid string");
// This is the path to the intermediate object file for our library.
let obj_path = libdir_path.join("go_handle.o");
// This is the path to the static library file.
let lib_path = libdir_path.join("libgo_handle.a");
// clang -c -o tmp/go_handle.o ../cpp/go_handle.cpp -I ../include
let res = std::process::Command::new("clang++")
.arg("-c")
.arg("-I")
.arg("../include/pan")
//.arg("-I ../include/pan/pan.h")
//.arg("-I ../include/pan/go_handle.hpp")
.arg("-o")
.arg(&obj_path)
.arg("../cpp/go_handle.cpp")
.arg("-DBINDGEN")
.output();
// if !res.expect("cannot execute clang").status.success()
match res {
Ok(o) => {
print!("output: {:?}\n", o);
}
Err(e) => {
// doesnt work for some reason :(
// you have to enter the above command manually
//panic!("could not compile object file: {}",res.err().unwrap());
panic!("could not compile object file: {}", e);
}
}
// ar rcs tmp/libgo_handle.a tmp/go_handle.o
let res1 = std::process::Command::new("ar")
.arg("rcs")
.arg(lib_path)
.arg(obj_path)
.output();
if !res1.is_ok() {
// Panic if the command was not successful.
panic!("could not emit library file: {}", res1.err().unwrap());
}
/* match fs::copy("../build/go/libpand.a","tmp/libpand.a")
{
Err( err ) => { panic!("could not copy file"); }
Ok( o) =>{}
}
*/
// println!("cargo:rustc-link-search=all={},../build/go", libdir_path.to_str().unwrap());
println!("cargo:rustc-link-search=all=tmp");
println!("cargo:rustc-link-search=all={}", &out_dir);
println!("cargo:rustc-link-search=all=../build/go");
println!("cargo:rustc-link-search=all=/lib/x86_64-linux-gnu");
// println!("cargo:rustc-link-search=../build/go");
println!("cargo:rustc-link-lib=static:+bundle=go_handle");
println!("cargo:rustc-link-lib=static:+bundle=pan");
println!("cargo:rustc-link-lib=stdc++");
//println!("cargo:rustc-link-lib=go_handle");
//println!("cargo:rustc-link-lib=pan");
// println!("cargo:rustc-flags=-l go_handle.a -l pand.a -L ../build/go -L tmp "); // -Wl,-Bstatic
// Tell cargo to invalidate the built crate whenever the header changes.
println!("cargo:rerun-if-changed={}", headers_path_str);
println!("cargo:rerun-if-changed=../build");
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.clang_arg("-DBINDGEN")
.clang_arg("-xc++")
.clang_arg("-std=c++11")
.clang_arg("-I ../include")
.clang_arg("-I ../include/pan")
.header("../include/pan/pan_cdefs.h")
.header("../include/pan/pan.h")
.header(headers_path_str)
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(CargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(out_dir).join("bindings.rs");
env::set_var("BINDINGS_PATH", &*out_path.to_string_lossy() );
bindings
.write_to_file(out_path.clone() )
.expect("Couldn't write bindings!");
// copy bindings to PROJECT_DIR/rust/src/bindings.rs where lib.rs expects them
std::fs::copy(out_path, dir.join("src/bindings.rs") )
.expect("cannot copy generated bindings to where lib.rs expects them");
}