compiler: -g and -debug should always add -g at least in the C compiler by default

* compiler: -g and -debug should always add -g at least in the C compiler by default.

* Set first the C backend debug_options, so that the optimization_options can override them later.

* Implement cleaner named is_debug, is_vlines, is_keep_c and is_cache options (i.e. -g/-cg, -keep_c, -cache v flags).

* Check and reset file/line numbers in the generated main program, only if v.pref.is_vlines is true.
pull/2312/head
Delyan Angelov 2019-10-12 13:54:01 +03:00 committed by Alexander Medvednikov
parent 342e6a14a2
commit 065ce39577
7 changed files with 61 additions and 44 deletions

View File

@ -77,29 +77,30 @@ fn (v mut V) cc() {
println('Building ${v.out_name}...') println('Building ${v.out_name}...')
} }
mut debug_options := '' debug_mode := v.pref.is_debug
mut debug_options := '-g'
mut optimization_options := '-O2' mut optimization_options := '-O2'
if v.pref.ccompiler.contains('clang') { if v.pref.ccompiler.contains('clang') {
if v.pref.is_debuggable { if debug_mode {
debug_options = '-g -O0' debug_options = '-g -O0'
} }
optimization_options = '-O3 -flto' optimization_options = '-O3 -flto'
} }
if v.pref.ccompiler.contains('gcc') { if v.pref.ccompiler.contains('gcc') {
if v.pref.is_debug { if debug_mode {
debug_options = '-g3' debug_options = '-g3'
} }
optimization_options = '-O3 -fno-strict-aliasing -flto' optimization_options = '-O3 -fno-strict-aliasing -flto'
} }
if debug_mode {
a << debug_options
}
if v.pref.is_prod { if v.pref.is_prod {
a << optimization_options a << optimization_options
} }
else {
a << debug_options if debug_mode && os.user_os() != 'windows'{
}
if v.pref.is_debuggable && os.user_os() != 'windows'{
a << ' -rdynamic ' // needed for nicer symbolic backtraces a << ' -rdynamic ' // needed for nicer symbolic backtraces
} }
@ -115,7 +116,7 @@ fn (v mut V) cc() {
if v.pref.build_mode == .build_module { if v.pref.build_mode == .build_module {
a << '-c' a << '-c'
} }
else if v.pref.is_debug { else if v.pref.is_cache {
vexe := os.executable() vexe := os.executable()
builtin_o_path := '$v_modules_path${os.PathSeparator}cache${os.PathSeparator}vlib${os.PathSeparator}builtin.o' builtin_o_path := '$v_modules_path${os.PathSeparator}cache${os.PathSeparator}vlib${os.PathSeparator}builtin.o'
if os.file_exists(builtin_o_path) { if os.file_exists(builtin_o_path) {
@ -225,7 +226,7 @@ fn (v mut V) cc() {
partial_output := res.output.limit(200).trim_right('\r\n') partial_output := res.output.limit(200).trim_right('\r\n')
print(partial_output) print(partial_output)
if res.output.len > partial_output.len { if res.output.len > partial_output.len {
println('...\n(Use `v -debug` to print the entire error message)\n') println('...\n(Use `v -g` to print the entire error message)\n')
}else{ }else{
println('') println('')
} }
@ -261,7 +262,7 @@ fn (v mut V) cc() {
println('linux cross compilation done. resulting binary: "$v.out_name"') println('linux cross compilation done. resulting binary: "$v.out_name"')
} }
*/ */
if !v.pref.is_debug && v.out_name_c != 'v.c' { if !v.pref.is_keep_c && v.out_name_c != 'v.c' {
os.rm(v.out_name_c) os.rm(v.out_name_c)
} }
if v.pref.compress { if v.pref.compress {

View File

@ -807,7 +807,7 @@ fn (p mut Parser) fn_call_args(f mut Fn) &Fn {
p.check(.rpar) p.check(.rpar)
return f return f
} }
// add debug information to panic when -debug arg is passed // add debug information to panic when -g arg is passed
if p.v.pref.is_debug && f.name == 'panic' && !p.is_js { if p.v.pref.is_debug && f.name == 'panic' && !p.is_js {
mod_name := p.mod.replace('_dot_', '.') mod_name := p.mod.replace('_dot_', '.')
fn_name := p.cur_fn.name.replace('${p.mod}__', '') fn_name := p.cur_fn.name.replace('${p.mod}__', '')

View File

@ -82,13 +82,8 @@ fn (v &V) generate_hot_reload_code() {
msvc = '-os msvc' msvc = '-os msvc'
} }
mut debug := '' so_debug_flag := if v.pref.is_debug { '-g' } else { '' }
cmd_compile_shared_library := '$vexe $msvc $so_debug_flag -o $file_base -shared $file'
if v.pref.is_debug {
debug = '-debug'
}
cmd_compile_shared_library := '$vexe $msvc $debug -o $file_base -shared $file'
if v.pref.show_c_cmd { if v.pref.show_c_cmd {
println(cmd_compile_shared_library) println(cmd_compile_shared_library)
} }

View File

@ -91,8 +91,14 @@ mut:
is_run bool is_run bool
show_c_cmd bool // `v -show_c_cmd` prints the C command to build program.v.c 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 sanitize bool // use Clang's new "-fsanitize" option
is_debuggable bool
is_debug bool // keep compiled C files is_debug bool // false by default, turned on by -g or -cg, it tells v to pass -g to the C backend compiler.
is_vlines bool // turned on by -g, false by default (it slows down .tmp.c generation slightly).
is_keep_c bool // -keep_c , tell v to leave the generated .tmp.c alone (since by default v will delete them after c backend finishes)
// NB: passing -cg instead of -g will set is_vlines to false and is_g to true, thus making v generate cleaner C files,
// which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks).
is_cache bool // turns on v usage of the module cache to speed up compilation.
is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run
no_auto_free bool // `v -nofree` disable automatic `free()` insertion for better performance in some applications (e.g. compilers) no_auto_free bool // `v -nofree` disable automatic `free()` insertion for better performance in some applications (e.g. compilers)
cflags string // Additional options which will be passed to the C compiler. cflags string // Additional options which will be passed to the C compiler.
@ -460,14 +466,16 @@ fn (v mut V) generate_main() {
mut cgen := v.cgen mut cgen := v.cgen
$if js { return } $if js { return }
///// After this point, the v files are compiled. if v.pref.is_vlines {
///// The rest is auto generated code, which will not have ///// After this point, the v files are compiled.
///// different .v source file/line numbers. ///// The rest is auto generated code, which will not have
lines_so_far := cgen.lines.join('\n').count('\n') + 5 ///// different .v source file/line numbers.
cgen.genln('') lines_so_far := cgen.lines.join('\n').count('\n') + 5
cgen.genln('////////////////// Reset the file/line numbers //////////') cgen.genln('')
cgen.lines << '#line $lines_so_far "${cescaped_path(os.realpath(cgen.out_path))}"' cgen.genln('////////////////// Reset the file/line numbers //////////')
cgen.genln('') cgen.lines << '#line $lines_so_far "${cescaped_path(os.realpath(cgen.out_path))}"'
cgen.genln('')
}
// Make sure the main function exists // Make sure the main function exists
// Obviously we don't need it in libraries // Obviously we don't need it in libraries
@ -612,7 +620,7 @@ fn (v mut V) add_v_files_to_compile() {
mut builtin_files := v.get_builtin_files() mut builtin_files := v.get_builtin_files()
// Builtin cache exists? Use it. // Builtin cache exists? Use it.
builtin_vh := '$v_modules_path${os.PathSeparator}vlib${os.PathSeparator}builtin.vh' builtin_vh := '$v_modules_path${os.PathSeparator}vlib${os.PathSeparator}builtin.vh'
if v.pref.is_debug && os.file_exists(builtin_vh) { if v.pref.is_cache && os.file_exists(builtin_vh) {
v.cached_mods << 'builtin' v.cached_mods << 'builtin'
builtin_files = [builtin_vh] builtin_files = [builtin_vh]
} }
@ -656,7 +664,7 @@ fn (v mut V) add_v_files_to_compile() {
if v.pref.build_mode != .build_module && !mod.contains('vweb') { if v.pref.build_mode != .build_module && !mod.contains('vweb') {
mod_path := mod.replace('.', os.PathSeparator) mod_path := mod.replace('.', os.PathSeparator)
vh_path := '$v_modules_path${os.PathSeparator}vlib${os.PathSeparator}${mod_path}.vh' vh_path := '$v_modules_path${os.PathSeparator}vlib${os.PathSeparator}${mod_path}.vh'
if v.pref.is_debug && os.file_exists(vh_path) { if v.pref.is_cache && os.file_exists(vh_path) {
println('using cached module `$mod`: $vh_path') println('using cached module `$mod`: $vh_path')
v.cached_mods << mod v.cached_mods << mod
v.files << vh_path v.files << vh_path
@ -941,8 +949,12 @@ fn new_v(args[]string) &V {
is_so: '-shared' in args is_so: '-shared' in args
is_prod: '-prod' in args is_prod: '-prod' in args
is_verbose: '-verbose' in args || '--verbose' in args is_verbose: '-verbose' in args || '--verbose' in args
is_debuggable: '-g' in args
is_debug: '-debug' in args || '-g' in args is_debug: '-g' in args || '-cg' in args
is_vlines: '-g' in args && !('-cg' in args)
is_keep_c: '-keep_c' in args
is_cache: '-cache' in args
is_stats: '-stats' in args is_stats: '-stats' in args
obfuscate: obfuscate obfuscate: obfuscate
is_prof: '-prof' in args is_prof: '-prof' in args

View File

@ -213,7 +213,7 @@ fn find_msvc() ?MsvcResult {
pub fn (v mut V) cc_msvc() { pub fn (v mut V) cc_msvc() {
r := find_msvc() or { r := find_msvc() or {
// TODO: code reuse // TODO: code reuse
if !v.pref.is_debug && v.out_name_c != 'v.c' && v.out_name_c != 'v_macos.c' { if !v.pref.is_keep_c && v.out_name_c != 'v.c' && v.out_name_c != 'v_macos.c' {
os.rm(v.out_name_c) os.rm(v.out_name_c)
} }
verror('Cannot find MSVC on this OS') verror('Cannot find MSVC on this OS')
@ -358,7 +358,7 @@ pub fn (v mut V) cc_msvc() {
// println(res) // println(res)
// println('C OUTPUT:') // println('C OUTPUT:')
if !v.pref.is_debug && v.out_name_c != 'v.c' && v.out_name_c != 'v_macos.c' { if !v.pref.is_keep_c && v.out_name_c != 'v.c' && v.out_name_c != 'v_macos.c' {
os.rm(v.out_name_c) os.rm(v.out_name_c)
} }

View File

@ -103,7 +103,7 @@ fn (v mut V) new_parser_from_string(text string, id string) Parser {
fn (v mut V) reset_cgen_file_line_parameters(){ fn (v mut V) reset_cgen_file_line_parameters(){
v.cgen.line = 0 v.cgen.line = 0
v.cgen.file = '' v.cgen.file = ''
v.cgen.line_directives = v.pref.is_debuggable v.cgen.line_directives = v.pref.is_vlines
} }
fn (v mut V) new_parser_from_file(path string) Parser { fn (v mut V) new_parser_from_file(path string) Parser {

View File

@ -39,19 +39,28 @@ Options/commands:
-os <OS> Produce an executable for the selected OS. -os <OS> Produce an executable for the selected OS.
OS can be linux, mac, windows, msvc. OS can be linux, mac, windows, msvc.
Use msvc if you want to use the MSVC compiler on Windows. Use msvc if you want to use the MSVC compiler on Windows.
-shared Build a shared library.
-stats Show additional stats when compiling/running tests. Try `v -stats test .`
-cache Turn on usage of the precompiled module cache.
It very significantly speeds up secondary compilations.
-obf Obfuscate the resulting binary.
- Shorthand for `v runrepl`.
Options for debugging/troubleshooting v programs:
-g Generate debugging information in the backtraces. Add *V* line numbers to the generated executable.
-cg Same as -g, but add *C* line numbers to the generated executable instead of *V* line numbers.
-keep_c Do NOT remove the generated .tmp.c files after compilation.
It is useful when using debuggers like gdb/visual studio, when given after -g / -cg .
-show_c_cmd Print the full C compilation command and how much time it took.
-cc <ccompiler> Specify which C compiler you want to use as a C backend. -cc <ccompiler> Specify which C compiler you want to use as a C backend.
The C backend compiler should be able to handle C99 compatible C code. The C backend compiler should be able to handle C99 compatible C code.
Common C compilers are gcc, clang, tcc, icc, cl... Common C compilers are gcc, clang, tcc, icc, cl...
-cflags <flags> Pass additional C flags to the C backend compiler. -cflags <flags> Pass additional C flags to the C backend compiler.
Example: -cflags `sdl2-config --cflags` Example: -cflags `sdl2-config --cflags`
-debug Keep the generated C file for debugging in program.tmp.c even after compilation.
-shared Build a shared library.
-stats Show additional stats when compiling/running tests. Try `v -stats test .`
-g Show v line numbers in backtraces. Implies -debug.
-obf Obfuscate the resulting binary.
-show_c_cmd Print the full C compilation command and how much time it took.
- Shorthand for `v runrepl`.
Commands:
up Update V. Run `v up` at least once per day, since V development is rapid and features/bugfixes are added constantly. up Update V. Run `v up` at least once per day, since V development is rapid and features/bugfixes are added constantly.
run <file.v> Build and execute the V program in file.v. You can add arguments for the V program *after* the file name. run <file.v> Build and execute the V program in file.v. You can add arguments for the V program *after* the file name.
build <module> Compile a module into an object file. build <module> Compile a module into an object file.