Skip to content

Commit

Permalink
Add support for PlatformIO platform = native (#97)
Browse files Browse the repository at this point in the history
* Add support for PlatformIO `platform = native`

* change the call, not the function
  • Loading branch information
delan authored Nov 30, 2024
1 parent 04e5c4c commit 0e49675
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 16 deletions.
2 changes: 1 addition & 1 deletion cargo-pio/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
};
Expand Down
2 changes: 1 addition & 1 deletion src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
Expand Down
6 changes: 5 additions & 1 deletion src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ impl Crate {
}
}

/// Create a `config.toml` in `.cargo` with a `[target]` and `[unstable]` section.
/// 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<impl AsRef<str>>,
Expand Down
17 changes: 10 additions & 7 deletions src/pio/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ pub struct SconsVariables {
pub linkflags: String,
pub link: String,
pub linkcom: String,
pub mcu: String,
pub mcu: Option<String>,
pub clangargs: Option<String>,

pub pio_platform_dir: String,
pub pio_framework_dir: String,
pub pio_platform_dir: Option<String>,
pub pio_framework_dir: Option<String>,
}

impl SconsVariables {
Expand All @@ -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
Expand Down Expand Up @@ -313,7 +313,10 @@ impl Builder {
)?;

let rust_lib = cargo_crate.set_library_type(["staticlib"])?;
cargo_crate.create_config_toml(Some(resolution.target.clone()), 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)?;
Expand Down
27 changes: 21 additions & 6 deletions src/pio/resources/platformio.cargo.py.resource
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "")
Expand Down Expand Up @@ -66,25 +66,40 @@ 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")

return result

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)

0 comments on commit 0e49675

Please sign in to comment.