Build 3dsx for *all* executables built by a given command
ian-h-chamberlain opened this issue · comments
This might be tricky to solve, but it would be nice if we could generate a .3dsx
for every binary artifact generated by a given command. Otherwise, it's kinda weird that you might get a different .3dsx
depending on which one built first, since we just take the last one currently (which I think is non-deterministic order as binaries can be built in parallel).
Potential use cases:
cargo 3ds test
(can build lib tests and possibly multiple integration tests. Doc tests are separate due to needingdoctest-xcompile
currently)- Any
cargo 3ds build
command with multiple binaries explicitly requested, e.g.--examples
,--bin foo --bin bar
, etc.
Part of what will make this hard to implement is figuring out how to specify the metadata for each binary. Most of the fields can probably still be pulled from cargo_metadata
like author
, name
etc., but some things might be useful to specify per-executable, especially icon and RomFS.
Side note: should we call it
romfs-dir
instead? Most other Cargo.toml keys seem to bekebab-case
rather thansnake_case
In the case of lib tests, we can probably just use what we already have, but for bin
s, integration tests
and example
s I think we might need a new scheme. Initially I'd propose something like this:
[[example]]
name = "ex1"
# I think "description" is non-standard here as it's not documented in
# https://doc.rust-lang.org/cargo/reference/cargo-targets.html#configuring-a-target
# We could still look for it, but we'd have to manually read in from Cargo.toml
# examples/ex2.rs may exist but not be defined explicitly in Cargo.toml
[[bin]]
name = "mybin"
# etc. for tests, benches if need be
[package.metadata.cargo-3ds]
romfs_dir = "examples/romfs" # still optional
# should we call these "example", "bin" etc. to match the top-level key?
examples.ex1.romfs_dir = "examples/ex1_romfs"
examples.ex2.romfs_dir = "examples/ex2_romfs"
tests.integration.romfs_dir = "tests/romfs"
# mybin falls back to using "examples/romfs"
# if we needed something else for lib tests we could also do something like this
# but probably it should just use the top level one if we can manage that
lib.romfs_dir = "..."
As a further enhancement, we could allow setting .icon
to specify a custom path to an icon, instead of always looking for ./icon.png
, or really any of the CTRConfig
fields could be overridden on a per-target basis if we want. I think the important ones would probably just be
- romfs dir
- icon
- description
Overall, I think the flow would look something like this:
- Collect package metadata with
cargo_metadata::MetadataCommand
. This gives us a list of all possible targets (bin
,example
, etc. including auto-discovered ones), as well as the contents ofpackage.metadata.cargo-3ds
. - Construct a
CTRConfig
for each target (either now or on the fly later, if we store the metadata, doesn't matter too much) - Run the underlying
cargo build
for whatever command, collecting the output withcargo_metadata::Message
- For each artifact found in the build output:
- lookup/construct its
CTRConfig
from earlier by kind and name (e.g.(Example, "foobar")
) - generate SMDH
- Generate 3dsx
- lookup/construct its
Obviously, this is a pretty big change so I thought I'd start by proposing it and see if there's any discussion to be had before an implementation. This isn't really a super important thing to have since it can always be worked around by building one thing at a time, but it would be nice if it basically Just Worked the way cargo
does.
Curious to hear other people's thoughts on this!