mirror of
https://github.com/SeleDreams/cargo-nds.git
synced 2025-06-18 19:15:43 -04:00
started work on migrating it to cargo-nds
This commit is contained in:
parent
af2d8bfd79
commit
d991297793
118
Cargo.lock
generated
118
Cargo.lock
generated
@ -66,7 +66,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo-3ds"
|
name = "cargo-nds"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
@ -91,15 +91,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo_metadata"
|
name = "cargo_metadata"
|
||||||
version = "0.14.2"
|
version = "0.18.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
|
checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"camino",
|
"camino",
|
||||||
"cargo-platform",
|
"cargo-platform",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -149,6 +150,12 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
@ -159,12 +166,28 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
@ -184,19 +207,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "memchr"
|
||||||
version = "1.0.70"
|
version = "2.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.81"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@ -269,6 +298,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -283,9 +321,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.39"
|
version = "2.0.60"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -309,12 +347,57 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "thiserror"
|
||||||
version = "0.5.11"
|
version = "1.0.59"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.59"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -460,3 +543,12 @@ name = "windows_x86_64_msvc"
|
|||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.6.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
14
Cargo.toml
14
Cargo.toml
@ -1,22 +1,22 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cargo-3ds"
|
name = "cargo-nds"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
authors = ["Rust3DS Org", "Andrea Ciliberti <meziu210@icloud.com>"]
|
authors = ["Rustnds Org", "Andrea Ciliberti <meziu210@icloud.com>"]
|
||||||
description = "Cargo wrapper for developing Nintendo 3DS homebrew apps"
|
description = "Cargo wrapper for developing Nintendo nds homebrew apps"
|
||||||
repository = "https://github.com/rust3ds/cargo-3ds"
|
repository = "https://github.com/rustnds/cargo-nds"
|
||||||
keywords = ["3ds", "homebrew"]
|
keywords = ["nds", "homebrew"]
|
||||||
categories = ["command-line-utilities", "development-tools::cargo-plugins"]
|
categories = ["command-line-utilities", "development-tools::cargo-plugins"]
|
||||||
exclude = [".github"]
|
exclude = [".github"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cargo_metadata = "0.14.0"
|
cargo_metadata = "0.18.1"
|
||||||
rustc_version = "0.4.0"
|
rustc_version = "0.4.0"
|
||||||
semver = "1.0.10"
|
semver = "1.0.10"
|
||||||
serde = { version = "1.0.139", features = ["derive"] }
|
serde = { version = "1.0.139", features = ["derive"] }
|
||||||
tee = "0.1.0"
|
tee = "0.1.0"
|
||||||
toml = "0.5.6"
|
toml = "0.8.12"
|
||||||
clap = { version = "4.0.15", features = ["derive", "wrap_help"] }
|
clap = { version = "4.0.15", features = ["derive", "wrap_help"] }
|
||||||
shlex = "1.1.0"
|
shlex = "1.1.0"
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
|
145
src/command.rs
145
src/command.rs
@ -1,4 +1,4 @@
|
|||||||
use std::fs;
|
use std::{env, fs};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
@ -6,12 +6,12 @@ use std::sync::OnceLock;
|
|||||||
use cargo_metadata::Message;
|
use cargo_metadata::Message;
|
||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, Parser, Subcommand};
|
||||||
|
|
||||||
use crate::{build_3dsx, build_smdh, cargo, get_metadata, link, print_command, CTRConfig};
|
use crate::{build_nds, cargo, get_metadata, link, print_command, NDSConfig};
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(name = "cargo", bin_name = "cargo")]
|
#[command(name = "cargo", bin_name = "cargo")]
|
||||||
pub enum Cargo {
|
pub enum Cargo {
|
||||||
#[command(name = "3ds")]
|
#[command(name = "nds")]
|
||||||
Input(Input),
|
Input(Input),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ pub struct Input {
|
|||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
pub cmd: CargoCmd,
|
pub cmd: CargoCmd,
|
||||||
|
|
||||||
/// Print the exact commands `cargo-3ds` is running. Note that this does not
|
/// Print the exact commands `cargo-nds` is running. Note that this does not
|
||||||
/// set the verbose flag for cargo itself. To set cargo's verbosity flag, add
|
/// set the verbose flag for cargo itself. To set cargo's verbosity flag, add
|
||||||
/// `-- -v` to the end of the command line.
|
/// `-- -v` to the end of the command line.
|
||||||
#[arg(long, short = 'v', global = true)]
|
#[arg(long, short = 'v', global = true)]
|
||||||
@ -34,32 +34,32 @@ pub struct Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run a cargo command. COMMAND will be forwarded to the real
|
/// Run a cargo command. COMMAND will be forwarded to the real
|
||||||
/// `cargo` with the appropriate arguments for the 3DS target.
|
/// `cargo` with the appropriate arguments for the nds target.
|
||||||
///
|
///
|
||||||
/// If an unrecognized COMMAND is used, it will be passed through unmodified
|
/// If an unrecognized COMMAND is used, it will be passed through unmodified
|
||||||
/// to `cargo` with the appropriate flags set for the 3DS target.
|
/// to `cargo` with the appropriate flags set for the nds target.
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
#[command(allow_external_subcommands = true)]
|
#[command(allow_external_subcommands = true)]
|
||||||
pub enum CargoCmd {
|
pub enum CargoCmd {
|
||||||
/// Builds an executable suitable to run on a 3DS (3dsx).
|
/// Builds an executable suitable to run on a DS (nds).
|
||||||
Build(Build),
|
Build(Build),
|
||||||
|
|
||||||
/// Builds an executable and sends it to a device with `3dslink`.
|
/// Builds an executable and sends it to a device with `dslink`.
|
||||||
Run(Run),
|
Run(Run),
|
||||||
|
|
||||||
/// Builds a test executable and sends it to a device with `3dslink`.
|
/// Builds a test executable and sends it to a device with `dslink`.
|
||||||
///
|
///
|
||||||
/// This can be used with `--test` for integration tests, or `--lib` for
|
/// This can be used with `--test` for integration tests, or `--lib` for
|
||||||
/// unit tests (which require a custom test runner).
|
/// unit tests (which require a custom test runner).
|
||||||
Test(Test),
|
Test(Test),
|
||||||
|
|
||||||
/// Sets up a new cargo project suitable to run on a 3DS.
|
/// Sets up a new cargo project suitable to run on a DS.
|
||||||
New(New),
|
New(New),
|
||||||
|
|
||||||
// NOTE: it seems docstring + name for external subcommands are not rendered
|
// NOTE: it seems docstring + name for external subcommands are not rendered
|
||||||
// in help, but we might as well set them here in case a future version of clap
|
// in help, but we might as well set them here in case a future version of clap
|
||||||
// does include them in help text.
|
// does include them in help text.
|
||||||
/// Run any other `cargo` command with custom building tailored for the 3DS.
|
/// Run any other `cargo` command with custom building tailored for the nds.
|
||||||
#[command(external_subcommand, name = "COMMAND")]
|
#[command(external_subcommand, name = "COMMAND")]
|
||||||
Passthrough(Vec<String>),
|
Passthrough(Vec<String>),
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ pub struct RemainingArgs {
|
|||||||
///
|
///
|
||||||
/// To pass arguments to an executable being run, a *second* `--` must be
|
/// To pass arguments to an executable being run, a *second* `--` must be
|
||||||
/// used to disambiguate cargo arguments from executable arguments.
|
/// used to disambiguate cargo arguments from executable arguments.
|
||||||
/// For example, `cargo 3ds run -- -- xyz` runs an executable with the argument
|
/// For example, `cargo nds run -- -- xyz` runs an executable with the argument
|
||||||
/// `xyz`.
|
/// `xyz`.
|
||||||
#[arg(
|
#[arg(
|
||||||
trailing_var_arg = true,
|
trailing_var_arg = true,
|
||||||
@ -97,23 +97,23 @@ pub struct Build {
|
|||||||
pub struct Run {
|
pub struct Run {
|
||||||
/// Specify the IP address of the device to send the executable to.
|
/// Specify the IP address of the device to send the executable to.
|
||||||
///
|
///
|
||||||
/// Corresponds to 3dslink's `--address` arg, which defaults to automatically
|
/// Corresponds to ndslink's `--address` arg, which defaults to automatically
|
||||||
/// finding the device.
|
/// finding the device.
|
||||||
#[arg(long, short = 'a')]
|
#[arg(long, short = 'a')]
|
||||||
pub address: Option<std::net::Ipv4Addr>,
|
pub address: Option<std::net::Ipv4Addr>,
|
||||||
|
|
||||||
/// Set the 0th argument of the executable when running it. Corresponds to
|
/// Set the 0th argument of the executable when running it. Corresponds to
|
||||||
/// 3dslink's `--argv0` argument.
|
/// ndslink's `--argv0` argument.
|
||||||
#[arg(long, short = '0')]
|
#[arg(long, short = '0')]
|
||||||
pub argv0: Option<String>,
|
pub argv0: Option<String>,
|
||||||
|
|
||||||
/// Start the 3dslink server after sending the executable. Corresponds to
|
/// Start the ndslink server after sending the executable. Corresponds to
|
||||||
/// 3dslink's `--server` argument.
|
/// ndslink's `--server` argument.
|
||||||
#[arg(long, short = 's', default_value_t = false)]
|
#[arg(long, short = 's', default_value_t = false)]
|
||||||
pub server: bool,
|
pub server: bool,
|
||||||
|
|
||||||
/// Set the number of tries when connecting to the device to send the executable.
|
/// Set the number of tries when connecting to the device to send the executable.
|
||||||
/// Corresponds to 3dslink's `--retries` argument.
|
/// Corresponds to ndslink's `--retries` argument.
|
||||||
// Can't use `short = 'r'` because that would conflict with cargo's `--release/-r`
|
// Can't use `short = 'r'` because that would conflict with cargo's `--release/-r`
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub retries: Option<usize>,
|
pub retries: Option<usize>,
|
||||||
@ -133,7 +133,7 @@ pub struct Test {
|
|||||||
pub no_run: bool,
|
pub no_run: bool,
|
||||||
|
|
||||||
/// If set, documentation tests will be built instead of unit tests.
|
/// If set, documentation tests will be built instead of unit tests.
|
||||||
/// This implies `--no-run`, unless Cargo's `target.armv6k-nintendo-3ds.runner`
|
/// This implies `--no-run`, unless Cargo's `target.armv6k-nintendo-nds.runner`
|
||||||
/// is configured.
|
/// is configured.
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub doc: bool,
|
pub doc: bool,
|
||||||
@ -158,7 +158,7 @@ impl CargoCmd {
|
|||||||
/// Returns the additional arguments run by the "official" cargo subcommand.
|
/// Returns the additional arguments run by the "official" cargo subcommand.
|
||||||
pub fn cargo_args(&self) -> Vec<String> {
|
pub fn cargo_args(&self) -> Vec<String> {
|
||||||
match self {
|
match self {
|
||||||
CargoCmd::Build(build) => build.passthrough.cargo_args(),
|
CargoCmd::Build(build) =>build.passthrough.cargo_args(),
|
||||||
CargoCmd::Run(run) => run.build_args.passthrough.cargo_args(),
|
CargoCmd::Run(run) => run.build_args.passthrough.cargo_args(),
|
||||||
CargoCmd::Test(test) => test.cargo_args(),
|
CargoCmd::Test(test) => test.cargo_args(),
|
||||||
CargoCmd::New(new) => {
|
CargoCmd::New(new) => {
|
||||||
@ -172,7 +172,7 @@ impl CargoCmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the cargo subcommand run by `cargo-3ds` when handling a [`CargoCmd`].
|
/// Returns the cargo subcommand run by `cargo-nds` when handling a [`CargoCmd`].
|
||||||
///
|
///
|
||||||
/// # Notes
|
/// # Notes
|
||||||
///
|
///
|
||||||
@ -203,13 +203,13 @@ impl CargoCmd {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether or not this command should build a 3DSX executable file.
|
/// Whether or not this command should build a ndsX executable file.
|
||||||
pub fn should_build_3dsx(&self) -> bool {
|
pub fn should_build_ndsx(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Build(_) | CargoCmd::Run(_) => true,
|
Self::Build(_) | CargoCmd::Run(_) => true,
|
||||||
&Self::Test(Test { doc, .. }) => {
|
&Self::Test(Test { doc, .. }) => {
|
||||||
if doc {
|
if doc {
|
||||||
eprintln!("Documentation tests requested, no 3dsx will be built");
|
eprintln!("Documentation tests requested, no ndsx will be built");
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@ -219,8 +219,8 @@ impl CargoCmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether or not the resulting executable should be sent to the 3DS with
|
/// Whether or not the resulting executable should be sent to the nds with
|
||||||
/// `3dslink`.
|
/// `ndslink`.
|
||||||
pub fn should_link_to_device(&self) -> bool {
|
pub fn should_link_to_device(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Test(Test { no_run: true, .. }) => false,
|
Self::Test(Test { no_run: true, .. }) => false,
|
||||||
@ -247,7 +247,7 @@ impl CargoCmd {
|
|||||||
|
|
||||||
if let Self::Test(Test { doc: true, .. }) = self {
|
if let Self::Test(Test { doc: true, .. }) = self {
|
||||||
// We don't care about JSON output for doctests since we're not
|
// We don't care about JSON output for doctests since we're not
|
||||||
// building any 3dsx etc. Just use the default output as it's more
|
// building any ndsx etc. Just use the default output as it's more
|
||||||
// readable compared to DEFAULT_MESSAGE_FORMAT
|
// readable compared to DEFAULT_MESSAGE_FORMAT
|
||||||
Ok(Some(String::from("human")))
|
Ok(Some(String::from("human")))
|
||||||
} else {
|
} else {
|
||||||
@ -293,11 +293,11 @@ impl CargoCmd {
|
|||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// - `cargo 3ds build` and other "build" commands will use their callbacks to build the final `.3dsx` file and link it.
|
/// - `cargo nds build` and other "build" commands will use their callbacks to build the final `.ndsx` file and link it.
|
||||||
/// - `cargo 3ds new` and other generic commands will use their callbacks to make 3ds-specific changes to the environment.
|
/// - `cargo nds new` and other generic commands will use their callbacks to make nds-specific changes to the environment.
|
||||||
pub fn run_callback(&self, messages: &[Message]) {
|
pub fn run_callback(&self, messages: &[Message]) {
|
||||||
// Process the metadata only for commands that have it/use it
|
// Process the metadata only for commands that have it/use it
|
||||||
let config = if self.should_build_3dsx() {
|
let config = if self.should_build_ndsx() {
|
||||||
eprintln!("Getting metadata");
|
eprintln!("Getting metadata");
|
||||||
|
|
||||||
Some(get_metadata(messages))
|
Some(get_metadata(messages))
|
||||||
@ -343,78 +343,45 @@ impl RemainingArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Build {
|
impl Build {
|
||||||
/// Callback for `cargo 3ds build`.
|
/// Callback for `cargo nds build`.
|
||||||
///
|
///
|
||||||
/// This callback handles building the application as a `.3dsx` file.
|
/// This callback handles building the application as a `.ndsx` file.
|
||||||
fn callback(&self, config: &Option<CTRConfig>) {
|
fn callback(&self, config: &Option<NDSConfig>) {
|
||||||
if let Some(config) = config {
|
if let Some(config) = config {
|
||||||
eprintln!("Building smdh: {}", config.path_smdh().display());
|
eprintln!("Building nds: {}", config.path_nds().display());
|
||||||
build_smdh(config, self.verbose);
|
build_nds(config, self.verbose);
|
||||||
|
|
||||||
eprintln!("Building 3dsx: {}", config.path_3dsx().display());
|
|
||||||
build_3dsx(config, self.verbose);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Run {
|
impl Run {
|
||||||
/// Get the args to pass to `3dslink` based on these options.
|
/// Get the args to pass to `ndslink` based on these options.
|
||||||
pub fn get_3dslink_args(&self) -> Vec<String> {
|
pub fn get_dslink_args(&self) -> Vec<String> {
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
|
|
||||||
if let Some(address) = self.address {
|
if let Some(address) = self.address {
|
||||||
args.extend(["--address".to_string(), address.to_string()]);
|
args.extend(["-a".to_string(), address.to_string()]);
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(argv0) = &self.argv0 {
|
|
||||||
args.extend(["--arg0".to_string(), argv0.clone()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(retries) = self.retries {
|
|
||||||
args.extend(["--retries".to_string(), retries.to_string()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.server {
|
|
||||||
args.push("--server".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let exe_args = self.build_args.passthrough.exe_args();
|
|
||||||
if !exe_args.is_empty() {
|
|
||||||
// For some reason 3dslink seems to want 2 instances of `--`, one
|
|
||||||
// in front of all of the args like this...
|
|
||||||
args.extend(["--args".to_string(), "--".to_string()]);
|
|
||||||
|
|
||||||
let mut escaped = false;
|
|
||||||
for arg in exe_args.iter().cloned() {
|
|
||||||
if arg.starts_with('-') && !escaped {
|
|
||||||
// And one before the first `-` arg that is passed in.
|
|
||||||
args.extend(["--".to_string(), arg]);
|
|
||||||
escaped = true;
|
|
||||||
} else {
|
|
||||||
args.push(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback for `cargo 3ds run`.
|
/// Callback for `cargo nds run`.
|
||||||
///
|
///
|
||||||
/// This callback handles launching the application via `3dslink`.
|
/// This callback handles launching the application via `dslink`.
|
||||||
fn callback(&self, config: &Option<CTRConfig>) {
|
fn callback(&self, config: &Option<NDSConfig>) {
|
||||||
// Run the normal "build" callback
|
// Run the normal "build" callback
|
||||||
self.build_args.callback(config);
|
self.build_args.callback(config);
|
||||||
|
|
||||||
if !self.use_custom_runner() {
|
if !self.use_custom_runner() {
|
||||||
if let Some(cfg) = config {
|
if let Some(cfg) = config {
|
||||||
eprintln!("Running 3dslink");
|
eprintln!("Running dslink");
|
||||||
link(cfg, self, self.build_args.verbose);
|
link(cfg, self, self.build_args.verbose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the cargo environment has `target.armv6k-nintendo-3ds.runner`
|
/// Returns whether the cargo environment has `target.armv6k-nintendo-nds.runner`
|
||||||
/// configured. This will only be checked once during the lifetime of the program,
|
/// configured. This will only be checked once during the lifetime of the program,
|
||||||
/// and takes into account the usual ways Cargo looks for its
|
/// and takes into account the usual ways Cargo looks for its
|
||||||
/// [configuration](https://doc.rust-lang.org/cargo/reference/config.html):
|
/// [configuration](https://doc.rust-lang.org/cargo/reference/config.html):
|
||||||
@ -426,14 +393,16 @@ impl Run {
|
|||||||
static HAS_RUNNER: OnceLock<bool> = OnceLock::new();
|
static HAS_RUNNER: OnceLock<bool> = OnceLock::new();
|
||||||
|
|
||||||
let &custom_runner_configured = HAS_RUNNER.get_or_init(|| {
|
let &custom_runner_configured = HAS_RUNNER.get_or_init(|| {
|
||||||
|
let blocksds = env::var("BLOCKSDS").unwrap_or("/opt/wonderful/thirdparty/blocksds/core".to_owned());
|
||||||
|
env::set_var("RUSTFLAGS", format!("-C link-args=-specs={blocksds}/sys/crts/ds_arm9.specs"));
|
||||||
|
|
||||||
let mut cmd = cargo(&self.config);
|
let mut cmd = cargo(&self.config);
|
||||||
cmd.args([
|
cmd.args([
|
||||||
// https://github.com/rust-lang/cargo/issues/9301
|
// https://github.com/rust-lang/cargo/issues/9301
|
||||||
"-Z",
|
"-Z",
|
||||||
"unstable-options",
|
"build-std=core,alloc",
|
||||||
"config",
|
"--target",
|
||||||
"get",
|
"./armv5te-nintendo-ds.json"
|
||||||
"target.armv6k-nintendo-3ds.runner",
|
|
||||||
])
|
])
|
||||||
.stdout(Stdio::null())
|
.stdout(Stdio::null())
|
||||||
.stderr(Stdio::null());
|
.stderr(Stdio::null());
|
||||||
@ -458,10 +427,10 @@ impl Run {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Test {
|
impl Test {
|
||||||
/// Callback for `cargo 3ds test`.
|
/// Callback for `cargo nds test`.
|
||||||
///
|
///
|
||||||
/// This callback handles launching the application via `3dslink`.
|
/// This callback handles launching the application via `ndslink`.
|
||||||
fn callback(&self, config: &Option<CTRConfig>) {
|
fn callback(&self, config: &Option<NDSConfig>) {
|
||||||
if self.no_run {
|
if self.no_run {
|
||||||
// If the tests don't have to run, use the "build" callback
|
// If the tests don't have to run, use the "build" callback
|
||||||
self.run_args.build_args.callback(config);
|
self.run_args.build_args.callback(config);
|
||||||
@ -479,7 +448,7 @@ impl Test {
|
|||||||
fn cargo_args(&self) -> Vec<String> {
|
fn cargo_args(&self) -> Vec<String> {
|
||||||
let mut cargo_args = self.run_args.build_args.passthrough.cargo_args();
|
let mut cargo_args = self.run_args.build_args.passthrough.cargo_args();
|
||||||
|
|
||||||
// We can't run 3DS executables on the host, but we want to respect
|
// We can't run nds executables on the host, but we want to respect
|
||||||
// the user's "runner" configuration if set.
|
// the user's "runner" configuration if set.
|
||||||
//
|
//
|
||||||
// If doctests were requested, `--no-run` will be rejected on the
|
// If doctests were requested, `--no-run` will be rejected on the
|
||||||
@ -512,9 +481,9 @@ impl Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const TOML_CHANGES: &str = r#"ctru-rs = { git = "https://github.com/rust3ds/ctru-rs" }
|
const TOML_CHANGES: &str = r#"ctru-rs = { git = "https://github.com/rustnds/ctru-rs" }
|
||||||
|
|
||||||
[package.metadata.cargo-3ds]
|
[package.metadata.cargo-nds]
|
||||||
romfs_dir = "romfs"
|
romfs_dir = "romfs"
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@ -541,9 +510,9 @@ fn main() {
|
|||||||
"#;
|
"#;
|
||||||
|
|
||||||
impl New {
|
impl New {
|
||||||
/// Callback for `cargo 3ds new`.
|
/// Callback for `cargo nds new`.
|
||||||
///
|
///
|
||||||
/// This callback handles the custom environment modifications when creating a new 3DS project.
|
/// This callback handles the custom environment modifications when creating a new nds project.
|
||||||
fn callback(&self) {
|
fn callback(&self) {
|
||||||
// Commmit changes to the project only if is meant to be a binary
|
// Commmit changes to the project only if is meant to be a binary
|
||||||
if self.cargo_args.args.contains(&"--lib".to_string()) {
|
if self.cargo_args.args.contains(&"--lib".to_string()) {
|
||||||
@ -672,7 +641,7 @@ mod tests {
|
|||||||
expected_exe: &["bar"],
|
expected_exe: &["bar"],
|
||||||
},
|
},
|
||||||
] {
|
] {
|
||||||
let input: Vec<&str> = ["cargo", "3ds", "run"]
|
let input: Vec<&str> = ["cargo", "nds", "run"]
|
||||||
.iter()
|
.iter()
|
||||||
.chain(param.input)
|
.chain(param.input)
|
||||||
.copied()
|
.copied()
|
||||||
|
173
src/lib.rs
173
src/lib.rs
@ -21,7 +21,7 @@ use crate::graph::UnitGraph;
|
|||||||
/// parsing and returning the messages from the spawned process.
|
/// parsing and returning the messages from the spawned process.
|
||||||
///
|
///
|
||||||
/// For commands that produce an executable output, this function will build the
|
/// For commands that produce an executable output, this function will build the
|
||||||
/// `.elf` binary that can be used to create other 3ds files.
|
/// `.elf` binary that can be used to create other nds files.
|
||||||
pub fn run_cargo(input: &Input, message_format: Option<String>) -> (ExitStatus, Vec<Message>) {
|
pub fn run_cargo(input: &Input, message_format: Option<String>) -> (ExitStatus, Vec<Message>) {
|
||||||
let mut command = make_cargo_command(input, &message_format);
|
let mut command = make_cargo_command(input, &message_format);
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ pub fn run_cargo(input: &Input, message_format: Option<String>) -> (ExitStatus,
|
|||||||
let buf_reader: &mut dyn BufRead = match (message_format, &input.cmd) {
|
let buf_reader: &mut dyn BufRead = match (message_format, &input.cmd) {
|
||||||
// The user presumably cares about the message format if set, so we should
|
// The user presumably cares about the message format if set, so we should
|
||||||
// copy stuff to stdout like they expect. We can still extract the executable
|
// copy stuff to stdout like they expect. We can still extract the executable
|
||||||
// information out of it that we need for 3dsxtool etc.
|
// information out of it that we need for ndstool etc.
|
||||||
(Some(_), _) |
|
(Some(_), _) |
|
||||||
// Rustdoc unfortunately prints to stdout for compile errors, so
|
// Rustdoc unfortunately prints to stdout for compile errors, so
|
||||||
// we also use a tee when building doc tests too.
|
// we also use a tee when building doc tests too.
|
||||||
@ -104,14 +104,11 @@ fn should_use_ctru_debuginfo(cargo_cmd: &Command, verbose: bool) -> bool {
|
|||||||
|
|
||||||
/// Create a cargo command based on the context.
|
/// Create a cargo command based on the context.
|
||||||
///
|
///
|
||||||
/// For "build" commands (which compile code, such as `cargo 3ds build` or `cargo 3ds clippy`),
|
/// For "build" commands (which compile code, such as `cargo nds build` or `cargo nds clippy`),
|
||||||
/// if there is no pre-built std detected in the sysroot, `build-std` will be used instead.
|
/// if there is no pre-built std detected in the sysroot, `build-std` will be used instead.
|
||||||
pub fn make_cargo_command(input: &Input, message_format: &Option<String>) -> Command {
|
pub fn make_cargo_command(input: &Input, message_format: &Option<String>) -> Command {
|
||||||
let devkitpro =
|
let blocksds = env::var("BLOCKSDS").unwrap_or("/opt/wonderful/thirdparty/blocksds/core".to_owned());
|
||||||
env::var("DEVKITPRO").expect("DEVKITPRO is not defined as an environment variable");
|
let rustflags = format!("-C link-args=-specs={blocksds}/sys/crts/ds_arm9.specs");
|
||||||
// TODO: should we actually prepend the user's RUSTFLAGS for linking order? not sure
|
|
||||||
let rustflags =
|
|
||||||
env::var("RUSTFLAGS").unwrap_or_default() + &format!(" -L{devkitpro}/libctru/lib");
|
|
||||||
|
|
||||||
let cargo_cmd = &input.cmd;
|
let cargo_cmd = &input.cmd;
|
||||||
|
|
||||||
@ -125,21 +122,15 @@ pub fn make_cargo_command(input: &Input, message_format: &Option<String>) -> Com
|
|||||||
if cargo_cmd.should_compile() {
|
if cargo_cmd.should_compile() {
|
||||||
command
|
command
|
||||||
.arg("--target")
|
.arg("--target")
|
||||||
.arg("armv6k-nintendo-3ds")
|
.arg("armv5te-nintendo-ds.json")
|
||||||
|
.arg("-Z")
|
||||||
|
.arg("build-std=core,alloc")
|
||||||
.arg("--message-format")
|
.arg("--message-format")
|
||||||
.arg(
|
.arg(
|
||||||
message_format
|
message_format
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.unwrap_or(CargoCmd::DEFAULT_MESSAGE_FORMAT),
|
.unwrap_or(CargoCmd::DEFAULT_MESSAGE_FORMAT),
|
||||||
);
|
);
|
||||||
|
|
||||||
let sysroot = find_sysroot();
|
|
||||||
if !sysroot.join("lib/rustlib/armv6k-nintendo-3ds").exists() {
|
|
||||||
eprintln!("No pre-build std found, using build-std");
|
|
||||||
// Always building the test crate is not ideal, but we don't know if the
|
|
||||||
// crate being built uses #![feature(test)], so we build it just in case.
|
|
||||||
command.arg("-Z").arg("build-std=std,test");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let CargoCmd::Test(test) = cargo_cmd {
|
if let CargoCmd::Test(test) = cargo_cmd {
|
||||||
@ -212,10 +203,10 @@ pub fn check_rust_version() {
|
|||||||
let rustc_version = rustc_version::version_meta().unwrap();
|
let rustc_version = rustc_version::version_meta().unwrap();
|
||||||
|
|
||||||
if rustc_version.channel > Channel::Nightly {
|
if rustc_version.channel > Channel::Nightly {
|
||||||
eprintln!("cargo-3ds requires a nightly rustc version.");
|
eprintln!("cargo-nds requires a nightly rustc version.");
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Please run `rustup override set nightly` to use nightly in the \
|
"Please run `rustup override set nightly` to use nightly in the \
|
||||||
current directory, or use `cargo +nightly 3ds` to use it for a \
|
current directory, or use `cargo +nightly nds` to use it for a \
|
||||||
single invocation."
|
single invocation."
|
||||||
);
|
);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
@ -237,17 +228,17 @@ pub fn check_rust_version() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if old_version || old_commit {
|
if old_version || old_commit {
|
||||||
eprintln!("cargo-3ds requires rustc nightly version >= {MINIMUM_COMMIT_DATE}");
|
eprintln!("cargo-nds requires rustc nightly version >= {MINIMUM_COMMIT_DATE}");
|
||||||
eprintln!("Please run `rustup update nightly` to upgrade your nightly version");
|
eprintln!("Please run `rustup update nightly` to upgrade your nightly version");
|
||||||
|
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses messages returned by "build" cargo commands (such as `cargo 3ds build` or `cargo 3ds run`).
|
/// Parses messages returned by "build" cargo commands (such as `cargo nds build` or `cargo nds run`).
|
||||||
/// The returned [`CTRConfig`] is then used for further building in and execution
|
/// The returned [`CTRConfig`] is then used for further building in and execution
|
||||||
/// in [`build_smdh`], [`build_3dsx`], and [`link`].
|
/// in [`build_nds`], and [`link`].
|
||||||
pub fn get_metadata(messages: &[Message]) -> CTRConfig {
|
pub fn get_metadata(messages: &[Message]) -> NDSConfig {
|
||||||
let metadata = MetadataCommand::new()
|
let metadata = MetadataCommand::new()
|
||||||
.no_deps()
|
.no_deps()
|
||||||
.exec()
|
.exec()
|
||||||
@ -275,12 +266,12 @@ pub fn get_metadata(messages: &[Message]) -> CTRConfig {
|
|||||||
|
|
||||||
let (package, artifact) = (package.unwrap(), artifact.unwrap());
|
let (package, artifact) = (package.unwrap(), artifact.unwrap());
|
||||||
|
|
||||||
let mut icon = String::from("./icon.png");
|
let mut icon = String::from("./icon.bmp");
|
||||||
|
|
||||||
if !Path::new(&icon).exists() {
|
if !Path::new(&icon).exists() {
|
||||||
icon = format!(
|
icon = format!(
|
||||||
"{}/libctru/default_icon.png",
|
"{}/sys/icon.bmp",
|
||||||
env::var("DEVKITPRO").unwrap()
|
env::var("BLOCKSDS").unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,63 +291,41 @@ pub fn get_metadata(messages: &[Message]) -> CTRConfig {
|
|||||||
[] => String::from("Unspecified Author"), // as standard with the devkitPRO toolchain
|
[] => String::from("Unspecified Author"), // as standard with the devkitPRO toolchain
|
||||||
};
|
};
|
||||||
|
|
||||||
CTRConfig {
|
NDSConfig {
|
||||||
name,
|
name,
|
||||||
author,
|
author,
|
||||||
description: package
|
description: package
|
||||||
.description
|
.description
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| String::from("Homebrew Application")),
|
.unwrap_or_else(|| String::from("Homebrew Application")),
|
||||||
icon,
|
icon : icon,
|
||||||
target_path: artifact.executable.unwrap().into(),
|
target_path: artifact.executable.unwrap().into(),
|
||||||
cargo_manifest_path: package.manifest_path.into(),
|
cargo_manifest_path: package.manifest_path.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the smdh using `smdhtool`.
|
/// Builds the nds using `ndstool`.
|
||||||
/// This will fail if `smdhtool` is not within the running directory or in a directory found in $PATH
|
/// This will fail if `ndstool` is not within the running directory or in a directory found in $PATH
|
||||||
pub fn build_smdh(config: &CTRConfig, verbose: bool) {
|
pub fn build_nds(config: &NDSConfig, verbose: bool) {
|
||||||
let mut command = Command::new("smdhtool");
|
let mut command = Command::new("ndstool");
|
||||||
|
let banner_text = format!("\"{};{};{}\"", &config.name, &config.description, &config.author);
|
||||||
command
|
command
|
||||||
.arg("--create")
|
.arg("-c")
|
||||||
.arg(&config.name)
|
.arg(config.path_nds())
|
||||||
.arg(&config.description)
|
.arg("-9")
|
||||||
.arg(&config.author)
|
.arg(config.path_arm9())
|
||||||
|
.arg("-7")
|
||||||
|
.arg(config.path_arm7())
|
||||||
|
.arg("-b")
|
||||||
.arg(&config.icon)
|
.arg(&config.icon)
|
||||||
.arg(config.path_smdh())
|
.arg(banner_text);
|
||||||
.stdin(Stdio::inherit())
|
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit());
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
print_command(&command);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut process = command
|
|
||||||
.spawn()
|
|
||||||
.expect("smdhtool command failed, most likely due to 'smdhtool' not being in $PATH");
|
|
||||||
|
|
||||||
let status = process.wait().unwrap();
|
|
||||||
|
|
||||||
if !status.success() {
|
|
||||||
process::exit(status.code().unwrap_or(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the 3dsx using `3dsxtool`.
|
|
||||||
/// This will fail if `3dsxtool` is not within the running directory or in a directory found in $PATH
|
|
||||||
pub fn build_3dsx(config: &CTRConfig, verbose: bool) {
|
|
||||||
let mut command = Command::new("3dsxtool");
|
|
||||||
command
|
|
||||||
.arg(&config.target_path)
|
|
||||||
.arg(config.path_3dsx())
|
|
||||||
.arg(format!("--smdh={}", config.path_smdh().to_string_lossy()));
|
|
||||||
|
|
||||||
// If romfs directory exists, automatically include it
|
// If romfs directory exists, automatically include it
|
||||||
let (romfs_path, is_default_romfs) = get_romfs_path(config);
|
let (romfs_path, is_default_romfs) = get_romfs_path(config);
|
||||||
if romfs_path.is_dir() {
|
if romfs_path.is_dir() {
|
||||||
eprintln!("Adding RomFS from {}", romfs_path.display());
|
eprintln!("Adding RomFS from {}", romfs_path.display());
|
||||||
command.arg(format!("--romfs={}", romfs_path.to_string_lossy()));
|
command.arg("-d")
|
||||||
|
.arg(&romfs_path);
|
||||||
} else if !is_default_romfs {
|
} else if !is_default_romfs {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Could not find configured RomFS dir: {}",
|
"Could not find configured RomFS dir: {}",
|
||||||
@ -374,7 +343,7 @@ pub fn build_3dsx(config: &CTRConfig, verbose: bool) {
|
|||||||
.stdout(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
.stderr(Stdio::inherit())
|
.stderr(Stdio::inherit())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("3dsxtool command failed, most likely due to '3dsxtool' not being in $PATH");
|
.expect("ndstool command failed, most likely due to 'ndstool' not being in $PATH");
|
||||||
|
|
||||||
let status = process.wait().unwrap();
|
let status = process.wait().unwrap();
|
||||||
|
|
||||||
@ -383,13 +352,13 @@ pub fn build_3dsx(config: &CTRConfig, verbose: bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Link the generated 3dsx to a 3ds to execute and test using `3dslink`.
|
/// Link the generated nds to a ds to execute and test using `dslink`.
|
||||||
/// This will fail if `3dslink` is not within the running directory or in a directory found in $PATH
|
/// This will fail if `dslink` is not within the running directory or in a directory found in $PATH
|
||||||
pub fn link(config: &CTRConfig, run_args: &Run, verbose: bool) {
|
pub fn link(config: &NDSConfig, run_args: &Run, verbose: bool) {
|
||||||
let mut command = Command::new("3dslink");
|
let mut command = Command::new("dslink");
|
||||||
command
|
command
|
||||||
.arg(config.path_3dsx())
|
.args(run_args.get_dslink_args())
|
||||||
.args(run_args.get_3dslink_args())
|
.arg(config.path_nds())
|
||||||
.stdin(Stdio::inherit())
|
.stdin(Stdio::inherit())
|
||||||
.stdout(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
.stderr(Stdio::inherit());
|
.stderr(Stdio::inherit());
|
||||||
@ -407,7 +376,7 @@ pub fn link(config: &CTRConfig, run_args: &Run, verbose: bool) {
|
|||||||
|
|
||||||
/// Read the `RomFS` path from the Cargo manifest. If it's unset, use the default.
|
/// Read the `RomFS` path from the Cargo manifest. If it's unset, use the default.
|
||||||
/// The returned boolean is true when the default is used.
|
/// The returned boolean is true when the default is used.
|
||||||
pub fn get_romfs_path(config: &CTRConfig) -> (PathBuf, bool) {
|
pub fn get_romfs_path(config: &NDSConfig) -> (PathBuf, bool) {
|
||||||
let manifest_path = &config.cargo_manifest_path;
|
let manifest_path = &config.cargo_manifest_path;
|
||||||
let manifest_str = std::fs::read_to_string(manifest_path)
|
let manifest_str = std::fs::read_to_string(manifest_path)
|
||||||
.unwrap_or_else(|e| panic!("Could not open {}: {e}", manifest_path.display()));
|
.unwrap_or_else(|e| panic!("Could not open {}: {e}", manifest_path.display()));
|
||||||
@ -422,9 +391,9 @@ pub fn get_romfs_path(config: &CTRConfig) -> (PathBuf, bool) {
|
|||||||
.and_then(toml::Value::as_table)
|
.and_then(toml::Value::as_table)
|
||||||
.and_then(|table| table.get("metadata"))
|
.and_then(|table| table.get("metadata"))
|
||||||
.and_then(toml::Value::as_table)
|
.and_then(toml::Value::as_table)
|
||||||
.and_then(|table| table.get("cargo-3ds"))
|
.and_then(|table| table.get("nds"))
|
||||||
.and_then(toml::Value::as_table)
|
.and_then(toml::Value::as_table)
|
||||||
.and_then(|table| table.get("romfs_dir"))
|
.and_then(|table| table.get("romfs"))
|
||||||
.and_then(toml::Value::as_str)
|
.and_then(toml::Value::as_str)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
is_default = true;
|
is_default = true;
|
||||||
@ -437,8 +406,41 @@ pub fn get_romfs_path(config: &CTRConfig) -> (PathBuf, bool) {
|
|||||||
(romfs_path, is_default)
|
(romfs_path, is_default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the `icon` path from the Cargo manifest. If it's unset, use the default.
|
||||||
|
/// The returned boolean is true when the default is used.
|
||||||
|
pub fn get_icon_path(config: &NDSConfig) -> (PathBuf, bool) {
|
||||||
|
let manifest_path = &config.cargo_manifest_path;
|
||||||
|
let manifest_str = std::fs::read_to_string(manifest_path)
|
||||||
|
.unwrap_or_else(|e| panic!("Could not open {}: {e}", manifest_path.display()));
|
||||||
|
let manifest_data: toml::Value =
|
||||||
|
toml::de::from_str(&manifest_str).expect("Could not parse Cargo manifest as TOML");
|
||||||
|
|
||||||
|
// Find the icon setting and compute the path
|
||||||
|
let mut is_default = false;
|
||||||
|
|
||||||
|
let icon_setting = manifest_data
|
||||||
|
.as_table()
|
||||||
|
.and_then(|table| table.get("package"))
|
||||||
|
.and_then(toml::Value::as_table)
|
||||||
|
.and_then(|table| table.get("metadata"))
|
||||||
|
.and_then(toml::Value::as_table)
|
||||||
|
.and_then(|table| table.get("nds"))
|
||||||
|
.and_then(toml::Value::as_table)
|
||||||
|
.and_then(|table| table.get("icon"))
|
||||||
|
.and_then(toml::Value::as_str)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
is_default = true;
|
||||||
|
"/opt/wonderful/thirdparty/blocksds/core/sys/icon.bmp"
|
||||||
|
});
|
||||||
|
let mut icon_path = manifest_path.clone();
|
||||||
|
icon_path.pop(); // Pop Cargo.toml
|
||||||
|
icon_path.push(icon_setting);
|
||||||
|
|
||||||
|
(icon_path, is_default)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CTRConfig {
|
pub struct NDSConfig {
|
||||||
name: String,
|
name: String,
|
||||||
author: String,
|
author: String,
|
||||||
description: String,
|
description: String,
|
||||||
@ -447,13 +449,20 @@ pub struct CTRConfig {
|
|||||||
cargo_manifest_path: PathBuf,
|
cargo_manifest_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CTRConfig {
|
impl NDSConfig {
|
||||||
pub fn path_3dsx(&self) -> PathBuf {
|
pub fn path_nds(&self) -> PathBuf {
|
||||||
self.target_path.with_extension("3dsx")
|
self.target_path.with_extension("nds")
|
||||||
}
|
}
|
||||||
|
pub fn path_arm9(&self) -> PathBuf {
|
||||||
pub fn path_smdh(&self) -> PathBuf {
|
self.target_path.with_extension("arm9.elf")
|
||||||
self.target_path.with_extension("smdh")
|
}
|
||||||
|
pub fn path_arm7(&self) -> PathBuf {
|
||||||
|
let arm7 =self.target_path.with_extension("arm7.elf");
|
||||||
|
if arm7.exists() {
|
||||||
|
return arm7;
|
||||||
|
}
|
||||||
|
let blocksds= env::var("BLOCKSDS").unwrap_or("/opt/wonderful/thirdparty/blocksds/core".to_owned());
|
||||||
|
PathBuf::from(format!("{}/sys/default_arm7/arm7.elf",blocksds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use std::process;
|
use std::{env, process};
|
||||||
|
|
||||||
use cargo_3ds::command::Cargo;
|
use cargo_nds::command::Cargo;
|
||||||
use cargo_3ds::{check_rust_version, run_cargo};
|
use cargo_nds::{check_rust_version, run_cargo};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
check_rust_version();
|
check_rust_version();
|
||||||
|
|
||||||
let Cargo::Input(mut input) = Cargo::parse();
|
let Cargo::Input(mut input) = Cargo::parse();
|
||||||
|
|
||||||
let message_format = match input.cmd.extract_message_format() {
|
let message_format = match input.cmd.extract_message_format() {
|
||||||
|
Loading…
Reference in New Issue
Block a user