Skip to content

Commit

Permalink
Auto merge of #116518 - vita-rust:vita, r=workingjubilee
Browse files Browse the repository at this point in the history
Updated libc and doc for Vita target

Doc changes:

- Updated Vita target readme. The recommended approach to build artifacts for the platform now is [cargo-vita](https://crates.io/crates/cargo-vita) which wraps all the convoluted steps previously described in a yaml for `cargo-make`
- Updated maintainer list for Vita target. (`@ZetaNumbers` `@pheki` please agree to be added to the list, `@amg98` please let us know if you're still planning on actively maintaining target support)

Code changes:
- ~Updated libc for rust-lang/libc#3284 and rust-lang/libc#3366~ (Already merged in #116527)
- In dupfd changed the flag same as for esp target, there is no CLOEXEC on Vita
- Enabled `new_pair` since we've implemented `socketpair` in Vita newlib
  • Loading branch information
bors committed Oct 17, 2023
2 parents 347452e + ba13e37 commit 2e57d64
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 109 deletions.
6 changes: 3 additions & 3 deletions library/std/src/os/fd/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ impl BorrowedFd<'_> {
// We want to atomically duplicate this file descriptor and set the
// CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
// is a POSIX flag that was added to Linux in 2.6.24.
#[cfg(not(target_os = "espidf"))]
#[cfg(not(any(target_os = "espidf", target_os = "vita")))]
let cmd = libc::F_DUPFD_CLOEXEC;

// For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics
// will never be supported, as this is a bare metal framework with
// no capabilities for multi-process execution. While F_DUPFD is also
// not supported yet, it might be (currently it returns ENOSYS).
#[cfg(target_os = "espidf")]
#[cfg(any(target_os = "espidf", target_os = "vita"))]
let cmd = libc::F_DUPFD;

// Avoid using file descriptors below 3 as they are used for stdio
Expand All @@ -119,7 +119,7 @@ impl BorrowedFd<'_> {
pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
Err(crate::io::const_io_error!(
crate::io::ErrorKind::Unsupported,
"operation not supported on WASI yet",
"operation not supported on this platform",
))
}
}
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl Socket {
}
}

