From 71f351873fbb349a7ee55b45396ab857defc5d46 Mon Sep 17 00:00:00 2001 From: Thomas Bleeker Date: Mon, 13 Nov 2023 22:00:25 +0100 Subject: [PATCH 1/3] Remove compilation of all recursive C files in config dir Add missing rerun-if-env-changed for config path env var --- lvgl-sys/build.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lvgl-sys/build.rs b/lvgl-sys/build.rs index fbf0ac53..0c373a48 100644 --- a/lvgl-sys/build.rs +++ b/lvgl-sys/build.rs @@ -57,7 +57,7 @@ fn main() { #[cfg(feature = "drivers")] let drivers = vendor.join("lv_drivers"); - + println!("cargo:rerun-if-env-changed={}", CONFIG_NAME); let lv_config_dir = { let conf_path = env::var(CONFIG_NAME) .map(PathBuf::from) @@ -134,7 +134,6 @@ fn main() { add_c_files(&mut cfg, p) } add_c_files(&mut cfg, &lvgl_src); - add_c_files(&mut cfg, &lv_config_dir); add_c_files(&mut cfg, &shims_dir); #[cfg(feature = "drivers")] add_c_files(&mut cfg, &drivers); From aa883057d7a9556542c023c1ecb22495208ded48 Mon Sep 17 00:00:00 2001 From: Thomas Bleeker Date: Fri, 10 Nov 2023 22:38:09 +0100 Subject: [PATCH 2/3] Refactor build script: separate library and indings in separate functions --- lvgl-sys/build.rs | 215 +++++++++++++++++++++++++--------------------- 1 file changed, 118 insertions(+), 97 deletions(-) diff --git a/lvgl-sys/build.rs b/lvgl-sys/build.rs index 0c373a48..09ffee21 100644 --- a/lvgl-sys/build.rs +++ b/lvgl-sys/build.rs @@ -27,25 +27,52 @@ fn main() { let project_dir = canonicalize(PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())); let shims_dir = project_dir.join("shims"); let vendor = project_dir.join("vendor"); - let lvgl_src = vendor.join("lvgl").join("src"); - #[cfg(feature = "rust_timer")] - let timer_shim = vendor.join("include").join("timer"); + println!("cargo:rerun-if-env-changed={}", CONFIG_NAME); + let lv_config_dir = get_conf_path(&vendor); + let font_extra_src: Option = get_font_extra_dir(); + if let Some(p) = &font_extra_src { + println!("cargo:rerun-if-changed={}", p.to_str().unwrap()) + } + + let conf = BuildConf { + lv_config_dir: lv_config_dir.as_path(), + vendor: vendor.as_path(), + shims_dir: &shims_dir, + font_extra_src: font_extra_src.as_ref().map(PathBuf::as_path), + }; - let font_extra_src: Option; + compile_library(&conf); + generate_bindings(&conf); +} + +fn get_font_extra_dir() -> Option { if let Ok(v) = env::var("PWD") { let current_dir = canonicalize(PathBuf::from(v)); - font_extra_src = { - if let Ok(p) = env::var("LVGL_FONTS_DIR") { - Some(canonicalize(PathBuf::from(p))) - } else if current_dir.join("fonts").exists() { - Some(current_dir.join("fonts")) - } else { - None - } - }; + if let Ok(p) = env::var("LVGL_FONTS_DIR") { + Some(canonicalize(PathBuf::from(p))) + } else if current_dir.join("fonts").exists() { + Some(current_dir.join("fonts")) + } else { + None + } } else { - font_extra_src = None + None } +} + +struct BuildConf<'a> { + lv_config_dir: &'a Path, + vendor: &'a Path, + shims_dir: &'a Path, + font_extra_src: Option<&'a Path>, +} + +fn compile_library(conf: &BuildConf) { + let vendor = conf.vendor; + + let lvgl_src = vendor.join("lvgl").join("src"); + #[cfg(feature = "rust_timer")] + let timer_shim = vendor.join("include").join("timer"); // Some basic defaults; SDL2 is the only driver enabled in the provided // driver config by default @@ -57,71 +84,6 @@ fn main() { #[cfg(feature = "drivers")] let drivers = vendor.join("lv_drivers"); - println!("cargo:rerun-if-env-changed={}", CONFIG_NAME); - let lv_config_dir = { - let conf_path = env::var(CONFIG_NAME) - .map(PathBuf::from) - .unwrap_or_else(|_| { - match std::env::var("DOCS_RS") { - Ok(_) => { - // We've detected that we are building for docs.rs - // so let's use the vendored `lv_conf.h` file. - vendor.join("include") - } - Err(_) => { - #[cfg(not(feature = "use-vendored-config"))] - panic!( - "The environment variable {} is required to be defined", - CONFIG_NAME - ); - - #[cfg(feature = "use-vendored-config")] - vendor.join("include") - } - } - }); - - if !conf_path.exists() { - panic!( - "Directory {} referenced by {} needs to exist", - conf_path.to_string_lossy(), - CONFIG_NAME - ); - } - if !conf_path.is_dir() { - panic!("{} needs to be a directory", CONFIG_NAME); - } - if !conf_path.join("lv_conf.h").exists() { - panic!( - "Directory {} referenced by {} needs to contain a file called lv_conf.h", - conf_path.to_string_lossy(), - CONFIG_NAME - ); - } - #[cfg(feature = "drivers")] - if !conf_path.join("lv_drv_conf.h").exists() { - panic!( - "Directory {} referenced by {} needs to contain a file called lv_drv_conf.h", - conf_path.to_string_lossy(), - CONFIG_NAME - ); - } - - if let Some(p) = &font_extra_src { - println!("cargo:rerun-if-changed={}", p.to_str().unwrap()) - } - - println!( - "cargo:rerun-if-changed={}", - conf_path.join("lv_conf.h").to_str().unwrap() - ); - #[cfg(feature = "drivers")] - println!( - "cargo:rerun-if-changed={}", - conf_path.join("lv_drv_conf.h").to_str().unwrap() - ); - conf_path - }; #[cfg(feature = "drivers")] { @@ -130,11 +92,11 @@ fn main() { } let mut cfg = Build::new(); - if let Some(p) = &font_extra_src { + if let Some(p) = conf.font_extra_src { add_c_files(&mut cfg, p) } add_c_files(&mut cfg, &lvgl_src); - add_c_files(&mut cfg, &shims_dir); + add_c_files(&mut cfg, conf.shims_dir); #[cfg(feature = "drivers")] add_c_files(&mut cfg, &drivers); @@ -142,8 +104,8 @@ fn main() { .include(&lvgl_src) .include(&vendor) .warnings(false) - .include(&lv_config_dir); - if let Some(p) = &font_extra_src { + .include(conf.lv_config_dir); + if let Some(p) = conf.font_extra_src { cfg.includes(p); } #[cfg(feature = "rust_timer")] @@ -155,12 +117,19 @@ fn main() { cfg.compile("lvgl"); + #[cfg(feature = "drivers")] + link_extra.split(',').for_each(|a| { + println!("cargo:rustc-link-lib={a}"); + //println!("cargo:rustc-link-search=") + }); +} +fn generate_bindings(conf: &BuildConf) { let mut cc_args = vec![ "-DLV_CONF_INCLUDE_SIMPLE=1", "-I", - lv_config_dir.to_str().unwrap(), + conf.lv_config_dir.to_str().unwrap(), "-I", - vendor.to_str().unwrap(), + conf.vendor.to_str().unwrap(), "-fvisibility=default", ]; @@ -213,11 +182,11 @@ fn main() { let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); let bindings = - bindgen::Builder::default().header(shims_dir.join("lvgl_sys.h").to_str().unwrap()); - let bindings = add_font_headers(bindings, &font_extra_src); + bindgen::Builder::default().header(conf.shims_dir.join("lvgl_sys.h").to_str().unwrap()); + let bindings = add_font_headers(bindings, conf.font_extra_src); #[cfg(feature = "drivers")] let bindings = bindings - .header(shims_dir.join("lvgl_drv.h").to_str().unwrap()) + .header(conf.shims_dir.join("lvgl_drv.h").to_str().unwrap()) .parse_callbacks(Box::new(ignored_macros)); //#[cfg(feature = "rust_timer")] //let bindings = bindings.header(shims_dir.join("rs_timer.h").to_str().unwrap()); @@ -235,21 +204,73 @@ fn main() { bindings .write_to_file(out_path.join("bindings.rs")) .expect("Can't write bindings!"); +} +fn get_conf_path(vendor: &PathBuf) -> PathBuf { + let conf_path = env::var(CONFIG_NAME) + .map(PathBuf::from) + .unwrap_or_else(|_| { + match std::env::var("DOCS_RS") { + Ok(_) => { + // We've detected that we are building for docs.rs + // so let's use the vendored `lv_conf.h` file. + vendor.join("include") + } + Err(_) => { + #[cfg(not(feature = "use-vendored-config"))] + panic!( + "The environment variable {} is required to be defined", + CONFIG_NAME + ); + + #[cfg(feature = "use-vendored-config")] + vendor.join("include") + } + } + }); + + if !conf_path.exists() { + panic!( + "Directory {} referenced by {} needs to exist", + conf_path.to_string_lossy(), + CONFIG_NAME + ); + } + if !conf_path.is_dir() { + panic!("{} needs to be a directory", CONFIG_NAME); + } + if !conf_path.join("lv_conf.h").exists() { + panic!( + "Directory {} referenced by {} needs to contain a file called lv_conf.h", + conf_path.to_string_lossy(), + CONFIG_NAME + ); + } #[cfg(feature = "drivers")] - link_extra.split(',').for_each(|a| { - println!("cargo:rustc-link-lib={a}"); - //println!("cargo:rustc-link-search=") - }) + if !conf_path.join("lv_drv_conf.h").exists() { + panic!( + "Directory {} referenced by {} needs to contain a file called lv_drv_conf.h", + conf_path.to_string_lossy(), + CONFIG_NAME + ); + } + + println!( + "cargo:rerun-if-changed={}", + conf_path.join("lv_conf.h").to_str().unwrap() + ); + #[cfg(feature = "drivers")] + println!( + "cargo:rerun-if-changed={}", + conf_path.join("lv_drv_conf.h").to_str().unwrap() + ); + conf_path } -fn add_font_headers( - bindings: bindgen::Builder, - dir: &Option>, -) -> bindgen::Builder { +fn add_font_headers(bindings: bindgen::Builder, dir: Option<&Path>) -> bindgen::Builder { if let Some(p) = dir { let mut temp = bindings; - for e in p.as_ref().read_dir().unwrap() { + for e in p.read_dir().unwrap() { let e = e.unwrap(); let path = e.path(); if !e.file_type().unwrap().is_dir() From 4f3fdd8e49f8cd9d286fdc50994c1f6a4eac36be Mon Sep 17 00:00:00 2001 From: Thomas Bleeker Date: Sun, 12 Nov 2023 21:57:30 +0100 Subject: [PATCH 3/3] Add library and raw-bindings features to lvgl-sys. Correct CROSS_COMPILE target for bindgen --- lvgl-sys/Cargo.toml | 2 ++ lvgl-sys/build.rs | 10 +++++++++- lvgl-sys/src/lib.rs | 2 ++ lvgl/Cargo.toml | 4 ++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lvgl-sys/Cargo.toml b/lvgl-sys/Cargo.toml index b42c74be..674f8693 100644 --- a/lvgl-sys/Cargo.toml +++ b/lvgl-sys/Cargo.toml @@ -32,6 +32,8 @@ cc = "1.0.79" bindgen = "0.65.1" [features] +library = [] +raw-bindings = [] use-vendored-config = [] drivers = [] rust_timer = [] diff --git a/lvgl-sys/build.rs b/lvgl-sys/build.rs index 09ffee21..268b5680 100644 --- a/lvgl-sys/build.rs +++ b/lvgl-sys/build.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "library")] use cc::Build; #[cfg(feature = "drivers")] use std::collections::HashSet; @@ -41,7 +42,9 @@ fn main() { font_extra_src: font_extra_src.as_ref().map(PathBuf::as_path), }; + #[cfg(feature = "library")] compile_library(&conf); + generate_bindings(&conf); } @@ -67,6 +70,7 @@ struct BuildConf<'a> { font_extra_src: Option<&'a Path>, } +#[cfg(feature = "library")] fn compile_library(conf: &BuildConf) { let vendor = conf.vendor; @@ -134,7 +138,10 @@ fn generate_bindings(conf: &BuildConf) { ]; // Set correct target triple for bindgen when cross-compiling - let target = env::var("TARGET").expect("Cargo build scripts always have TARGET"); + let target = env::var("CROSS_COMPILE").map_or_else( + |_| env::var("TARGET").expect("Cargo build scripts always have TARGET"), + |c| c.trim_end_matches('-').to_owned(), + ); let host = env::var("HOST").expect("Cargo build scripts always have HOST"); if target != host { cc_args.push("-target"); @@ -285,6 +292,7 @@ fn add_font_headers(bindings: bindgen::Builder, dir: Option<&Path>) -> bindgen:: } } +#[cfg(feature = "library")] fn add_c_files(build: &mut cc::Build, path: impl AsRef) { for e in path.as_ref().read_dir().unwrap() { let e = e.unwrap(); diff --git a/lvgl-sys/src/lib.rs b/lvgl-sys/src/lib.rs index fd35f222..cbce70b0 100644 --- a/lvgl-sys/src/lib.rs +++ b/lvgl-sys/src/lib.rs @@ -7,10 +7,12 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +#[cfg(feature = "raw-bindings")] pub fn _bindgen_raw_src() -> &'static str { include_str!(concat!(env!("OUT_DIR"), "/bindings.rs")) } +#[cfg(feature = "library")] mod string_impl; #[cfg(test)] diff --git a/lvgl/Cargo.toml b/lvgl/Cargo.toml index 15069d1c..58bed958 100644 --- a/lvgl/Cargo.toml +++ b/lvgl/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["littlevgl", "lvgl", "graphical_interfaces"] build = "build.rs" [dependencies] -lvgl-sys = { version = "0.6.2", path = "../lvgl-sys" } +lvgl-sys = { version = "0.6.2", path = "../lvgl-sys", features = ["library"]} cty = "0.2.2" embedded-graphics = { version = "0.8.0", optional = true } cstr_core = { version = "0.2.6", default-features = false, features = ["alloc"] } @@ -77,7 +77,7 @@ unsafe_no_autoinit = [] quote = "1.0.23" proc-macro2 = "1.0.51" lvgl-codegen = { version = "0.6.2", path = "../lvgl-codegen" } -lvgl-sys = { version = "0.6.2", path = "../lvgl-sys" } +lvgl-sys = { version = "0.6.2", path = "../lvgl-sys", features = ["raw-bindings"]} [dev-dependencies] embedded-graphics-simulator = "0.5.0"