Skip to content

Commit 2e983cf

Browse files
authored
v.builder: enable gc back with msvc, build separate .debug.obj thirdparty files when -g is passed, to prevent linking issues (#26215)
1 parent d970d45 commit 2e983cf

3 files changed

Lines changed: 34 additions & 34 deletions

File tree

‎vlib/v/builder/cc.v‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,7 @@ fn (mut b Builder) build_thirdparty_obj_files() {
11761176
}
11771177

11781178
fn (mut v Builder) build_thirdparty_obj_file(mod string, path string, moduleflags []cflag.CFlag) {
1179+
trace_thirdparty_obj_files := 'trace_thirdparty_obj_files' in v.pref.compile_defines
11791180
obj_path := os.real_path(path)
11801181
mut cfile := '${obj_path[..obj_path.len - 2]}.c'
11811182
mut cpp_file := false
@@ -1218,13 +1219,13 @@ fn (mut v Builder) build_thirdparty_obj_file(mod string, path string, moduleflag
12181219
// If the third party object file requires a CPP file compilation, switch to a CPP compiler
12191220
mut ccompiler := v.pref.ccompiler
12201221
if cpp_file {
1221-
$if trace_thirdparty_obj_files ? {
1222+
if trace_thirdparty_obj_files {
12221223
println('>>> build_thirdparty_obj_files switched from compiler "${ccompiler}" to "${v.pref.cppcompiler}"')
12231224
}
12241225
ccompiler = v.pref.cppcompiler
12251226
}
12261227
cmd := '${v.quote_compiler_name(ccompiler)} ${cc_options}'
1227-
$if trace_thirdparty_obj_files ? {
1228+
if trace_thirdparty_obj_files {
12281229
println('>>> build_thirdparty_obj_files cmd: ${cmd}')
12291230
}
12301231
res := os.execute(cmd)
@@ -1246,7 +1247,7 @@ fn (mut v Builder) build_thirdparty_obj_file(mod string, path string, moduleflag
12461247
if v.pref.show_cc {
12471248
println('>> OBJECT FILE compilation cmd: ${cmd}')
12481249
}
1249-
$if trace_thirdparty_obj_files ? {
1250+
if trace_thirdparty_obj_files {
12501251
if res.output != '' {
12511252
println(res.output)
12521253
}

‎vlib/v/builder/msvc_windows.v‎

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -313,21 +313,6 @@ pub fn (mut v Builder) cc_msvc() {
313313
if v.pref.build_mode == .build_module {
314314
// Compile only
315315
a << '/c'
316-
} else if v.pref.build_mode == .default_mode {
317-
/*
318-
b := os.real_path( '${pref.default_module_path}/vlib/builtin.obj' )
319-
alibs << '"$b"'
320-
if !os.exists(b) {
321-
println('`builtin.obj` not found')
322-
exit(1)
323-
}
324-
for imp in v.ast.imports {
325-
if imp == 'webview' {
326-
continue
327-
}
328-
alibs << '"' + os.real_path( '${pref.default_module_path}/vlib/${imp}.obj' ) + '"'
329-
}
330-
*/
331316
}
332317
if v.pref.sanitize {
333318
eprintln('Sanitize not supported on msvc.')
@@ -342,7 +327,7 @@ pub fn (mut v Builder) cc_msvc() {
342327
// Not all of these are needed (but the compiler should discard them if they are not used)
343328
// these are the defaults used by msbuild and visual studio
344329
mut real_libs := ['kernel32.lib', 'user32.lib', 'advapi32.lib', 'ws2_32.lib']
345-
sflags := msvc_string_flags(v.get_os_cflags())
330+
sflags := v.msvc_string_flags(v.get_os_cflags())
346331
real_libs << sflags.real_libs
347332
inc_paths := sflags.inc_paths
348333
lib_paths := sflags.lib_paths
@@ -424,27 +409,35 @@ pub fn (mut v Builder) cc_msvc() {
424409
}
425410

426411
fn (mut v Builder) build_thirdparty_obj_file_with_msvc(_mod string, path string, moduleflags []cflag.CFlag) {
427-
msvc := v.cached_msvc
428-
if msvc.valid == false {
412+
if v.cached_msvc.valid == false {
429413
verror('cannot find MSVC on this OS')
430414
}
415+
msvc := v.cached_msvc
416+
trace_thirdparty_obj_files := 'trace_thirdparty_obj_files' in v.pref.compile_defines
431417
// msvc expects .obj not .o
432418
path_without_o_postfix := path[..path.len - 2] // remove .o
433-
mut obj_path := '${path_without_o_postfix}.obj'
419+
mut obj_path := if v.pref.is_debug {
420+
// compiling in debug mode (-cg / -g), should produce and use its own completely separate .obj file,
421+
// since it uses /MDD . Those .obj files can not be mixed with programs/objects compiled with just /MD .
422+
// See https://stackoverflow.com/questions/924830/what-is-difference-btw-md-and-mdd-in-visualstudio-c
423+
'${path_without_o_postfix}.debug.obj'
424+
} else {
425+
'${path_without_o_postfix}.obj'
426+
}
434427
obj_path = os.real_path(obj_path)
435428
if os.exists(obj_path) {
436429
// println('$obj_path already built.')
437430
return
438431
}
439-
$if trace_thirdparty_obj_files ? {
432+
if trace_thirdparty_obj_files {
440433
println('${obj_path} not found, building it (with msvc)...')
441434
}
442435
cfile := if os.exists('${path_without_o_postfix}.c') {
443436
'${path_without_o_postfix}.c'
444437
} else {
445438
'${path_without_o_postfix}.cpp'
446439
}
447-
flags := msvc_string_flags(moduleflags)
440+
flags := v.msvc_string_flags(moduleflags)
448441
inc_dirs := flags.inc_paths.join(' ')
449442
defines := flags.defines.join(' ')
450443

@@ -460,13 +453,15 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(_mod string, path string,
460453
if v.pref.is_prod {
461454
if !v.pref.no_prod_options {
462455
oargs << '/O2'
463-
oargs << '/MD'
464-
oargs << '/DNDEBUG'
465-
oargs << '/DNO_DEBUGGING'
466456
}
467-
} else {
457+
}
458+
if v.pref.is_debug {
468459
oargs << '/MDd'
469460
oargs << '/D_DEBUG'
461+
} else {
462+
oargs << '/MD'
463+
oargs << '/DNDEBUG'
464+
oargs << '/DNO_DEBUGGING'
470465
}
471466
oargs << defines
472467
oargs << msvc.include_paths()
@@ -482,7 +477,7 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(_mod string, path string,
482477
str_oargs := oargs.join(' ')
483478
cmd := '"${msvc.full_cl_exe_path}" ${str_oargs}'
484479
// Note: the quotes above ARE balanced.
485-
$if trace_thirdparty_obj_files ? {
480+
if trace_thirdparty_obj_files {
486481
println('>>> build_thirdparty_obj_file_with_msvc cmd: ${cmd}')
487482
}
488483
// Note, that building object files with msvc can fail with permission denied errors,
@@ -511,7 +506,7 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(_mod string, path string,
511506
cmd:\n${cmd}
512507
result:\n${res.output}')
513508
}
514-
$if trace_thirdparty_obj_files ? {
509+
if trace_thirdparty_obj_files {
515510
println(res.output)
516511
}
517512
}
@@ -528,8 +523,7 @@ mut:
528523
other_flags []string
529524
}
530525

531-
// pub fn (cflags []CFlag) msvc_string_flags() MsvcStringFlags {
532-
pub fn msvc_string_flags(cflags []cflag.CFlag) MsvcStringFlags {
526+
pub fn (mut v Builder) msvc_string_flags(cflags []cflag.CFlag) MsvcStringFlags {
533527
mut real_libs := []string{}
534528
mut inc_paths := []string{}
535529
mut lib_paths := []string{}
@@ -564,7 +558,12 @@ pub fn msvc_string_flags(cflags []cflag.CFlag) MsvcStringFlags {
564558
} else if flag.value.ends_with('.o') {
565559
// TODO: use flag.format() here as well; `#flag -L$when_first_existing(...)` is a more explicit way to achieve the same
566560
// msvc expects .obj not .o
567-
other_flags << '"${flag.value}bj"'
561+
path_with_no_o := flag.value[..flag.value.len - 2]
562+
if v.pref.is_debug {
563+
other_flags << '"${path_with_no_o}.debug.obj"'
564+
} else {
565+
other_flags << '"${path_with_no_o}.obj"'
566+
}
568567
} else if flag.value.starts_with('-D') {
569568
defines << '/D${flag.value[2..]}'
570569
} else {

‎vlib/v/pref/default.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ pub fn (mut p Preferences) fill_with_defaults() {
157157
p.parse_define('cross') // TODO: remove when `$if cross {` works
158158
}
159159
if p.gc_mode == .unknown {
160-
if p.backend != .c || p.building_v || p.is_bare || p.ccompiler == 'msvc' {
160+
if p.backend != .c || p.building_v || p.is_bare {
161161
p.gc_mode = .no_gc
162162
p.build_options << ['-gc', 'none']
163163
} else {

0 commit comments

Comments
 (0)