builder,pref: add support for `-no-builtin` (useful for writing Linux kernel modules)

pull/12278/head
Delyan Angelov 2021-10-23 12:53:53 +03:00
parent aa22751d26
commit 008d15dcb5
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
5 changed files with 48 additions and 16 deletions

View File

@ -211,6 +211,10 @@ fn (mut v Builder) set_module_lookup_paths() {
} }
pub fn (v Builder) get_builtin_files() []string { 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') v.log('v.pref.lookup_path: $v.pref.lookup_path')
// Lookup for built-in folder in lookup path. // Lookup for built-in folder in lookup path.
// Assumption: `builtin/` folder implies usable implementation of builtin // Assumption: `builtin/` folder implies usable implementation of builtin

View File

@ -290,6 +290,11 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) {
// shared libs do not need to have a main // shared libs do not need to have a main
return 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 { if !has_main_mod_file {
c.error('project must include a `main` module or be a shared library (compile with `v -shared`)', c.error('project must include a `main` module or be a shared library (compile with `v -shared`)',
token.Position{}) token.Position{})

View File

@ -591,11 +591,13 @@ pub fn (mut g Gen) init() {
g.write_multi_return_types() g.write_multi_return_types()
g.definitions.writeln('// end of definitions #endif') g.definitions.writeln('// end of definitions #endif')
// //
if !g.pref.no_builtin {
g.stringliterals.writeln('') g.stringliterals.writeln('')
g.stringliterals.writeln('// >> string literal consts') g.stringliterals.writeln('// >> string literal consts')
if g.pref.build_mode != .build_module { if g.pref.build_mode != .build_module {
g.stringliterals.writeln('void vinit_string_literals(){') g.stringliterals.writeln('void vinit_string_literals(){')
} }
}
if g.pref.compile_defines_all.len > 0 { if g.pref.compile_defines_all.len > 0 {
g.comptime_defines.writeln('// V compile time defines by -d or -define flags:') g.comptime_defines.writeln('// V compile time defines by -d or -define flags:')
g.comptime_defines.writeln('// All custom defines : ' + g.comptime_defines.writeln('// All custom defines : ' +
@ -665,11 +667,13 @@ pub fn (mut g Gen) init() {
} }
pub fn (mut g Gen) finish() { pub fn (mut g Gen) finish() {
if !g.pref.no_builtin {
if g.pref.build_mode != .build_module { if g.pref.build_mode != .build_module {
g.stringliterals.writeln('}') g.stringliterals.writeln('}')
} }
g.stringliterals.writeln('// << string literal consts') g.stringliterals.writeln('// << string literal consts')
g.stringliterals.writeln('') g.stringliterals.writeln('')
}
if g.pref.is_prof && g.pref.build_mode != .build_module { if g.pref.is_prof && g.pref.build_mode != .build_module {
g.gen_vprint_profile_stats() g.gen_vprint_profile_stats()
} }
@ -736,6 +740,9 @@ pub fn (mut g Gen) write_typeof_functions() {
} }
g.writeln('}') g.writeln('}')
} else if typ.kind == .interface_ { } else if typ.kind == .interface_ {
if typ.info !is ast.Interface {
continue
}
inter_info := typ.info as ast.Interface inter_info := typ.info as ast.Interface
if inter_info.is_generic { if inter_info.is_generic {
continue 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) { 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 info := sym.info as ast.Interface
if info.is_generic { if info.is_generic {
return return
@ -6094,6 +6104,9 @@ fn (g &Gen) checker_bug(s string, pos token.Position) {
} }
fn (mut g Gen) write_init_function() { fn (mut g Gen) write_init_function() {
if g.pref.no_builtin {
return
}
util.timing_start(@METHOD) util.timing_start(@METHOD)
defer { defer {
util.timing_measure(@METHOD) util.timing_measure(@METHOD)
@ -6179,6 +6192,9 @@ const (
) )
fn (mut g Gen) write_builtin_types() { fn (mut g Gen) write_builtin_types() {
if g.pref.no_builtin {
return
}
mut builtin_types := []ast.TypeSymbol{} // builtin types mut builtin_types := []ast.TypeSymbol{} // builtin types
// builtin types need to be on top // builtin types need to be on top
// everything except builtin will get sorted // everything except builtin will get sorted
@ -6313,7 +6329,7 @@ fn (mut g Gen) write_types(types []ast.TypeSymbol) {
g.type_definitions.writeln('} $name;') g.type_definitions.writeln('} $name;')
} }
} else { } else {
if !g.pref.is_bare { if !g.pref.is_bare && !g.pref.no_builtin {
g.type_definitions.writeln('typedef pthread_t $name;') g.type_definitions.writeln('typedef pthread_t $name;')
} }
} }
@ -7038,6 +7054,9 @@ fn (mut g Gen) interface_table() string {
if ityp.kind != .interface_ { if ityp.kind != .interface_ {
continue continue
} }
if ityp.info !is ast.Interface {
continue
}
inter_info := ityp.info as ast.Interface inter_info := ityp.info as ast.Interface
if inter_info.is_generic { if inter_info.is_generic {
continue continue

View File

@ -305,6 +305,9 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
g.writeln(');') g.writeln(');')
return return
} }
if node.params.len == 0 {
g.definitions.write_string('void')
}
g.definitions.writeln(');') g.definitions.writeln(');')
g.writeln(') {') g.writeln(') {')
for i, is_promoted in heap_promoted { for i, is_promoted in heap_promoted {

View File

@ -144,19 +144,16 @@ pub mut:
autofree bool // `v -manualfree` => false, `v -autofree` => true; false by default for now. 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) // Disabling `free()` insertion results in better performance in some applications (e.g. compilers)
compress bool // when set, use `upx` to compress the generated executable 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 // 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 enable_globals bool // allow __global for low level code
is_fmt bool is_fmt bool
is_vet 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 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 custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files
lookup_path []string 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 prealloc bool
vroot string vroot string
@ -405,6 +402,10 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences
'-no-retry-compilation' { '-no-retry-compilation' {
res.retry_compilation = false res.retry_compilation = false
} }
'-no-builtin' {
res.no_builtin = true
res.build_options << arg
}
'-no-preludes' { '-no-preludes' {
res.no_preludes = true res.no_preludes = true
res.build_options << arg res.build_options << arg