Nintendo switch support (#8069)

* Add config section for Nintendo Switch
* Add compiler configuration for Nintendo Switch and it's CPU
* Add specific lib code for Nintendo Switch
* Add GC support for Nintendo Switch
* Update changelog for Nintendo Switch
* Update changelog with more info about fixed paths
* Cleaned up GC memory management a bit
* Relocate docs for Switch
* Rename aarch64NoneElfGcc to nintendoSwitchGCC
* Remove armv8a57
* Fix installer.ini
* Reuse code in linux and amd64
* Add posix defs for nintendo switch
* Add more defined sections for nintendo switch
* Remove old comment
* Add what's not supported for Nintendo Switch docs
* Make nintendoswitch == posix
* Remove DEVKITPRO references from nim.cfg
* Make PR extccomp changes
* Remove Result type alias
* Add separate switch consts file
* Update docs for nintendo switch
* Fix travis errors with undefined consts and add correct wait.h procs
This commit is contained in:
Joey
2018-06-27 19:35:09 +09:00
committed by Andreas Rumpf
parent b74b16ffde
commit 559a7615ad
21 changed files with 1352 additions and 43 deletions

View File

@@ -182,4 +182,7 @@
- ``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. See [the compiler user guide](https://nim-lang.org/docs/nimc.html)
for more info.
### Bugfixes

View File

@@ -83,6 +83,31 @@ compiler gcc:
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
hasAttribute})
# GNU C and C++ Compiler
compiler nintendoSwitchGCC:
result = (
name: "switch_gcc",
objExt: "o",
optSpeed: " -O3 -ffast-math ",
optSize: " -Os -ffast-math ",
compilerExe: "aarch64-none-elf-gcc",
cppCompiler: "aarch64-none-elf-g++",
compileTmpl: "-MMD -MP -MF $dfile -c $options $include -o $objfile $file",
buildGui: " -mwindows",
buildDll: " -shared",
buildLib: "aarch64-none-elf-gcc-ar rcs $libfile $objfiles",
linkerExe: "aarch64-none-elf-gcc",
linkTmpl: "$buildgui $builddll -Wl,-Map,$mapfile -o $exefile $objfiles $options",
includeCmd: " -I",
linkDirCmd: " -L",
linkLibCmd: " -l$1",
debug: "",
pic: "-fPIE",
asmStmtFrmt: "asm($1);$n",
structStmtFmt: "$1 $3 $2 ", # struct|union [packed] $name
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
hasAttribute})
# LLVM Frontend for GCC/G++
compiler llvmGcc:
result = gcc() # Uses settings from GCC
@@ -316,6 +341,7 @@ compiler ucc:
const
CC*: array[succ(low(TSystemCC))..high(TSystemCC), TInfoCC] = [
gcc(),
nintendoSwitchGCC(),
llvmGcc(),
clang(),
lcc(),
@@ -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.changeFileExt(".d").quoteShell()
objfile = quoteShell(objfile)
cf = quoteShell(cf)
result = quoteShell(compilePattern % [
"dfile", dfile,
"file", cf, "objfile", objfile, "options", options,
"include", includeCmd, "nim", getPrefixDir(conf),
"nim", getPrefixDir(conf), "lib", conf.libpath])
add(result, ' ')
addf(result, CC[c].compileTmpl, [
"dfile", dfile,
"file", cf, "objfile", objfile,
"options", options, "include", includeCmd,
"nim", quoteShell(getPrefixDir(conf)),
@@ -659,16 +691,23 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string =
if optCDebug in conf.globalOptions:
writeDebugInfo(exefile.changeFileExt("ndb"))
exefile = quoteShell(exefile)
# Map files are required by Nintendo Switch compilation. They are a list
# of all function calls in the library and where they come from.
let mapfile = quoteShell(getNimcacheDir(conf) / splitFile(projectFile).name & ".map")
let linkOptions = getLinkOptions(conf) & " " &
getConfigVar(conf, conf.cCompiler, ".options.linker")
var linkTmpl = getConfigVar(conf, conf.cCompiler, ".linkTmpl")
if linkTmpl.len == 0:
linkTmpl = CC[conf.cCompiler].linkTmpl
result = quoteShell(result % ["builddll", builddll,
"mapfile", mapfile,
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
"exefile", exefile, "nim", getPrefixDir(conf), "lib", conf.libpath])
result.add ' '
addf(result, linkTmpl, ["builddll", builddll,
"mapfile", mapfile,
"buildgui", buildgui, "options", linkOptions,
"objfiles", objfiles, "exefile", exefile,
"nim", quoteShell(getPrefixDir(conf)),

View File

@@ -15,6 +15,7 @@ Platforms: """
dragonfly: i386;amd64
haiku: i386;amd64
android: i386;arm;arm64
nintendoswitch: arm64
"""
Authors: "Andreas Rumpf"

View File

@@ -124,7 +124,7 @@ type
disabledSf, writeOnlySf, readOnlySf, v2Sf
TSystemCC* = enum
ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc,
ccNone, ccGcc, ccNintendoSwitch, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc,
ccTcc, ccPcc, ccUcc, ccIcl, ccIcc
CfileFlag* {.pure.} = enum
@@ -345,7 +345,7 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
osQnx, osAtari, osAix,
osHaiku, osVxWorks, osSolaris, osNetbsd,
osFreebsd, osOpenbsd, osDragonfly, osMacosx,
osAndroid}
osAndroid, osNintendoSwitch}
of "linux":
result = conf.target.targetOS in {osLinux, osAndroid}
of "bsd":
@@ -356,6 +356,8 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
of "mswindows", "win32": result = conf.target.targetOS == osWindows
of "macintosh": result = conf.target.targetOS in {osMacos, osMacosx}
of "sunos": result = conf.target.targetOS == osSolaris
of "nintendoswitch":
result = conf.target.targetOS == osNintendoSwitch
of "littleendian": result = CPU[conf.target.targetCPU].endian == platform.littleEndian
of "bigendian": result = CPU[conf.target.targetCPU].endian == platform.bigEndian
of "cpu8": result = CPU[conf.target.targetCPU].bit == 8

View File

@@ -22,7 +22,7 @@ type
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osAix, osPalmos, osQnx,
osAmiga, osAtari, osNetware, osMacos, osMacosx, osHaiku, osAndroid, osVxworks
osGenode, osJS, osNimVM, osStandalone
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch
type
TInfoOSProp* = enum
@@ -168,7 +168,12 @@ const
(name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {})]
props: {}),
(name: "NintendoSwitch", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: ".elf", extSep: ".",
props: {ospNeedsPIC, ospPosix}),
]
type
TSystemCPU* = enum # Also add CPU for in initialization section and

View File

@@ -109,6 +109,14 @@ path="$lib/pure"
@end
@end
@if nintendoswitch:
cc = "switch_gcc"
switch_gcc.options.linker = "-g -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE $SWITCH_LIBS"
switch_gcc.cpp.options.linker = "-g -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE $SWITCH_LIBS"
switch_gcc.options.always = "-g -Wall -O2 -ffunction-sections -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE $SWITCH_INCLUDES -D__SWITCH__"
switch_gcc.cpp.options.always = "-g -Wall -O2 -ffunction-sections -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE $SWITCH_INCLUDES -D__SWITCH__ -fno-rtti -fno-exceptions -std=gnu++11"
@end
# Configuration for the Intel C/C++ compiler:
@if windows:
icl.options.speed = "/Ox /arch:SSE2"

View File

