Skip to content

Commit

Permalink
Remove legacy, add tests (#387)
Browse files Browse the repository at this point in the history
* remove legacy build-plan

* add tests
  • Loading branch information
boozook authored Jun 17, 2024
1 parent 32d8dfd commit bd59cdf
Show file tree
Hide file tree
Showing 25 changed files with 335 additions and 51 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ system = { version = "0.3", path = "api/system", package = "playdate-system", de
sys = { version = "0.4", path = "api/sys", package = "playdate-sys", default-features = false }

tool = { version = "0.1", path = "support/tool", package = "playdate-tool" }
build = { version = "=0.4.0-pre3", path = "support/build", package = "playdate-build", default-features = false }
build = { version = "0.4", path = "support/build", package = "playdate-build", default-features = false }
utils = { version = "0.3", path = "support/utils", package = "playdate-build-utils", default-features = false }
device = { version = "0.2", path = "support/device", package = "playdate-device" }
simulator = { version = "0.1", path = "support/sim-ctrl", package = "playdate-simulator-utils", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion cargo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargo-playdate"
version = "0.5.0-beta.6"
version = "0.5.0-pre.1"
readme = "README.md"
description = "Build tool for neat yellow console."
keywords = ["playdate", "build", "cargo", "plugin", "cargo-subcommand"]
Expand Down
34 changes: 14 additions & 20 deletions cargo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ It can build programs written in Rust, manage assets, build package for Playdate
Usually it builds static or dynamic libraries for sim and hardware,
but also it can build executable binaries for hardware and this method produces highly optimized output with dramatically minimized size (thanks to DCE & LTO)\*.

\* _For executable binaries use `--no-gcc` argument._
\* _For executable binaries use `--no-gcc` argument needed to set up alternative linking final binary._

### Platform specific pre-req install instructions

Expand Down Expand Up @@ -57,10 +57,7 @@ cargo +nightly playdate --version

Or install to use bleeding edge bits from a local git clone:
```bash
mkdir ~/code
cd ~/code
git clone https://github.com/boozook/playdate.git
cargo +nightly install --path="$HOME/code/playdate/cargo" cargo-playdate
cargo +nightly install cargo-playdate --git=https://github.com/boozook/playdate.git
```

## Hello World
Expand Down Expand Up @@ -109,30 +106,27 @@ Execute `cargo playdate -h` for more details, or with `--help` for further more.

### Limitations

1. Global crate-level attributes like `crate_type` and `crate_name` doesn't supported, e.g:
```rust
#![crate_name = "Game"]
#![crate_type = "lib"]
```

2. Cargo-targets such as `bin` and `example` should be in the cargo manifest. Autodetect isn't yet tested and may not work. Example:
```toml
[[example]]
name = "demo"
crate-type = ["dylib", "staticlib"]
path = "examples/demo.rs"
```
* The `cargo-playdate` supports [cargo's auto-targets][target-auto-discovery] such as `bin` and `example`, but only for binary executable targets ignoring `#![crate_type = "lib"]` attribute. So if you want to build `example`-target as `lib`, that needed for run in simulator, you could declare it in the package manifest like this:
```toml
[[example]]
name = "demo"
crate-type = ["dylib", "staticlib"]
path = "examples/demo.rs"
```
Otherwise `example` will be built as `bin` and runnable on device only.
In future versions it may be fixed with adding support of `rustc` command like it does `cargo rustc` to set `--crate-type`.

[target-auto-discovery]: https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery

3. Assets especially for `example` cargo-targets inherits from package assets. Currently there's no way to set assets for single cargo-target, but only for entire package __or for dev-targets__ - [there is `dev-assets` extra table][dev-assets-doc] inherited by main.
* Assets especially for `example` cargo-targets inherits from package assets. Currently there's no way to set assets for single cargo-target, but only for entire package __and for dev-targets__ - [there is `dev-assets` extra table][dev-assets-doc] inherited by package assets.


[dev-assets-doc]: https://github.com/boozook/playdate/tree/main/support/build#dev-assets


## Troubleshooting

* On windows in some cases hardware cannot be ejected because of no permissions. Try to give rights and/or build `cargo-playdate` with feature `eject`.
* On any OS in case of a restricted environment hardware cannot be ejected because of no permissions. Try to give rights and/or build `cargo-playdate` with feature `eject`.

* Welcome to [discussions](https://github.com/boozook/playdate/discussions) and [issues](https://github.com/boozook/playdate/issues).

Expand Down
7 changes: 0 additions & 7 deletions cargo/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ pub struct Config<'cfg> {
sdk: Lazy<Sdk>,
gcc: Lazy<ArmToolchain>,
rustflags: Lazy<Rustflags>,
build_plan: Lazy<crate::utils::cargo::build_plan::format::BuildPlan>,
unit_graph: Lazy<crate::utils::cargo::unit_graph::format::UnitGraph>,
ws_metadata: Lazy<crate::utils::cargo::metadata::CargoMetadataPd>,
target_infos: Lazy<HashMap<CompileKind, Lazy<TargetInfo>>>,
Expand Down Expand Up @@ -130,7 +129,6 @@ impl<'cfg> Config<'cfg> {
sdk: Lazy::new(),
gcc: Lazy::new(),
rustflags: Lazy::new(),
build_plan: Lazy::new(),
unit_graph: Lazy::new(),
ws_metadata: Lazy::new(),
target_infos: Lazy::new(),
Expand Down Expand Up @@ -166,11 +164,6 @@ impl<'cfg> Config<'cfg> {
})
}

#[deprecated = "corrupts cargo build cache"]
pub fn build_plan(&self) -> CargoResult<&crate::utils::cargo::build_plan::format::BuildPlan> {
self.build_plan
.try_get_or_create(|| crate::utils::cargo::build_plan::build_plan(self))
}

pub fn unit_graph(&self) -> CargoResult<&crate::utils::cargo::unit_graph::format::UnitGraph> {
self.unit_graph
Expand Down
1 change: 0 additions & 1 deletion cargo/src/package/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use anyhow::anyhow;
use anyhow::bail;
use cargo::core::PackageId;
use cargo::CargoResult;
use cargo::core::Package;
use cargo::core::compiler::CompileKind;
use cargo::core::compiler::CrateType;
use cargo::core::profiles::DebugInfo;
Expand Down
2 changes: 1 addition & 1 deletion cargo/src/proc/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ pub mod format {
use serde::Serialize;
use serde::Deserialize;
use cargo::core::PackageId;
use crate::utils::cargo::build_plan::format::de_crate_types;
use crate::utils::cargo::format::de_crate_types;
use crate::utils::cargo::format::de_package_id_or_spec;
pub use crate::utils::cargo::format::TargetKind;

Expand Down
26 changes: 26 additions & 0 deletions cargo/src/utils/cargo/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,32 @@ impl Serialize for TargetKind {
}


#[derive(Debug, Clone, Copy)]
pub enum TargetKindWild {
Lib,
Bin,
Test,
Bench,
ExampleLib,
ExampleBin,
CustomBuild,
}

impl PartialEq<TargetKind> for TargetKindWild {
fn eq(&self, other: &TargetKind) -> bool {
match self {
TargetKindWild::Lib => matches!(other, TargetKind::Lib(_)),
TargetKindWild::Bin => matches!(other, TargetKind::Bin),
TargetKindWild::Test => matches!(other, TargetKind::Test),
TargetKindWild::Bench => matches!(other, TargetKind::Bench),
TargetKindWild::ExampleLib => matches!(other, TargetKind::Example),
TargetKindWild::ExampleBin => matches!(other, TargetKind::Example),
TargetKindWild::CustomBuild => matches!(other, TargetKind::CustomBuild),
}
}
}


pub fn de_package_id_or_specs<'de, D>(deserializer: D) -> Result<Vec<PackageId>, D::Error>
where D: Deserializer<'de> {
let items = Vec::<String>::deserialize(deserializer)?;
Expand Down
4 changes: 2 additions & 2 deletions cargo/src/utils/cargo/meta_deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use serde::de::IntoDeserializer;
use crate::config::Config;
use crate::logger::LogErr;

use super::build_plan::format::TargetKind;
use super::build_plan::TargetKindWild;
use super::format::TargetKind;
use super::format::TargetKindWild;
use super::metadata::format::{Package, CrateMetadata};
use super::metadata::CargoMetadataPd;
use super::unit_graph::format::{Unit, UnitTarget};
Expand Down
1 change: 0 additions & 1 deletion cargo/src/utils/cargo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use playdate::consts::DEVICE_TARGET;

/// Shared format
pub(crate) mod format;
pub mod build_plan;
pub mod unit_graph;
pub mod meta_deps;
pub mod metadata;
Expand Down
3 changes: 1 addition & 2 deletions cargo/src/utils/cargo/unit_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ use crate::cli::cmd::Cmd;
use crate::config::Config;
use crate::proc::cargo_proxy_cmd;
use crate::proc::read_cargo_json;
use super::format::TargetKindWild;
use self::format::UnitGraph;

use super::build_plan::TargetKindWild;


pub fn unit_graph(cfg: &Config) -> CargoResult<UnitGraph> {
let mut cargo = cargo_proxy_cmd(cfg, &Cmd::Build)?;
Expand Down
1 change: 1 addition & 0 deletions cargo/tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ mod common;

pub mod build {
pub mod simple;
pub mod auto_target;
}
91 changes: 91 additions & 0 deletions cargo/tests/build/auto_target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use std::ffi::OsStr;
use std::ffi::OsString;
use std::path::Path;
use std::path::PathBuf;
use std::process::Output;
use anyhow::Result;

use ::build::consts::DEVICE_TARGET;
use crate::common::*;


fn run_build(crate_path: &Path,
args: impl IntoIterator<Item = impl Into<OsString>>)
-> Result<(Output, &'static Path)> {
println!("crate: {}", crate_path.display());

let target_dir = target_dir();
let target_dir_arg = format!("--target-dir={}", target_dir.display());
let args = args.into_iter()
.map(Into::into)
.chain([OsString::from(target_dir_arg)]);
let output = Tool::build(crate_path, args)?;
assert!(
output.status.success(),
"Tool failed with stderr:\n{}",
std::str::from_utf8(&output.stderr).unwrap()
);
Ok((output, target_dir))
}

fn test_artifact_dev(path: &Path, _debug: bool) {
println!("validating: {}", path.display());
assert!(path.exists(), "path does not exist: {}", path.display());
}


fn export_dir(target_dir: &Path, target: &str, profile: &str) -> PathBuf { target_dir.join(target).join(profile) }


#[test]
fn bins_examples() -> Result<()> {
let target = DEVICE_TARGET;
let args = ["--device", "--bins", "--examples"].into_iter().map(OsStr::new);

let path = auto_target()?;
let (_, target_dir) = run_build(path, args.clone())?;
let export_dir = export_dir(target_dir, target, "debug");

// check expectations:
let package_name = "test-auto-target";
let cargo_package_name = to_cargo_package_crate_name(Path::new(package_name)).expect("package_crate_name");
for trg in ["test-auto-target", "auto-bin", "example-bin"] {
let cargo_target_fullname = format!("{cargo_package_name}-{trg}");
let artifact = export_dir.join("playdate")
.join(cargo_target_fullname)
.join(PathBuf::from("build/pdex.elf"));
println!("should be there: {artifact:?}");
test_artifact_dev(&artifact, false);
}

Ok(())
}


#[test]
#[cfg_attr(windows, ignore = "Off until paths on Windows fixed.")]
// Error on Windows:
// failed to parse value from --config argument `target.thumbv7em-none-eabihf.rustflags=["-Ctarget-cpu=cortex-m7", "-Clink-args=--emit-relocs", "-Crelocation-model=pic", "-Csoft-float=no", "-Clink-arg=--cref", "-Clink-arg=--gc-sections", "-Clink-arg=--entry=eventHandlerShim", "-Clink-arg=-T\\?\\D:\\a\playdate\\playdate\\target\\tmp\\pd.x"]` as a dotted key expression
fn bins_examples_no_gcc() -> Result<()> {
let target = DEVICE_TARGET;
let args = ["--device", "--bins", "--examples", "--no-gcc"].into_iter()
.map(OsStr::new);

let path = auto_target()?;
let (_, target_dir) = run_build(path, args.clone())?;
let export_dir = export_dir(target_dir, target, "debug");

// check expectations:
let package_name = "test-auto-target";
let cargo_package_name = to_cargo_package_crate_name(Path::new(package_name)).expect("package_crate_name");
for trg in ["test-auto-target", "auto-bin", "example-bin"] {
let cargo_target_fullname = format!("{cargo_package_name}-{trg}");
let artifact = export_dir.join("playdate")
.join(cargo_target_fullname)
.join(PathBuf::from("build/pdex.elf"));
println!("should be there: {artifact:?}");
test_artifact_dev(&artifact, false);
}

Ok(())
}
7 changes: 0 additions & 7 deletions cargo/tests/build/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ const EXAMPLE_PREFIX: &str = "example";
fn dev_lib_release() -> Result<()> {
let target = DEVICE_TARGET;
let args = ["--device", "--lib", "--release"].into_iter().map(OsStr::new);
// let args = ["--device", "--no-sdk", "--no-gcc", "--release"].into_iter().map(OsStr::new);

for path in simple_crates()? {
let (_, target_dir) = run_build(&path, args.clone())?;
Expand Down Expand Up @@ -200,12 +199,6 @@ fn dev_sim_release_exp() -> Result<()> {
}


// (issue: #315) Convert dir-name to package-name, then to crate_name
fn to_cargo_package_crate_name(path: &Path) -> Option<String> {
Some(path.file_name()?.to_str()?.replace('-', "_"))
}


mod examples {
use super::*;
use std::ffi::OsStr;
Expand Down
12 changes: 12 additions & 0 deletions cargo/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ pub fn simple_crates() -> Result<impl Iterator<Item = PathBuf>> {
Ok(crates)
}

pub fn auto_target() -> Result<&'static Path> {
let root = Path::new("tests/crates/auto-target");
assert!(root.exists());
Ok(root)
}

pub fn workspace() -> Result<&'static Path> {
let root = Path::new("tests/crates/workspace");
assert!(root.exists());
Expand Down Expand Up @@ -154,3 +160,9 @@ pub fn target_triple() -> String {
)
}
}


// (issue: #315) Convert dir-name to package-name, then to crate_name
pub fn to_cargo_package_crate_name(path: &Path) -> Option<String> {
Some(path.file_name()?.to_str()?.replace('-', "_"))
}
21 changes: 21 additions & 0 deletions cargo/tests/crates/auto-target/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[workspace]

[package]
name = "test-auto-target"
version = "0.1.0"
edition = "2021"
publish = false

autotests = false
autobenches = false


[dependencies.pd]
package = "playdate-sys"
path = "../../../../api/sys"
features = ["lang-items"]


[profile]
dev.panic = "abort"
release.panic = "abort"
Loading

0 comments on commit bd59cdf

Please sign in to comment.