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