mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
initial Nim compiler and standard library support
https://nim-lang.org/ Fix #1879
This commit is contained in:
parent
d0bc389e93
commit
5f27c7b9eb
@ -85,6 +85,41 @@ endif
|
||||
$(MSG_CONVERT)$@
|
||||
$(VERBOSE)ar p $< $*.0.o > $@
|
||||
|
||||
#
|
||||
# Compiling Nim source code
|
||||
#
|
||||
ifneq ($(SRC_NIM),)
|
||||
|
||||
ifeq ($(NIM_CPU),)
|
||||
$(warning NIM_CPU not defined for any of the following SPECS: $(SPECS))
|
||||
else
|
||||
|
||||
NIM_MAKEFILES := $(foreach X,$(SRC_NIM),$(X).mk)
|
||||
NIM_ARGS = --compileOnly --os:genode --cpu:$(NIM_CPU)
|
||||
NIM_ARGS += --verbosity:0 --hint[Processing]:off --nimcache:.
|
||||
NIM_ARGS += $(NIM_OPT)
|
||||
|
||||
# Generate the C++ sources and compilation info
|
||||
#
|
||||
# Unfortunately the existing sources must be purged
|
||||
# because of comma problems in the JSON recipe
|
||||
%.nim.mk: %.nim
|
||||
$(MSG_BUILD)$(basename $@).cpp
|
||||
$(VERBOSE) rm -f stdlib_*.cpp
|
||||
$(VERBOSE)$(NIM) compileToCpp $(NIM_ARGS) $<
|
||||
$(VERBOSE)$(JQ) --raw-output '"SRC_O_NIM +=" + (.link | join(" ")) +"\n" + (.compile | map((.[0] | sub("cpp$$";"o: ")) + .[0] + "\n\t"+(.[1] | sub("^g\\++";"$$(MSG_COMP)$$@\n\t$$(VERBOSE)$$(NIM_CC)"))) | join("\n"))' < $(basename $(basename $@)).json > $@
|
||||
|
||||
NIM_CC := $(CXX) $(CXX_DEF) $(CC_CXX_OPT) $(INCLUDES) -D__GENODE__
|
||||
|
||||
# Parse the generated makefiles
|
||||
-include $(NIM_MAKEFILES)
|
||||
|
||||
# Append the new objects
|
||||
SRC_O += $(sort $(SRC_O_NIM))
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# Assembler files that must be preprocessed are fed to the C compiler.
|
||||
#
|
||||
|
@ -50,6 +50,16 @@ STRIP = $(CUSTOM_STRIP)
|
||||
GNATMAKE = $(CUSTOM_GNATMAKE)
|
||||
HOST_CC = $(CUSTOM_HOST_CC)
|
||||
|
||||
#
|
||||
# Nim toolchain
|
||||
#
|
||||
NIM ?= nim
|
||||
|
||||
#
|
||||
# JSON parsing utility
|
||||
#
|
||||
JQ ?= jq
|
||||
|
||||
#
|
||||
# Compiler and Linker options
|
||||
#
|
||||
|
@ -5,6 +5,8 @@ REP_INC_DIR += include/spec/arm
|
||||
|
||||
SPECS += 32bit
|
||||
|
||||
NIM_CPU ?= arm
|
||||
|
||||
#
|
||||
# Prevent compiler message
|
||||
# "note: the mangling of 'va_list' has changed in GCC 4.4"
|
||||
|
@ -16,5 +16,7 @@ CC_MARCH ?= -march=i686 -m32
|
||||
LD_MARCH ?= -melf_i386
|
||||
AS_MARCH ?= -march=i686 --32
|
||||
|
||||
NIM_CPU ?= i386
|
||||
|
||||
include $(BASE_DIR)/mk/spec/32bit.mk
|
||||
include $(BASE_DIR)/mk/spec/x86.mk
|
||||
|
@ -20,5 +20,7 @@ CC_MARCH ?= -m64
|
||||
#
|
||||
LD_MARCH ?= -melf_x86_64
|
||||
|
||||
NIM_CPU ?= amd64
|
||||
|
||||
include $(BASE_DIR)/mk/spec/64bit.mk
|
||||
include $(BASE_DIR)/mk/spec/x86.mk
|
||||
|
@ -55,3 +55,8 @@ CC_OPT += -D__ISO_C_VISIBLE=1999
|
||||
# or 'sincosf', which is a GNU extension, not provided by our libc.
|
||||
#
|
||||
CC_OPT += -fno-builtin-sin -fno-builtin-cos -fno-builtin-sinf -fno-builtin-cosf
|
||||
|
||||
#
|
||||
# Enable Nim POSIX support when linking with this library
|
||||
#
|
||||
NIM_OPT += -d:posix
|
||||
|
1
repos/libports/lib/import/import-nim-threads.mk
Normal file
1
repos/libports/lib/import/import-nim-threads.mk
Normal file
@ -0,0 +1 @@
|
||||
NIM_OPT += --threads:on --tlsEmulation:on
|
0
repos/libports/lib/mk/nim-threads.mk
Normal file
0
repos/libports/lib/mk/nim-threads.mk
Normal file
62
repos/libports/run/nim.run
Normal file
62
repos/libports/run/nim.run
Normal file
@ -0,0 +1,62 @@
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
drivers/rtc
|
||||
test/nim
|
||||
}
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
set config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<default caps="64"/>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="rtc_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Rtc"/> </provides>
|
||||
</start>
|
||||
<start name="test-nim">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<config>
|
||||
<vfs>
|
||||
<ram/> <log/> <rtc/>
|
||||
</vfs>
|
||||
<libc stdout="/log" stderr="/log" rtc="/rtc"/>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
set boot_modules {
|
||||
core init ld.lib.so
|
||||
libc.lib.so
|
||||
rtc_drv
|
||||
test-nim
|
||||
timer
|
||||
}
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args "-nographic"
|
||||
|
||||
run_genode_until {child "test-nim" exited with exit value 0} 30
|
84
repos/libports/run/nim_netty.run
Normal file
84
repos/libports/run/nim_netty.run
Normal file
@ -0,0 +1,84 @@
|
||||
assert_spec linux
|
||||
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer drivers/nic server/ram_fs server/vfs
|
||||
test/nim_echo_server
|
||||
lib/vfs/lxip
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
set config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<default caps="128"/>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="nic_drv">
|
||||
<binary name="linux_nic_drv"/>
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="netty">
|
||||
<binary name="test-nim_echo_server"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<config ld_verbose="yes">
|
||||
<vfs>
|
||||
<dir name="socket">
|
||||
<lxip ip_addr="10.0.2.55" netmask="255.255.255.0" gateway="10.0.2.1" nameserver="8.8.8.8"/>
|
||||
</dir>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
<dir name="tmp"> <ram/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||
</config>
|
||||
</start>
|
||||
}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
set boot_modules {
|
||||
core init timer linux_nic_drv ram_fs vfs
|
||||
ld.lib.so libc.lib.so libm.lib.so
|
||||
libc_resolv.lib.so stdcxx.lib.so libc_pipe.lib.so
|
||||
vfs_lxip.lib.so lxip.lib.so
|
||||
test-nim_echo_server
|
||||
}
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
# vi: set ft=tcl :
|
112
repos/libports/src/test/nim/main.nim
Normal file
112
repos/libports/src/test/nim/main.nim
Normal file
@ -0,0 +1,112 @@
|
||||
import unittest
|
||||
const
|
||||
Text = "Hello world!"
|
||||
|
||||
suite "echo":
|
||||
echo Text
|
||||
|
||||
suite "system":
|
||||
echo "compile date: ", CompileDate, " - ", CompileTime
|
||||
echo("endianness: ",
|
||||
case cpuEndian:
|
||||
of littleEndian:
|
||||
"littleEndian"
|
||||
of bigEndian:
|
||||
"bigEndian"
|
||||
)
|
||||
echo "hostCPU: ", hostCPU
|
||||
echo "NimVersion: ", NimVersion
|
||||
echo "nativeStackTraceSupported: ", $nativeStackTraceSupported
|
||||
echo "getStackTrace:\n", getStackTrace()
|
||||
echo "getFreeMem: ", getFreeMem()
|
||||
echo "getTotalMem: ", getTotalMem()
|
||||
echo "getOccupiedMem: ", getOccupiedMem()
|
||||
|
||||
test "isMainModule":
|
||||
assert isMainModule == true
|
||||
test "hostOS == genode":
|
||||
assert hostOS == "genode"
|
||||
|
||||
test "alloc/dealloc":
|
||||
let p = alloc 768
|
||||
assert(not p.isNil)
|
||||
dealloc p
|
||||
|
||||
test "exception handling":
|
||||
type NovelError = object of SystemError
|
||||
try: raise newException(NovelError, "test exception")
|
||||
except NovelError:
|
||||
discard
|
||||
|
||||
import locks, threadpool
|
||||
suite "threadpool":
|
||||
|
||||
test "spawn":
|
||||
var L: Lock
|
||||
|
||||
proc threadProc(interval: tuple[a,b: int]) =
|
||||
for i in interval.a..interval.b:
|
||||
acquire L
|
||||
echo i
|
||||
release L
|
||||
|
||||
initLock L
|
||||
for i in 0..3:
|
||||
spawn threadProc((i*10, i*10+4))
|
||||
sync()
|
||||
deinitLock L
|
||||
|
||||
test "threadvar":
|
||||
var
|
||||
L: Lock
|
||||
x {.threadvar.}: int
|
||||
y: int
|
||||
|
||||
proc printVal(id: string) =
|
||||
acquire L
|
||||
echo(
|
||||
id,
|
||||
" x: ", repr(addr(x)),
|
||||
" y: ", repr(addr(y))
|
||||
)
|
||||
inc x
|
||||
inc y
|
||||
release L
|
||||
|
||||
initLock L
|
||||
release L
|
||||
printVal("main thread")
|
||||
for i in 1..4:
|
||||
spawn printVal("spawn "& $i)
|
||||
sync()
|
||||
deinitLock L
|
||||
|
||||
suite "I/O":
|
||||
const
|
||||
TestFile = "/testfile"
|
||||
Text = NimVersion & " - " & CompileDate & " - " & CompileTime
|
||||
test "writeFile":
|
||||
writeFile(TestFile, Text)
|
||||
test "readFile":
|
||||
assert readFile(TestFile) == Text
|
||||
|
||||
suite "staticExec":
|
||||
const rev = staticExec("git describe")
|
||||
echo "compile time 'git describe': ", rev
|
||||
|
||||
import times
|
||||
suite "time":
|
||||
|
||||
echo "epochTime() float value: ", epochTime()
|
||||
echo "getTime() float value: ", toSeconds(getTime())
|
||||
echo "cpuTime() float value: ", cpuTime()
|
||||
echo "An hour from now : ", getLocalTime(getTime()) + 1.hours
|
||||
echo "An hour from (UTC) now: ", getGmTime(getTime()) + initInterval(0,0,0,1)
|
||||
|
||||
test "getTime":
|
||||
assert(getTime() != 0.Time)
|
||||
|
||||
suite "garbage collector":
|
||||
echo GC_getStatistics()
|
||||
|
||||
echo "done"
|
6
repos/libports/src/test/nim/target.mk
Normal file
6
repos/libports/src/test/nim/target.mk
Normal file
@ -0,0 +1,6 @@
|
||||
TARGET = test-nim
|
||||
LIBS = nim-threads libc
|
||||
SRC_NIM = main.nim
|
||||
|
||||
# Enable extra system assertions
|
||||
NIM_OPT += -d:useSysAssert
|
27
repos/libports/src/test/nim_echo_server/main.nim
Normal file
27
repos/libports/src/test/nim_echo_server/main.nim
Normal file
@ -0,0 +1,27 @@
|
||||
import asyncnet, asyncdispatch
|
||||
|
||||
const
|
||||
CRLF* = "\c\L"
|
||||
|
||||
proc processClient(address: string, client: AsyncSocket) {.async.} =
|
||||
echo "accepted connection from ", address
|
||||
while not client.isClosed():
|
||||
let line = await client.recvLine()
|
||||
if line == "":
|
||||
break
|
||||
await client.send(line & CRLF)
|
||||
echo address, " closed connection"
|
||||
|
||||
proc serve() {.async.} =
|
||||
let server = newAsyncSocket()
|
||||
server.bindAddr(7.Port)
|
||||
server.listen()
|
||||
|
||||
echo "echo service listening on port 7"
|
||||
|
||||
while true:
|
||||
let res = await server.acceptAddr()
|
||||
asyncCheck processClient(res[0], res[1])
|
||||
|
||||
asyncCheck serve()
|
||||
runForever()
|
6
repos/libports/src/test/nim_echo_server/target.mk
Normal file
6
repos/libports/src/test/nim_echo_server/target.mk
Normal file
@ -0,0 +1,6 @@
|
||||
TARGET = test-nim_echo_server
|
||||
LIBS = libc libc_resolv
|
||||
SRC_NIM = main.nim
|
||||
|
||||
# Enable extra system assertions
|
||||
NIM_OPT += -d:useSysAssert
|
Loading…
Reference in New Issue
Block a user