mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
remove duplication by using a new Preferences struct
This commit is contained in:
committed by
Alexander Medvednikov
parent
42a622c10f
commit
74d234f8cd
158
compiler/main.v
158
compiler/main.v
@@ -58,32 +58,38 @@ enum Pass {
|
||||
main
|
||||
}
|
||||
*/
|
||||
|
||||
struct Preferences {
|
||||
mut:
|
||||
build_mode BuildMode
|
||||
nofmt bool // disable vfmt
|
||||
is_test bool // `v test string_test.v`
|
||||
is_script bool // single file mode (`v program.v`), `fn main(){}` can be skipped
|
||||
is_live bool // for hot code reloading
|
||||
is_so bool
|
||||
is_prof bool // benchmark every function
|
||||
translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
|
||||
is_prod bool // use "-O2"
|
||||
is_verbose bool // print extra information with `v.log()`
|
||||
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
|
||||
is_play bool // playground mode
|
||||
is_repl bool
|
||||
is_run bool
|
||||
show_c_cmd bool // `v -show_c_cmd` prints the C command to build program.v.c
|
||||
sanitize bool // use Clang's new "-fsanitize" option
|
||||
}
|
||||
|
||||
struct V {
|
||||
mut:
|
||||
build_mode BuildMode
|
||||
os Os // the OS to build for
|
||||
nofmt bool // disable vfmt
|
||||
out_name_c string // name of the temporary C file
|
||||
files []string // all V files that need to be parsed and compiled
|
||||
dir string // directory (or file) being compiled (TODO rename to path?)
|
||||
table *Table // table with types, vars, functions etc
|
||||
cgen *CGen // C code generator
|
||||
is_test bool // `v test string_test.v`
|
||||
is_script bool // single file mode (`v program.v`), `fn main(){}` can be skipped
|
||||
is_so bool
|
||||
is_live bool // for hot code reloading
|
||||
is_prof bool // benchmark every function
|
||||
translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
|
||||
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
|
||||
lang_dir string // path to V repo
|
||||
is_verbose bool // print extra information with `v.log()`
|
||||
is_run bool // `v run program.v`
|
||||
is_play bool // playground mode
|
||||
show_c_cmd bool // `v -show_c_cmd` prints the C command to build program.v.c
|
||||
sanitize bool // use Clang's new "-fsanitize" option
|
||||
pref *Preferences // all the prefrences and settings extracted to a struct for reusability
|
||||
lang_dir string // "~/code/v"
|
||||
out_name string // "program.exe"
|
||||
is_prod bool // use "-O2"
|
||||
is_repl bool
|
||||
vroot string
|
||||
}
|
||||
|
||||
@@ -137,7 +143,7 @@ fn main() {
|
||||
}
|
||||
// Construct the V object from command line arguments
|
||||
mut c := new_v(args)
|
||||
if c.is_verbose {
|
||||
if c.pref.is_verbose {
|
||||
println(args)
|
||||
}
|
||||
// Generate the docs and exit
|
||||
@@ -153,7 +159,7 @@ fn (c mut V) compile() {
|
||||
cgen.genln('// Generated by V')
|
||||
// Add user files to compile
|
||||
c.add_user_v_files()
|
||||
if c.is_verbose {
|
||||
if c.pref.is_verbose {
|
||||
println('all .v files:')
|
||||
println(c.files)
|
||||
}
|
||||
@@ -164,7 +170,7 @@ fn (c mut V) compile() {
|
||||
}
|
||||
// Main pass
|
||||
cgen.run = RUN_MAIN
|
||||
if c.is_play {
|
||||
if c.pref.is_play {
|
||||
cgen.genln('#define VPLAY (1) ')
|
||||
}
|
||||
cgen.genln('
|
||||
@@ -238,23 +244,23 @@ void reload_so();
|
||||
void init_consts();')
|
||||
imports_json := c.table.imports.contains('json')
|
||||
// TODO remove global UI hack
|
||||
if c.os == MAC && ((c.build_mode == EMBED_VLIB && c.table.imports.contains('ui')) ||
|
||||
(c.build_mode == BUILD && c.dir.contains('/ui'))) {
|
||||
if c.os == MAC && ((c.pref.build_mode == EMBED_VLIB && c.table.imports.contains('ui')) ||
|
||||
(c.pref.build_mode == BUILD && c.dir.contains('/ui'))) {
|
||||
cgen.genln('id defaultFont = 0; // main.v')
|
||||
}
|
||||
// TODO remove ugly .c include once V has its own json parser
|
||||
// Embed cjson either in embedvlib or in json.o
|
||||
if imports_json && c.build_mode == EMBED_VLIB ||
|
||||
(c.build_mode == BUILD && c.out_name.contains('json.o')) {
|
||||
if imports_json && c.pref.build_mode == EMBED_VLIB ||
|
||||
(c.pref.build_mode == BUILD && c.out_name.contains('json.o')) {
|
||||
cgen.genln('#include "cJSON.c" ')
|
||||
}
|
||||
// We need the cjson header for all the json decoding user will do in default mode
|
||||
if c.build_mode == DEFAULT_MODE {
|
||||
if c.pref.build_mode == DEFAULT_MODE {
|
||||
if imports_json {
|
||||
cgen.genln('#include "cJSON.h"')
|
||||
}
|
||||
}
|
||||
if c.build_mode == EMBED_VLIB || c.build_mode == DEFAULT_MODE {
|
||||
if c.pref.build_mode == EMBED_VLIB || c.pref.build_mode == DEFAULT_MODE {
|
||||
// If we declare these for all modes, then when running `v a.v` we'll get
|
||||
// `/usr/bin/ld: multiple definition of 'total_m'`
|
||||
// TODO
|
||||
@@ -277,7 +283,7 @@ void init_consts();')
|
||||
p.parse()
|
||||
// p.g.gen_x64()
|
||||
// Format all files (don't format automatically generated vlib headers)
|
||||
if !c.nofmt && !file.contains('/vlib/') {
|
||||
if !c.pref.nofmt && !file.contains('/vlib/') {
|
||||
// new vfmt is not ready yet
|
||||
}
|
||||
}
|
||||
@@ -292,14 +298,14 @@ void init_consts();')
|
||||
d.writeln(cgen.fns.join_lines())
|
||||
d.writeln(cgen.consts.join_lines())
|
||||
d.writeln(cgen.thread_args.join_lines())
|
||||
if c.is_prof {
|
||||
if c.pref.is_prof {
|
||||
d.writeln('; // Prof counters:')
|
||||
d.writeln(c.prof_counters())
|
||||
}
|
||||
dd := d.str()
|
||||
cgen.lines.set(defs_pos, dd)// TODO `def.str()` doesn't compile
|
||||
// if c.build_mode in [.default, .embed_vlib] {
|
||||
if c.build_mode == DEFAULT_MODE || c.build_mode == EMBED_VLIB {
|
||||
if c.pref.build_mode == DEFAULT_MODE || c.pref.build_mode == EMBED_VLIB {
|
||||
// vlib can't have `init_consts()`
|
||||
cgen.genln('void init_consts() { g_str_buf=malloc(1000); ${cgen.consts_init.join_lines()} }')
|
||||
// _STR function can't be defined in vlib
|
||||
@@ -339,10 +345,10 @@ string _STR_TMP(const char *fmt, ...) {
|
||||
}
|
||||
// Make sure the main function exists
|
||||
// Obviously we don't need it in libraries
|
||||
if c.build_mode != BUILD {
|
||||
if !c.table.main_exists() && !c.is_test {
|
||||
if c.pref.build_mode != BUILD {
|
||||
if !c.table.main_exists() && !c.pref.is_test {
|
||||
// It can be skipped in single file programs
|
||||
if c.is_script {
|
||||
if c.pref.is_script {
|
||||
//println('Generating main()...')
|
||||
cgen.genln('int main() { $cgen.fn_main; return 0; }')
|
||||
}
|
||||
@@ -351,7 +357,7 @@ string _STR_TMP(const char *fmt, ...) {
|
||||
}
|
||||
}
|
||||
// Generate `main` which calls every single test function
|
||||
else if c.is_test {
|
||||
else if c.pref.is_test {
|
||||
cgen.genln('int main() { init_consts();')
|
||||
for v in c.table.fns {
|
||||
if v.name.starts_with('test_') {
|
||||
@@ -361,7 +367,7 @@ string _STR_TMP(const char *fmt, ...) {
|
||||
cgen.genln('return g_test_ok == 0; }')
|
||||
}
|
||||
}
|
||||
if c.is_live {
|
||||
if c.pref.is_live {
|
||||
cgen.genln(' int load_so(byteptr path) {
|
||||
printf("load_so %s\\n", path); dlclose(live_lib); live_lib = dlopen(path, RTLD_LAZY);
|
||||
if (!live_lib) {puts("open failed"); exit(1); return 0;}
|
||||
@@ -372,13 +378,13 @@ string _STR_TMP(const char *fmt, ...) {
|
||||
cgen.genln('return 1; }')
|
||||
}
|
||||
cgen.save()
|
||||
if c.is_verbose {
|
||||
if c.pref.is_verbose {
|
||||
c.log('flags=')
|
||||
println(c.table.flags)
|
||||
}
|
||||
c.cc()
|
||||
if c.is_test || c.is_run {
|
||||
if true || c.is_verbose {
|
||||
if c.pref.is_test || c.pref.is_run {
|
||||
if true || c.pref.is_verbose {
|
||||
println('============ running $c.out_name ============')
|
||||
}
|
||||
mut cmd := if c.out_name.starts_with('/') {
|
||||
@@ -405,32 +411,31 @@ string _STR_TMP(const char *fmt, ...) {
|
||||
}
|
||||
|
||||
fn (c mut V) cc() {
|
||||
ticks := time.ticks()
|
||||
linux_host := os.user_os() == 'linux'
|
||||
c.log('cc() isprod=$c.is_prod outname=$c.out_name')
|
||||
c.log('cc() isprod=$c.pref.is_prod outname=$c.out_name')
|
||||
mut a := ['-w']// arguments for the C compiler
|
||||
flags := c.table.flags.join(' ')
|
||||
/*
|
||||
mut shared := ''
|
||||
if c.is_so {
|
||||
if c.pref.is_so {
|
||||
a << '-shared'// -Wl,-z,defs'
|
||||
c.out_name = c.out_name + '.so'
|
||||
}
|
||||
*/
|
||||
if c.is_prod {
|
||||
if c.pref.is_prod {
|
||||
a << '-O2'
|
||||
}
|
||||
else {
|
||||
a << '-g'
|
||||
}
|
||||
mut libs := ''// builtin.o os.o http.o etc
|
||||
if c.build_mode == BUILD {
|
||||
if c.pref.build_mode == BUILD {
|
||||
a << '-c'
|
||||
}
|
||||
else if c.build_mode == EMBED_VLIB {
|
||||
else if c.pref.build_mode == EMBED_VLIB {
|
||||
//
|
||||
}
|
||||
else if c.build_mode == DEFAULT_MODE {
|
||||
else if c.pref.build_mode == DEFAULT_MODE {
|
||||
libs = '$TmpPath/vlib/builtin.o'
|
||||
if !os.file_exists(libs) {
|
||||
println('`builtin.o` not found')
|
||||
@@ -453,7 +458,7 @@ mut args := ''
|
||||
}
|
||||
}
|
||||
*/
|
||||
if c.sanitize {
|
||||
if c.pref.sanitize {
|
||||
a << '-fsanitize=leak'
|
||||
}
|
||||
// Cross compiling linux
|
||||
@@ -485,11 +490,11 @@ mut args := ''
|
||||
a << '-x objective-c'
|
||||
}
|
||||
// Without these libs compilation will fail on Linux
|
||||
if c.os == LINUX && c.build_mode != BUILD {
|
||||
if c.os == LINUX && c.pref.build_mode != BUILD {
|
||||
a << '-lm -ldl -lpthread'
|
||||
}
|
||||
// Find clang executable
|
||||
fast_clang := 'ff'///usr/local/Cellar/llvm/8.0.0/bin/clang'
|
||||
fast_clang := '/usr/local/Cellar/llvm/8.0.0/bin/clang'
|
||||
args := a.join(' ')
|
||||
mut cmd := if os.file_exists(fast_clang) {
|
||||
'$fast_clang $args'
|
||||
@@ -501,7 +506,7 @@ mut args := ''
|
||||
cmd = 'gcc $args'
|
||||
}
|
||||
// Print the C command
|
||||
if c.show_c_cmd || c.is_verbose {
|
||||
if c.pref.show_c_cmd || c.pref.is_verbose {
|
||||
println('\n==========\n$cmd\n=========\n')
|
||||
}
|
||||
// Run
|
||||
@@ -512,7 +517,7 @@ mut args := ''
|
||||
panic('clang error')
|
||||
}
|
||||
// Link it if we are cross compiling and need an executable
|
||||
if c.os == LINUX && !linux_host && c.build_mode != BUILD {
|
||||
if c.os == LINUX && !linux_host && c.pref.build_mode != BUILD {
|
||||
c.out_name = c.out_name.replace('.o', '')
|
||||
obj_file := c.out_name + '.o'
|
||||
println('linux obj_file=$obj_file out_name=$c.out_name')
|
||||
@@ -531,10 +536,6 @@ mut args := ''
|
||||
}
|
||||
println('linux cross compilation done. resulting binary: "$c.out_name"')
|
||||
}
|
||||
if c.show_c_cmd {
|
||||
diff := time.ticks() - ticks
|
||||
println('cc() took $diff ms ')
|
||||
}
|
||||
//os.rm('$TmpPath/$c.out_name_c')
|
||||
}
|
||||
|
||||
@@ -546,7 +547,7 @@ fn (c &V) v_files_from_dir(dir string) []string {
|
||||
panic('$dir isn\'t a directory')
|
||||
}
|
||||
mut files := os.ls(dir)
|
||||
if c.is_verbose {
|
||||
if c.pref.is_verbose {
|
||||
println('v_files_from_dir ("$dir")')
|
||||
}
|
||||
// println(files.len)
|
||||
@@ -617,7 +618,7 @@ fn (c mut V) add_user_v_files() {
|
||||
println('No input .v files')
|
||||
exit(1)
|
||||
}
|
||||
if c.is_verbose {
|
||||
if c.pref.is_verbose {
|
||||
c.log('user_files:')
|
||||
println(user_files)
|
||||
}
|
||||
@@ -627,7 +628,7 @@ fn (c mut V) add_user_v_files() {
|
||||
p.parse()
|
||||
}
|
||||
// Parse lib imports
|
||||
if c.build_mode == DEFAULT_MODE {
|
||||
if c.pref.build_mode == DEFAULT_MODE {
|
||||
for i := 0; i < c.table.imports.len; i++ {
|
||||
pkg := c.table.imports[i]
|
||||
vfiles := c.v_files_from_dir('$TmpPath/vlib/$pkg')
|
||||
@@ -652,7 +653,7 @@ fn (c mut V) add_user_v_files() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.is_verbose {
|
||||
if c.pref.is_verbose {
|
||||
c.log('imports:')
|
||||
println(c.table.imports)
|
||||
}
|
||||
@@ -662,7 +663,7 @@ fn (c mut V) add_user_v_files() {
|
||||
// If we are in default mode, we don't parse vlib .v files, but header .vh files in
|
||||
// TmpPath/vlib
|
||||
// These were generated by vfmt
|
||||
if c.build_mode == DEFAULT_MODE || c.build_mode == BUILD {
|
||||
if c.pref.build_mode == DEFAULT_MODE || c.pref.build_mode == BUILD {
|
||||
module_path = '$TmpPath/vlib/$pkg'
|
||||
}
|
||||
vfiles := c.v_files_from_dir(module_path)
|
||||
@@ -695,13 +696,13 @@ fn get_arg(joined_args, arg, def string) string {
|
||||
}
|
||||
|
||||
fn (c &V) log(s string) {
|
||||
if !c.is_verbose {
|
||||
if !c.pref.is_verbose {
|
||||
return
|
||||
}
|
||||
println(s)
|
||||
}
|
||||
|
||||
fn new_v(args []string) *V {
|
||||
fn new_v(args[]string) *V {
|
||||
mut dir := args.last()
|
||||
if args.contains('run') {
|
||||
dir = args[2]
|
||||
@@ -823,7 +824,25 @@ fn new_v(args []string) *V {
|
||||
files << f
|
||||
}
|
||||
}
|
||||
obfuscate := args.contains('-obf')
|
||||
obfuscate := args.contains('-obf')
|
||||
pref := &Preferences {
|
||||
is_test: is_test
|
||||
is_script: is_script
|
||||
is_so: args.contains('-shared')
|
||||
is_play: args.contains('play')
|
||||
is_prod: args.contains('-prod')
|
||||
is_verbose: args.contains('-verbose')
|
||||
obfuscate: obfuscate
|
||||
is_prof: args.contains('-prof')
|
||||
is_live: args.contains('-live')
|
||||
sanitize: args.contains('-sanitize')
|
||||
nofmt: args.contains('-nofmt')
|
||||
show_c_cmd: args.contains('-show_c_cmd')
|
||||
translated: args.contains('translated')
|
||||
is_run: args.contains('run')
|
||||
is_repl: args.contains('-repl')
|
||||
build_mode: build_mode
|
||||
}
|
||||
return &V {
|
||||
os: _os
|
||||
out_name: out_name
|
||||
@@ -833,24 +852,9 @@ fn new_v(args []string) *V {
|
||||
table: new_table(obfuscate)
|
||||
out_name: out_name
|
||||
out_name_c: out_name_c
|
||||
is_test: is_test
|
||||
is_script: is_script
|
||||
is_so: args.contains('-shared')
|
||||
is_play: args.contains('play')
|
||||
is_prod: args.contains('-prod')
|
||||
is_verbose: args.contains('-verbose')
|
||||
obfuscate: args.contains('-obf')
|
||||
is_prof: args.contains('-prof')
|
||||
is_live: args.contains('-live')
|
||||
sanitize: args.contains('-sanitize')
|
||||
nofmt: args.contains('-nofmt')
|
||||
show_c_cmd: args.contains('-show_c_cmd')
|
||||
translated: args.contains('translated')
|
||||
cgen: new_cgen(out_name_c)
|
||||
build_mode: build_mode
|
||||
is_run: args.contains('run')
|
||||
is_repl: args.contains('-repl')
|
||||
vroot: lang_dir
|
||||
pref: pref
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user