From 5bf5c5444757b0eb85f92e3ebb16b439ff6e209b Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 6 Dec 2020 02:00:34 -0800 Subject: [PATCH] Switch to SCU build (aka 'Single File' or 'Unity build') for imgui/cimgui code --- imgui-sys/Cargo.toml | 2 ++ imgui-sys/build.rs | 35 +++++++++++++++++++-------------- imgui-sys/include_all_imgui.cpp | 11 +++++++++++ 3 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 imgui-sys/include_all_imgui.cpp diff --git a/imgui-sys/Cargo.toml b/imgui-sys/Cargo.toml index 49d0892..c7a3ff4 100644 --- a/imgui-sys/Cargo.toml +++ b/imgui-sys/Cargo.toml @@ -10,6 +10,8 @@ license = "MIT/Apache-2.0" categories = ["gui", "external-ffi-bindings"] build = "build.rs" links = "imgui" +# exclude json, lua, and the imgui subdirs (imgui/examples, imgui/docs, etc) +exclude = ["third-party/*.json", "third-party/*.lua", "third-party/imgui/*/"] [build-dependencies] cc = "1.0" diff --git a/imgui-sys/build.rs b/imgui-sys/build.rs index a449e76..934f5b9 100644 --- a/imgui-sys/build.rs +++ b/imgui-sys/build.rs @@ -4,14 +4,6 @@ use std::fs; use std::io; use std::path::Path; -const CPP_FILES: [&str; 5] = [ - "third-party/cimgui.cpp", - "third-party/imgui/imgui.cpp", - "third-party/imgui/imgui_demo.cpp", - "third-party/imgui/imgui_draw.cpp", - "third-party/imgui/imgui_widgets.cpp", -]; - const DEFINES: &[(&str, Option<&str>)] = &[ // Disabled due to linking issues ("CIMGUI_NO_EXPORT", None), @@ -41,20 +33,33 @@ fn main() -> io::Result<()> { for (key, value) in DEFINES.iter() { println!("cargo:DEFINE_{}={}", key, value.unwrap_or("")); } - #[cfg(not(feature = "wasm"))] - { + if !std::env::var_os("CARGO_FEATURE_WASM").is_some() { + // Check submodule status. (Anything else should be a compile error in + // the C code). + assert_file_exists("third-party/cimgui.cpp")?; + assert_file_exists("third-party/imgui/imgui.cpp")?; + let mut build = cc::Build::new(); + build.cpp(true); for (key, value) in DEFINES.iter() { build.define(key, *value); } - build.flag_if_supported("-Wno-return-type-c-linkage"); - for path in &CPP_FILES { - assert_file_exists(path)?; - build.file(path); + let compiler = build.get_compiler(); + // Avoid the if-supported flag functions for easy cases, as they're + // kinda costly. + if compiler.is_like_gnu() || compiler.is_like_clang() { + build + .flag("-fno-exceptions") + .flag("-fno-rtti"); } - build.compile("libcimgui.a"); + // TODO: disable linking C++ stdlib? Not sure if it's allowed. + build + .warnings(false) + .file("include_all_imgui.cpp") + .compile("libcimgui.a") + ; } Ok(()) } diff --git a/imgui-sys/include_all_imgui.cpp b/imgui-sys/include_all_imgui.cpp new file mode 100644 index 0000000..cc6eb59 --- /dev/null +++ b/imgui-sys/include_all_imgui.cpp @@ -0,0 +1,11 @@ +// This improves build speed by only compiling a single file, and performance by +// allowing the optimizer to inline across separate object files (note that even +// when rust is built with LTO, unless the steps are taken to allow cross-lang +// LTO (tricky), the C/C++ code won't be LTOed). +#include "./third-party/imgui/imgui.cpp" +#include "./third-party/imgui/imgui_demo.cpp" +#include "./third-party/imgui/imgui_draw.cpp" +#include "./third-party/imgui/imgui_widgets.cpp" +#include "./third-party/cimgui.cpp" + +