Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(DRAFT) Rust support #512

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Conversation

kosmas12
Copy link
Contributor

@kosmas12 kosmas12 commented Sep 27, 2021

After some experimenting, I managed to get freestanding Rust executables compiling and running on Xbox (or, more accurately, xemu, as it was the only way to check with a debugger since there was no visual change). It worked, so I'm pushing what I have right now and opening this PR as a progress report for Rust support in nxdk. Please close if inappropriate.

The sample is located in the samples/rust directory and a make should fix it right up.

This is NOT meant for use on an actual Xbox.

Arguably, I shouldn't have opened this PR without Xbox testing (as this is an Xbox toolchain, not an Xbox emulator toolchain), but IMO getting it running on an emulator is progress enough for the prototype.

I am open to anything you all might have to say and suggest, and I'm looking forward to your feedback!

Notes:

It uses cross for cross-compiling to 32-bit Windows and then runs the generated .exe through CXBE. I am using cross for this as it's more convenient to set up than a GNU/MinGW compiler toolchain. More info on how to set up cross in the linked repository. This has changed as of b66ab57 to use stock cargo with a custom Xbox target file with -Zbuild-std=core to build the core standard library parts that we can currently get.

The GitHub CI builds don't work due to how cross is not installed in the environment by default the required toolchain not being installed (as of b66ab57).

The build system can (and should) get an improvement. This will happen eventually. (Kind of changed in b66ab57 to use a Rust build script to link against nxdk libs. Still must be improved.)

As I said, this is just a quickly hacked-together prototype/proof-of-concept for now. It will all be improved and fixed up eventually.

We should at one point make a standard library port and runtime port and perhaps Rust bindings for our C APIs such as SDL 2 and WinAPI and xaudio and whatnot. (As of b66ab57, it's possible to call WinAPI, xboxkrnl, xboxrt and pdclib using extern "C" blocks)

The binary sometimes works, but most of the time it doesn't even get into the BIOS screen when booting with xemu. This is currently being investigated, however as I don't know what might be the cause there's no ETA. Fixed as of b66ab57 when linking with some nxdk libs.

It's currently a very small step (and perhaps not even properly tested-fixed), but IMO it's enough to start this "progress monitor".

Good day to everyone!

Copy link
Member

@thrimbor thrimbor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done!

For the time being, I'd prefer to keep this external, though. Until we have an improved build system, the integration feels weird (overwriting the all target in the makefile etc) and the build process deviates from how rust usually builds.
It also looks like there are quite a few workarounds necessary even in a simple bit of code, just to get things running. Ideally, the support would be at a stage where simple code can run on the Xbox without any modifications before it's integrated into nxdk itself.

I encourage you to keep working on this, though. Getting rust to work on the Xbox was something I planned to eventually get to myself, but I'm more than happy to see others push the limits of what's doable with nxdk.

XBE_TITLE = rusttest
NXDK_DIR = /home/$(USER)/rust_nxdk
OUTPUT_DIR = bin
RUSTFLAGS := --target i686-pc-windows-gnu
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks problematic. The GNU ABI drivers differs from the MSVC ABI used by nxdk. Does rust not support MSVC, or is that a limitation of the cross-compiling tool?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, Rust does support MSVC, and so does the cross-compiling tool, I just thought it wouldn't make a difference so I prefered to use the GNU toolchain. I'll change that to MSVC, and, well, if we're lucky, perhaps it might even fix some problems.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, it's actually not supported by the cross-compile tool.

We might have to make a custom Docker image for it (perhaps we could reuse components from the nxdk Docker images, or perhaps even the whole images with just some more stuff?).

@kosmas12
Copy link
Contributor Author

Been a while since we've talked about this, so would like to revive it. Our problem right now is, the cross compiler doesn't have an MSVC image ready for use out-of-the-box. I don't know what we might be able to do about this other than make our own image with all the required tools for the job. I want to hear suggestions.

@kosmas12
Copy link
Contributor Author

kosmas12 commented Nov 17, 2021

So, after a bit of looking around, I discovered that the binary is not malformed, nor is the ABI the problem (probably).

I see that if we run a regular XBE written in C(++) and then run this, it will work. However, this is only when ran in xemu. It doesn't work at all on real hardware. I believe there is something about setting up the environment that the binary is missing but persists between resets on xemu. I'd like to further investigate by trying to set up TLS on the Rust binary first before saying anything for sure (this seems to be the only hardware-related init required that nxdk does for C(++) code).

EDIT: It seems that a C(++) XBE file is not necessary to run this. I just need to load the disc again after trying to run it once. Then it will do the same thing and also need me to reload the disc. I am not 100% sure it works even after this, but it does show the OpenXDK logo which means it loads up the binary, probably runs it as well. Haven't been able to attach gdb to debug as it doesn't like xemu resetting.

@kosmas12
Copy link
Contributor Author

kosmas12 commented Apr 19, 2022

I took another look at this today, and I managed to get it to work some what better.

First of all, this does not require luck to run any more, and boots normally
Secondly, I wrote a build script to do the Rust compilation and link to the nxdk libs
Last but not least, due to linking with the libs, it's now possible to call nxdk code from Rust (specifically anything from pdclib, xboxrt, xboxkrnl and winapi) using extern fn. Bindings would be better, but currently not something I have.

@antangelo has done some work on this, too, and he has made bindings as well, so would be nice to see his work here.

P.S.: CI fails due to not-installed toolchains, which I believe is more of a GitHub CI machine thing, so the tasks script would have to change to fix that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants