Bug 1368083 - Read bindgen flags from a generated file. r=emilio draft
authorRalph Giles <giles@mozilla.com>
Wed, 05 Jul 2017 18:09:02 -0700
changeset 605591 3e1c28cb5ea674f7429c98dbaf915c33b2089de7
parent 605590 0acf6d20442604f925aaef9c56945fe33bd3d831
child 605592 99c2e6f2c5c8d3222354e5bc867cb1ae2d3789ae
child 605593 75f84cdad3a88defe422f8e9412abd65e26beb41
push id67458
push userbmo:giles@thaumas.net
push dateSat, 08 Jul 2017 01:32:00 +0000
reviewersemilio
bugs1368083
milestone56.0a1
Bug 1368083 - Read bindgen flags from a generated file. r=emilio Bindgen needs some build-specific flags, like the isysroot passed to clang for the C++ compilation. Try to read these from $objdir/layout/style/bindgen.toml which is created by the build system, and merge them into the config. MozReview-Commit-ID: 2tpAHnYjJlA
servo/components/style/build_gecko.rs
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -56,41 +56,54 @@ mod bindings {
 
     fn structs_file(build_type: BuildType) -> &'static str {
         match build_type {
             BuildType::Debug => STRUCTS_DEBUG_FILE,
             BuildType::Release => STRUCTS_RELEASE_FILE
         }
     }
 
+    fn read_config(path: &PathBuf) -> toml::Table {
+        println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
+        update_last_modified(&path);
+
+        let mut contents = String::new();
+        File::open(path).expect("Failed to open config file")
+            .read_to_string(&mut contents).expect("Failed to read config file");
+        let mut parser = toml::Parser::new(&contents);
+        if let Some(result) = parser.parse() {
+            result
+        } else {
+            use std::fmt::Write;
+            let mut reason = String::from("Failed to parse config file:");
+            for err in parser.errors.iter() {
+                let parsed = &contents[..err.lo];
+                write!(&mut reason, "\n* line {} column {}: {}",
+                       parsed.lines().count(),
+                       parsed.lines().last().map_or(0, |l| l.len()),
+                       err).unwrap();
+            }
+            panic!(reason)
+        }
+    }
+
     lazy_static! {
         static ref CONFIG: toml::Table = {
+            // Load Gecko's binding generator config from the source tree.
             let path = PathBuf::from(env::var("MOZ_SRC").unwrap())
                 .join("layout/style/ServoBindings.toml");
-            println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
-            update_last_modified(&path);
-
-            let mut contents = String::new();
-            File::open(path).expect("Failed to open config file")
-                .read_to_string(&mut contents).expect("Failed to read config file");
-            let mut parser = toml::Parser::new(&contents);
-            if let Some(result) = parser.parse() {
-                result
-            } else {
-                use std::fmt::Write;
-                let mut reason = String::from("Failed to parse config file:");
-                for err in parser.errors.iter() {
-                    let parsed = &contents[..err.lo];
-                    write!(&mut reason, "\n* line {} column {}: {}",
-                           parsed.lines().count(),
-                           parsed.lines().last().map_or(0, |l| l.len()),
-                           err).unwrap();
-                }
-                panic!(reason)
-            }
+            read_config(&path)
+        };
+        static ref BUILD_CONFIG: toml::Table = {
+            // Load build-specific config overrides.
+            // FIXME: We should merge with CONFIG above instead of
+            // forcing callers to do it.
+            let path = PathBuf::from(env::var("MOZ_TOPOBJDIR").unwrap())
+                .join("layout/style/bindgen.toml");
+            read_config(&path)
         };
         static ref TARGET_INFO: HashMap<String, String> = {
             const TARGET_PREFIX: &'static str = "CARGO_CFG_TARGET_";
             let mut result = HashMap::new();
             for (k, v) in env::vars() {
                 if k.starts_with(TARGET_PREFIX) {
                     result.insert(k[TARGET_PREFIX.len()..].to_lowercase(), v);
                 }
@@ -208,16 +221,18 @@ mod bindings {
 
             if build_type == BuildType::Debug {
                 builder = builder.clang_arg("-DDEBUG=1").clang_arg("-DJS_DEBUG=1");
             }
 
             let mut matched_os = false;
             let build_config = CONFIG["build"].as_table().expect("Malformed config file");
             builder = add_clang_args(builder, build_config, &mut matched_os);
+            let build_config = BUILD_CONFIG["build"].as_table().expect("Malformed config file");
+            builder = add_clang_args(builder, build_config, &mut matched_os);
             if !matched_os {
                 panic!("Unknown platform");
             }
             builder
         }
         fn include<T: Into<String>>(self, file: T) -> Builder {
             self.clang_arg("-include").clang_arg(file)
         }