Skip to content

Commit b37465d

Browse files
abreadTheJokr
authored andcommitted
Fix rerun directive issuance for build inputs
561158b changed build.rs to use CargoCallbacks with the option to issue the rerun directive for all input headers. This caused unconditional rebuilds of foundations because one of the input headers is generated in build.rs. While 9479fad prevents unconditional rebuilds, it also prevents the rerun directive from being issued for any input header, which can be annoying during development. This change fine tunes rerun directive issuance, allowing it to be issued for input headers but excluding all generated files (which we assume are all files under `out_dir`). We also now issue the rerun directive for the `seccomp.h` header template.
1 parent 4c53c67 commit b37465d

File tree

1 file changed

+44
-4
lines changed

1 file changed

+44
-4
lines changed

foundations/build.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ mod security {
122122
}
123123

124124
fn render_header(out_dir: &Path, include_dir: &Path) -> PathBuf {
125-
let rendered = fs::read_to_string(include_dir.join("seccomp.h.in"))
125+
let template = include_dir.join("seccomp.h.in");
126+
let rendered = fs::read_to_string(&template)
126127
.unwrap()
127128
.replace(
128129
"@VERSION_MAJOR@",
@@ -141,6 +142,10 @@ mod security {
141142

142143
fs::write(&header_file, rendered).unwrap();
143144

145+
// We don't emit cargo:rerun-if-changed for the generated header to avoid unconditionally
146+
// recompiling foundations, but we should emit it for the template its generated from.
147+
println!("cargo:rerun-if-changed={}", template.display());
148+
144149
header_file
145150
}
146151

@@ -175,9 +180,9 @@ mod security {
175180
.allowlist_var("PR_GET_SECCOMP")
176181
.allowlist_var("PR_SET_NAME")
177182
.derive_default(true)
178-
.parse_callbacks(Box::new(
179-
bindgen::CargoCallbacks::new().rerun_on_header_files(false),
180-
))
183+
.parse_callbacks(Box::new(CargoCallbacksIgnoreGenHeaders::new(
184+
out_dir.to_owned(),
185+
)))
181186
.generate()
182187
.unwrap()
183188
.write_to_file(out_dir.join("security_sys.rs"))
@@ -196,4 +201,39 @@ mod security {
196201
.try_compile("check_have_linux_seccomp_h")
197202
.is_ok()
198203
}
204+
205+
/// Customized version of bindgen::CargoCallbacks that ignores files under out_dir.
206+
///
207+
/// We cannot emit cargo:rerun-if-changed for generated files because it leads to
208+
/// unconditional recompilation. This assumes all files under out_dir are generated.
209+
#[derive(Debug)]
210+
struct CargoCallbacksIgnoreGenHeaders {
211+
out_dir: PathBuf,
212+
}
213+
214+
impl CargoCallbacksIgnoreGenHeaders {
215+
fn new(out_dir: PathBuf) -> Self {
216+
Self { out_dir }
217+
}
218+
219+
fn is_generated_file(&self, filename: &str) -> bool {
220+
Path::new(filename).starts_with(&self.out_dir)
221+
}
222+
}
223+
224+
impl bindgen::callbacks::ParseCallbacks for CargoCallbacksIgnoreGenHeaders {
225+
fn header_file(&self, filename: &str) {
226+
self.include_file(filename);
227+
}
228+
229+
fn include_file(&self, filename: &str) {
230+
if !self.is_generated_file(filename) {
231+
println!("cargo:rerun-if-changed={filename}");
232+
}
233+
}
234+
235+
fn read_env_var(&self, key: &str) {
236+
println!("cargo:rerun-if-env-changed={key}");
237+
}
238+
}
199239
}

0 commit comments

Comments
 (0)