From 50db1fe8650838a6ab4247b8560dc438b89bdba8 Mon Sep 17 00:00:00 2001 From: Delan Azabani Date: Sat, 30 Nov 2024 12:35:02 +0800 Subject: [PATCH 1/2] Add support for PlatformIO `platform = native` --- cargo-pio/src/main.rs | 2 +- src/bindgen.rs | 2 +- src/cargo.rs | 18 ++----------- src/pio/project.rs | 14 +++++----- .../resources/platformio.cargo.py.resource | 27 ++++++++++++++----- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/cargo-pio/src/main.rs b/cargo-pio/src/main.rs index d3a212a..9047883 100644 --- a/cargo-pio/src/main.rs +++ b/cargo-pio/src/main.rs @@ -341,7 +341,7 @@ fn main() -> Result<()> { "linkflags" => scons_vars.linkflags, "link" => scons_vars.link, "linkcom" => scons_vars.linkcom, - "mcu" => scons_vars.mcu, + "mcu" => format!("{:?}", scons_vars.mcu), "clangargs" => scons_vars.clangargs.unwrap_or_else(|| "".into()), _ => panic!(), }; diff --git a/src/bindgen.rs b/src/bindgen.rs index 420dbd9..e3933a3 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -40,7 +40,7 @@ impl Factory { Ok(Self { clang_args, linker: Some(scons_vars.full_path(scons_vars.link.clone())?), - mcu: Some(scons_vars.mcu.clone()), + mcu: scons_vars.mcu.clone(), force_cpp: false, sysroot: None, }) diff --git a/src/cargo.rs b/src/cargo.rs index 03593dd..c3d9e2e 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -106,12 +106,8 @@ impl Crate { } } - /// Create a `config.toml` in `.cargo` with a `[target]` and `[unstable]` section. - pub fn create_config_toml( - &self, - target: Option>, - build_std: BuildStd, - ) -> Result<()> { + /// Create a `config.toml` in `.cargo` with an `[unstable]` section. + pub fn create_config_toml(&self, build_std: BuildStd) -> Result<()> { let cargo_config_toml_path = self.0.join(".cargo").join("config.toml"); debug!( @@ -121,16 +117,6 @@ impl Crate { let mut data = String::new(); - if let Some(target) = target { - write!( - &mut data, - r#"[build] -target = "{}" -"#, - target.as_ref() - )?; - } - if build_std != BuildStd::None { write!( &mut data, diff --git a/src/pio/project.rs b/src/pio/project.rs index 8441962..6933ede 100644 --- a/src/pio/project.rs +++ b/src/pio/project.rs @@ -61,11 +61,11 @@ pub struct SconsVariables { pub linkflags: String, pub link: String, pub linkcom: String, - pub mcu: String, + pub mcu: Option, pub clangargs: Option, - pub pio_platform_dir: String, - pub pio_framework_dir: String, + pub pio_platform_dir: Option, + pub pio_framework_dir: Option, } impl SconsVariables { @@ -83,11 +83,11 @@ impl SconsVariables { linkflags: env::var(VAR_BUILD_LINK_FLAGS).ok()?, link: env::var(VAR_BUILD_LINK).ok()?, linkcom: env::var(VAR_BUILD_LINKCOM).ok()?, - mcu: env::var(VAR_BUILD_MCU).ok()?, + mcu: env::var(VAR_BUILD_MCU).ok(), clangargs: env::var(VAR_BUILD_BINDGEN_EXTRA_CLANG_ARGS).ok(), - pio_platform_dir: env::var(VAR_BUILD_PIO_PLATFORM_DIR).ok()?, - pio_framework_dir: env::var(VAR_BUILD_PIO_FRAMEWORK_DIR).ok()?, + pio_platform_dir: env::var(VAR_BUILD_PIO_PLATFORM_DIR).ok(), + pio_framework_dir: env::var(VAR_BUILD_PIO_FRAMEWORK_DIR).ok(), }) } else { None @@ -313,7 +313,7 @@ impl Builder { )?; let rust_lib = cargo_crate.set_library_type(["staticlib"])?; - cargo_crate.create_config_toml(Some(resolution.target.clone()), build_std)?; + cargo_crate.create_config_toml(build_std)?; if arduino { self.create_file(PathBuf::from("src").join("lib.rs"), LIB_ARDUINO_RS)?; diff --git a/src/pio/resources/platformio.cargo.py.resource b/src/pio/resources/platformio.cargo.py.resource index 3f5ce13..469817d 100644 --- a/src/pio/resources/platformio.cargo.py.resource +++ b/src/pio/resources/platformio.cargo.py.resource @@ -27,7 +27,7 @@ class Cargo: self.__cargo_ran = False self.__rust_lib = env.GetProjectOption("rust_lib") - self.__rust_target = env.GetProjectOption("rust_target") + self.__rust_target = env.GetProjectOption("rust_target", default = None) self.__rust_bindgen_enabled = env.GetProjectOption("rust_bindgen_enabled", default = "false").lower() == "true" self.__rust_bindgen_extra_clang_args = env.GetProjectOption("rust_bindgen_extra_clang_args", default = "") @@ -66,17 +66,28 @@ class Cargo: env["ENV"]["CARGO_PIO_BUILD_LINK_FLAGS"] = env.subst("$LINKFLAGS") env["ENV"]["CARGO_PIO_BUILD_LINK"] = env.subst("$LINK") env["ENV"]["CARGO_PIO_BUILD_LINKCOM"] = env.subst("$LINKCOM") - env["ENV"]["CARGO_PIO_BUILD_MCU"] = board_mcu + if board_mcu is not None: + env["ENV"]["CARGO_PIO_BUILD_MCU"] = board_mcu if self.__rust_bindgen_enabled: env["ENV"]["CARGO_PIO_BUILD_BINDGEN_RUN"] = "True" env["ENV"]["CARGO_PIO_BUILD_BINDGEN_EXTRA_CLANG_ARGS"] = self.__rust_bindgen_extra_clang_args - env["ENV"]["CARGO_PIO_BUILD_PIO_PLATFORM_DIR"] = env.PioPlatform().get_dir()[0] - env["ENV"]["CARGO_PIO_BUILD_PIO_FRAMEWORK_DIR"] = env.PioPlatform().get_package_dir(env.PioPlatform().frameworks[env.GetProjectOption("framework")[0]]["package"]) + pio_platform_dir = env.PioPlatform().get_dir()[0] + if pio_platform_dir is not None: + env["ENV"]["CARGO_PIO_BUILD_PIO_PLATFORM_DIR"] = pio_platform_dir + framework = env.GetProjectOption("framework") + if framework: + pio_framework_dir = env.PioPlatform().get_package_dir(env.PioPlatform().frameworks[framework[0]]["package"]) + if pio_framework_dir is not None: + env["ENV"]["CARGO_PIO_BUILD_PIO_FRAMEWORK_DIR"] = pio_framework_dir + if self.__rust_target is not None: + cargo_target_option = f"--target {self.__rust_target}" + else: + cargo_target_option = "" self.__cargo_ran = True - result = env.Execute(f"cargo build {'--release' if self.__cargo_profile == 'release' else ''} --lib --target {self.__rust_target} {self.__cargo_options}") + result = env.Execute(f"cargo build {'--release' if self.__cargo_profile == 'release' else ''} --lib {cargo_target_option} {self.__cargo_options}") print("<<< CARGO") @@ -84,7 +95,11 @@ class Cargo: def __link_cargo(self, source, target, env): env.Prepend(LINKFLAGS = ["-Wl,--allow-multiple-definition"]) # A hack to workaround this issue with Rust's compiler intrinsics: https://github.com/rust-lang/compiler-builtins/issues/353 - env.Prepend(LIBPATH = [env.subst(os.path.join(self.__cargo_target_dir, self.__rust_target, self.__cargo_profile))]) + if self.__rust_target is not None: + cargo_profile_path = os.path.join(self.__cargo_target_dir, self.__rust_target, self.__cargo_profile) + else: + cargo_profile_path = os.path.join(self.__cargo_target_dir, self.__cargo_profile) + env.Prepend(LIBPATH = [env.subst(cargo_profile_path)]) env.Prepend(LIBS = [self.__rust_lib]) Cargo().run(env) From dea89a1bed5b9dbbe62b6da0867b70c7ab4f5a1f Mon Sep 17 00:00:00 2001 From: Delan Azabani Date: Sat, 30 Nov 2024 16:23:48 +0800 Subject: [PATCH 2/2] change the call, not the function --- src/cargo.rs | 22 ++++++++++++++++++++-- src/pio/project.rs | 5 ++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/cargo.rs b/src/cargo.rs index c3d9e2e..8ab192d 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -106,8 +106,16 @@ impl Crate { } } - /// Create a `config.toml` in `.cargo` with an `[unstable]` section. - pub fn create_config_toml(&self, build_std: BuildStd) -> Result<()> { + /// Create a `config.toml` in `.cargo` with an `[unstable]` section, and a `[build] target` + /// if a `target` is given. + /// + /// `[build] target` changes the default `cargo --target`, so it should only be used when the + /// default target is unwanted. + pub fn create_config_toml( + &self, + target: Option>, + build_std: BuildStd, + ) -> Result<()> { let cargo_config_toml_path = self.0.join(".cargo").join("config.toml"); debug!( @@ -117,6 +125,16 @@ impl Crate { let mut data = String::new(); + if let Some(target) = target { + write!( + &mut data, + r#"[build] +target = "{}" +"#, + target.as_ref() + )?; + } + if build_std != BuildStd::None { write!( &mut data, diff --git a/src/pio/project.rs b/src/pio/project.rs index 6933ede..5b132cd 100644 --- a/src/pio/project.rs +++ b/src/pio/project.rs @@ -313,7 +313,10 @@ impl Builder { )?; let rust_lib = cargo_crate.set_library_type(["staticlib"])?; - cargo_crate.create_config_toml(build_std)?; + + // No `[build] target`, because it would change the default target used when + // running `cargo` without `--target`, which `platform = native` relies on. + cargo_crate.create_config_toml(None::<&str>, build_std)?; if arduino { self.create_file(PathBuf::from("src").join("lib.rs"), LIB_ARDUINO_RS)?;