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 {
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

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
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{})

View File

@ -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

View File

@ -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 {

View File

@ -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