#[cfg(not(any(target_os = "vxworks", target_os = "vita")))]
#[cfg(not(target_os = "vxworks"))]
pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> {
unsafe {
let mut fds = [0, 0];
Expand Down Expand Up @@ -135,7 +135,7 @@ impl Socket {
}
}

#[cfg(any(target_os = "vxworks", target_os = "vita"))]
#[cfg(target_os = "vxworks")]
pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> {
unimplemented!()
}
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ target | std | host | notes
`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | ARMv6 NetBSD w/hard-float
[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? | | ARMv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | | | ARMv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARMv7-A OpenHarmony |
[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7-A Linux with uClibc, softfloat
[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7-A Linux with uClibc, hardfloat
Expand Down
137 changes: 34 additions & 103 deletions src/doc/rustc/src/platform-support/armv7-sony-vita-newlibeabihf.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

**Tier: 3**

This tier supports the ARM Cortex A9 processor running on a PlayStation Vita console. `armv7-vita-newlibeabihf` aims to have support for `std` crate using `newlib` as a bridge.
This tier supports the ARM Cortex A9 processor running on a PlayStation Vita console.

Rust support for this target is not affiliated with Sony, and is not derived
from nor used with any official Sony SDK.

## Target maintainers

* [@amg98](https://github.com/amg98)
* [@nikarh](https://github.com/nikarh)
* [@pheki](https://github.com/pheki)
* [@ZetaNumbers](https://github.com/ZetaNumbers)

## Requirements

Expand All @@ -20,132 +21,62 @@ This target is cross-compiled, and requires installing [VITASDK](https://vitasdk
`alloc`, and `panic_abort`.

`std` is partially supported, but mostly works. Some APIs are unimplemented
and will simply return an error, such as `std::process`. An allocator is provided
by default.
and will simply return an error, such as `std::process`.

In order to support some APIs, binaries must be linked against `libc` written
for the target, using a linker for the target. These are provided by the
VITASDK toolchain.
This target generates binaries in the ELF format with thumb ISA by default.

Binaries are linked with `arm-vita-eabi-gcc` provided by VITASDK toolchain.

This target generates binaries in the ELF format with thumb ISA.

## Building the target

Rust does not ship pre-compiled artifacts for this target. You can use `build-std` flag to build binaries with `std`:
Rust does not ship pre-compiled artifacts for this target. You can use `build-std` flag to build ELF binaries with `std`:

```sh
cargo build -Z build-std=std,panic_abort --target=armv7-sony-vita-newlibeabihf --release
```

## Building Rust programs

To test your developed rust programs on PlayStation Vita, first you must correctly package your elf. These steps can be preformed using tools available in VITASDK, and can be automated using a tool like `cargo-make`.
The recommended way to build artifacts that can be installed and run on PlayStation Vita is by using the [cargo-vita](https://github.com/vita-rust/cargo-vita) tool. This tool uses `build-std` and VITASDK toolchain to build artifacts runnable on Vita.

To install the tool run:

```sh
cargo install cargo-vita
```

First, set up environment variables for `VITASDK`, and it's binaries:
[VITASDK](https://vitasdk.org/) toolchain must be installed, and the `VITASDK` environment variable must be set to its location, e.g.:

```sh
export VITASDK=/opt/vitasdk
export PATH=$PATH:$VITASDK/bin
```

Use the example below as a template for your project:
Add the following section to your project's `Cargo.toml`:


```toml
[env]
TITLE = "Rust Hello World"
TITLEID = "RUST00001"

# At least a "sce_sys" folder should be place there for app metadata (title, icons, description...)
# You can find sample assets for that on $VITASDK/share/gcc-arm-vita-eabi/samples/hello_world/sce_sys/
STATIC_DIR = "static" # Folder where static assets should be placed (sce_sys folder is at $STATIC_DIR/sce_sys)
CARGO_TARGET_DIR = { script = ["echo ${CARGO_TARGET_DIR:=target}"] }
CARGO_OUT_DIR = "${CARGO_TARGET_DIR}/${RUST_TARGET}/release"

[tasks.build]
description = "Build the project using `cargo`."
command = "cargo"
args = ["build", "-Z", "build-std=std,panic_abort", "--target=armv7-sony-vita-newlibeabihf", "--release"]

[tasks.strip]
description = "Strip the produced ELF executable."
dependencies = ["build"]
command = "arm-vita-eabi-strip"
args = ["-g", '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_FS_NAME}.elf']

[tasks.velf]
description = "Build an VELF executable from the obtained ELF file."
dependencies = ["strip"]
command = "vita-elf-create"
args = ['${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.elf', '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.velf']

[tasks.eboot-bin]
description = "Build an `eboot.bin` file from the obtained VELF file."
dependencies = ["velf"]
command = "vita-make-fself"
args = ["-s", '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.velf', '${CARGO_OUT_DIR}/eboot.bin']

[tasks.param-sfo]
description = "Build the `param.sfo` manifest using with given TITLE and TITLEID."
command = "vita-mksfoex"
args = ["-s", 'TITLE_ID=${TITLEID}', '${TITLE}', '${CARGO_OUT_DIR}/param.sfo']

[tasks.manifest]
description = "List all static resources into a manifest file."
script = [
'mkdir -p "${CARGO_OUT_DIR}"',
'''
if [ -d "${STATIC_DIR}" ]; then
find "${STATIC_DIR}" -type f > "${CARGO_OUT_DIR}/MANIFEST"
else
touch "${CARGO_OUT_DIR}/MANIFEST"
fi
'''
]

[tasks.vpk]
description = "Build a VPK distribution of the project executable and resources."
dependencies = ["eboot-bin", "param-sfo", "manifest"]
script_runner = "@rust"
script = [
'''
use std::io::BufRead;
use std::fs::File;
fn main() {
let crate_name = env!("CARGO_MAKE_CRATE_NAME");
let static_dir = env!("STATIC_DIR");
let out_dir = std::path::PathBuf::from(env!("CARGO_OUT_DIR"));
let mut cmd = ::std::process::Command::new("vita-pack-vpk");
cmd.arg("-s").arg(out_dir.join("param.sfo"));
cmd.arg("-b").arg(out_dir.join("eboot.bin"));
// Add files from MANIFEST
if let Ok(file) = File::open(out_dir.join("MANIFEST")) {
let mut reader = ::std::io::BufReader::new(file);
let mut lines = reader.lines();
while let Some(Ok(line)) = lines.next() {
let p1 = ::std::path::PathBuf::from(line); // path on FS
let p2 = p1.strip_prefix(static_dir).unwrap(); // path in VPK
cmd.arg("--add").arg(format!("{}={}", p1.display(), p2.display()));
}
}
cmd.arg(out_dir.join(format!("{}.vpk", crate_name)))
.output()
.expect("command failed.");
}
'''
]
[package.metadata.vita]
# A unique 9 character alphanumeric identifier of the app.
title_id = "RUSTAPP01"
# A title that will be used for the app. Optional, name will be used if not defined
title_name = "My application"
```

After running the above script, you should be able to get a *.vpk file in the same folder your *.elf executable resides. Now you can pick it and install it on your own PlayStation Vita using, or you can use an [Vita3K](https://vita3k.org/) emulator.
To build a VPK with ELF in the release profile, run:

```sh
cargo vita build vpk --release
```

After building a *.vpk file it can be uploaded to a PlayStation Vita and installed, or used with a [Vita3K](https://vita3k.org/) emulator.

## Testing

Currently there is no support to run the rustc test suite for this target.
The default Rust test runner is supported, and tests can be compiled to an elf and packed to a *.vpk file using `cargo-vita` tool. Filtering tests is not currently supported since passing command-line arguments to the executable is not supported on Vita, so the runner will always execute all tests.

The Rust test suite for `library/std` is not yet supported.

## Cross-compilation

This target can be cross-compiled from `x86_64` on either Windows, MacOS or Linux systems. Other hosts are not supported for cross-compilation.
This target can be cross-compiled from `x86_64` on Windows, MacOS or Linux systems. Other hosts are not supported for cross-compilation.

0 comments on commit 2e57d64

Please sign in to comment.