builder: implement `-dump-c-flags flags.txt`
parent
49b01549da
commit
4d180171ba
|
@ -127,3 +127,8 @@ see also `v help build`.
|
|||
|
||||
-show-c-output
|
||||
Prints the output, that your C compiler produced, while compiling your program.
|
||||
|
||||
-dump-c-flags file.txt
|
||||
Write all C flags into `file.txt`, one flag per line.
|
||||
If `file.txt` is `-`, then write the flags to stdout, one flag per line.
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import os
|
|||
import v.cflag
|
||||
import v.pref
|
||||
import v.util
|
||||
import v.vcache
|
||||
import term
|
||||
|
||||
const (
|
||||
|
@ -135,7 +136,7 @@ fn (mut v Builder) rebuild_cached_module(vexe string, imp_path string) string {
|
|||
os.chdir(vroot)
|
||||
boptions := v.pref.build_options.join(' ')
|
||||
rebuild_cmd := '$vexe $boptions build-module $imp_path'
|
||||
// eprintln('>> rebuild_cmd: $rebuild_cmd')
|
||||
vcache.dlog('| Builder.' + @FN, 'vexe: $vexe | imp_path: $imp_path | rebuild_cmd: $rebuild_cmd')
|
||||
os.system(rebuild_cmd)
|
||||
rebuilded_o := v.pref.cache_manager.exists('.o', imp_path) or {
|
||||
panic('could not rebuild cache module for $imp_path, error: $err')
|
||||
|
@ -177,6 +178,7 @@ mut:
|
|||
args []string // ordinary C options like `-O2`
|
||||
wargs []string // for `-Wxyz` *exclusively*
|
||||
o_args []string // for `-o target`
|
||||
source_args []string // for `x.tmp.c`
|
||||
post_args []string // options that should go after .o_args
|
||||
linker_flags []string // `-lm`
|
||||
}
|
||||
|
@ -184,8 +186,8 @@ mut:
|
|||
fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
|
||||
mut ccoptions := CcompilerOptions{}
|
||||
//
|
||||
mut debug_options := '-g'
|
||||
mut optimization_options := '-O2'
|
||||
mut debug_options := ['-g']
|
||||
mut optimization_options := ['-O2']
|
||||
// arguments for the C compiler
|
||||
// TODO : activate -Werror once no warnings remain
|
||||
// '-Werror',
|
||||
|
@ -233,22 +235,22 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
|
|||
}
|
||||
if ccoptions.is_cc_clang {
|
||||
if ccoptions.debug_mode {
|
||||
debug_options = '-g -O0'
|
||||
debug_options = ['-g', '-O0']
|
||||
}
|
||||
optimization_options = '-O3'
|
||||
optimization_options = ['-O3']
|
||||
mut have_flto := true
|
||||
$if openbsd {
|
||||
have_flto = false
|
||||
}
|
||||
if have_flto {
|
||||
optimization_options += ' -flto'
|
||||
optimization_options << '-flto'
|
||||
}
|
||||
}
|
||||
if ccoptions.is_cc_gcc {
|
||||
if ccoptions.debug_mode {
|
||||
debug_options = '-g -no-pie'
|
||||
debug_options = ['-g', '-no-pie']
|
||||
}
|
||||
optimization_options = '-O3 -fno-strict-aliasing -flto'
|
||||
optimization_options = ['-O3', '-fno-strict-aliasing', '-flto']
|
||||
}
|
||||
//
|
||||
if ccoptions.debug_mode {
|
||||
|
@ -307,7 +309,7 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
|
|||
}
|
||||
}
|
||||
// The C file we are compiling
|
||||
ccoptions.post_args << '"$v.out_name_c"'
|
||||
ccoptions.source_args << '"$v.out_name_c"'
|
||||
if v.pref.os == .macos {
|
||||
ccoptions.post_args << '-x none'
|
||||
}
|
||||
|
@ -320,10 +322,11 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
|
|||
ccoptions.post_args << '-municode'
|
||||
}
|
||||
cflags := v.get_os_cflags()
|
||||
// add .o files
|
||||
ccoptions.o_args << cflags.c_options_only_object_files()
|
||||
// add all flags (-I -l -L etc) not .o files
|
||||
ccoptions.post_args << cflags.c_options_without_object_files()
|
||||
defines, others, libs := cflags.defines_others_libs()
|
||||
ccoptions.args << defines
|
||||
ccoptions.args << others
|
||||
ccoptions.linker_flags << libs
|
||||
// TODO: why is this duplicated from above?
|
||||
if v.pref.use_cache && v.pref.build_mode != .build_module {
|
||||
// vexe := pref.vexe_path()
|
||||
|
@ -382,6 +385,7 @@ fn (ccoptions CcompilerOptions) all_args() []string {
|
|||
all << ccoptions.env_cflags
|
||||
all << ccoptions.args
|
||||
all << ccoptions.o_args
|
||||
all << ccoptions.source_args
|
||||
all << ccoptions.post_args
|
||||
all << ccoptions.linker_flags
|
||||
all << ccoptions.env_ldflags
|
||||
|
@ -472,6 +476,17 @@ fn (mut v Builder) vjs_cc() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
fn (mut v Builder) dump_c_options(all_args []string) {
|
||||
if v.pref.dump_c_flags != '' {
|
||||
non_empty_args := all_args.filter(it != '').join('\n') + '\n'
|
||||
if v.pref.dump_c_flags == '-' {
|
||||
print(non_empty_args)
|
||||
} else {
|
||||
os.write_file(v.pref.dump_c_flags, non_empty_args) or { panic(err) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut v Builder) cc() {
|
||||
if os.executable().contains('vfmt') {
|
||||
return
|
||||
|
@ -523,13 +538,13 @@ fn (mut v Builder) cc() {
|
|||
v.build_thirdparty_obj_files()
|
||||
v.setup_output_name()
|
||||
//
|
||||
mut libs := '' // builtin.o os.o http.o etc
|
||||
mut libs := []string{} // builtin.o os.o http.o etc
|
||||
if v.pref.build_mode == .build_module {
|
||||
v.ccoptions.args << '-c'
|
||||
} else if v.pref.use_cache {
|
||||
mut built_modules := []string{}
|
||||
builtin_obj_path := v.rebuild_cached_module(vexe, 'vlib/builtin')
|
||||
libs += ' ' + builtin_obj_path
|
||||
libs << builtin_obj_path
|
||||
for ast_file in v.parsed_files {
|
||||
is_test := ast_file.path.ends_with('_test.v')
|
||||
if is_test && ast_file.mod.name != 'main' {
|
||||
|
@ -538,7 +553,7 @@ fn (mut v Builder) cc() {
|
|||
break
|
||||
}
|
||||
obj_path := v.rebuild_cached_module(vexe, imp_path)
|
||||
libs += ' ' + obj_path
|
||||
libs << obj_path
|
||||
built_modules << ast_file.mod.name
|
||||
}
|
||||
for imp_stmt in ast_file.imports {
|
||||
|
@ -576,9 +591,10 @@ fn (mut v Builder) cc() {
|
|||
break
|
||||
}
|
||||
obj_path := v.rebuild_cached_module(vexe, imp_path)
|
||||
libs += ' ' + obj_path
|
||||
libs << obj_path
|
||||
if obj_path.ends_with('vlib/ui.o') {
|
||||
v.ccoptions.post_args << '-framework Cocoa -framework Carbon'
|
||||
v.ccoptions.post_args << '-framework Cocoa'
|
||||
v.ccoptions.post_args << '-framework Carbon'
|
||||
}
|
||||
built_modules << imp
|
||||
}
|
||||
|
@ -594,6 +610,7 @@ fn (mut v Builder) cc() {
|
|||
}
|
||||
//
|
||||
all_args := v.ccoptions.all_args()
|
||||
v.dump_c_options(all_args)
|
||||
str_args := all_args.join(' ')
|
||||
// write args to response file
|
||||
response_file := '${v.out_name_c}.rsp'
|
||||
|
@ -631,9 +648,9 @@ fn (mut v Builder) cc() {
|
|||
v.show_c_compiler_output(res)
|
||||
}
|
||||
os.chdir(original_pwd)
|
||||
$if trace_use_cache ? {
|
||||
eprintln('>>>> v.pref.use_cache: $v.pref.use_cache | v.pref.retry_compilation: $v.pref.retry_compilation | cmd res.exit_code: $res.exit_code | cmd: $cmd')
|
||||
}
|
||||
vcache.dlog('| Builder.' + @FN, '> v.pref.use_cache: $v.pref.use_cache | v.pref.retry_compilation: $v.pref.retry_compilation')
|
||||
vcache.dlog('| Builder.' + @FN, '> cmd res.exit_code: $res.exit_code | cmd: $cmd')
|
||||
vcache.dlog('| Builder.' + @FN, '> response_file_content:\n$response_file_content')
|
||||
if res.exit_code != 0 {
|
||||
if ccompiler.contains('tcc.exe') {
|
||||
// a TCC problem? Retry with the system cc:
|
||||
|
@ -753,28 +770,38 @@ fn (mut b Builder) cc_linux_cross() {
|
|||
}
|
||||
}
|
||||
obj_file := b.out_name_c + '.o'
|
||||
mut cc_args := '-fPIC -w -c -target x86_64-linux-gnu -c -o $obj_file $b.out_name_c -I $sysroot/include '
|
||||
cflags := b.get_os_cflags()
|
||||
cc_args += cflags.c_options_without_object_files()
|
||||
cc_cmd := 'cc $cc_args'
|
||||
defines, others, libs := cflags.defines_others_libs()
|
||||
mut cc_args := []string{}
|
||||
cc_args << '-w'
|
||||
cc_args << '-fPIC'
|
||||
cc_args << '-c'
|
||||
cc_args << '-target x86_64-linux-gnu'
|
||||
cc_args << defines
|
||||
cc_args << '-I $sysroot/include '
|
||||
cc_args << others
|
||||
cc_args << '-o "$obj_file"'
|
||||
cc_args << '-c "$b.out_name_c"'
|
||||
cc_args << libs
|
||||
cc_cmd := 'cc ' + cc_args.join(' ')
|
||||
if b.pref.show_cc {
|
||||
println(cc_cmd)
|
||||
}
|
||||
cc_res := os.exec(cc_cmd) or {
|
||||
println('Cross compilation for Linux failed (first step, cc). Make sure you have clang installed.')
|
||||
verror(err)
|
||||
return
|
||||
}
|
||||
cc_res := os.exec(cc_cmd) or { os.Result{
|
||||
exit_code: 1
|
||||
output: 'no `cc` command found'
|
||||
} }
|
||||
if cc_res.exit_code != 0 {
|
||||
println('Cross compilation for Linux failed (first step, cc). Make sure you have clang installed.')
|
||||
verror(cc_res.output)
|
||||
return
|
||||
}
|
||||
linker_args := ['-L $sysroot/usr/lib/x86_64-linux-gnu/', '--sysroot=$sysroot -v -o $b.pref.out_name -m elf_x86_64',
|
||||
'-dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2', '$sysroot/crt1.o $sysroot/crti.o $obj_file',
|
||||
'-lc', '-lcrypto', '-lssl', '-lpthread', '$sysroot/crtn.o', cflags.c_options_only_object_files()]
|
||||
mut linker_args := ['-L $sysroot/usr/lib/x86_64-linux-gnu/', '--sysroot=$sysroot', '-v', '-o $b.pref.out_name',
|
||||
'-m elf_x86_64', '-dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2', '$sysroot/crt1.o $sysroot/crti.o $obj_file',
|
||||
'-lc', '-lcrypto', '-lssl', '-lpthread', '$sysroot/crtn.o']
|
||||
linker_args << cflags.c_options_only_object_files()
|
||||
// -ldl
|
||||
linker_args_str := linker_args.join(' ')
|
||||
linker_cmd := '$sysroot/ld.lld $linker_args_str'
|
||||
linker_cmd := '$sysroot/ld.lld ' + linker_args.join(' ')
|
||||
// s = s.replace('SYSROOT', sysroot) // TODO $ inter bug
|
||||
// s = s.replace('-o hi', '-o ' + c.pref.out_name)
|
||||
if b.pref.show_cc {
|
||||
|
@ -800,46 +827,48 @@ fn (mut c Builder) cc_windows_cross() {
|
|||
if !c.pref.out_name.ends_with('.exe') {
|
||||
c.pref.out_name += '.exe'
|
||||
}
|
||||
mut args := ''
|
||||
args += ' $c.pref.cflags '
|
||||
args += ' -o $c.pref.out_name -w -L. '
|
||||
mut args := []string{}
|
||||
args << '$c.pref.cflags'
|
||||
args << '-o $c.pref.out_name'
|
||||
args << '-w -L.'
|
||||
//
|
||||
cflags := c.get_os_cflags()
|
||||
// -I flags
|
||||
args += if c.pref.ccompiler == 'msvc' {
|
||||
cflags.c_options_before_target_msvc()
|
||||
if c.pref.ccompiler == 'msvc' {
|
||||
args << cflags.c_options_before_target_msvc()
|
||||
} else {
|
||||
cflags.c_options_before_target()
|
||||
args << cflags.c_options_before_target()
|
||||
}
|
||||
mut optimization_options := ''
|
||||
mut debug_options := ''
|
||||
mut optimization_options := []string{}
|
||||
mut debug_options := []string{}
|
||||
if c.pref.is_prod {
|
||||
if c.pref.ccompiler != 'msvc' {
|
||||
optimization_options = ' -O3 -fno-strict-aliasing -flto '
|
||||
optimization_options = ['-O3', '-fno-strict-aliasing', '-flto']
|
||||
}
|
||||
}
|
||||
if c.pref.is_debug {
|
||||
if c.pref.ccompiler != 'msvc' {
|
||||
debug_options = ' -O0 -g -gdwarf-2 '
|
||||
debug_options = ['-O0', '-g', '-gdwarf-2']
|
||||
}
|
||||
}
|
||||
mut libs := ''
|
||||
mut libs := []string{}
|
||||
if false && c.pref.build_mode == .default_mode {
|
||||
libs = '"$pref.default_module_path/vlib/builtin.o"'
|
||||
if !os.exists(libs) {
|
||||
verror('`$libs` not found')
|
||||
builtin_o := '"$pref.default_module_path/vlib/builtin.o"'
|
||||
libs << builtin_o
|
||||
if !os.exists(builtin_o) {
|
||||
verror('$builtin_o not found')
|
||||
}
|
||||
for imp in c.table.imports {
|
||||
libs += ' "$pref.default_module_path/vlib/${imp}.o"'
|
||||
libs << '"$pref.default_module_path/vlib/${imp}.o"'
|
||||
}
|
||||
}
|
||||
// add the thirdparty .o files, produced by all the #flag directives:
|
||||
args += ' ' + cflags.c_options_only_object_files() + ' '
|
||||
args += ' $c.out_name_c '
|
||||
args += if c.pref.ccompiler == 'msvc' {
|
||||
cflags.c_options_after_target_msvc()
|
||||
args << cflags.c_options_only_object_files()
|
||||
args << c.out_name_c
|
||||
if c.pref.ccompiler == 'msvc' {
|
||||
args << cflags.c_options_after_target_msvc()
|
||||
} else {
|
||||
cflags.c_options_after_target()
|
||||
args << cflags.c_options_after_target()
|
||||
}
|
||||
/*
|
||||
winroot := '${pref.default_module_path}/winroot'
|
||||
|
@ -860,7 +889,14 @@ fn (mut c Builder) cc_windows_cross() {
|
|||
println(os.user_os())
|
||||
panic('your platform is not supported yet')
|
||||
}
|
||||
mut cmd := '$builder.mingw_cc $optimization_options $debug_options -std=gnu11 $args -municode'
|
||||
mut all_args := []string{}
|
||||
all_args << optimization_options
|
||||
all_args << debug_options
|
||||
all_args << '-std=gnu11'
|
||||
all_args << args
|
||||
all_args << '-municode'
|
||||
c.dump_c_options(all_args)
|
||||
mut cmd := '$builder.mingw_cc ' + all_args.join(' ')
|
||||
// cmd := 'clang -o $obj_name -w $include -m32 -c -target x86_64-win32 ${pref.default_module_path}/$c.out_name_c'
|
||||
if c.pref.is_verbose || c.pref.show_cc {
|
||||
println(cmd)
|
||||
|
@ -908,8 +944,6 @@ fn (mut v Builder) build_thirdparty_obj_files() {
|
|||
fn (mut v Builder) build_thirdparty_obj_file(path string, moduleflags []cflag.CFlag) {
|
||||
obj_path := os.real_path(path)
|
||||
cfile := '${obj_path[..obj_path.len - 2]}.c'
|
||||
btarget := moduleflags.c_options_before_target()
|
||||
atarget := moduleflags.c_options_after_target()
|
||||
opath := v.pref.cache_manager.postfix_with_key2cpath('.o', obj_path)
|
||||
if os.exists(opath) {
|
||||
return
|
||||
|
@ -928,8 +962,13 @@ fn (mut v Builder) build_thirdparty_obj_file(path string, moduleflags []cflag.CF
|
|||
current_folder := os.getwd()
|
||||
os.chdir(os.dir(pref.vexe_path()))
|
||||
//
|
||||
cc_options := v.ccoptions.thirdparty_object_args([v.pref.third_party_option, btarget, '-o',
|
||||
'"$opath"', '-c', '"$cfile"', atarget]).join(' ')
|
||||
mut all_options := []string{}
|
||||
all_options << v.pref.third_party_option
|
||||
all_options << moduleflags.c_options_before_target()
|
||||
all_options << '-o "$opath"'
|
||||
all_options << '-c "$cfile"'
|
||||
all_options << moduleflags.c_options_after_target()
|
||||
cc_options := v.ccoptions.thirdparty_object_args(all_options).join(' ')
|
||||
cmd := '$v.pref.ccompiler $cc_options'
|
||||
$if trace_thirdparty_obj_files ? {
|
||||
println('>>> build_thirdparty_obj_files cmd: $cmd')
|
||||
|
|
|
@ -37,37 +37,28 @@ pub fn (cf &CFlag) format() string {
|
|||
}
|
||||
|
||||
// TODO: implement msvc specific c_options_before_target and c_options_after_target ...
|
||||
pub fn (cflags []CFlag) c_options_before_target_msvc() string {
|
||||
return ''
|
||||
pub fn (cflags []CFlag) c_options_before_target_msvc() []string {
|
||||
return []
|
||||
}
|
||||
|
||||
pub fn (cflags []CFlag) c_options_after_target_msvc() string {
|
||||
return ''
|
||||
pub fn (cflags []CFlag) c_options_after_target_msvc() []string {
|
||||
return []
|
||||
}
|
||||
|
||||
pub fn (cflags []CFlag) c_options_before_target() string {
|
||||
// -I flags, optimization flags and so on
|
||||
pub fn (cflags []CFlag) c_options_before_target() []string {
|
||||
defines, others, _ := cflags.defines_others_libs()
|
||||
mut args := []string{}
|
||||
for flag in cflags {
|
||||
if flag.name != '-l' && !flag.value.ends_with('.o') {
|
||||
args << flag.format()
|
||||
}
|
||||
}
|
||||
return args.join(' ')
|
||||
args << defines
|
||||
args << others
|
||||
return args
|
||||
}
|
||||
|
||||
pub fn (cflags []CFlag) c_options_after_target() string {
|
||||
// -l flags (libs)
|
||||
mut args := []string{}
|
||||
for flag in cflags {
|
||||
if flag.name == '-l' {
|
||||
args << flag.format()
|
||||
}
|
||||
}
|
||||
return args.join(' ')
|
||||
pub fn (cflags []CFlag) c_options_after_target() []string {
|
||||
_, _, libs := cflags.defines_others_libs()
|
||||
return libs
|
||||
}
|
||||
|
||||
pub fn (cflags []CFlag) c_options_without_object_files() string {
|
||||
pub fn (cflags []CFlag) c_options_without_object_files() []string {
|
||||
mut args := []string{}
|
||||
for flag in cflags {
|
||||
if flag.value.ends_with('.o') || flag.value.ends_with('.obj') {
|
||||
|
@ -75,15 +66,34 @@ pub fn (cflags []CFlag) c_options_without_object_files() string {
|
|||
}
|
||||
args << flag.format()
|
||||
}
|
||||
return args.join(' ')
|
||||
return args
|
||||
}
|
||||
|
||||
pub fn (cflags []CFlag) c_options_only_object_files() string {
|
||||
pub fn (cflags []CFlag) c_options_only_object_files() []string {
|
||||
mut args := []string{}
|
||||
for flag in cflags {
|
||||
if flag.value.ends_with('.o') || flag.value.ends_with('.obj') {
|
||||
args << flag.format()
|
||||
}
|
||||
}
|
||||
return args.join(' ')
|
||||
return args
|
||||
}
|
||||
|
||||
pub fn (cflags []CFlag) defines_others_libs() ([]string, []string, []string) {
|
||||
copts_without_obj_files := cflags.c_options_without_object_files()
|
||||
mut defines := []string{}
|
||||
mut others := []string{}
|
||||
mut libs := []string{}
|
||||
for copt in copts_without_obj_files {
|
||||
if copt.starts_with('-l') {
|
||||
libs << copt
|
||||
continue
|
||||
}
|
||||
if copt.starts_with('-D') {
|
||||
defines << copt
|
||||
continue
|
||||
}
|
||||
others << copt
|
||||
}
|
||||
return defines, others, libs
|
||||
}
|
||||
|
|
|
@ -78,8 +78,10 @@ pub mut:
|
|||
// NB: passing -cg instead of -g will set is_vlines to false and is_debug 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).
|
||||
// use cached modules to speed up compilation.
|
||||
dump_c_flags string // `-dump-c-flags file.txt` - let V store all C flags, passed to the backend C compiler
|
||||
// in `file.txt`, one C flag/value per line.
|
||||
use_cache bool // = true
|
||||
retry_compilation bool = true
|
||||
retry_compilation bool = true // retry the compilation with another C compiler, if tcc fails.
|
||||
is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run
|
||||
// TODO Convert this into a []string
|
||||
cflags string // Additional options which will be passed to the C compiler.
|
||||
|
@ -276,6 +278,10 @@ pub fn parse_args(args []string) (&Preferences, string) {
|
|||
'-show-c-output' {
|
||||
res.show_c_output = true
|
||||
}
|
||||
'-dump-c-flags' {
|
||||
res.dump_c_flags = cmdline.option(current_args, arg, '-')
|
||||
i++
|
||||
}
|
||||
'-experimental' {
|
||||
res.experimental = true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue