154 lines
5.4 KiB
Rust
154 lines
5.4 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
use std::{env, path::Path};
|
|
|
|
fn main() {
|
|
windows_manifest();
|
|
crash_annotations();
|
|
set_mock_cfg();
|
|
set_glean_metrics_file();
|
|
generate_buildid_section();
|
|
}
|
|
|
|
fn windows_manifest() {
|
|
use embed_manifest::{embed_manifest, manifest, new_manifest};
|
|
|
|
if std::env::var_os("CARGO_CFG_WINDOWS").is_none() {
|
|
return;
|
|
}
|
|
|
|
// See https://docs.rs/embed-manifest/1.4.0/embed_manifest/fn.new_manifest.html for what the
|
|
// default manifest includes. The defaults include almost all of the settings used in the old
|
|
// crash reporter.
|
|
let manifest = new_manifest("CrashReporter")
|
|
// Use legacy active code page because GDI doesn't support per-process UTF8 (and older
|
|
// win10 may not support this setting anyway).
|
|
.active_code_page(manifest::ActiveCodePage::Legacy)
|
|
// We support WM_DPICHANGED for scaling, but need to set our DPI awareness to receive the
|
|
// messages.
|
|
.dpi_awareness(manifest::DpiAwareness::PerMonitorV2);
|
|
|
|
embed_manifest(manifest).expect("unable to embed windows manifest file");
|
|
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
}
|
|
|
|
/// Generate crash annotation information from the yaml definition file.
|
|
fn crash_annotations() {
|
|
use std::fs::File;
|
|
use std::io::{BufWriter, Write};
|
|
use yaml_rust::{Yaml, YamlLoader};
|
|
|
|
let crash_annotations = Path::new("../../CrashAnnotations.yaml")
|
|
.canonicalize()
|
|
.unwrap();
|
|
println!("cargo:rerun-if-changed={}", crash_annotations.display());
|
|
|
|
let crash_ping_file = Path::new(&env::var("OUT_DIR").unwrap()).join("crash_annotations.rs");
|
|
|
|
let yaml = std::fs::read_to_string(crash_annotations).unwrap();
|
|
let Yaml::Hash(entries) = YamlLoader::load_from_str(&yaml)
|
|
.unwrap()
|
|
.into_iter()
|
|
.next()
|
|
.unwrap()
|
|
else {
|
|
panic!("unexpected crash annotations root type");
|
|
};
|
|
|
|
let mut ping_annotations = phf_codegen::Set::new();
|
|
let mut report_annotations = phf_codegen::Set::new();
|
|
|
|
for (k, v) in entries {
|
|
let scope = v["scope"].as_str().unwrap_or("client");
|
|
match scope {
|
|
"ping" => {
|
|
ping_annotations.entry(k.into_string().unwrap());
|
|
}
|
|
"report" => {
|
|
report_annotations.entry(k.into_string().unwrap());
|
|
}
|
|
_ => (),
|
|
}
|
|
}
|
|
|
|
let mut file = BufWriter::new(File::create(&crash_ping_file).unwrap());
|
|
writeln!(
|
|
&mut file,
|
|
"static PING_ANNOTATIONS: phf::Set<&'static str> = {};",
|
|
ping_annotations.build(),
|
|
)
|
|
.unwrap();
|
|
writeln!(
|
|
&mut file,
|
|
"static REPORT_ANNOTATIONS: phf::Set<&'static str> = {};",
|
|
report_annotations.build(),
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
/// Set the mock configuration option when tests are enabled or when the mock feature is enabled.
|
|
fn set_mock_cfg() {
|
|
// Very inconveniently, there's no way to detect `cfg(test)` from build scripts. See
|
|
// https://github.com/rust-lang/cargo/issues/4789. This seems like an arbitrary and pointless
|
|
// limitation, and only complicates the evaluation of mock behavior. Because of this, we have a
|
|
// `mock` feature which is activated by `toolkit/library/rust/moz.build`.
|
|
println!("cargo:rustc-check-cfg=cfg(mock)");
|
|
if env::var_os("CARGO_FEATURE_MOCK").is_some() || mozbuild::config::MOZ_CRASHREPORTER_MOCK {
|
|
println!("cargo:rustc-cfg=mock");
|
|
}
|
|
}
|
|
|
|
/// Set the GLEAN_METRICS_FILE environment variable to the location of the generated Glean metrics.
|
|
///
|
|
/// We do this here to avoid a hardcoded path in the source (just in case this crate's src dir
|
|
/// moves, not that it's likely).
|
|
fn set_glean_metrics_file() {
|
|
let full_path = Path::new(env!("CARGO_MANIFEST_DIR"));
|
|
let relative_path = full_path
|
|
.strip_prefix(mozbuild::TOPSRCDIR)
|
|
.expect("CARGO_MANIFEST_DIR not a child of TOPSRCDIR");
|
|
let glean_metrics_path = {
|
|
let mut p = mozbuild::TOPOBJDIR.join(relative_path);
|
|
// Generated by generate_glean.py
|
|
p.push("glean_metrics.rs");
|
|
p
|
|
};
|
|
// We don't really need anything like `rerun-if-env-changed=CARGO_MANIFEST_DIR` because that
|
|
// will inevitably mean the entire crate has moved or the srcdir has moved, which would result
|
|
// in a rebuild anyway.
|
|
println!(
|
|
"cargo:rustc-env=GLEAN_METRICS_FILE={}",
|
|
glean_metrics_path.display()
|
|
);
|
|
}
|
|
|
|
/// Generate the buildid section name (we read the buildid at runtime using buildid_reader).
|
|
fn generate_buildid_section() {
|
|
use mozbuild::config::BINDGEN_SYSTEM_FLAGS as CFLAGS;
|
|
|
|
let defines = if cfg!(target_os = "macos") {
|
|
"#define XP_DARWIN"
|
|
} else if cfg!(target_os = "windows") {
|
|
"#define XP_WIN"
|
|
} else {
|
|
""
|
|
};
|
|
|
|
let bindings = bindgen::Builder::default()
|
|
.header_contents("defines.h", defines)
|
|
.header(format!(
|
|
"{}/toolkit/library/buildid_section.h",
|
|
mozbuild::TOPSRCDIR.display()
|
|
))
|
|
.clang_args(CFLAGS)
|
|
.generate_cstr(true)
|
|
.generate()
|
|
.expect("unable to generate buildid_section.h");
|
|
let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
|
bindings
|
|
.write_to_file(out_path.join("buildid_section.rs"))
|
|
.expect("failed to write buildid section");
|
|
}
|