-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Nintendo switch support #8069
Nintendo switch support #8069
Conversation
Well, now I just have to buy a Nintendo Switch :P Nice work! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to have this in the compiler. Not sure what @Araq's thoughts about it are, but this is awesome :)
changelog.md
Outdated
@@ -170,4 +170,15 @@ | |||
- ``experimental`` is now a pragma / command line switch that can enable specific | |||
language extensions, it is not an all-or-nothing switch anymore. | |||
|
|||
- Nintendo Switch was added as a new platform target. Simply add --os:nintendoswitch | |||
to your usual ``nim c`` or ``nim cpp`` command. DevkitPro setup must be the same as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! But I think a better place for it is in the nimc
docs: https://github.com/nim-lang/Nim/blob/devel/doc/nimc.rst
You can link to them from the changelog :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, sounds good. I'll make that change.
compiler/extccomp.nim
Outdated
@@ -83,6 +83,31 @@ compiler gcc: | |||
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm, | |||
hasAttribute}) | |||
|
|||
# GNU C and C++ Compiler | |||
compiler aarch64NoneElfGCC: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick but I would name this switchGCC
. We might have a generic aarch64-none-elf-gcc
in the future (I guess?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
compiler/installer.ini
Outdated
@@ -15,6 +15,7 @@ Platforms: """ | |||
dragonfly: i386;amd64 | |||
haiku: i386;amd64 | |||
android: i386;arm;arm64 | |||
nintendoswitch: armv8a57 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is only necessary if you are going to be compiling Nim on the Nintendo Switch. I'm guessing that won't happen, will it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you never know. Linux can run on the switch already :)
compiler/options.nim
Outdated
@@ -124,7 +124,7 @@ type | |||
disabledSf, writeOnlySf, readOnlySf, v2Sf | |||
|
|||
TSystemCC* = enum | |||
ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc, | |||
ccNone, ccGcc, ccaarch64NoneElfGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I'd probably call this ccSwitch
or ccNintendoSwitch
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, that makes more sense. I wasn't sure what to call it, so ccNintendoSwitch shall be it's name!
compiler/platform.nim
Outdated
@@ -208,7 +213,8 @@ const | |||
(name: "sparc64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64), | |||
(name: "mips64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64), | |||
(name: "mips64el", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), | |||
(name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64)] | |||
(name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), | |||
(name: "armv8a57", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't arm64
be reused? Is there a specific reason you need bigEndian
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, you're right. Checked the switch's cpu mode and it can be either.
lib/system/threads.nim
Outdated
Pthread_attr {.importc: "pthread_attr_t", | ||
header: "<sys/types.h>".} = object | ||
ThreadVarSlot {.importc: "pthread_key_t", | ||
header: "<sys/types.h>".} = distinct cuint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is very similar to the code above it, can the above code be reused for this branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, you're right. I just wasn't sure about the abi: array[56 div sizeof(clong), clong]
, but it looks like it's fine.
@dom96 Cool to see you're on board. It's super cool to have a program running Nim on the switch! |
@@ -312,6 +312,8 @@ else: | |||
include ioselects/ioselectors_poll # need to replace it with event ports | |||
elif defined(genode): | |||
include ioselects/ioselectors_select # TODO: use the native VFS layer | |||
elif defined(nintendoswitch): | |||
include ioselects/ioselectors_select |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't the os have something better than select? kqueue, epoll?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, not that I can find. If you can find it in the devkitPro libs, I would be up for changing it.
I like it very much but travis is not happy:
|
@Araq, is that due to my code? I didn't mess with the times module. I'll check it out. |
Yep, it's due to my stuff. Looks like I have more stuff to implement! |
final, pure.} = object | ||
abi: array[((64+(sizeof(clong) * 8)-1) div (sizeof(clong) * 8)), clong] | ||
|
||
proc si_pid*(info: SigInfo): Pid = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this is to get around the issue that Switch's header struct for siginfo doesn't contain si_pid, which means waiting for a child process to finish doesn't work. I don't think that's too big of a deal right now, but what are your thoughts on this? Is there some other way to correctly identify where the Signal is coming from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know, sorry.
Well I'm okay with the way this is now if you are. I can add a note in the docs about how waiting on subprocesses isn't supported yet and then I think it's done if it's okay with you guys. |
And if you have no comments on my most recent commits of course :) |
I don't know anything about this, but if nintendo switch is supported by |
@GULPF Yeah, you're right. I should have realized that. Nice find! |
@dom96 looks like the build failed, but I don't think it was me this time. It looks like yarn wasn't able to be found or something? Does this happen sometimes? |
Nevermind, I think it had to do with some old code. I updated from latest devel and ran the tests locally and it all looks good! Hopefully travis agrees :) |
Okay, I think I'm happy with this now. If there are any other outstanding issues, please let me know! |
compiler/extccomp.nim
Outdated
@@ -556,14 +582,20 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string = | |||
else: | |||
cfile.obj | |||
|
|||
# D files are required by nintendo switch libs for | |||
# compilation. They are basically a list of all includes. | |||
let dfile = objfile.replace(".o", ".d").quoteShell() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use changeFileExt
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
posix_nintendoswitch.nim seems copy&pasted code and I dunno why that is.
compiler/extccomp.nim
Outdated
# Map files are required by Nintendo Switch compilation. They are a list | ||
# of all function calls in the library and where they come from. | ||
var mapfile = getNimcacheDir(conf) / splitFile(projectFile).name & ".map" | ||
mapfile = quoteShell(mapfile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Combine these two statements.
doc/nimc.rst
Outdated
Simply add --os:nintendoswitch | ||
to your usual ``nim c`` or ``nim cpp`` command. DevkitPro setup must be the same as | ||
what is the default with their new installer | ||
[here for Mac/Linux](https://github.com/devkitPro/pacman/releases) or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not how RST links look like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, copy pasted from MD file. I'll update to be in line with rst.
doc/nimc.rst
Outdated
to your usual ``nim c`` or ``nim cpp`` command. DevkitPro setup must be the same as | ||
what is the default with their new installer | ||
[here for Mac/Linux](https://github.com/devkitPro/pacman/releases) or | ||
[here for Windows](https://github.com/devkitPro/installer/releases). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
doc/nimc.rst
Outdated
|
||
This will generate a file called ``switchhomebrew.elf`` which can then be turned into | ||
an nro file with the ``elf2nro`` tool in the DevkitPro release. Examples can be found at | ||
[the nim-libnx github repo](https://github.com/jyapayne/nim-libnx.git). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
doc/nimc.rst
Outdated
There are a few things that don't work because the DevkitPro libraries don't support them. | ||
They are: | ||
|
||
1. Waiting for a subprocess to finish. A subprocess can be started, but right |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't indent this list.
Run nim rst2html doc/nimc.rst
and look at the produced HTML.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the tip! I didn't know about this command.
# | ||
|
||
proc dlclose(lib: LibHandle) = | ||
raise newException(OSError, "dlclose not implemented on Nintendo Switch!") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better if these would cause a compile-time error but I can imagine why that's rather hard to do...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way that you usually do this in Nim?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
proc dlclose(lib: LibHandle) {.error: "not implemented".}
but it's a compilerProc so it needs a patch in cgen.nim
.
lib/posix/posix_nintendoswitch.nim
Outdated
# | ||
# | ||
# Nim's Runtime Library | ||
# (c) Copyright 2018 Andreas Rumpf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use 'Nim contributors' as the name or your own name.
lib/posix/posix_nintendoswitch.nim
Outdated
|
||
# To be included from posix.nim! | ||
|
||
{.deadCodeElim: on.} # dce option deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this line.
lib/posix/posix_nintendoswitch.nim
Outdated
aio_offset*: Off ## File offset. | ||
reserved: array[32, uint8] | ||
|
||
when hasSpawnH: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is nintendo specific code, you know whether this hasSpawnH
is true or not.
lib/posix/posix_nintendoswitch.nim
Outdated
timezone* {.importc: "_timezone", header: "<time.h>".}: clong | ||
|
||
# Regenerate using detect.nim! | ||
include posix_linux_amd64_consts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really? You detected these and put them into posix_linux_amd64_consts
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I missed that one. I'll update to the generated code from the switch.
I did copy & paste from amd64 because the file was largely the same but the fields in each object were slightly different. I thought about doing |
Alright then. |
@jyapayne Your patience is admirable! |
@kobi2187 OSS contributions require a lot of patience most of the time :) Thank you for the kind words! |
The long-awaited Nintendo Switch support! This allows compilation of Nintendo Switch architecture compatible
elf
files using the--os:nintendoswitch
flag.Environment vars required:
DEVKITPRO
which is the path to the root of your devkit pro installation. There are some directories expected to exist in a specific structure for now until I figure out a better way to specify them. They are:Other environment variables that are not required:
SWITCH_LIBS
for any extra libraries required by your application (-lLIBNAME
or-LLIBPATH
), andSWITCH_INCLUDES
for any extra include files (-IINCLUDE_PATH
)