summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJoey <jyapayne@gmail.com>2018-06-27 19:35:09 +0900
committerAndreas Rumpf <rumpf_a@web.de>2018-06-27 12:35:09 +0200
commit559a7615ad8e2e169aa9684f034c156881d88d4d (patch)
treee93f1f2ff0a85a556a5d867c7f541cf3e995502b
parentb74b16ffde64262eeea57f36816a1a4b2d0cedfd (diff)
downloadNim-559a7615ad8e2e169aa9684f034c156881d88d4d.tar.gz
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
-rw-r--r--changelog.md3
-rw-r--r--compiler/extccomp.nim39
-rw-r--r--compiler/installer.ini1
-rw-r--r--compiler/options.nim6
-rw-r--r--compiler/platform.nim9
-rw-r--r--config/nim.cfg8
-rw-r--r--doc/nimc.rst46
-rw-r--r--lib/nintendoswitch/switch_memory.nim21
-rw-r--r--lib/posix/posix.nim68
-rw-r--r--lib/posix/posix_nintendoswitch.nim506
-rw-r--r--lib/posix/posix_nintendoswitch_consts.nim586
-rw-r--r--lib/pure/dynlib.nim22
-rw-r--r--lib/pure/os.nim12
-rw-r--r--lib/pure/ospaths.nim2
-rw-r--r--lib/pure/selectors.nim2
-rw-r--r--lib/system/ansi_c.nim2
-rw-r--r--lib/system/dyncalls.nim18
-rw-r--r--lib/system/osalloc.nim37
-rw-r--r--lib/system/platforms.nim3
-rw-r--r--lib/system/sysio.nim4
-rw-r--r--lib/system/threads.nim2
21 files changed, 1353 insertions, 44 deletions
diff --git a/changelog.md b/changelog.md
index 4ee9dcee9..bbe526124 100644
--- a/changelog.md
+++ b/changelog.md
@@ -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
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 17133624b..a48067abb 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -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)),
diff --git a/compiler/installer.ini b/compiler/installer.ini
index 2847e4e62..79eb7178a 100644
--- a/compiler/installer.ini
+++ b/compiler/installer.ini
@@ -15,6 +15,7 @@ Platforms: """
   dragonfly: i386;amd64
   haiku: i386;amd64
   android: i386;arm;arm64
+  nintendoswitch: arm64
 """
 
 Authors: "Andreas Rumpf"
diff --git a/compiler/options.nim b/compiler/options.nim
index 1d6ddb09f..2aa515e35 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -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
diff --git a/compiler/platform.nim b/compiler/platform.nim
index 0db16f26c..7eb897816 100644
--- a/compiler/platform.nim
+++ b/compiler/platform.nim
@@ -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
diff --git a/config/nim.cfg b/config/nim.cfg
index e11826587..626f4494a 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -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"
diff --git a/doc/nimc.rst b/doc/nimc.rst
index 29dbdea42..a3adcc143 100644
--- a/doc/nimc.rst
+++ b/doc/nimc.rst
@@ -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
 ==============
diff --git a/lib/nintendoswitch/switch_memory.nim b/lib/nintendoswitch/switch_memory.nim
new file mode 100644
index 000000000..09b34c5d0
--- /dev/null
+++ b/lib/nintendoswitch/switch_memory.nim
@@ -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.}
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index db5f575af..97b4124ec 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -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>".}
-
-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>".}
+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 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>".}
diff --git a/lib/posix/posix_nintendoswitch.nim b/lib/posix/posix_nintendoswitch.nim
new file mode 100644
index 000000000..892ea3370
--- /dev/null
+++ b/lib/posix/posix_nintendoswitch.nim
@@ -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
diff --git a/lib/posix/posix_nintendoswitch_consts.nim b/lib/posix/posix_nintendoswitch_consts.nim
new file mode 100644
index 000000000..33470d22b
--- /dev/null
+++ b/lib/posix/posix_nintendoswitch_consts.nim
@@ -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)
diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim
index 5bd06f6fb..d030ad532 100644
--- a/lib/pure/dynlib.nim
+++ b/lib/pure/dynlib.nim
@@ -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):
   #
   # =======================================================================
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 3bc87728b..599745176 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -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()
diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim
index c0d3ef512..905a65925 100644
--- a/lib/pure/ospaths.nim
+++ b/lib/pure/ospaths.nim
@@ -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):
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index 640df8282..935250e08 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -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
 
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index 0bac979e7..52cb15e39 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -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)
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index f1ff307da..8fb694829 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -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".}
 
diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim
index a63eadf8e..048077b50 100644
--- a/lib/system/osalloc.nim
+++ b/lib/system/osalloc.nim
@@ -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
diff --git a/lib/system/platforms.nim b/lib/system/platforms.nim
index b561cd3ba..31d2cb01e 100644
--- a/lib/system/platforms.nim
+++ b/lib/system/platforms.nim
@@ -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.
 
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 86b290230..f3a576be0 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -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.}
diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index c8ea03f92..3bfaa1dc2 100644
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -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