mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +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)$@
|
$(MSG_CONVERT)$@
|
||||||
$(VERBOSE)ar p $< $*.0.o > $@
|
$(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.
|
# Assembler files that must be preprocessed are fed to the C compiler.
|
||||||
#
|
#
|
||||||
|
@ -50,6 +50,16 @@ STRIP = $(CUSTOM_STRIP)
|
|||||||
GNATMAKE = $(CUSTOM_GNATMAKE)
|
GNATMAKE = $(CUSTOM_GNATMAKE)
|
||||||
HOST_CC = $(CUSTOM_HOST_CC)
|
HOST_CC = $(CUSTOM_HOST_CC)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Nim toolchain
|
||||||
|
#
|
||||||
|
NIM ?= nim
|
||||||
|
|
||||||
|
#
|
||||||
|
# JSON parsing utility
|
||||||
|
#
|
||||||
|
JQ ?= jq
|
||||||
|
|
||||||
#
|
#
|
||||||
# Compiler and Linker options
|
# Compiler and Linker options
|
||||||
#
|
#
|
||||||
|
@ -5,6 +5,8 @@ REP_INC_DIR += include/spec/arm
|
|||||||
|
|
||||||
SPECS += 32bit
|
SPECS += 32bit
|
||||||
|
|
||||||
|
NIM_CPU ?= arm
|
||||||
|
|
||||||
#
|
#
|
||||||
# Prevent compiler message
|
# Prevent compiler message
|
||||||
# "note: the mangling of 'va_list' has changed in GCC 4.4"
|
# "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
|
LD_MARCH ?= -melf_i386
|
||||||
AS_MARCH ?= -march=i686 --32
|
AS_MARCH ?= -march=i686 --32
|
||||||
|
|
||||||
|
NIM_CPU ?= i386
|
||||||
|
|
||||||
include $(BASE_DIR)/mk/spec/32bit.mk
|
include $(BASE_DIR)/mk/spec/32bit.mk
|
||||||
include $(BASE_DIR)/mk/spec/x86.mk
|
include $(BASE_DIR)/mk/spec/x86.mk
|
||||||
|
@ -20,5 +20,7 @@ CC_MARCH ?= -m64
|
|||||||
#
|
#
|
||||||
LD_MARCH ?= -melf_x86_64
|
LD_MARCH ?= -melf_x86_64
|
||||||
|
|
||||||
|
NIM_CPU ?= amd64
|
||||||
|
|
||||||
include $(BASE_DIR)/mk/spec/64bit.mk
|
include $(BASE_DIR)/mk/spec/64bit.mk
|
||||||
include $(BASE_DIR)/mk/spec/x86.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.
|
# 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
|
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