From 008d15dcb5aaa4dc2725fea222a6e4331ec07238 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 23 Oct 2021 12:53:53 +0300 Subject: [PATCH] builder,pref: add support for `-no-builtin` (useful for writing Linux kernel modules) --- vlib/v/builder/compile.v | 4 ++++ vlib/v/checker/checker.v | 5 +++++ vlib/v/gen/c/cgen.v | 37 ++++++++++++++++++++++++++++--------- vlib/v/gen/c/fn.v | 3 +++ vlib/v/pref/pref.v | 15 ++++++++------- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 835e42b734..fc2c2740a2 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -211,6 +211,10 @@ fn (mut v Builder) set_module_lookup_paths() { } pub fn (v Builder) get_builtin_files() []string { + if v.pref.no_builtin { + v.log('v.pref.no_builtin is true, get_builtin_files == []') + return [] + } v.log('v.pref.lookup_path: $v.pref.lookup_path') // Lookup for built-in folder in lookup path. // Assumption: `builtin/` folder implies usable implementation of builtin diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3321189bdb..b320ea001c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -290,6 +290,11 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) { // shared libs do not need to have a main return } + if c.pref.no_builtin { + // `v -no-builtin module/` do not necessarily need to have a `main` function + // This is useful for compiling linux kernel modules for example. + return + } if !has_main_mod_file { c.error('project must include a `main` module or be a shared library (compile with `v -shared`)', token.Position{}) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index e6f7889eab..ead8b325fa 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -591,10 +591,12 @@ pub fn (mut g Gen) init() { g.write_multi_return_types() g.definitions.writeln('// end of definitions #endif') // - g.stringliterals.writeln('') - g.stringliterals.writeln('// >> string literal consts') - if g.pref.build_mode != .build_module { - g.stringliterals.writeln('void vinit_string_literals(){') + if !g.pref.no_builtin { + g.stringliterals.writeln('') + g.stringliterals.writeln('// >> string literal consts') + if g.pref.build_mode != .build_module { + g.stringliterals.writeln('void vinit_string_literals(){') + } } if g.pref.compile_defines_all.len > 0 { g.comptime_defines.writeln('// V compile time defines by -d or -define flags:') @@ -665,11 +667,13 @@ pub fn (mut g Gen) init() { } pub fn (mut g Gen) finish() { - if g.pref.build_mode != .build_module { - g.stringliterals.writeln('}') + if !g.pref.no_builtin { + if g.pref.build_mode != .build_module { + g.stringliterals.writeln('}') + } + g.stringliterals.writeln('// << string literal consts') + g.stringliterals.writeln('') } - g.stringliterals.writeln('// << string literal consts') - g.stringliterals.writeln('') if g.pref.is_prof && g.pref.build_mode != .build_module { g.gen_vprint_profile_stats() } @@ -736,6 +740,9 @@ pub fn (mut g Gen) write_typeof_functions() { } g.writeln('}') } else if typ.kind == .interface_ { + if typ.info !is ast.Interface { + continue + } inter_info := typ.info as ast.Interface if inter_info.is_generic { continue @@ -1153,6 +1160,9 @@ pub fn (mut g Gen) write_interface_typedef(sym ast.TypeSymbol) { } pub fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol) { + if sym.info !is ast.Interface { + return + } info := sym.info as ast.Interface if info.is_generic { return @@ -6094,6 +6104,9 @@ fn (g &Gen) checker_bug(s string, pos token.Position) { } fn (mut g Gen) write_init_function() { + if g.pref.no_builtin { + return + } util.timing_start(@METHOD) defer { util.timing_measure(@METHOD) @@ -6179,6 +6192,9 @@ const ( ) fn (mut g Gen) write_builtin_types() { + if g.pref.no_builtin { + return + } mut builtin_types := []ast.TypeSymbol{} // builtin types // builtin types need to be on top // everything except builtin will get sorted @@ -6313,7 +6329,7 @@ fn (mut g Gen) write_types(types []ast.TypeSymbol) { g.type_definitions.writeln('} $name;') } } else { - if !g.pref.is_bare { + if !g.pref.is_bare && !g.pref.no_builtin { g.type_definitions.writeln('typedef pthread_t $name;') } } @@ -7038,6 +7054,9 @@ fn (mut g Gen) interface_table() string { if ityp.kind != .interface_ { continue } + if ityp.info !is ast.Interface { + continue + } inter_info := ityp.info as ast.Interface if inter_info.is_generic { continue diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index c83ca39995..4baabd2e08 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -305,6 +305,9 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) { g.writeln(');') return } + if node.params.len == 0 { + g.definitions.write_string('void') + } g.definitions.writeln(');') g.writeln(') {') for i, is_promoted in heap_promoted { diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 6125b7f40b..af8b784290 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -144,20 +144,17 @@ pub mut: autofree bool // `v -manualfree` => false, `v -autofree` => true; false by default for now. // Disabling `free()` insertion results in better performance in some applications (e.g. compilers) compress bool // when set, use `upx` to compress the generated executable - // skip_builtin bool // Skips re-compilation of the builtin module - // to increase compilation time. - // This is on by default, since a vast majority of users do not - // work on the builtin module itself. // generating_vh bool + no_builtin bool // Skip adding the `builtin` module implicitly. The generated C code may not compile. enable_globals bool // allow __global for low level code is_fmt bool is_vet bool - is_bare bool + is_bare bool // set by -freestanding + bare_builtin_dir string // Set by -bare-builtin-dir xyz/ . The xyz/ module should contain implementations of malloc, memset, etc, that are used by the rest of V's `builtin` module. That option is only useful with -freestanding (i.e. when is_bare is true). no_preludes bool // Prevents V from generating preludes in resulting .c files custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files lookup_path []string - bare_builtin_dir string // Path to implementation of malloc, memset, etc. Only used if is_bare is true - output_cross_c bool // true, when the user passed `-os cross` + output_cross_c bool // true, when the user passed `-os cross` prealloc bool vroot string out_name_c string // full os.real_path to the generated .tmp.c file; set by builder. @@ -405,6 +402,10 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences '-no-retry-compilation' { res.retry_compilation = false } + '-no-builtin' { + res.no_builtin = true + res.build_options << arg + } '-no-preludes' { res.no_preludes = true res.build_options << arg