compiler: fix MSVC flag parsing
parent
9ff8793666
commit
151686501d
|
@ -204,6 +204,11 @@ fn find_msvc() ?MsvcResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ParsedFlag {
|
||||||
|
f string
|
||||||
|
arg string
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
@ -296,33 +301,76 @@ pub fn (v mut V) cc_msvc() {
|
||||||
// this is a hack to try and support -l -L and object files
|
// this is a hack to try and support -l -L and object files
|
||||||
// passed on the command line
|
// passed on the command line
|
||||||
for f in v.table.flags {
|
for f in v.table.flags {
|
||||||
|
// People like to put multiple flags per line (which really complicates things)
|
||||||
|
// ...so we need to handle that
|
||||||
|
mut rest := f
|
||||||
|
|
||||||
|
mut flags := []ParsedFlag{}
|
||||||
|
for {
|
||||||
|
mut base := rest
|
||||||
|
|
||||||
|
fl := if rest.starts_with('-') {
|
||||||
|
base = rest.right(2).trim_space()
|
||||||
|
rest.left(2)
|
||||||
|
} else {
|
||||||
|
''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which ever one of these is lowest we use
|
||||||
|
// TODO: we really shouldnt support all of these cmon
|
||||||
|
mut lowest := base.index('-')
|
||||||
|
for x in [base.index(' '), base.index(',')] {
|
||||||
|
if (x < lowest && x != -1) || lowest == -1 {
|
||||||
|
lowest = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arg := if lowest != -1 {
|
||||||
|
rest = base.right(lowest).trim_space().trim(`,`)
|
||||||
|
base.left(lowest).trim_space().trim(`,`)
|
||||||
|
} else {
|
||||||
|
rest = ''
|
||||||
|
base.trim_space()
|
||||||
|
}
|
||||||
|
|
||||||
|
flags << ParsedFlag {
|
||||||
|
fl, arg
|
||||||
|
}
|
||||||
|
|
||||||
|
if rest.len == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for flag in flags {
|
||||||
|
fl := flag.f
|
||||||
|
arg := flag.arg
|
||||||
// We need to see if the flag contains -l
|
// We need to see if the flag contains -l
|
||||||
// -l isnt recognised and these libs will be passed straight to the linker
|
// -l isnt recognised and these libs will be passed straight to the linker
|
||||||
// by the compiler
|
// by the compiler
|
||||||
if f.starts_with('-l') {
|
if fl == '-l' {
|
||||||
lib_base := f.right(2).trim_space()
|
if arg.ends_with('.dll') {
|
||||||
|
panic('MSVC cannot link against a dll (`#flag -l $arg`)')
|
||||||
if lib_base.ends_with('.dll') {
|
|
||||||
panic('MSVC cannot link against a dll (`#flag -l $lib_base`)')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MSVC has no method of linking against a .dll
|
// MSVC has no method of linking against a .dll
|
||||||
// TODO: we should look for .defs aswell
|
// TODO: we should look for .defs aswell
|
||||||
lib_lib := lib_base + '.lib'
|
lib_lib := arg + '.lib'
|
||||||
real_libs << lib_lib
|
real_libs << lib_lib
|
||||||
}
|
}
|
||||||
else if f.starts_with('-L') {
|
else if fl == '-L' {
|
||||||
lib_paths << f.right(2).trim_space()
|
lib_paths << f.right(2).trim_space()
|
||||||
}
|
}
|
||||||
else if f.ends_with('.o') {
|
else if arg.ends_with('.o') {
|
||||||
// msvc expects .obj not .o
|
// msvc expects .obj not .o
|
||||||
other_flags << f + 'bj'
|
other_flags << arg + 'bj'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
other_flags << f
|
other_flags << arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Include the base paths
|
// Include the base paths
|
||||||
a << '-I "$r.ucrt_include_path" -I "$r.vs_include_path" -I "$r.um_include_path" -I "$r.shared_include_path"'
|
a << '-I "$r.ucrt_include_path" -I "$r.vs_include_path" -I "$r.um_include_path" -I "$r.shared_include_path"'
|
||||||
|
|
||||||
|
@ -369,9 +417,10 @@ pub fn (v mut V) cc_msvc() {
|
||||||
|
|
||||||
if !v.pref.is_debug && v.out_name_c != 'v.c' && v.out_name_c != 'v_macos.c' {
|
if !v.pref.is_debug && 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')
|
||||||
os.rm('$out_name_obj')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always remove the object file - it is completely unnecessary
|
||||||
|
os.rm('$out_name_obj')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_thirdparty_obj_file_with_msvc(flag string) {
|
fn build_thirdparty_obj_file_with_msvc(flag string) {
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
fn test_flag_parsing() {
|
||||||
|
mut rest := '-lGlfw -f gl2,-ltest_nice_meme,-l cc,-Ldl test.o a.o ' //, whatever.o'
|
||||||
|
result := ['-l', 'Glfw',
|
||||||
|
'-f', 'gl2',
|
||||||
|
'-l', 'test_nice_meme',
|
||||||
|
'-l', 'cc',
|
||||||
|
'-L', 'dl',
|
||||||
|
'', 'test.o',
|
||||||
|
'', 'a.o']
|
||||||
|
|
||||||
|
mut flags := []string
|
||||||
|
for {
|
||||||
|
mut base := rest
|
||||||
|
|
||||||
|
fl := if rest.starts_with('-') {
|
||||||
|
base = rest.right(2).trim_space()
|
||||||
|
rest.left(2)
|
||||||
|
} else {
|
||||||
|
''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which ever one of these is lowest we use
|
||||||
|
// TODO: we really shouldnt support all of these cmon
|
||||||
|
mut lowest := base.index('-')
|
||||||
|
for x in [base.index(' '), base.index(',')] {
|
||||||
|
if (x < lowest && x != -1) || lowest == -1 {
|
||||||
|
lowest = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arg := if lowest != -1 {
|
||||||
|
rest = base.right(lowest).trim_space().trim(`,`)
|
||||||
|
base.left(lowest).trim_space().trim(`,`)
|
||||||
|
} else {
|
||||||
|
rest = ''
|
||||||
|
base.trim_space()
|
||||||
|
}
|
||||||
|
|
||||||
|
flags << fl
|
||||||
|
flags << arg
|
||||||
|
|
||||||
|
if rest.len == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, f in flags {
|
||||||
|
assert f == result[i]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue