shadow_build_common/
lib.rs
1#![deny(unsafe_op_in_unsafe_fn)]
3
4use std::path::Path;
5
6pub struct ShadowBuildCommon {
7 deps: Option<system_deps::Dependencies>,
8 build_src_root: Box<Path>,
9 src_root: Box<Path>,
10}
11
12impl ShadowBuildCommon {
13 pub fn new(repo_root: &Path, system_deps: Option<system_deps::Dependencies>) -> Self {
14 let src_root = {
15 let mut p = repo_root.to_path_buf();
16 p.push("src");
17 p.into_boxed_path()
18 };
19
20 let build_src_root = {
21 let mut p = repo_root.to_path_buf();
22 p.push("build");
23 p.push("src");
24 p.into_boxed_path()
25 };
26
27 println!("cargo:rerun-if-changed=.");
30
31 Self {
32 deps: system_deps,
33 build_src_root,
34 src_root,
35 }
36 }
37
38 pub fn cc_build(&self) -> cc::Build {
39 let mut b = cc::Build::new();
40 println!("cargo:rerun-if-env-changed=CC");
41 println!("cargo:rerun-if-env-changed=CXX");
42 println!("cargo:rerun-if-env-changed=CFLAGS");
43 println!("cargo:rerun-if-env-changed=CXXFLAGS");
44
45 b.define("_GNU_SOURCE", None)
49 .include(&*self.build_src_root)
50 .include(&*self.src_root)
51 .warnings(false)
54 .warnings_into_errors(false);
58
59 if let Some(deps) = &self.deps {
60 b.includes(deps.all_include_paths());
61 }
62
63 if let Some("true") = std::env::var("DEBUG").ok().as_deref() {
64 b.flag("-DDEBUG")
65 .flag("-Wunused-function");
69 } else {
70 b.flag("-DNDEBUG");
71 }
72
73 b
74 }
75
76 #[cfg(feature = "bindgen")]
77 pub fn bindgen_builder(&self) -> bindgen::Builder {
78 let mut builder = bindgen::Builder::default()
79 .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
82 .clang_args(&[
83 &format!("-I{}", self.build_src_root.to_str().unwrap()),
84 &format!("-I{}", self.src_root.to_str().unwrap()),
85 "-D_GNU_SOURCE",
86 ])
87 .enable_function_attribute_detection();
89
90 if let Some(deps) = &self.deps {
91 for path in deps.all_include_paths() {
92 builder = builder.clang_args(&[format!("-I{}", path.to_str().unwrap())]);
93 }
94 }
95 builder
96 }
97
98 #[cfg(feature = "cbindgen")]
99 pub fn cbindgen_base_config(&self) -> cbindgen::Config {
100 let header = "
101/*
102 * The Shadow Simulator
103 * See LICENSE for licensing information
104 */
105// clang-format off";
106
107 cbindgen::Config {
108 language: cbindgen::Language::C,
109 line_length: 100,
110 documentation_style: cbindgen::DocumentationStyle::C99,
111 macro_expansion: cbindgen::MacroExpansionConfig {
112 bitflags: true,
113 },
114 header: Some(header.into()),
115 autogen_warning: Some(
116 "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
117 .into(),
118 ),
119 enumeration: cbindgen::EnumConfig {
120 prefix_with_name: true,
121 rename_variants: cbindgen::RenameRule::ScreamingSnakeCase,
122 ..cbindgen::EnumConfig::default()
123 },
124 function: cbindgen::FunctionConfig {
125 must_use: Some("__attribute__((warn_unused_result))".into()),
126 no_return: Some("__attribute__((noreturn))".into()),
127 ..cbindgen::FunctionConfig::default()
128 },
129 export: cbindgen::ExportConfig {
130 rename: std::collections::HashMap::from([
131 ("timeval".into(), "struct timeval".into()),
132 ("timespec".into(), "struct timespec".into()),
133 ]),
134 item_types: vec![
136 cbindgen::ItemType::Enums,
137 cbindgen::ItemType::Constants,
138 cbindgen::ItemType::Globals,
139 cbindgen::ItemType::Structs,
140 cbindgen::ItemType::Unions,
141 cbindgen::ItemType::Typedefs,
142 cbindgen::ItemType::OpaqueItems,
143 cbindgen::ItemType::Functions,
144 ],
145 ..cbindgen::ExportConfig::default()
146 },
147 ..Default::default()
148 }
149 }
150}
151
152#[cfg(feature = "cbindgen")]
153pub trait CBindgenExt {
154 fn get_mut(&mut self) -> &mut cbindgen::Config;
155
156 fn add_opaque_types(&mut self, types: &[&str]) {
162 let c = self.get_mut();
163 if types.is_empty() {
164 return;
165 }
166 if c.after_includes.is_none() {
167 c.after_includes.replace("".into());
168 }
169 for t in types {
170 c.after_includes
171 .as_mut()
172 .unwrap()
173 .push_str(&format!("typedef struct {t} {t};\n"));
174 c.export.exclude.push((*t).into());
175 }
176 }
177}
178
179#[cfg(feature = "cbindgen")]
180impl CBindgenExt for cbindgen::Config {
181 fn get_mut(&mut self) -> &mut cbindgen::Config {
182 self
183 }
184}