Skip to content

Commit 615302c

Browse files
committed
fix: use CFLAGS from Makefile
1 parent a129a2e commit 615302c

File tree

1 file changed

+62
-34
lines changed

1 file changed

+62
-34
lines changed

nginx-sys/build/main.rs

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ impl NginxSource {
192192
/// Generates Rust bindings for NGINX
193193
fn generate_binding(nginx: &NginxSource) {
194194
let autoconf_makefile_path = nginx.build_dir.join("Makefile");
195-
let includes: Vec<_> = parse_includes_from_makefile(&autoconf_makefile_path)
195+
let (includes, defines) = parse_makefile(&autoconf_makefile_path);
196+
let includes: Vec<_> = includes
196197
.into_iter()
197198
.map(|path| {
198199
if path.is_absolute() {
@@ -207,7 +208,7 @@ fn generate_binding(nginx: &NginxSource) {
207208
.map(|path| format!("-I{}", path.to_string_lossy()))
208209
.collect();
209210

210-
print_cargo_metadata(nginx, &includes).expect("cargo dependency metadata");
211+
print_cargo_metadata(nginx, &includes, &defines).expect("cargo dependency metadata");
211212

212213
// bindgen targets the latest known stable by default
213214
let rust_target: bindgen::RustTarget = env::var("CARGO_PKG_RUST_VERSION")
@@ -243,20 +244,27 @@ fn generate_binding(nginx: &NginxSource) {
243244
/// Reads through the makefile generated by autoconf and finds all of the includes
244245
/// used to compile nginx. This is used to generate the correct bindings for the
245246
/// nginx source code.
246-
fn parse_includes_from_makefile(nginx_autoconf_makefile_path: &PathBuf) -> Vec<PathBuf> {
247-
fn extract_include_part(line: &str) -> &str {
248-
line.strip_suffix('\\').map_or(line, |s| s.trim())
249-
}
250-
/// Extracts the include path from a line of the autoconf generated makefile.
251-
fn extract_after_i_flag(line: &str) -> Option<&str> {
252-
let mut parts = line.split("-I ");
253-
match parts.next() {
254-
Some(_) => parts.next().map(extract_include_part),
255-
None => None,
247+
pub fn parse_makefile(
248+
nginx_autoconf_makefile_path: &PathBuf,
249+
) -> (Vec<PathBuf>, Vec<(String, Option<String>)>) {
250+
fn add_includes(includes: &mut Vec<String>, line: &str) {
251+
let mut words = line.split_ascii_whitespace();
252+
while let Some(word) = words.next() {
253+
if word == "-I" {
254+
if let Some(inc) = words.next() {
255+
includes.push(inc.to_string());
256+
}
257+
} else if let Some(inc) = word.strip_prefix("-I") {
258+
includes.push(inc.to_string());
259+
}
256260
}
257261
}
258262

259263
let mut includes = vec![];
264+
let mut cflags_includes = vec![];
265+
266+
let mut defines = vec![];
267+
260268
let makefile_contents = match read_to_string(nginx_autoconf_makefile_path) {
261269
Ok(path) => path,
262270
Err(e) => {
@@ -268,35 +276,47 @@ fn parse_includes_from_makefile(nginx_autoconf_makefile_path: &PathBuf) -> Vec<P
268276
}
269277
};
270278

271-
let mut includes_lines = false;
272-
for line in makefile_contents.lines() {
273-
if !includes_lines {
274-
if let Some(stripped) = line.strip_prefix("ALL_INCS") {
275-
includes_lines = true;
276-
if let Some(part) = extract_after_i_flag(stripped) {
277-
includes.push(part);
278-
}
279-
continue;
280-
}
279+
let lines = makefile_contents.lines();
280+
let mut line: String = "".to_string();
281+
for l in lines {
282+
if let Some(part) = l.strip_suffix("\\") {
283+
line += part;
284+
continue;
281285
}
282286

283-
if includes_lines {
284-
if let Some(part) = extract_after_i_flag(line) {
285-
includes.push(part);
286-
} else {
287-
break;
287+
line += l;
288+
289+
if let Some(tail) = line.strip_prefix("ALL_INCS") {
290+
add_includes(&mut includes, tail);
291+
} else if let Some(tail) = line.strip_prefix("CFLAGS") {
292+
add_includes(&mut cflags_includes, tail);
293+
294+
let words = line.split_ascii_whitespace();
295+
for word in words {
296+
if let Some(def) = word.strip_prefix("-D") {
297+
if let Some((name, value)) = def.split_once("=") {
298+
defines.push((name.to_string(), Some(value.to_string())));
299+
} else {
300+
defines.push((def.to_string(), None));
301+
}
302+
}
288303
}
289304
}
305+
306+
line.clear();
290307
}
291308

292-
includes.into_iter().map(PathBuf::from).collect()
309+
includes.append(&mut cflags_includes);
310+
311+
(includes.into_iter().map(PathBuf::from).collect(), defines)
293312
}
294313

295314
/// Collect info about the nginx configuration and expose it to the dependents via
296315
/// `DEP_NGINX_...` variables.
297316
pub fn print_cargo_metadata<T: AsRef<Path>>(
298317
nginx: &NginxSource,
299318
includes: &[T],
319+
defines: &[(String, Option<String>)],
300320
) -> Result<(), Box<dyn StdError>> {
301321
// Unquote and merge C string constants
302322
let unquote_re = regex::Regex::new(r#""(.*?[^\\])"\s*"#).unwrap();
@@ -311,7 +331,7 @@ pub fn print_cargo_metadata<T: AsRef<Path>>(
311331
let mut ngx_features: Vec<String> = vec![];
312332
let mut ngx_os = String::new();
313333

314-
let expanded = expand_definitions(includes)?;
334+
let expanded = expand_definitions(includes, defines)?;
315335
for line in String::from_utf8(expanded)?.lines() {
316336
let Some((name, value)) = line
317337
.trim()
@@ -372,7 +392,10 @@ pub fn print_cargo_metadata<T: AsRef<Path>>(
372392
Ok(())
373393
}
374394

375-
fn expand_definitions<T: AsRef<Path>>(includes: &[T]) -> Result<Vec<u8>, Box<dyn StdError>> {
395+
fn expand_definitions<T: AsRef<Path>>(
396+
includes: &[T],
397+
defines: &[(String, Option<String>)],
398+
) -> Result<Vec<u8>, Box<dyn StdError>> {
376399
let path = PathBuf::from(env::var("OUT_DIR")?).join("expand.c");
377400
let mut writer = std::io::BufWriter::new(File::create(&path)?);
378401

@@ -418,8 +441,13 @@ RUST_CONF_{flag}=NGX_{flag}
418441
writer.flush()?;
419442
drop(writer);
420443

421-
Ok(cc::Build::new()
422-
.includes(includes)
423-
.file(path)
424-
.try_expand()?)
444+
let mut builder = cc::Build::new();
445+
446+
builder.includes(includes).file(path);
447+
448+
for def in defines {
449+
builder.define(&def.0, def.1.as_deref());
450+
}
451+
452+
Ok(builder.try_expand()?)
425453
}

0 commit comments

Comments
 (0)