@@ -228,6 +228,52 @@ configuration file should contain something like::
arm.linux.gcc.exe = "arm-linux-gcc"
arm.linux.gcc.linkerexe = "arm-linux-gcc"
Cross compilation for Nintendo Switch
=====================================
Simply add --os:nintendoswitch
to your usual ``nim c`` or ``nim cpp`` command and set the ``SWITCH_LIBS``
and ``SWITCH_INCLUDES`` environment variables to something like:
.. code-block:: console
export SWITCH_INCLUDES="-I$DEVKITPRO/libnx/include"
export SWITCH_LIBS="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
or setup a nim.cfg file like so:
.. code-block:: Nim
#nim.cfg
--passC="-I$DEVKITPRO/libnx/include"
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
The DevkitPro setup must be the same as 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>`_.
For example, with the above mentioned config::
nim c --os:nintendoswitch switchhomebrew.nim
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>`_ or you can use
`the switch builder tool <https://github.com/jyapayne/switch-builder.git>`_.
Environment variables are:
- ``SWITCH_LIBS`` for any extra libraries required by your application (``-lLIBNAME`` or ``-LLIBPATH``)
- ``SWITCH_INCLUDES`` for any extra include files (``-IINCLUDE_PATH``)
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
now it can't be waited on, which sort of makes subprocesses a bit hard to use
2. Dynamic calls. DevkitPro libraries have no dlopen/dlclose functions.
3. Command line parameters. It doesn't make sense to have these for a console
anyways, so no big deal here.
4. mqueue. Sadly there are no mqueue headers.
5. ucontext. No headers for these either. No coroutines for now :(
6. nl_types. No headers for this.
DLL generation
==============

View File

@@ -0,0 +1,21 @@
const virtMemHeader = "<switch/kernel/virtmem.h>"
const svcHeader = "<switch/kernel/virtmem.h>"
const mallocHeader = "<malloc.h>"
proc memalign*(bytes: csize, size: csize): pointer {.importc: "memalign",
header: mallocHeader.}
proc free*(address: pointer) {.importc: "free",
header: mallocHeader.}
proc svcMapMemory*(dst_addr: pointer; src_addr: pointer; size: uint64): uint32 {.
importc: "svcMapMemory", header: svcHeader.}
proc svcUnmapMemory*(dst_addr: pointer; src_addr: pointer; size: uint64): uint32 {.
importc: "svcUnmapMemory", header: svcHeader.}
proc virtmemReserveMap*(size: csize): pointer {.importc: "virtmemReserveMap",
header: virtMemHeader.}
proc virtmemFreeMap*(address: pointer; size: csize) {.importc: "virtmemFreeMap",
header: virtMemHeader.}

View File

@@ -94,6 +94,8 @@ const StatHasNanoseconds* = defined(linux) or defined(freebsd) or
when defined(linux) and defined(amd64):
include posix_linux_amd64
elif defined(nintendoswitch):
include posix_nintendoswitch
else:
include posix_other
@@ -185,7 +187,7 @@ proc fnmatch*(a1, a2: cstring, a3: cint): cint {.importc, header: "<fnmatch.h>".
proc ftw*(a1: cstring,
a2: proc (x1: cstring, x2: ptr Stat, x3: cint): cint {.noconv.},
a3: cint): cint {.importc, header: "<ftw.h>".}
when not (defined(linux) and defined(amd64)):
when not (defined(linux) and defined(amd64)) and not defined(nintendoswitch):
proc nftw*(a1: cstring,
a2: proc (x1: cstring, x2: ptr Stat,
x3: cint, x4: ptr FTW): cint {.noconv.},
@@ -226,25 +228,26 @@ proc setlocale*(a1: cint, a2: cstring): cstring {.
proc strfmon*(a1: cstring, a2: int, a3: cstring): int {.varargs,
importc, header: "<monetary.h>".}
proc mq_close*(a1: Mqd): cint {.importc, header: "<mqueue.h>".}
proc mq_getattr*(a1: Mqd, a2: ptr MqAttr): cint {.
importc, header: "<mqueue.h>".}
proc mq_notify*(a1: Mqd, a2: ptr SigEvent): cint {.
importc, header: "<mqueue.h>".}
proc mq_open*(a1: cstring, a2: cint): Mqd {.
varargs, importc, header: "<mqueue.h>".}
proc mq_receive*(a1: Mqd, a2: cstring, a3: int, a4: var int): int {.
importc, header: "<mqueue.h>".}
proc mq_send*(a1: Mqd, a2: cstring, a3: int, a4: int): cint {.
importc, header: "<mqueue.h>".}
proc mq_setattr*(a1: Mqd, a2, a3: ptr MqAttr): cint {.
importc, header: "<mqueue.h>".}
when not defined(nintendoswitch):
proc mq_close*(a1: Mqd): cint {.importc, header: "<mqueue.h>".}
proc mq_getattr*(a1: Mqd, a2: ptr MqAttr): cint {.
importc, header: "<mqueue.h>".}
proc mq_notify*(a1: Mqd, a2: ptr SigEvent): cint {.
importc, header: "<mqueue.h>".}
proc mq_open*(a1: cstring, a2: cint): Mqd {.
varargs, importc, header: "<mqueue.h>".}
proc mq_receive*(a1: Mqd, a2: cstring, a3: int, a4: var int): int {.
importc, header: "<mqueue.h>".}
proc mq_send*(a1: Mqd, a2: cstring, a3: int, a4: int): cint {.
importc, header: "<mqueue.h>".}
proc mq_setattr*(a1: Mqd, a2, a3: ptr MqAttr): cint {.
importc, header: "<mqueue.h>".}
proc mq_timedreceive*(a1: Mqd, a2: cstring, a3: int, a4: int,
a5: ptr Timespec): int {.importc, header: "<mqueue.h>".}
proc mq_timedsend*(a1: Mqd, a2: cstring, a3: int, a4: int,
a5: ptr Timespec): cint {.importc, header: "<mqueue.h>".}
proc mq_unlink*(a1: cstring): cint {.importc, header: "<mqueue.h>".}
proc mq_timedreceive*(a1: Mqd, a2: cstring, a3: int, a4: int,
a5: ptr Timespec): int {.importc, header: "<mqueue.h>".}
proc mq_timedsend*(a1: Mqd, a2: cstring, a3: int, a4: int,
a5: ptr Timespec): cint {.importc, header: "<mqueue.h>".}
proc mq_unlink*(a1: cstring): cint {.importc, header: "<mqueue.h>".}
proc getpwnam*(a1: cstring): ptr Passwd {.importc, header: "<pwd.h>".}
@@ -603,7 +606,7 @@ proc posix_madvise*(a1: pointer, a2: int, a3: cint): cint {.
importc, header: "<sys/mman.h>".}
proc posix_mem_offset*(a1: pointer, a2: int, a3: var Off,
a4: var int, a5: var cint): cint {.importc, header: "<sys/mman.h>".}
when not (defined(linux) and defined(amd64)):
when not (defined(linux) and defined(amd64)) and not defined(nintendoswitch):
proc posix_typed_mem_get_info*(a1: cint,
a2: var Posix_typed_mem_info): cint {.importc, header: "<sys/mman.h>".}
proc posix_typed_mem_open*(a1: cstring, a2, a3: cint): cint {.
@@ -713,12 +716,12 @@ proc sigwait*(a1: var Sigset, a2: var cint): cint {.
proc sigwaitinfo*(a1: var Sigset, a2: var SigInfo): cint {.
importc, header: "<signal.h>".}
proc catclose*(a1: Nl_catd): cint {.importc, header: "<nl_types.h>".}
proc catgets*(a1: Nl_catd, a2, a3: cint, a4: cstring): cstring {.
importc, header: "<nl_types.h>".}
proc catopen*(a1: cstring, a2: cint): Nl_catd {.
importc, header: "<nl_types.h>".}
when not defined(nintendoswitch):
proc catclose*(a1: Nl_catd): cint {.importc, header: "<nl_types.h>".}
proc catgets*(a1: Nl_catd, a2, a3: cint, a4: cstring): cstring {.
importc, header: "<nl_types.h>".}
proc catopen*(a1: cstring, a2: cint): Nl_catd {.
importc, header: "<nl_types.h>".}
proc sched_get_priority_max*(a1: cint): cint {.importc, header: "<sched.h>".}
proc sched_get_priority_min*(a1: cint): cint {.importc, header: "<sched.h>".}
@@ -800,11 +803,12 @@ when hasSpawnH:
a4: var Tposix_spawnattr,
a5, a6: cstringArray): cint {.importc, header: "<spawn.h>".}
proc getcontext*(a1: var Ucontext): cint {.importc, header: "<ucontext.h>".}
proc makecontext*(a1: var Ucontext, a4: proc (){.noconv.}, a3: cint) {.
varargs, importc, header: "<ucontext.h>".}
proc setcontext*(a1: var Ucontext): cint {.importc, header: "<ucontext.h>".}
proc swapcontext*(a1, a2: var Ucontext): cint {.importc, header: "<ucontext.h>".}
when not defined(nintendoswitch):
proc getcontext*(a1: var Ucontext): cint {.importc, header: "<ucontext.h>".}
proc makecontext*(a1: var Ucontext, a4: proc (){.noconv.}, a3: cint) {.
varargs, importc, header: "<ucontext.h>".}
proc setcontext*(a1: var Ucontext): cint {.importc, header: "<ucontext.h>".}
proc swapcontext*(a1, a2: var Ucontext): cint {.importc, header: "<ucontext.h>".}
proc readv*(a1: cint, a2: ptr IOVec, a3: cint): int {.
importc, header: "<sys/uio.h>".}

View File

@@ -0,0 +1,506 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2018 Joey Yakimowich-Payne
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# To be included from posix.nim!
const
hasSpawnH = true
hasAioH = false
type
DIR* {.importc: "DIR", header: "<dirent.h>",
incompleteStruct.} = object
const SIG_HOLD* = cast[SigHandler](2)
type
SocketHandle* = distinct cint # The type used to represent socket descriptors
type
Time* {.importc: "time_t", header: "<time.h>".} = distinct clong
Timespec* {.importc: "struct timespec",
header: "<time.h>", final, pure.} = object ## struct timespec
tv_sec*: Time ## Seconds.
tv_nsec*: clong ## Nanoseconds.
Dirent* {.importc: "struct dirent",
header: "<dirent.h>", final, pure.} = object ## dirent_t struct
d_ino*: Ino
d_type*: int8 # cuchar really!
d_name*: array[256, cchar]
Tflock* {.importc: "struct flock", final, pure,
header: "<fcntl.h>".} = object ## flock type
l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
l_whence*: cshort ## Flag for starting offset.
l_start*: Off ## Relative offset in bytes.
l_len*: Off ## Size; if 0 then until EOF.
l_pid*: Pid ## Process ID of the process holding the lock;
## returned with F_GETLK.
# no struct FTW on linux
Glob* {.importc: "glob_t", header: "<glob.h>",
final, pure.} = object ## glob_t
gl_pathc*: cint ## Count of paths matched by pattern.
gl_matchc*: cint ## Count of paths matching pattern
gl_offs*: cint ## Slots to reserve at the beginning of gl_pathv.
gl_flags*: cint
gl_pathv*: cstringArray ## Pointer to a list of matched pathnames.
gl_errfunc*: pointer
gl_closedir*: pointer
gl_readdir*: pointer
gl_opendir*: pointer
gl_lstat*: pointer
gl_stat*: pointer
Group* {.importc: "struct group", header: "<grp.h>",
final, pure.} = object ## struct group
gr_name*: cstring ## The name of the group.
gr_passwd*: cstring
gr_gid*: Gid ## Numerical group ID.
gr_mem*: cstringArray ## Pointer to a null-terminated array of character
## pointers to member names.
Iconv* {.importc: "iconv_t", header: "<iconv.h>".} = pointer
## Identifies the conversion from one codeset to another.
Lconv* {.importc: "struct lconv", header: "<locale.h>", final,
pure.} = object
decimal_point*: cstring
thousands_sep*: cstring
grouping*: cstring
int_curr_symbol*: cstring
currency_symbol*: cstring
mon_decimal_point*: cstring
mon_thousands_sep*: cstring
mon_grouping*: cstring
positive_sign*: cstring
negative_sign*: cstring
int_frac_digits*: char
frac_digits*: char
p_cs_precedes*: char
p_sep_by_space*: char
n_cs_precedes*: char
n_sep_by_space*: char
p_sign_posn*: char
n_sign_posn*: char
int_n_cs_precedes*: char
int_n_sep_by_space*: char
int_n_sign_posn*: char
int_p_cs_precedes*: char
int_p_sep_by_space*: char
int_p_sign_posn*: char
Passwd* {.importc: "struct passwd", header: "<pwd.h>",
final, pure.} = object ## struct passwd
pw_name*: cstring ## User's login name.
pw_passwd*: cstring
pw_uid*: Uid ## Numerical user ID.
pw_gid*: Gid ## Numerical group ID.
pw_comment*: cstring
pw_gecos*: cstring
pw_dir*: cstring ## Initial working directory.
pw_shell*: cstring ## Program to use as shell.
Blkcnt* {.importc: "blkcnt_t", header: "<sys/types.h>".} = clong
## used for file block counts
Blksize* {.importc: "blksize_t", header: "<sys/types.h>".} = clong
## used for block sizes
Clock* {.importc: "clock_t", header: "<sys/types.h>".} = clong
ClockId* {.importc: "clockid_t", header: "<sys/types.h>".} = cint
Dev* {.importc: "dev_t", header: "<sys/types.h>".} = culong
Fsblkcnt* {.importc: "fsblkcnt_t", header: "<sys/types.h>".} = culong
Fsfilcnt* {.importc: "fsfilcnt_t", header: "<sys/types.h>".} = culong
Gid* {.importc: "gid_t", header: "<sys/types.h>".} = cuint
Id* {.importc: "id_t", header: "<sys/types.h>".} = cuint
Ino* {.importc: "ino_t", header: "<sys/types.h>".} = culong
Key* {.importc: "key_t", header: "<sys/types.h>".} = cint
Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint # cuint really!
Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = culong
Off* {.importc: "off_t", header: "<sys/types.h>".} = clong
Pid* {.importc: "pid_t", header: "<sys/types.h>".} = cint
Pthread_attr* {.importc: "pthread_attr_t", header: "<sys/types.h>",
pure, final.} = object
abi: array[56 div sizeof(clong), clong]
Pthread_barrier* {.importc: "pthread_barrier_t",
header: "<sys/types.h>", pure, final.} = object
abi: array[32 div sizeof(clong), clong]
Pthread_barrierattr* {.importc: "pthread_barrierattr_t",
header: "<sys/types.h>", pure, final.} = object
abi: array[4 div sizeof(cint), cint]
Pthread_cond* {.importc: "pthread_cond_t", header: "<sys/types.h>",
pure, final.} = object
abi: array[48 div sizeof(clonglong), clonglong]
Pthread_condattr* {.importc: "pthread_condattr_t",
header: "<sys/types.h>", pure, final.} = object
abi: array[4 div sizeof(cint), cint]
Pthread_key* {.importc: "pthread_key_t", header: "<sys/types.h>".} = cuint
Pthread_mutex* {.importc: "pthread_mutex_t", header: "<sys/types.h>",
pure, final.} = object
abi: array[48 div sizeof(clong), clong]
Pthread_mutexattr* {.importc: "pthread_mutexattr_t",
header: "<sys/types.h>", pure, final.} = object
abi: array[4 div sizeof(cint), cint]
Pthread_once* {.importc: "pthread_once_t", header: "<sys/types.h>".} = cint
Pthread_rwlock* {.importc: "pthread_rwlock_t",
header: "<sys/types.h>", pure, final.} = object
abi: array[56 div sizeof(clong), clong]
Pthread_rwlockattr* {.importc: "pthread_rwlockattr_t",
header: "<sys/types.h>".} = object
abi: array[8 div sizeof(clong), clong]
Pthread_spinlock* {.importc: "pthread_spinlock_t",
header: "<sys/types.h>".} = cint
Pthread* {.importc: "pthread_t", header: "<sys/types.h>".} = culong
Suseconds* {.importc: "suseconds_t", header: "<sys/types.h>".} = clong
#Ttime* {.importc: "time_t", header: "<sys/types.h>".} = int
Timer* {.importc: "timer_t", header: "<sys/types.h>".} = pointer
Uid* {.importc: "uid_t", header: "<sys/types.h>".} = cuint
Useconds* {.importc: "useconds_t", header: "<sys/types.h>".} = cuint
Utsname* {.importc: "struct utsname",
header: "<sys/utsname.h>",
final, pure.} = object ## struct utsname
sysname*, ## Name of this implementation of the operating system.
nodename*, ## Name of this node within the communications
## network to which this node is attached, if any.
release*, ## Current release level of this implementation.
version*, ## Current version level of this release.
machine*, ## Name of the hardware type on which the
## system is running.
domainname*: array[65, char]
Sem* {.importc: "sem_t", header: "<semaphore.h>", final, pure.} = object
abi: array[32 div sizeof(clong), clong]
Stat* {.importc: "struct stat",
header: "<sys/stat.h>", final, pure.} = object ## struct stat
st_dev*: Dev ## Device ID of device containing file.
st_ino*: Ino ## File serial number.
st_mode*: Mode ## Mode of file (see below).
st_nlink*: Nlink ## Number of hard links to the file.
st_uid*: Uid ## User ID of file.
st_gid*: Gid ## Group ID of file.
st_rdev*: Dev ## Device ID (if file is character or block special).
st_size*: Off ## For regular files, the file size in bytes.
## For symbolic links, the length in bytes of the
## pathname contained in the symbolic link.
## For a shared memory object, the length in bytes.
## For a typed memory object, the length in bytes.
## For other file types, the use of this field is
## unspecified.
when StatHasNanoseconds:
st_atim*: Timespec ## Time of last access.
pad1: clong
st_mtim*: Timespec ## Time of last data modification.
pad2: clong
st_ctim*: Timespec ## Time of last status change.
pad3: clong
else:
st_atime*: Time ## Time of last access.
pad1: clong
st_mtime*: Time ## Time of last data modification.
pad2: clong
st_ctime*: Time ## Time of last status change.
pad3: clong
st_blksize*: Blksize ## A file system-specific preferred I/O block size
## for this object. In some file system types, this
## may vary from file to file.
st_blocks*: Blkcnt ## Number of blocks allocated for this object.
reserved: array[2, clong]
Statvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>",
final, pure.} = object ## struct statvfs
f_bsize*: culong ## File system block size.
f_frsize*: culong ## Fundamental file system block size.
f_blocks*: Fsblkcnt ## Total number of blocks on file system
## in units of f_frsize.
f_bfree*: Fsblkcnt ## Total number of free blocks.
f_bavail*: Fsblkcnt ## Number of free blocks available to
## non-privileged process.
f_files*: Fsfilcnt ## Total number of file serial numbers.
f_ffree*: Fsfilcnt ## Total number of free file serial numbers.
f_favail*: Fsfilcnt ## Number of file serial numbers available to
## non-privileged process.
f_fsid*: culong ## File system ID.
f_flag*: culong ## Bit mask of f_flag values.
f_namemax*: culong ## Maximum filename length.
# No Posix_typed_mem_info
Tm* {.importc: "struct tm", header: "<time.h>",
final, pure.} = object ## struct tm
tm_sec*: cint ## Seconds [0,60].
tm_min*: cint ## Minutes [0,59].
tm_hour*: cint ## Hour [0,23].
tm_mday*: cint ## Day of month [1,31].
tm_mon*: cint ## Month of year [0,11].
tm_year*: cint ## Years since 1900.
tm_wday*: cint ## Day of week [0,6] (Sunday =0).
tm_yday*: cint ## Day of year [0,365].
tm_isdst*: cint ## Daylight Savings flag.
Itimerspec* {.importc: "struct itimerspec", header: "<time.h>",
final, pure.} = object ## struct itimerspec
it_interval*: Timespec ## Timer period.
it_value*: Timespec ## Timer expiration.
Sig_atomic* {.importc: "sig_atomic_t", header: "<signal.h>".} = cint
## Possibly volatile-qualified integer type of an object that can be
## accessed as an atomic entity, even in the presence of asynchronous
## interrupts.
Sigset* {.importc: "sigset_t", header: "<signal.h>", final.} = culong
SigEvent* {.importc: "struct sigevent",
header: "<signal.h>", final, pure.} = object ## struct sigevent
sigev_notify*: cint ## Notification type.
sigev_signo*: cint ## Signal number.
sigev_value*: SigVal ## Signal value.
SigVal* {.importc: "union sigval",
header: "<signal.h>", final, pure.} = object ## struct sigval
sival_int*: cint ## integer signal value
sival_ptr*: pointer ## pointer signal value;
Sigaction* {.importc: "struct sigaction",
header: "<signal.h>", final, pure.} = object ## struct sigaction
sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching
## function or one of the macros
## SIG_IGN or SIG_DFL.
sa_mask*: Sigset ## Set of signals to be blocked during execution of
## the signal handling function.
sa_flags*: cint ## Special flags.
Stack* {.importc: "stack_t",
header: "<signal.h>", final, pure.} = object ## stack_t
ss_sp*: pointer ## Stack base or pointer.
ss_flags*: cint ## Flags.
ss_size*: csize ## Stack size.
SigInfo* {.importc: "siginfo_t",
header: "<signal.h>", final, pure.} = object ## siginfo_t
si_signo*: cint ## Signal number.
si_code*: cint ## Signal code.
si_value*: SigVal ## Signal value.
Nl_item* {.importc: "nl_item", header: "<langinfo.h>".} = cint
Sched_param* {.importc: "struct sched_param",
header: "<sched.h>",
final, pure.} = object ## struct sched_param
sched_priority*: cint
Timeval* {.importc: "struct timeval", header: "<sys/select.h>",
final, pure.} = object ## struct timeval
tv_sec*: Time ## Seconds.
tv_usec*: Suseconds ## Microseconds.
TFdSet* {.importc: "fd_set", header: "<sys/select.h>",
final, pure.} = object
abi: array[((64+(sizeof(clong) * 8)-1) div (sizeof(clong) * 8)), clong]
proc si_pid*(info: SigInfo): Pid =
## This might not be correct behavior. si_pid doesn't exist in Switch's
## devkitpro headers
raise newException(OSError, "Nintendo switch cannot get si_pid!")
type
Taiocb* {.importc: "struct aiocb", header: "<aio.h>",
final, pure.} = object ## struct aiocb
aio_fildes*: cint ## File descriptor.
aio_lio_opcode*: cint ## Operation to be performed.
aio_reqprio*: cint ## Request priority offset.
aio_buf*: pointer ## Location of buffer.
aio_nbytes*: csize ## Length of transfer.
aio_sigevent*: SigEvent ## Signal number and value.
next_prio: pointer
abs_prio: cint
policy: cint
error_Code: cint
return_value: clong
aio_offset*: Off ## File offset.
reserved: array[32, uint8]
type
Tposix_spawnattr* {.importc: "posix_spawnattr_t",
header: "<spawn.h>", final, pure.} = object
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t",
header: "<spawn.h>", final, pure.} = object
# from sys/un.h
const Sockaddr_un_path_length* = 108
type
Socklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint
# cushort really
TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cshort
SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr
sa_len: cuchar
sa_family*: TSa_Family ## Address family.
sa_data*: array[14, char] ## Socket address (variable-length data).
Sockaddr_storage* {.importc: "struct sockaddr_storage",
header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr_storage
ss_len: cuchar
ss_family*: TSa_Family ## Address family.
ss_padding1: array[64 - sizeof(cuchar) - sizeof(cshort), char]
ss_align: clonglong
ss_padding2: array[
128 - sizeof(cuchar) - sizeof(cshort) -
(64 - sizeof(cuchar) - sizeof(cshort)) - 64, char]
Tif_nameindex* {.importc: "struct if_nameindex", final,
pure, header: "<net/if.h>".} = object ## struct if_nameindex
if_index*: cuint ## Numeric index of the interface.
if_name*: cstring ## Null-terminated name of the interface.
IOVec* {.importc: "struct iovec", pure, final,
header: "<sys/socket.h>".} = object ## struct iovec
iov_base*: pointer ## Base address of a memory region for input or output.
iov_len*: csize ## The size of the memory pointed to by iov_base.
Tmsghdr* {.importc: "struct msghdr", pure, final,
header: "<sys/socket.h>".} = object ## struct msghdr
msg_name*: pointer ## Optional address.
msg_namelen*: Socklen ## Size of address.
msg_iov*: ptr IOVec ## Scatter/gather array.
msg_iovlen*: csize ## Members in msg_iov.
msg_control*: pointer ## Ancillary data; see below.
msg_controllen*: csize ## Ancillary data buffer len.
msg_flags*: cint ## Flags on received message.
Tcmsghdr* {.importc: "struct cmsghdr", pure, final,
header: "<sys/socket.h>".} = object ## struct cmsghdr
cmsg_len*: csize ## Data byte count, including the cmsghdr.
cmsg_level*: cint ## Originating protocol.
cmsg_type*: cint ## Protocol-specific type.
TLinger* {.importc: "struct linger", pure, final,
header: "<sys/socket.h>".} = object ## struct linger
l_onoff*: cint ## Indicates whether linger option is enabled.
l_linger*: cint ## Linger time, in seconds.
# data follows...
InPort* = uint16
InAddrScalar* = uint32
InAddrT* {.importc: "in_addr_t", pure, final,
header: "<netinet/in.h>".} = uint32
InAddr* {.importc: "struct in_addr", pure, final,
header: "<netinet/in.h>".} = object ## struct in_addr
s_addr*: InAddrScalar
Sockaddr_in* {.importc: "struct sockaddr_in", pure, final,
header: "<netinet/in.h>".} = object ## struct sockaddr_in
sin_len*: cushort
sin_family*: TSa_Family ## AF_INET.
sin_port*: InPort ## Port number.
sin_addr*: InAddr ## IP address.
sin_zero: array[8, uint8]
In6Addr* {.importc: "struct in6_addr", pure, final,
header: "<netinet/in.h>".} = object ## struct in6_addr
s6_addr*: array[0..15, char]
Sockaddr_in6* {.importc: "struct sockaddr_in6", pure, final,
header: "<netinet/in.h>".} = object ## struct sockaddr_in6
sin6_family*: TSa_Family ## AF_INET6.
sin6_port*: InPort ## Port number.
sin6_flowinfo*: uint32 ## IPv6 traffic class and flow information.
sin6_addr*: In6Addr ## IPv6 address.
sin6_scope_id*: uint32 ## Set of interfaces for a scope.
Hostent* {.importc: "struct hostent", pure, final,
header: "<netdb.h>".} = object ## struct hostent
h_name*: cstring ## Official name of the host.
h_aliases*: cstringArray ## A pointer to an array of pointers to
## alternative host names, terminated by a
## null pointer.
h_addrtype*: cint ## Address type.
h_length*: cint ## The length, in bytes, of the address.
h_addr_list*: cstringArray ## A pointer to an array of pointers to network
## addresses (in network byte order) for the
## host, terminated by a null pointer.
Tnetent* {.importc: "struct netent", pure, final,
header: "<netdb.h>".} = object ## struct netent
n_name*: cstring ## Official, fully-qualified (including the
## domain) name of the host.
n_aliases*: cstringArray ## A pointer to an array of pointers to
## alternative network names, terminated by a
## null pointer.
n_addrtype*: cint ## The address type of the network.
n_net*: uint32 ## The network number, in host byte order.
Protoent* {.importc: "struct protoent", pure, final,
header: "<netdb.h>".} = object ## struct protoent
p_name*: cstring ## Official name of the protocol.
p_aliases*: cstringArray ## A pointer to an array of pointers to
## alternative protocol names, terminated by
## a null pointer.
p_proto*: cint ## The protocol number.
Servent* {.importc: "struct servent", pure, final,
header: "<netdb.h>".} = object ## struct servent
s_name*: cstring ## Official name of the service.
s_aliases*: cstringArray ## A pointer to an array of pointers to
## alternative service names, terminated by
## a null pointer.
s_port*: cint ## The port number at which the service
## resides, in network byte order.
s_proto*: cstring ## The name of the protocol to use when
## contacting the service.
AddrInfo* {.importc: "struct addrinfo", pure, final,
header: "<netdb.h>".} = object ## struct addrinfo
ai_flags*: cint ## Input flags.
ai_family*: cint ## Address family of socket.
ai_socktype*: cint ## Socket type.
ai_protocol*: cint ## Protocol of socket.
ai_addrlen*: Socklen ## Length of socket address.
ai_canonname*: cstring ## Canonical name of service location.
ai_addr*: ptr SockAddr ## Socket address of socket.
ai_next*: ptr AddrInfo ## Pointer to next in list.
TPollfd* {.importc: "struct pollfd", pure, final,
header: "<poll.h>".} = object ## struct pollfd
fd*: cint ## The following descriptor being polled.
events*: cshort ## The input event flags (see below).
revents*: cshort ## The output event flags (see below).
Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = culong
var
errno* {.importc, header: "<errno.h>".}: cint ## error variable
h_errno* {.importc, header: "<netdb.h>".}: cint
daylight* {.importc: "_daylight", header: "<time.h>".}: cint
timezone* {.importc: "_timezone", header: "<time.h>".}: clong
# Regenerate using detect.nim!
include posix_nintendoswitch_consts
const POSIX_SPAWN_USEVFORK* = cint(0x40) # needs _GNU_SOURCE!
# <sys/wait.h>
proc WEXITSTATUS*(s: cint): cint = (s shr 8) and 0xff
proc WIFEXITED*(s:cint) : bool = (s and 0xff) == 0
proc WTERMSIG*(s:cint): cint = s and 0x7f
proc WSTOPSIG*(s:cint): cint = WEXITSTATUS(s)
proc WIFSIGNALED*(s:cint) : bool = ((s and 0x7f) > 0) and ((s and 0x7f) < 0x7f)
proc WIFSTOPPED*(s:cint) : bool = (s and 0xff) == 0x7f

View File

@@ -0,0 +1,586 @@
# Generated by detect.nim
# <aio.h>
# <dlfcn.h>
# <errno.h>
const E2BIG* = cint(7)
const EACCES* = cint(13)
const EADDRINUSE* = cint(112)
const EADDRNOTAVAIL* = cint(125)
const EAFNOSUPPORT* = cint(106)
const EAGAIN* = cint(11)
const EALREADY* = cint(120)
const EBADF* = cint(9)
const EBADMSG* = cint(77)
const EBUSY* = cint(16)
const ECANCELED* = cint(140)
const ECHILD* = cint(10)
const ECONNABORTED* = cint(113)
const ECONNREFUSED* = cint(111)
const ECONNRESET* = cint(104)
const EDEADLK* = cint(45)
const EDESTADDRREQ* = cint(121)
const EDOM* = cint(33)
const EDQUOT* = cint(132)
const EEXIST* = cint(17)
const EFAULT* = cint(14)
const EFBIG* = cint(27)
const EHOSTUNREACH* = cint(118)
const EIDRM* = cint(36)
const EILSEQ* = cint(138)
const EINPROGRESS* = cint(119)
const EINTR* = cint(4)
const EINVAL* = cint(22)
const EIO* = cint(5)
const EISCONN* = cint(127)
const EISDIR* = cint(21)
const ELOOP* = cint(92)
const EMFILE* = cint(24)
const EMLINK* = cint(31)
const EMSGSIZE* = cint(122)
const EMULTIHOP* = cint(74)
const ENAMETOOLONG* = cint(91)
const ENETDOWN* = cint(115)
const ENETRESET* = cint(126)
const ENETUNREACH* = cint(114)
const ENFILE* = cint(23)
const ENOBUFS* = cint(105)
const ENODATA* = cint(61)
const ENODEV* = cint(19)
const ENOENT* = cint(2)
const ENOEXEC* = cint(8)
const ENOLCK* = cint(46)
const ENOLINK* = cint(67)
const ENOMEM* = cint(12)
const ENOMSG* = cint(35)
const ENOPROTOOPT* = cint(109)
const ENOSPC* = cint(28)
const ENOSR* = cint(63)
const ENOSTR* = cint(60)
const ENOSYS* = cint(88)
const ENOTCONN* = cint(128)
const ENOTDIR* = cint(20)
const ENOTEMPTY* = cint(90)
const ENOTSOCK* = cint(108)
const ENOTSUP* = cint(134)
const ENOTTY* = cint(25)
const ENXIO* = cint(6)
const EOPNOTSUPP* = cint(95)
const EOVERFLOW* = cint(139)
const EPERM* = cint(1)
const EPIPE* = cint(32)
const EPROTO* = cint(71)
const EPROTONOSUPPORT* = cint(123)
const EPROTOTYPE* = cint(107)
const ERANGE* = cint(34)
const EROFS* = cint(30)
const ESPIPE* = cint(29)
const ESRCH* = cint(3)
const ESTALE* = cint(133)
const ETIME* = cint(62)
const ETIMEDOUT* = cint(116)
const ETXTBSY* = cint(26)
const EWOULDBLOCK* = cint(11)
const EXDEV* = cint(18)
# <fcntl.h>
const F_DUPFD* = cint(0)
const F_GETFD* = cint(1)
const F_SETFD* = cint(2)
const F_GETFL* = cint(3)
const F_SETFL* = cint(4)
const F_GETLK* = cint(7)
const F_SETLK* = cint(8)
const F_SETLKW* = cint(9)
const F_GETOWN* = cint(5)
const F_SETOWN* = cint(6)
const FD_CLOEXEC* = cint(1)
const F_RDLCK* = cint(1)
const F_UNLCK* = cint(3)
const F_WRLCK* = cint(2)
const O_CREAT* = cint(512)
const O_EXCL* = cint(2048)
const O_NOCTTY* = cint(32768)
const O_TRUNC* = cint(1024)
const O_APPEND* = cint(8)
const O_NONBLOCK* = cint(16384)
const O_SYNC* = cint(8192)
const O_ACCMODE* = cint(3)
const O_RDONLY* = cint(0)
const O_RDWR* = cint(2)
const O_WRONLY* = cint(1)
# <fenv.h>
# <fmtmsg.h>
# <fnmatch.h>
const FNM_NOMATCH* = cint(1)
const FNM_PATHNAME* = cint(2)
const FNM_PERIOD* = cint(4)
const FNM_NOESCAPE* = cint(1)
# <ftw.h>
# <glob.h>
const GLOB_APPEND* = cint(1)
const GLOB_DOOFFS* = cint(2)
const GLOB_ERR* = cint(4)
const GLOB_MARK* = cint(8)
const GLOB_NOCHECK* = cint(16)
const GLOB_NOSORT* = cint(32)
const GLOB_NOSPACE* = cint(-1)
# <langinfo.h>
const CODESET* = cint(0)
const D_T_FMT* = cint(1)
const D_FMT* = cint(2)
const T_FMT* = cint(3)
const T_FMT_AMPM* = cint(4)
const AM_STR* = cint(5)
const PM_STR* = cint(6)
const DAY_1* = cint(7)
const DAY_2* = cint(8)
const DAY_3* = cint(9)
const DAY_4* = cint(10)
const DAY_5* = cint(11)
const DAY_6* = cint(12)
const DAY_7* = cint(13)
const ABDAY_1* = cint(14)
const ABDAY_2* = cint(15)
const ABDAY_3* = cint(16)
const ABDAY_4* = cint(17)
const ABDAY_5* = cint(18)
const ABDAY_6* = cint(19)
const ABDAY_7* = cint(20)
const MON_1* = cint(21)
const MON_2* = cint(22)
const MON_3* = cint(23)
const MON_4* = cint(24)
const MON_5* = cint(25)
const MON_6* = cint(26)
const MON_7* = cint(27)
const MON_8* = cint(28)
const MON_9* = cint(29)
const MON_10* = cint(30)
const MON_11* = cint(31)
const MON_12* = cint(32)
const ABMON_1* = cint(33)
const ABMON_2* = cint(34)
const ABMON_3* = cint(35)
const ABMON_4* = cint(36)
const ABMON_5* = cint(37)
const ABMON_6* = cint(38)
const ABMON_7* = cint(39)
const ABMON_8* = cint(40)
const ABMON_9* = cint(41)
const ABMON_10* = cint(42)
const ABMON_11* = cint(43)
const ABMON_12* = cint(44)
const ERA* = cint(45)
const ERA_D_FMT* = cint(46)
const ERA_D_T_FMT* = cint(47)
const ERA_T_FMT* = cint(48)
const ALT_DIGITS* = cint(49)
const RADIXCHAR* = cint(50)
const THOUSEP* = cint(51)
const YESEXPR* = cint(52)
const NOEXPR* = cint(53)
const CRNCYSTR* = cint(56)
# <locale.h>
const LC_ALL* = cint(0)
const LC_COLLATE* = cint(1)
const LC_CTYPE* = cint(2)
const LC_MESSAGES* = cint(6)
const LC_MONETARY* = cint(3)
const LC_NUMERIC* = cint(4)
const LC_TIME* = cint(5)
# <netdb.h>
const IPPORT_RESERVED* = cint(1024)
const HOST_NOT_FOUND* = cint(1)
const NO_DATA* = cint(4)
const NO_RECOVERY* = cint(3)
const TRY_AGAIN* = cint(2)
const AI_PASSIVE* = cint(1)
const AI_CANONNAME* = cint(2)
const AI_NUMERICHOST* = cint(4)
const AI_NUMERICSERV* = cint(8)
const AI_V4MAPPED* = cint(2048)
const AI_ALL* = cint(256)
const AI_ADDRCONFIG* = cint(1024)
const NI_NOFQDN* = cint(1)
const NI_NUMERICHOST* = cint(2)
const NI_NAMEREQD* = cint(4)
const NI_NUMERICSERV* = cint(8)
const NI_NUMERICSCOPE* = cint(32)
const NI_DGRAM* = cint(16)
const EAI_AGAIN* = cint(2)
const EAI_BADFLAGS* = cint(3)
const EAI_FAIL* = cint(4)
const EAI_FAMILY* = cint(5)
const EAI_MEMORY* = cint(6)
const EAI_NONAME* = cint(8)
const EAI_SERVICE* = cint(9)
const EAI_SOCKTYPE* = cint(10)
const EAI_SYSTEM* = cint(11)
const EAI_OVERFLOW* = cint(14)
# <net/if.h>
const IF_NAMESIZE* = cint(16)
# <netinet/in.h>
const IPPROTO_IP* = cint(0)
const IPPROTO_IPV6* = cint(41)
const IPPROTO_ICMP* = cint(1)
const IPPROTO_RAW* = cint(255)
const IPPROTO_TCP* = cint(6)
const IPPROTO_UDP* = cint(17)
const INADDR_ANY* = InAddrScalar(0)
const INADDR_LOOPBACK* = InAddrScalar(2130706433)
const INADDR_BROADCAST* = InAddrScalar(-1)
const INET_ADDRSTRLEN* = cint(16)
const INET6_ADDRSTRLEN* = cint(46)
const IPV6_JOIN_GROUP* = cint(12)
const IPV6_LEAVE_GROUP* = cint(13)
const IPV6_MULTICAST_HOPS* = cint(10)
const IPV6_MULTICAST_IF* = cint(9)
const IPV6_MULTICAST_LOOP* = cint(11)
const IPV6_UNICAST_HOPS* = cint(4)
const IPV6_V6ONLY* = cint(27)
# <netinet/tcp.h>
const TCP_NODELAY* = cint(1)
# <nl_types.h>
# <poll.h>
const POLLIN* = cshort(1)
const POLLRDNORM* = cshort(64)
const POLLRDBAND* = cshort(128)
const POLLPRI* = cshort(2)
const POLLOUT* = cshort(4)
const POLLWRNORM* = cshort(4)
const POLLWRBAND* = cshort(256)
const POLLERR* = cshort(8)
const POLLHUP* = cshort(16)
const POLLNVAL* = cshort(32)
# <pthread.h>
const PTHREAD_CREATE_DETACHED* = cint(0)
const PTHREAD_CREATE_JOINABLE* = cint(1)
const PTHREAD_EXPLICIT_SCHED* = cint(2)
const PTHREAD_INHERIT_SCHED* = cint(1)
const PTHREAD_SCOPE_PROCESS* = cint(0)
const PTHREAD_SCOPE_SYSTEM* = cint(1)
# <sched.h>
const SCHED_FIFO* = cint(1)
const SCHED_RR* = cint(2)
const SCHED_OTHER* = cint(0)
# <semaphore.h>
# <signal.h>
const SIGEV_NONE* = cint(1)
const SIGEV_SIGNAL* = cint(2)
const SIGEV_THREAD* = cint(3)
const SIGABRT* = cint(6)
const SIGALRM* = cint(14)
const SIGBUS* = cint(10)
const SIGCHLD* = cint(20)
const SIGCONT* = cint(19)
const SIGFPE* = cint(8)
const SIGHUP* = cint(1)
const SIGILL* = cint(4)
const SIGINT* = cint(2)
const SIGKILL* = cint(9)
const SIGPIPE* = cint(13)
const SIGQUIT* = cint(3)
const SIGSEGV* = cint(11)
const SIGSTOP* = cint(17)
const SIGTERM* = cint(15)
const SIGTSTP* = cint(18)
const SIGTTIN* = cint(21)
const SIGTTOU* = cint(22)
const SIGUSR1* = cint(30)
const SIGUSR2* = cint(31)
const SIGPOLL* = cint(23)
const SIGPROF* = cint(27)
const SIGSYS* = cint(12)
const SIGTRAP* = cint(5)
const SIGURG* = cint(16)
const SIGVTALRM* = cint(26)
const SIGXCPU* = cint(24)
const SIGXFSZ* = cint(25)
const SA_NOCLDSTOP* = cint(1)
const SIG_BLOCK* = cint(1)
const SIG_UNBLOCK* = cint(2)
const SIG_SETMASK* = cint(0)
const SS_ONSTACK* = cint(1)
const SS_DISABLE* = cint(2)
const MINSIGSTKSZ* = cint(2048)
const SIGSTKSZ* = cint(8192)
const SIG_DFL* = cast[Sighandler](0)
const SIG_ERR* = cast[Sighandler](-1)
const SIG_IGN* = cast[Sighandler](1)
# <sys/ipc.h>
# <sys/mman.h>
# <sys/resource.h>
# <sys/select.h>
const FD_SETSIZE* = cint(64)
# <sys/socket.h>
const MSG_CTRUNC* = cint(32)
const MSG_DONTROUTE* = cint(4)
const MSG_EOR* = cint(8)
const MSG_OOB* = cint(1)
const SCM_RIGHTS* = cint(1)
const SO_ACCEPTCONN* = cint(2)
const SO_BROADCAST* = cint(32)
const SO_DEBUG* = cint(1)
const SO_DONTROUTE* = cint(16)
const SO_ERROR* = cint(4103)
const SO_KEEPALIVE* = cint(8)
const SO_LINGER* = cint(128)
const SO_OOBINLINE* = cint(256)
const SO_RCVBUF* = cint(4098)
const SO_RCVLOWAT* = cint(4100)
const SO_RCVTIMEO* = cint(4102)
const SO_REUSEADDR* = cint(4)
const SO_SNDBUF* = cint(4097)
const SO_SNDLOWAT* = cint(4099)
const SO_SNDTIMEO* = cint(4101)
const SO_TYPE* = cint(4104)
const SOCK_DGRAM* = cint(2)
const SOCK_RAW* = cint(3)
const SOCK_SEQPACKET* = cint(5)
const SOCK_STREAM* = cint(1)
const SOL_SOCKET* = cint(65535)
const SOMAXCONN* = cint(128)
const SO_REUSEPORT* = cint(512)
const MSG_NOSIGNAL* = cint(131072)
const MSG_PEEK* = cint(2)
const MSG_TRUNC* = cint(16)
const MSG_WAITALL* = cint(64)
const AF_INET* = TSa_Family(2)
const AF_INET6* = TSa_Family(28)
const AF_UNIX* = TSa_Family(1)
const AF_UNSPEC* = TSa_Family(0)
const SHUT_RD* = cint(0)
const SHUT_RDWR* = cint(2)
const SHUT_WR* = cint(1)
# <sys/stat.h>
const S_IFBLK* = cint(24576)
const S_IFCHR* = cint(8192)
const S_IFDIR* = cint(16384)
const S_IFIFO* = cint(4096)
const S_IFLNK* = cint(40960)
const S_IFMT* = cint(61440)
const S_IFREG* = cint(32768)
const S_IFSOCK* = cint(49152)
const S_IRGRP* = cint(32)
const S_IROTH* = cint(4)
const S_IRUSR* = cint(256)
const S_IRWXG* = cint(56)
const S_IRWXO* = cint(7)
const S_IRWXU* = cint(448)
const S_ISGID* = cint(1024)
const S_ISUID* = cint(2048)
const S_ISVTX* = cint(512)
const S_IWGRP* = cint(16)
const S_IWOTH* = cint(2)
const S_IWUSR* = cint(128)
const S_IXGRP* = cint(8)
const S_IXOTH* = cint(1)
const S_IXUSR* = cint(64)
# <sys/statvfs.h>
const ST_RDONLY* = cint(1)
const ST_NOSUID* = cint(2)
# <sys/wait.h>
const WNOHANG* = cint(1)
const WUNTRACED* = cint(2)
# <spawn.h>
const POSIX_SPAWN_RESETIDS* = cint(1)
const POSIX_SPAWN_SETPGROUP* = cint(2)
const POSIX_SPAWN_SETSCHEDPARAM* = cint(4)
const POSIX_SPAWN_SETSCHEDULER* = cint(8)
const POSIX_SPAWN_SETSIGDEF* = cint(16)
const POSIX_SPAWN_SETSIGMASK* = cint(32)
# <stdio.h>
const IOFBF* = cint(0)
const IONBF* = cint(2)
# <time.h>
const CLOCKS_PER_SEC* = clong(100)
const CLOCK_REALTIME* = cint(1)
const TIMER_ABSTIME* = cint(4)
const CLOCK_MONOTONIC* = cint(4)
# <unistd.h>
const F_OK* = cint(0)
const R_OK* = cint(4)
const W_OK* = cint(2)
const X_OK* = cint(1)
const F_LOCK* = cint(1)
const F_TEST* = cint(3)
const F_TLOCK* = cint(2)
const F_ULOCK* = cint(0)
const PC_2_SYMLINKS* = cint(13)
const PC_ALLOC_SIZE_MIN* = cint(15)
const PC_ASYNC_IO* = cint(9)
const PC_CHOWN_RESTRICTED* = cint(6)
const PC_FILESIZEBITS* = cint(12)
const PC_LINK_MAX* = cint(0)
const PC_MAX_CANON* = cint(1)
const PC_MAX_INPUT* = cint(2)
const PC_NAME_MAX* = cint(3)
const PC_NO_TRUNC* = cint(7)
const PC_PATH_MAX* = cint(4)
const PC_PIPE_BUF* = cint(5)
const PC_PRIO_IO* = cint(10)
const PC_REC_INCR_XFER_SIZE* = cint(16)
const PC_REC_MIN_XFER_SIZE* = cint(18)
const PC_REC_XFER_ALIGN* = cint(19)
const PC_SYMLINK_MAX* = cint(14)
const PC_SYNC_IO* = cint(11)
const PC_VDISABLE* = cint(8)
const SC_2_C_BIND* = cint(108)
const SC_2_C_DEV* = cint(109)
const SC_2_CHAR_TERM* = cint(107)
const SC_2_FORT_DEV* = cint(110)
const SC_2_FORT_RUN* = cint(111)
const SC_2_LOCALEDEF* = cint(112)
const SC_2_PBS* = cint(113)
const SC_2_PBS_ACCOUNTING* = cint(114)
const SC_2_PBS_CHECKPOINT* = cint(115)
const SC_2_PBS_LOCATE* = cint(116)
const SC_2_PBS_MESSAGE* = cint(117)
const SC_2_PBS_TRACK* = cint(118)
const SC_2_SW_DEV* = cint(119)
const SC_2_UPE* = cint(120)
const SC_2_VERSION* = cint(121)
const SC_ADVISORY_INFO* = cint(54)
const SC_AIO_LISTIO_MAX* = cint(34)
const SC_AIO_MAX* = cint(35)
const SC_AIO_PRIO_DELTA_MAX* = cint(36)
const SC_ARG_MAX* = cint(0)
const SC_ASYNCHRONOUS_IO* = cint(21)
const SC_ATEXIT_MAX* = cint(55)
const SC_BARRIERS* = cint(56)
const SC_BC_BASE_MAX* = cint(57)
const SC_BC_DIM_MAX* = cint(58)
const SC_BC_SCALE_MAX* = cint(59)
const SC_BC_STRING_MAX* = cint(60)
const SC_CHILD_MAX* = cint(1)
const SC_CLK_TCK* = cint(2)
const SC_CLOCK_SELECTION* = cint(61)
const SC_COLL_WEIGHTS_MAX* = cint(62)
const SC_CPUTIME* = cint(63)
const SC_DELAYTIMER_MAX* = cint(37)
const SC_EXPR_NEST_MAX* = cint(64)
const SC_FSYNC* = cint(22)
const SC_GETGR_R_SIZE_MAX* = cint(50)
const SC_GETPW_R_SIZE_MAX* = cint(51)
const SC_HOST_NAME_MAX* = cint(65)
const SC_IOV_MAX* = cint(66)
const SC_IPV6* = cint(67)
const SC_JOB_CONTROL* = cint(5)
const SC_LINE_MAX* = cint(68)
const SC_LOGIN_NAME_MAX* = cint(52)
const SC_MAPPED_FILES* = cint(23)
const SC_MEMLOCK* = cint(24)
const SC_MEMLOCK_RANGE* = cint(25)
const SC_MEMORY_PROTECTION* = cint(26)
const SC_MESSAGE_PASSING* = cint(27)
const SC_MONOTONIC_CLOCK* = cint(69)
const SC_MQ_OPEN_MAX* = cint(13)
const SC_MQ_PRIO_MAX* = cint(14)
const SC_NGROUPS_MAX* = cint(3)
const SC_OPEN_MAX* = cint(4)
const SC_PAGE_SIZE* = cint(8)
const SC_PRIORITIZED_IO* = cint(28)
const SC_PRIORITY_SCHEDULING* = cint(101)
const SC_RAW_SOCKETS* = cint(70)
const SC_RE_DUP_MAX* = cint(73)
const SC_READER_WRITER_LOCKS* = cint(71)
const SC_REALTIME_SIGNALS* = cint(29)
const SC_REGEXP* = cint(72)
const SC_RTSIG_MAX* = cint(15)
const SC_SAVED_IDS* = cint(6)
const SC_SEM_NSEMS_MAX* = cint(16)
const SC_SEM_VALUE_MAX* = cint(17)
const SC_SEMAPHORES* = cint(30)
const SC_SHARED_MEMORY_OBJECTS* = cint(31)
const SC_SHELL* = cint(74)
const SC_SIGQUEUE_MAX* = cint(18)
const SC_SPAWN* = cint(75)
const SC_SPIN_LOCKS* = cint(76)
const SC_SPORADIC_SERVER* = cint(77)
const SC_SS_REPL_MAX* = cint(78)
const SC_STREAM_MAX* = cint(100)
const SC_SYMLOOP_MAX* = cint(79)
const SC_SYNCHRONIZED_IO* = cint(32)
const SC_THREAD_ATTR_STACKADDR* = cint(43)
const SC_THREAD_ATTR_STACKSIZE* = cint(44)
const SC_THREAD_CPUTIME* = cint(80)
const SC_THREAD_DESTRUCTOR_ITERATIONS* = cint(53)
const SC_THREAD_KEYS_MAX* = cint(38)
const SC_THREAD_PRIO_INHERIT* = cint(46)
const SC_THREAD_PRIO_PROTECT* = cint(47)
const SC_THREAD_PRIORITY_SCHEDULING* = cint(45)
const SC_THREAD_PROCESS_SHARED* = cint(48)
const SC_THREAD_SAFE_FUNCTIONS* = cint(49)
const SC_THREAD_SPORADIC_SERVER* = cint(81)
const SC_THREAD_STACK_MIN* = cint(39)
const SC_THREAD_THREADS_MAX* = cint(40)
const SC_THREADS* = cint(42)
const SC_TIMEOUTS* = cint(82)
const SC_TIMER_MAX* = cint(19)
const SC_TIMERS* = cint(33)
const SC_TRACE* = cint(83)
const SC_TRACE_EVENT_FILTER* = cint(84)
const SC_TRACE_EVENT_NAME_MAX* = cint(85)
const SC_TRACE_INHERIT* = cint(86)
const SC_TRACE_LOG* = cint(87)
const SC_TRACE_NAME_MAX* = cint(88)
const SC_TRACE_SYS_MAX* = cint(89)
const SC_TRACE_USER_EVENT_MAX* = cint(90)
const SC_TTY_NAME_MAX* = cint(41)
const SC_TYPED_MEMORY_OBJECTS* = cint(91)
const SC_TZNAME_MAX* = cint(20)
const SC_V6_ILP32_OFF32* = cint(92)
const SC_V6_ILP32_OFFBIG* = cint(93)
const SC_V6_LP64_OFF64* = cint(94)
const SC_V6_LPBIG_OFFBIG* = cint(95)
const SC_VERSION* = cint(7)
const SC_XBS5_ILP32_OFF32* = cint(92)
const SC_XBS5_ILP32_OFFBIG* = cint(93)
const SC_XBS5_LP64_OFF64* = cint(94)
const SC_XBS5_LPBIG_OFFBIG* = cint(95)
const SC_XOPEN_CRYPT* = cint(96)
const SC_XOPEN_ENH_I18N* = cint(97)
const SC_XOPEN_LEGACY* = cint(98)
const SC_XOPEN_REALTIME* = cint(99)
const SC_XOPEN_REALTIME_THREADS* = cint(102)
const SC_XOPEN_SHM* = cint(103)
const SC_XOPEN_STREAMS* = cint(104)
const SC_XOPEN_UNIX* = cint(105)
const SC_XOPEN_VERSION* = cint(106)
const SC_NPROCESSORS_ONLN* = cint(10)
const SEEK_SET* = cint(0)
const SEEK_CUR* = cint(1)
const SEEK_END* = cint(2)

View File

@@ -137,6 +137,28 @@ when defined(posix):
proc symAddr(lib: LibHandle, name: cstring): pointer =
return dlsym(lib, name)
elif defined(nintendoswitch):
#
# =========================================================================
# Nintendo switch DevkitPro sdk does not have these. Raise an error if called.
# =========================================================================
#
proc dlclose(lib: LibHandle) =
raise newException(OSError, "dlclose not implemented on Nintendo Switch!")
proc dlopen(path: cstring, mode: int): LibHandle =
raise newException(OSError, "dlopen not implemented on Nintendo Switch!")
proc dlsym(lib: LibHandle, name: cstring): pointer =
raise newException(OSError, "dlsym not implemented on Nintendo Switch!")
proc loadLib(path: string, global_symbols=false): LibHandle =
raise newException(OSError, "loadLib not implemented on Nintendo Switch!")
proc loadLib(): LibHandle =
raise newException(OSError, "loadLib not implemented on Nintendo Switch!")
proc unloadLib(lib: LibHandle) =
raise newException(OSError, "unloadLib not implemented on Nintendo Switch!")
proc symAddr(lib: LibHandle, name: cstring): pointer =
raise newException(OSError, "symAddr not implemented on Nintendo Switch!")
elif defined(windows) or defined(dos):
#
# =======================================================================

View File

@@ -819,7 +819,8 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
y = dir / y
var k = pcFile
when defined(linux) or defined(macosx) or defined(bsd) or defined(genode):
when defined(linux) or defined(macosx) or
defined(bsd) or defined(genode) or defined(nintendoswitch):
if x.d_type != DT_UNKNOWN:
if x.d_type == DT_DIR: k = pcDir
if x.d_type == DT_LNK:
@@ -1283,6 +1284,13 @@ elif defined(windows):
if i < ownArgv.len and i >= 0: return TaintedString(ownArgv[i])
raise newException(IndexError, "invalid index")
elif defined(nintendoswitch):
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
raise newException(OSError, "paramStr is not implemented on Nintendo Switch")
proc paramCount*(): int {.tags: [ReadIOEffect].} =
raise newException(OSError, "paramCount is not implemented on Nintendo Switch")
elif not defined(createNimRtl) and
not(defined(posix) and appType == "lib") and
not defined(genode):
@@ -1439,7 +1447,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
result = getApplAux("/proc/self/exe")
elif defined(solaris):
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
elif defined(genode):
elif defined(genode) or defined(nintendoswitch):
raiseOSError(OSErrorCode(-1), "POSIX command line not supported")
elif defined(freebsd) or defined(dragonfly):
result = getApplFreebsd()

View File

@@ -597,7 +597,7 @@ proc quoteShellPosix*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".}
else:
return "'" & s.replace("'", "'\"'\"'") & "'"
when defined(windows) or defined(posix):
when defined(windows) or defined(posix) or defined(nintendoswitch):
proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
## Quote ``s``, so it can be safely passed to shell.
when defined(windows):

View File

@@ -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
else:
include ioselects/ioselectors_poll

View File

@@ -45,7 +45,7 @@ when defined(windows):
SIGTERM = cint(15)
elif defined(macosx) or defined(linux) or defined(freebsd) or
defined(openbsd) or defined(netbsd) or defined(solaris) or
defined(dragonfly):
defined(dragonfly) or defined(nintendoswitch):
const
SIGABRT = cint(6)
SIGFPE = cint(8)

View File

@@ -167,6 +167,24 @@ elif defined(genode):
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr {.
error: "nimGetProcAddr not implemented".}
elif defined(nintendoswitch):
proc nimUnloadLibrary(lib: LibHandle) =
stderr.rawWrite("nimUnLoadLibrary not implemented")
stderr.rawWrite("\n")
quit(1)
proc nimLoadLibrary(path: string): LibHandle =
stderr.rawWrite("nimLoadLibrary not implemented")
stderr.rawWrite("\n")
quit(1)
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
stderr.rawWrite("nimGetProAddr not implemented")
stderr.write(name)
stderr.rawWrite("\n")
quit(1)
else:
{.error: "no implementation for dyncalls".}

View File

@@ -80,6 +80,43 @@ when defined(emscripten):
elif defined(genode):
include genode/alloc # osAllocPages, osTryAllocPages, osDeallocPages
elif defined(nintendoswitch):
import nintendoswitch/switch_memory
var
stack: pointer
proc alignSize(size: int): int =
(size + 0x00000FFF) and not 0x00000FFF
proc freeMem(p: pointer, msize: int) =
let size = alignSize(msize)
discard svcUnmapMemory(p, stack, size.uint64)
virtmemFreeMap(p, size.csize)
free(stack)
proc osAllocPages(msize: int): pointer {.inline.} =
let size = alignSize(msize)
stack = memalign(0x1000, size)
result = virtmemReserveMap(size.csize)
let rc = svcMapMemory(result, stack, size.uint64)
if rc.uint32 != 0:
freeMem(result, size)
raiseOutOfMem()
proc osTryAllocPages(msize: int): pointer {.inline.} =
let size = alignSize(msize)
stack = memalign(0x1000, size)
result = virtmemReserveMap(size.csize)
let rc = svcMapMemory(result, stack, size.uint64)
if rc.uint32 != 0:
freeMem(result, size)
result = nil
proc osDeallocPages(p: pointer, size: int) {.inline.} =
when reallyOsDealloc:
freeMem(p, size)
elif defined(posix):
const
PROT_READ = 1 # page can be read

View File

@@ -37,7 +37,7 @@ type
none, dos, windows, os2, linux, morphos, skyos, solaris,
irix, netbsd, freebsd, openbsd, aix, palmos, qnx, amiga,
atari, netware, macos, macosx, haiku, android, js, nimVM,
standalone
standalone, nintendoswitch
const
targetOS* = when defined(windows): OsPlatform.windows
@@ -64,6 +64,7 @@ const
elif defined(js): OsPlatform.js
elif defined(nimVM): OsPlatform.nimVM
elif defined(standalone): OsPlatform.standalone
elif defined(nintendoswitch): OsPlatform.nintendoswitch
else: OsPlatform.none
## the OS this program will run on.

View File

@@ -419,7 +419,7 @@ proc setStdIoUnbuffered() =
when declared(stdout):
proc echoBinSafe(args: openArray[string]) {.compilerProc.} =
# flockfile deadlocks some versions of Android 5.x.x
when not defined(windows) and not defined(android):
when not defined(windows) and not defined(android) and not defined(nintendoswitch):
proc flockfile(f: File) {.importc, noDecl.}
proc funlockfile(f: File) {.importc, noDecl.}
flockfile(stdout)
@@ -428,7 +428,7 @@ when declared(stdout):
const linefeed = "\n" # can be 1 or more chars
discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
discard c_fflush(stdout)
when not defined(windows) and not defined(android):
when not defined(windows) and not defined(android) and not defined(nintendoswitch):
funlockfile(stdout)
{.pop.}

View File

@@ -176,7 +176,7 @@ else:
else:
type Time = int
when defined(linux) and defined(amd64):
when (defined(linux) or defined(nintendoswitch)) and defined(amd64):
type
SysThread* {.importc: "pthread_t",
header: "<sys/types.h>" .} = distinct culong