diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index c415918da7..999c34bcd4 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -957,9 +957,9 @@ pub fn new_v(args[]string) &V { out_name_c = out_name.all_after(os.path_separator) + '_shared_lib.c' } $if !linux { - if pref.is_bare { - verror('-bare only works on Linux for now') - } + if pref.is_bare && !out_name.ends_with('.c') { + verror('-bare only works on Linux for now') + } } return &V{ os: _os diff --git a/vlib/os/bare/bare.S b/vlib/os/bare/bare.S new file mode 100644 index 0000000000..eb7c83401e --- /dev/null +++ b/vlib/os/bare/bare.S @@ -0,0 +1,28 @@ +.intel_syntax noprefix +.text + .globl _start, syscall5 + + _start: + xor rbp,rbp + pop rdi + mov rsi,rsp + and rsp,-16 + call main + + mov rdi,rax /* syscall param 1 = rax (ret value of main) */ + mov rax,60 /* SYS_exit */ + syscall + + ret /* should never be reached, but if the OS somehow fails + to kill us, it will cause a segmentation fault */ + + syscall5: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + mov rdx,rcx + mov r10,r8 + mov r8,r9 + syscall + ret + diff --git a/vlib/os/bare/bare.v b/vlib/os/bare/bare.v new file mode 100644 index 0000000000..d7b57ee4aa --- /dev/null +++ b/vlib/os/bare/bare.v @@ -0,0 +1,16 @@ +fn syscall5(number, arg1, arg2, arg3, arg4, arg5 voidptr) voidptr + +fn write(fd int, data voidptr, nbytes u64) int { + return syscall5( + 1, // SYS_write + fd, + data, + nbytes, + 0, // ignored + 0 // ignored + ) +} + +fn main() { +C.write(1, "hallo\n", 6) +}