diff --git a/vlib/compiler/cc.v b/vlib/compiler/cc.v index beb178752d..09b0361a7b 100644 --- a/vlib/compiler/cc.v +++ b/vlib/compiler/cc.v @@ -109,6 +109,9 @@ fn (v mut V) cc() { a << '-shared -fPIC '// -Wl,-z,defs' v.out_name = v.out_name + '.so' } + if v.pref.is_bare { + a << '-nostdlib $vdir/vlib/os/bare/bare.S' + } if v.pref.build_mode == .build_module { // Create the modules & out directory if it's not there. mut out_dir := if v.dir.starts_with('vlib') { @@ -279,7 +282,7 @@ start: return } */ - verror(err) + verror(err) return } if res.exit_code != 0 { diff --git a/vlib/compiler/cheaders.v b/vlib/compiler/cheaders.v index 3aee3abf38..dadfb149c8 100644 --- a/vlib/compiler/cheaders.v +++ b/vlib/compiler/cheaders.v @@ -2,7 +2,7 @@ module compiler const ( -CommonCHeaders = ' +c_headers = ' #include // TODO remove all these includes, define all function signatures and types manually #include @@ -10,7 +10,6 @@ CommonCHeaders = ' //#include "fns.h" #include #include // for va_list -#include // int64_t etc #include // memcpy #ifndef _WIN32 @@ -105,35 +104,6 @@ CommonCHeaders = ' #include #endif -//================================== TYPEDEFS ================================*/ - -typedef int64_t i64; -typedef int16_t i16; -typedef int8_t i8; -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t byte; -typedef uint32_t rune; -typedef float f32; -typedef double f64; -typedef unsigned char* byteptr; -typedef int* intptr; -typedef void* voidptr; -typedef struct array array; -typedef struct map map; -typedef array array_string; -typedef array array_int; -typedef array array_byte; -typedef array array_f32; -typedef array array_f64; -typedef map map_int; -typedef map map_string; -#ifndef bool - typedef int bool; - #define true 1 - #define false 0 -#endif //============================== HELPER C MACROS =============================*/ #define _PUSH(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push(arr, &tmp);} @@ -175,4 +145,39 @@ var map_string = function() {} var map_int = function() {} ' + + +c_builtin_types = ' + +//================================== TYPEDEFS ================================*/ + +#include // int64_t etc +typedef int64_t i64; +typedef int16_t i16; +typedef int8_t i8; +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t byte; +typedef uint32_t rune; +typedef float f32; +typedef double f64; +typedef unsigned char* byteptr; +typedef int* intptr; +typedef void* voidptr; +typedef struct array array; +typedef struct map map; +typedef array array_string; +typedef array array_int; +typedef array array_byte; +typedef array array_f32; +typedef array array_f64; +typedef map map_int; +typedef map map_string; +#ifndef bool + typedef int bool; + #define true 1 + #define false 0 +#endif +' ) diff --git a/vlib/compiler/fn.v b/vlib/compiler/fn.v index f538f5a7ac..26c74d50e5 100644 --- a/vlib/compiler/fn.v +++ b/vlib/compiler/fn.v @@ -1136,7 +1136,7 @@ fn (p mut Parser) fn_call_args(f mut Fn) { ! (expected == 'byte*' && got.contains(']byte')) && ! (expected == 'byte*' && got == 'string') && //! (expected == 'void*' && got == 'array_int') { - ! (expected == 'byte*' && got == 'byteptr') { + ! (expected == 'byte*' && got == 'byteptr') && !p.pref.is_bare { p.cgen.set_placeholder(ph, '& /*112 e="$expected" g="$got" */') } } diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index 0b047a1400..14aed44b2b 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -234,7 +234,10 @@ pub fn (v mut V) compile() { $if js { cgen.genln(js_headers) } $else { - cgen.genln(CommonCHeaders) + cgen.genln(c_builtin_types) + if !v.pref.is_bare { + cgen.genln(c_headers) + } } v.generate_hotcode_reloading_declarations() // We need the cjson header for all the json decoding that will be done in @@ -295,8 +298,10 @@ pub fn (v mut V) compile() { def.writeln(cgen.includes.join_lines()) def.writeln(cgen.typedefs.join_lines()) def.writeln(v.type_definitions()) - def.writeln('\nstring _STR(const char*, ...);\n') - def.writeln('\nstring _STR_TMP(const char*, ...);\n') + if !v.pref.is_bare { + def.writeln('\nstring _STR(const char*, ...);\n') + def.writeln('\nstring _STR_TMP(const char*, ...);\n') + } def.writeln(cgen.fns.join_lines()) // fn definitions def.writeln(v.interface_table()) } $else { @@ -353,6 +358,7 @@ fn (v mut V) generate_init() { } } consts_init_body := v.cgen.consts_init.join_lines() + if !v.pref.is_bare { // vlib can't have `init_consts()` v.cgen.genln('void init() { g_str_buf=malloc(1000); @@ -396,6 +402,7 @@ string _STR_TMP(const char *fmt, ...) { ') } + } } pub fn (v mut V) generate_main() { @@ -403,12 +410,12 @@ pub fn (v mut V) generate_main() { $if js { return } if v.pref.is_vlines { - ///// After this point, the v files are compiled. - ///// The rest is auto generated code, which will not have - ///// different .v source file/line numbers. + // After this point, the v files are compiled. + // The rest is auto generated code, which will not have + // different .v source file/line numbers. lines_so_far := cgen.lines.join('\n').count('\n') + 5 cgen.genln('') - cgen.genln('////////////////// Reset the file/line numbers //////////') + cgen.genln('// Reset the file/line numbers') cgen.lines << '#line $lines_so_far "${cescaped_path(os.realpath(cgen.out_path))}"' cgen.genln('') } @@ -460,7 +467,9 @@ pub fn (v mut V) generate_main() { pub fn (v mut V) gen_main_start(add_os_args bool){ v.cgen.genln('int main(int argc, char** argv) { ') - v.cgen.genln(' init();') + if !v.pref.is_bare { + v.cgen.genln(' init();') + } if add_os_args && 'os' in v.table.imports { v.cgen.genln(' os__args = os__init_os_args(argc, (byteptr*)argv);') } diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 719a8ee94c..a2fd81320d 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -2137,7 +2137,7 @@ fn (p mut Parser) string_expr() { Calling a C function sometimes requires a call to a string method C.fun('ssss'.to_wide()) => fun(string_to_wide(tos3("ssss"))) */ - if (p.calling_c && p.peek() != .dot) || (p.pref.translated && p.mod == 'main') { + if (p.calling_c && p.peek() != .dot) || p.pref.is_bare || (p.pref.translated && p.mod == 'main') { p.gen('"$f"') } else if p.is_sql { diff --git a/vlib/os/bare/bare.S b/vlib/os/bare/bare.S index eb7c83401e..0378691a8d 100644 --- a/vlib/os/bare/bare.S +++ b/vlib/os/bare/bare.S @@ -1,13 +1,13 @@ .intel_syntax noprefix .text - .globl _start, syscall5 + .globl _start, main__syscall5 _start: xor rbp,rbp pop rdi mov rsi,rsp and rsp,-16 - call main + call main__main mov rdi,rax /* syscall param 1 = rax (ret value of main) */ mov rax,60 /* SYS_exit */ @@ -16,7 +16,7 @@ ret /* should never be reached, but if the OS somehow fails to kill us, it will cause a segmentation fault */ - syscall5: + main__syscall5: mov rax,rdi mov rdi,rsi mov rsi,rdx diff --git a/vlib/os/bare/bare.v b/vlib/os/bare/bare.v index d7b57ee4aa..deacb9313a 100644 --- a/vlib/os/bare/bare.v +++ b/vlib/os/bare/bare.v @@ -1,16 +1,16 @@ fn syscall5(number, arg1, arg2, arg3, arg4, arg5 voidptr) voidptr fn write(fd int, data voidptr, nbytes u64) int { - return syscall5( + return syscall5( 1, // SYS_write - fd, - data, - nbytes, - 0, // ignored - 0 // ignored - ) + fd, + data, + nbytes, + 0, // ignored + 0 // ignored + ) } fn main() { -C.write(1, "hallo\n", 6) + write(1, "hallo\n", 6) }