From 2eeba4758abb0013127c71d6f537f41037371880 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 18 Sep 2021 09:14:21 +0300 Subject: [PATCH] v.builder: fix `-cc msvc -cflags /O2` and support CFLAGS and LDFLAGS env vars --- vlib/v/builder/c.v | 3 --- vlib/v/builder/cc.v | 10 ++++------ vlib/v/builder/msvc.v | 32 ++++++++++++++++++++++++-------- vlib/v/pref/default.v | 10 ++++++++-- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/vlib/v/builder/c.v b/vlib/v/builder/c.v index 20f9f672d3..4058923dec 100644 --- a/vlib/v/builder/c.v +++ b/vlib/v/builder/c.v @@ -29,9 +29,6 @@ pub fn (mut b Builder) build_c(v_files []string, out_file string) { } pub fn (mut b Builder) compile_c() { - if os.user_os() != 'windows' && b.pref.ccompiler == 'msvc' && !b.pref.out_name.ends_with('.c') { - verror('Cannot build with msvc on $os.user_os()') - } // cgen.genln('// Generated by V') // println('compile2()') if b.pref.is_verbose { diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index d61b78a46e..72e8a2a6bd 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -517,7 +517,7 @@ fn (mut v Builder) cc() { return } // Cross compiling for Windows - if v.pref.os == .windows { + if v.pref.os == .windows && v.pref.ccompiler != 'msvc' { $if !windows { v.cc_windows_cross() return @@ -618,11 +618,9 @@ fn (mut v Builder) cc() { v.ccoptions.post_args << libs } // - $if windows { - if ccompiler == 'msvc' { - v.cc_msvc() - return - } + if ccompiler == 'msvc' { + v.cc_msvc() + return } // all_args := v.all_args(v.ccoptions) diff --git a/vlib/v/builder/msvc.v b/vlib/v/builder/msvc.v index e556b2ae15..f4f44dc4e1 100644 --- a/vlib/v/builder/msvc.v +++ b/vlib/v/builder/msvc.v @@ -268,17 +268,23 @@ pub fn (mut v Builder) cc_msvc() { r := v.cached_msvc if r.valid == false { verror('Cannot find MSVC on this OS') - return } out_name_obj := os.real_path(v.out_name_c + '.obj') out_name_pdb := os.real_path(v.out_name_c + '.pdb') out_name_cmd_line := os.real_path(v.out_name_c + '.rsp') + // + env_cflags := os.getenv('CFLAGS') + env_ldflags := os.getenv('LDFLAGS') + mut a := [v.pref.cflags] + if env_cflags != '' { + a << env_cflags + } // Default arguments // volatile:ms enables atomic volatile (gcc _Atomic) // -w: no warnings // 2 unicode defines // /Fo sets the object file name - needed so we can clean up after ourselves properly - mut a := ['-w', '/we4013', '/volatile:ms', '/Fo"$out_name_obj"'] + a << ['-w', '/we4013', '/volatile:ms', '/Fo"$out_name_obj"'] if v.pref.is_prod { a << '/O2' a << '/MD' @@ -323,7 +329,7 @@ pub fn (mut v Builder) cc_msvc() { */ } if v.pref.sanitize { - println('Sanitize not supported on msvc.') + eprintln('Sanitize not supported on msvc.') } // The C file we are compiling // a << '"$TmpPath/$v.out_name_c"' @@ -332,7 +338,6 @@ pub fn (mut v Builder) cc_msvc() { // Not all of these are needed (but the compiler should discard them if they are not used) // these are the defaults used by msbuild and visual studio mut real_libs := ['kernel32.lib', 'user32.lib', 'advapi32.lib'] - // sflags := v.get_os_cflags().msvc_string_flags() sflags := msvc_string_flags(v.get_os_cflags()) real_libs << sflags.real_libs inc_paths := sflags.inc_paths @@ -362,6 +367,9 @@ pub fn (mut v Builder) cc_msvc() { a << '/OPT:ICF' } a << lib_paths + if env_ldflags != '' { + a << env_ldflags + } args := a.join(' ') // write args to a file so that we dont smash createprocess os.write_file(out_name_cmd_line, args) or { @@ -371,12 +379,14 @@ pub fn (mut v Builder) cc_msvc() { // It is hard to see it at first, but the quotes above ARE balanced :-| ... // Also the double quotes at the start ARE needed. v.show_cc(cmd, out_name_cmd_line, args) + if os.user_os() != 'windows' && !v.pref.out_name.ends_with('.c') { + verror('Cannot build with msvc on $os.user_os()') + } util.timing_start('C msvc') res := os.execute(cmd) if res.exit_code != 0 { eprintln(res.output) verror('msvc error') - return } util.timing_measure('C msvc') if v.pref.show_c_output { @@ -394,7 +404,6 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(path string, moduleflags msvc := v.cached_msvc if msvc.valid == false { verror('Cannot find MSVC on this OS') - return } // msvc expects .obj not .o mut obj_path := '${path}bj' @@ -410,7 +419,12 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(path string, moduleflags defines := flags.defines.join(' ') include_string := '-I "$msvc.ucrt_include_path" -I "$msvc.vs_include_path" -I "$msvc.um_include_path" -I "$msvc.shared_include_path" $inc_dirs' // println('cfiles: $cfiles') - mut oargs := []string{} + env_cflags := os.getenv('CFLAGS') + env_ldflags := os.getenv('LDFLAGS') + mut oargs := [v.pref.cflags] + if env_cflags != '' { + oargs << env_cflags + } if v.pref.is_prod { oargs << '/O2' oargs << '/MD' @@ -419,6 +433,9 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(path string, moduleflags oargs << '/MDd' oargs << '/D_DEBUG' } + if env_ldflags != '' { + oargs << env_ldflags + } str_oargs := oargs.join(' ') cmd := '"$msvc.full_cl_exe_path" /volatile:ms $str_oargs $defines $include_string /c $cfiles /Fo"$obj_path"' // NB: the quotes above ARE balanced. @@ -429,7 +446,6 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(path string, moduleflags if res.exit_code != 0 { println('msvc: failed to build a thirdparty object; cmd: $cmd') verror(res.output) - return } println(res.output) } diff --git a/vlib/v/pref/default.v b/vlib/v/pref/default.v index 6d179296ec..213bd84e18 100644 --- a/vlib/v/pref/default.v +++ b/vlib/v/pref/default.v @@ -141,8 +141,14 @@ pub fn (mut p Preferences) fill_with_defaults() { fn (mut p Preferences) find_cc_if_cross_compiling() { if p.os == .windows { $if !windows { - // Cross compiling to Windows - p.ccompiler = 'x86_64-w64-mingw32-gcc' + // Allow for explicit overrides like `v -showcc -cc msvc -os windows file.v`, + // so that the flag passing can be debugged on other OSes too, not only + // on windows (building will stop later, when -showcc already could display all + // options). + if p.ccompiler != 'msvc' { + // Cross compiling to Windows + p.ccompiler = 'x86_64-w64-mingw32-gcc' + } } } if p.os == .linux {