compiler: rework flags & support win path spaces + more
							parent
							
								
									e8068b5e1d
								
							
						
					
					
						commit
						8ac0a2b2dd
					
				|  | @ -10,6 +10,9 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| fn (v mut V) cc() { | fn (v mut V) cc() { | ||||||
|  | 	// build any thirdparty obj files
 | ||||||
|  | 	v.build_thirdparty_obj_files() | ||||||
|  | 
 | ||||||
| 	// Just create a c file and exit
 | 	// Just create a c file and exit
 | ||||||
| 	if v.out_name.ends_with('.c') { | 	if v.out_name.ends_with('.c') { | ||||||
| 		os.mv(v.out_name_c, v.out_name) | 		os.mv(v.out_name_c, v.out_name) | ||||||
|  | @ -33,15 +36,6 @@ fn (v mut V) cc() { | ||||||
| 	v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name') | 	v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name') | ||||||
| 	mut a := [v.pref.cflags, '-std=gnu11', '-w'] // arguments for the C compiler
 | 	mut a := [v.pref.cflags, '-std=gnu11', '-w'] // arguments for the C compiler
 | ||||||
| 
 | 
 | ||||||
| 	mut seenflags := map[string]int |  | ||||||
| 	mut uniqueflags := []string |  | ||||||
| 	for f in v.table.flags { |  | ||||||
| 		seenflags[ f ] = seenflags[ f ] + 1 |  | ||||||
| 		if seenflags[ f ] > 1 { continue } |  | ||||||
| 		uniqueflags << f |  | ||||||
| 	} |  | ||||||
| 	flags := uniqueflags.join(' ') |  | ||||||
| 	// Set out name
 |  | ||||||
| 	if v.pref.is_so { | 	if v.pref.is_so { | ||||||
| 		a << '-shared -fPIC '// -Wl,-z,defs'
 | 		a << '-shared -fPIC '// -Wl,-z,defs'
 | ||||||
| 		v.out_name = v.out_name + '.so' | 		v.out_name = v.out_name + '.so' | ||||||
|  | @ -92,7 +86,7 @@ fn (v mut V) cc() { | ||||||
| 	// -I flags
 | 	// -I flags
 | ||||||
| 	/* | 	/* | ||||||
| mut args := '' | mut args := '' | ||||||
| 	for flag in v.table.flags { | 	for flag in v.get_os_cflags() { | ||||||
| 		if !flag.starts_with('-l') { | 		if !flag.starts_with('-l') { | ||||||
| 			args += flag | 			args += flag | ||||||
| 			args += ' ' | 			args += ' ' | ||||||
|  | @ -133,7 +127,9 @@ mut args := '' | ||||||
| 	if v.os == .mac { | 	if v.os == .mac { | ||||||
| 		a << '-mmacosx-version-min=10.7' | 		a << '-mmacosx-version-min=10.7' | ||||||
| 	} | 	} | ||||||
| 	a << flags | 	for flag in v.get_os_cflags() { | ||||||
|  | 		a << flag.format() | ||||||
|  | 	} | ||||||
| 	a << libs | 	a << libs | ||||||
| 	// macOS code can include objective C  TODO remove once objective C is replaced with C
 | 	// macOS code can include objective C  TODO remove once objective C is replaced with C
 | ||||||
| 	// Without these libs compilation will fail on Linux
 | 	// Without these libs compilation will fail on Linux
 | ||||||
|  | @ -224,9 +220,9 @@ fn (c mut V) cc_windows_cross() { | ||||||
| 	} | 	} | ||||||
| 	mut args := '-o $c.out_name -w -L. ' | 	mut args := '-o $c.out_name -w -L. ' | ||||||
| 	// -I flags
 | 	// -I flags
 | ||||||
| 	for flag in c.table.flags { | 	for flag in c.get_os_cflags() { | ||||||
| 		if !flag.starts_with('-l') { | 		if flag.name != '-l' { | ||||||
| 				args += flag | 				args += flag.format() | ||||||
| 				args += ' ' | 				args += ' ' | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -243,9 +239,9 @@ fn (c mut V) cc_windows_cross() { | ||||||
| 	} | 	} | ||||||
| 	args += ' $c.out_name_c ' | 	args += ' $c.out_name_c ' | ||||||
| 	// -l flags (libs)
 | 	// -l flags (libs)
 | ||||||
| 	for flag in c.table.flags { | 	for flag in c.get_os_cflags() { | ||||||
| 			if flag.starts_with('-l') { | 			if flag.name == '-l' { | ||||||
| 					args += flag | 					args += flag.format() | ||||||
| 					args += ' ' | 					args += ' ' | ||||||
| 			} | 			} | ||||||
| 	} | 	} | ||||||
|  | @ -289,6 +285,19 @@ fn (c mut V) cc_windows_cross() { | ||||||
| 	println('Done!') | 	println('Done!') | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn (c V) build_thirdparty_obj_files() { | ||||||
|  | 	for flag in c.get_os_cflags() { | ||||||
|  | 		if flag.value.ends_with('.o') { | ||||||
|  | 			if c.os == .msvc { | ||||||
|  | 				build_thirdparty_obj_file_with_msvc(flag.value) | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				build_thirdparty_obj_file(flag.value) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| fn find_c_compiler() string { | fn find_c_compiler() string { | ||||||
| 	args := env_vflags_and_os_args().join(' ') | 	args := env_vflags_and_os_args().join(' ') | ||||||
| 	defaultcc := find_c_compiler_default() | 	defaultcc := find_c_compiler_default() | ||||||
|  | @ -306,10 +315,6 @@ fn find_c_compiler_default() string { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn find_c_compiler_thirdparty_options() string { | fn find_c_compiler_thirdparty_options() string { | ||||||
| 	$if windows {	return '' } | 	$if windows { return '' } | ||||||
| 	return '-fPIC' | 	return '-fPIC' | ||||||
| } | } | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,115 @@ | ||||||
|  | // Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by an MIT license
 | ||||||
|  | // that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | module main | ||||||
|  | 
 | ||||||
|  | import os | ||||||
|  | 
 | ||||||
|  | // C flag
 | ||||||
|  | struct CFlag{ | ||||||
|  | 	os    string // eg. windows | darwin | linux
 | ||||||
|  | 	name  string // eg. -I
 | ||||||
|  | 	value string // eg. /path/to/incude
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // check if cflag is in table
 | ||||||
|  | fn (table &Table) has_cflag(cflag CFlag) bool { | ||||||
|  | 	for cf in table.cflags { | ||||||
|  | 		if cf.os == cflag.os && cf.name == cflag.name && cf.value == cflag.value { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // get flags for current os
 | ||||||
|  | fn (v V) get_os_cflags() []CFlag { | ||||||
|  | 	mut flags := []CFlag | ||||||
|  | 	for flag in v.table.cflags { | ||||||
|  | 		if flag.os == '' | ||||||
|  | 		|| (flag.os == 'linux' && v.os == .linux) | ||||||
|  | 		|| (flag.os == 'darwin' && v.os == .mac) | ||||||
|  | 		|| (flag.os == 'windows' && (v.os == .windows || v.os == .msvc)) { | ||||||
|  | 			flags << flag | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return flags | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // format flag
 | ||||||
|  | fn (cf &CFlag) format() string { | ||||||
|  | 	mut value := cf.value | ||||||
|  | 	// convert to absolute path
 | ||||||
|  | 	if cf.name == '-I' || cf.name == '-L' || value.ends_with('.o') { | ||||||
|  | 		value = '"'+os.realpath(value)+'"' | ||||||
|  | 	} | ||||||
|  | 	return '$cf.name $value'.trim_space() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // parse the flags to []CFlag
 | ||||||
|  | // Note: clean up big time (joe-c)
 | ||||||
|  | fn (table mut Table) parse_cflag(cflag string) { | ||||||
|  | 	allowed_flags := [ | ||||||
|  | 		'framework', | ||||||
|  | 		'library', | ||||||
|  | 		'I', 'l', 'L',  | ||||||
|  | 	] | ||||||
|  | 	mut flag := cflag.trim_space() | ||||||
|  | 	if flag == '' { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	mut fos := '' | ||||||
|  | 	mut name := '' | ||||||
|  | 	if flag.starts_with('linux') || flag.starts_with('darwin') || flag.starts_with('windows') { | ||||||
|  | 		pos := flag.index(' ') | ||||||
|  | 		fos = flag.left(pos).trim_space() | ||||||
|  | 		flag = flag.right(pos).trim_space() | ||||||
|  | 	} | ||||||
|  | 	for { | ||||||
|  | 		mut index := -1 | ||||||
|  | 		mut value := '' | ||||||
|  | 		if flag[0] == `-` { | ||||||
|  | 			for f in allowed_flags { | ||||||
|  | 				i := 1+f.len | ||||||
|  | 				if i < flag.len && f == flag.substr(1,i) { | ||||||
|  | 					name = flag.left(i).trim_space() | ||||||
|  | 					flag = flag.right(i).trim_space() | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		for i in [flag.index(' '), flag.index(',')] { | ||||||
|  | 			if index == -1 || (i != -1 && i < index) { | ||||||
|  | 				index = i | ||||||
|  | 			} | ||||||
|  | 		} if index != -1 && flag[index] == ` ` && flag[index+1] == `-` { | ||||||
|  | 			for f in allowed_flags { | ||||||
|  | 				i := index+f.len | ||||||
|  | 				if i < flag.len && f == flag.substr(index, i) { | ||||||
|  | 					index = i | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			value = flag.left(index).trim_space() | ||||||
|  | 			flag = flag.right(index).trim_space() | ||||||
|  | 		} else if index != -1 && index < flag.len-2 && flag[index] == `,` { | ||||||
|  | 			value = flag.left(index).trim_space() | ||||||
|  | 			flag = flag.right(index+1).trim_space() | ||||||
|  | 		} else { | ||||||
|  | 			value = flag.trim_space() | ||||||
|  | 			index = -1 | ||||||
|  | 		} | ||||||
|  | 		cf := CFlag{ | ||||||
|  | 			os:    fos, | ||||||
|  | 			name:  name, | ||||||
|  | 			value: value | ||||||
|  | 		} | ||||||
|  | 		if !table.has_cflag(cf) { | ||||||
|  | 			table.cflags << cf | ||||||
|  | 		} | ||||||
|  | 		if index == -1 { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -240,13 +240,13 @@ fn (g mut CGen) add_to_main(s string) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| fn build_thirdparty_obj_file(flag string) { | fn build_thirdparty_obj_file(path string) { | ||||||
| 	obj_path := flag.all_after(' ') | 	obj_path := os.realpath(path) | ||||||
| 	if os.file_exists(obj_path) { | 	if os.file_exists(obj_path) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	println('$obj_path not found, building it...') | 	println('$obj_path not found, building it...') | ||||||
| 	parent := os.dir( obj_path ) | 	parent := os.dir(obj_path) | ||||||
| 	files := os.ls(parent) | 	files := os.ls(parent) | ||||||
| 	mut cfiles := '' | 	mut cfiles := '' | ||||||
| 	for file in files { | 	for file in files { | ||||||
|  | @ -281,15 +281,15 @@ fn os_name_to_ifdef(name string) string { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn platform_postfix_to_ifdefguard(name string) string { | fn platform_postfix_to_ifdefguard(name string) string { | ||||||
|   switch name { | 	switch name { | ||||||
|     case '.v': return '' // no guard needed
 | 		case '.v': return '' // no guard needed
 | ||||||
|     case '_win.v': return '#ifdef _WIN32' | 		case '_win.v': return '#ifdef _WIN32' | ||||||
|     case '_nix.v': return '#ifndef _WIN32' | 		case '_nix.v': return '#ifndef _WIN32' | ||||||
|     case '_lin.v': return '#ifdef __linux__' | 		case '_lin.v': return '#ifdef __linux__' | ||||||
|     case '_mac.v': return '#ifdef __APPLE__' | 		case '_mac.v': return '#ifdef __APPLE__' | ||||||
|   } | 	} | ||||||
|   cerror('bad platform_postfix "$name"') | 	cerror('bad platform_postfix "$name"') | ||||||
|   return '' | 	return '' | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // C struct definitions, ordered
 | // C struct definitions, ordered
 | ||||||
|  | @ -383,4 +383,3 @@ fn sort_structs(types []Type) []Type { | ||||||
| 	} | 	} | ||||||
| 	return types_sorted | 	return types_sorted | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -141,46 +141,11 @@ fn (p mut Parser) chash() { | ||||||
| 	is_sig := p.is_sig() | 	is_sig := p.is_sig() | ||||||
| 	if hash.starts_with('flag ') { | 	if hash.starts_with('flag ') { | ||||||
| 		mut flag := hash.right(5) | 		mut flag := hash.right(5) | ||||||
| 		// No the right os? Skip!
 | 		// expand `@VROOT` `@VMOD` to absolute path
 | ||||||
| 		// mut ok := true
 | 		flag = flag.replace('@VROOT', p.vroot) | ||||||
| 		if hash.contains('linux') && p.os != .linux { | 		flag = flag.replace('@VMOD', ModPath) | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		else if hash.contains('darwin') && p.os != .mac { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		else if hash.contains('windows') && (p.os != .windows && p.os != .msvc) { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		// Remove "linux" etc from flag
 |  | ||||||
| 		if flag.contains('linux') || flag.contains('darwin') || flag.contains('windows') { |  | ||||||
| 			pos := flag.index(' ') |  | ||||||
| 			flag = flag.right(pos) |  | ||||||
| 		} |  | ||||||
| 		has_vroot := flag.contains('@VROOT') |  | ||||||
| 		flag = flag.trim_space().replace('@VROOT', p.vroot) |  | ||||||
| 		if p.table.flags.contains(flag) { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		// expand `@VMOD/pg/pg.o` to absolute path
 |  | ||||||
| 		has_vmod := flag.contains('@VMOD') |  | ||||||
| 		flag = flag.trim_space().replace('@VMOD', ModPath) |  | ||||||
| 		if p.table.flags.contains(flag) { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		p.log('adding flag "$flag"') | 		p.log('adding flag "$flag"') | ||||||
| 		// `@VROOT/thirdparty/glad/glad.o`, make sure it exists, otherwise build it
 | 		p.table.parse_cflag(flag) | ||||||
| 		if (has_vroot || has_vmod) && flag.contains('.o') { |  | ||||||
| 			flag = os.realpath( flag ) |  | ||||||
| 			//println( 'absolute filepath to objectfile is now: $flag | os is: $p.os ')
 |  | ||||||
| 			if p.os == .msvc { |  | ||||||
| 				build_thirdparty_obj_file_with_msvc(flag) |  | ||||||
| 			} |  | ||||||
| 			else { |  | ||||||
| 				build_thirdparty_obj_file(flag) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		p.table.flags << flag |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if hash.starts_with('include') { | 	if hash.starts_with('include') { | ||||||
|  |  | ||||||
|  | @ -325,7 +325,9 @@ fn (v mut V) compile() { | ||||||
|   cgen.save() |   cgen.save() | ||||||
| 	if v.pref.is_verbose { | 	if v.pref.is_verbose { | ||||||
| 		v.log('flags=') | 		v.log('flags=') | ||||||
| 		println(v.table.flags) | 		for flag in v.get_os_cflags() { | ||||||
|  | 			println(' * ' + flag.format()) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	v.cc() | 	v.cc() | ||||||
| } | } | ||||||
|  | @ -437,7 +439,7 @@ fn (v V) run_compiled_executable_and_exit() { | ||||||
| 	if v.pref.is_verbose { | 	if v.pref.is_verbose { | ||||||
| 		println('============ running $v.out_name ============') | 		println('============ running $v.out_name ============') | ||||||
| 	}	 | 	}	 | ||||||
| 	mut cmd := final_target_out_name(v.out_name).replace('.exe','') | 	mut cmd := '"' + final_target_out_name(v.out_name).replace('.exe','') + '"' | ||||||
| 	if os.args.len > 3 { | 	if os.args.len > 3 { | ||||||
| 		cmd += ' ' + os.args.right(3).join(' ') | 		cmd += ' ' + os.args.right(3).join(' ') | ||||||
| 	} | 	} | ||||||
|  | @ -781,9 +783,7 @@ fn new_v(args[]string) &V { | ||||||
| 	vroot := os.dir(os.executable()) | 	vroot := os.dir(os.executable()) | ||||||
| 	//println('VROOT=$vroot')
 | 	//println('VROOT=$vroot')
 | ||||||
| 	// v.exe's parent directory should contain vlib
 | 	// v.exe's parent directory should contain vlib
 | ||||||
| 	if os.dir_exists(vroot) && os.dir_exists(vroot + '/vlib/builtin') { | 	if !os.dir_exists(vroot) || !os.dir_exists(vroot + '/vlib/builtin') { | ||||||
| 
 |  | ||||||
| 	}  else { |  | ||||||
| 		println('vlib not found. It should be next to the V executable. ') | 		println('vlib not found. It should be next to the V executable. ') | ||||||
| 		println('Go to https://vlang.io to install V.') | 		println('Go to https://vlang.io to install V.') | ||||||
| 		exit(1) | 		exit(1) | ||||||
|  |  | ||||||
							
								
								
									
										139
									
								
								compiler/msvc.v
								
								
								
								
							
							
						
						
									
										139
									
								
								compiler/msvc.v
								
								
								
								
							|  | @ -207,11 +207,6 @@ 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
 | ||||||
|  | @ -305,99 +300,41 @@ pub fn (v mut V) cc_msvc() { | ||||||
| 	mut lib_paths := []string{} | 	mut lib_paths := []string{} | ||||||
| 	mut other_flags := []string{} | 	mut other_flags := []string{} | ||||||
| 
 | 
 | ||||||
| 	// Emily:
 | 	for flag in v.get_os_cflags() { | ||||||
| 	// this is a hack to try and support -l -L and object files
 | 		mut arg := flag.value | ||||||
| 	// passed on the command line
 | 		//println('fl: $flag.name | flag arg: $arg')
 | ||||||
| 	mut seenflags := map[string]int // no need to add the same flags more than once
 |  | ||||||
| 	for f in v.table.flags { |  | ||||||
| 		seenflags[ f ] = seenflags[ f ] + 1 |  | ||||||
| 		if seenflags[ f ] > 1 { continue } |  | ||||||
| 		// People like to put multiple flags per line (which really complicates things)
 |  | ||||||
| 		// ...so we need to handle that
 |  | ||||||
| 		mut rest := f |  | ||||||
| 
 | 
 | ||||||
| 		mut flags := []ParsedFlag{} | 		// We need to see if the flag contains -l
 | ||||||
| 		for { | 		// -l isnt recognised and these libs will be passed straight to the linker
 | ||||||
| 			mut base := rest | 		// by the compiler
 | ||||||
| 
 | 		if flag.name == '-l' { | ||||||
| 			fl := if rest.starts_with('-') { | 			if arg.ends_with('.dll') { | ||||||
| 				base = rest.right(2).trim_space() | 				cerror('MSVC cannot link against a dll (`#flag -l $arg`)') | ||||||
| 				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('-') |  | ||||||
| 			// dont break paths with hyphens
 |  | ||||||
| 			if lowest != 0  { |  | ||||||
| 				lowest = -1 |  | ||||||
| 			} |  | ||||||
| 			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 |  | ||||||
| 			} | 			} | ||||||
|  | 			// MSVC has no method of linking against a .dll
 | ||||||
|  | 			// TODO: we should look for .defs aswell
 | ||||||
|  | 			lib_lib := arg + '.lib' | ||||||
|  | 			real_libs << lib_lib | ||||||
| 		} | 		} | ||||||
| 
 | 		else if flag.name == '-I' { | ||||||
| 		for flag in flags { | 			inc_paths << ' ' + flag.format() + ' ' | ||||||
| 			fl := flag.f | 		} | ||||||
| 			mut arg := flag.arg | 		else if flag.name == '-L' { | ||||||
| 			if fl == '-I' || fl == '-L' { | 			lpath := flag.value | ||||||
| 				arg = os.realpath( arg ) | 			lib_paths << '"' + lpath + '"' | ||||||
| 			} | 			lib_paths << '"' + lpath + os.PathSeparator + 'msvc' + '"' | ||||||
| 			//println('fl: $fl | flag arg: $arg')
 | 			// The above allows putting msvc specific .lib files in a subfolder msvc/ ,
 | ||||||
| 
 | 			// where gcc will NOT find them, but cl will do...
 | ||||||
| 			// We need to see if the flag contains -l
 | 			// NB: gcc is smart enough to not need .lib files at all in most cases, the .dll is enough.
 | ||||||
| 			// -l isnt recognised and these libs will be passed straight to the linker
 | 			// When both a msvc .lib file and .dll file are present in the same folder,
 | ||||||
| 			// by the compiler
 | 			// as for example for glfw3, compilation with gcc would fail.
 | ||||||
| 			if fl == '-l' { | 		} | ||||||
| 				if arg.ends_with('.dll') { | 		else if flag.value.ends_with('.o') { | ||||||
| 					cerror('MSVC cannot link against a dll (`#flag -l $arg`)') | 			other_flags << flag.format().replace('.o', '.obj') | ||||||
| 				} | 		} | ||||||
| 				// MSVC has no method of linking against a .dll
 | 		else { | ||||||
| 				// TODO: we should look for .defs aswell
 | 			other_flags << arg | ||||||
| 				lib_lib := arg + '.lib' |  | ||||||
| 				real_libs << lib_lib |  | ||||||
| 			} |  | ||||||
| 			else if fl == '-I' { |  | ||||||
| 				inc_paths << ' -I "$arg" ' |  | ||||||
| 			} |  | ||||||
| 			else if fl == '-L' { |  | ||||||
| 				lpath := f.right(2).trim_space() |  | ||||||
| 				lib_paths << lpath |  | ||||||
| 				lib_paths << lpath + os.PathSeparator + 'msvc' |  | ||||||
| 				// The above allows putting msvc specific .lib files in a subfolder msvc/ ,
 |  | ||||||
| 				// where gcc will NOT find them, but cl will do...
 |  | ||||||
| 				// NB: gcc is smart enough to not need .lib files at all in most cases, the .dll is enough.
 |  | ||||||
| 				// When both a msvc .lib file and .dll file are present in the same folder,
 |  | ||||||
| 				// as for example for glfw3, compilation with gcc would fail.
 |  | ||||||
| 			} |  | ||||||
| 			else if arg.ends_with('.o') { |  | ||||||
| 				// msvc expects .obj not .o
 |  | ||||||
| 				other_flags << arg + 'bj' |  | ||||||
| 			}  |  | ||||||
| 			else { |  | ||||||
| 				other_flags << arg |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		 |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Include the base paths
 | 	// Include the base paths
 | ||||||
|  | @ -463,18 +400,16 @@ pub fn (v mut V) cc_msvc() { | ||||||
| 	os.rm(out_name_obj) | 	os.rm(out_name_obj) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn build_thirdparty_obj_file_with_msvc(flag string) { | fn build_thirdparty_obj_file_with_msvc(path string) { | ||||||
| 	msvc := find_msvc() or { | 	msvc := find_msvc() or { | ||||||
| 		println('Could not find visual studio') | 		println('Could not find visual studio') | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	mut obj_path := flag.all_after(' ') | 	// msvc expects .obj not .o
 | ||||||
|  | 	mut obj_path := '${path}bj' | ||||||
| 
 | 
 | ||||||
| 	if obj_path.ends_with('.o') { | 	obj_path = os.realpath(obj_path) | ||||||
| 		// msvc expects .obj not .o
 |  | ||||||
| 		obj_path = obj_path + 'bj' |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if os.file_exists(obj_path) { | 	if os.file_exists(obj_path) { | ||||||
| 		println('$obj_path already build.') | 		println('$obj_path already build.') | ||||||
|  | @ -482,14 +417,14 @@ fn build_thirdparty_obj_file_with_msvc(flag string) { | ||||||
| 	}  | 	}  | ||||||
| 
 | 
 | ||||||
| 	println('$obj_path not found, building it (with msvc)...')  | 	println('$obj_path not found, building it (with msvc)...')  | ||||||
| 	parent := os.dir( obj_path ) | 	parent := os.dir(obj_path) | ||||||
| 	files := os.ls(parent) | 	files := os.ls(parent) | ||||||
| 
 | 
 | ||||||
| 	mut cfiles := ''  | 	mut cfiles := ''  | ||||||
| 	for file in files { | 	for file in files { | ||||||
| 		if file.ends_with('.c') {  | 		if file.ends_with('.c') {  | ||||||
| 			cfiles += '"' + os.realpath( parent + os.PathSeparator + file )  + '" ' | 			cfiles += '"' + os.realpath( parent + os.PathSeparator + file )  + '" ' | ||||||
| 		}  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	include_string := '-I "$msvc.ucrt_include_path" -I "$msvc.vs_include_path" -I "$msvc.um_include_path" -I "$msvc.shared_include_path"' | 	include_string := '-I "$msvc.ucrt_include_path" -I "$msvc.vs_include_path" -I "$msvc.um_include_path" -I "$msvc.shared_include_path"' | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ mut: | ||||||
| 	modules      []string // List of all modules registered by the application
 | 	modules      []string // List of all modules registered by the application
 | ||||||
| 	imports      []string // List of all imports
 | 	imports      []string // List of all imports
 | ||||||
| 	file_imports []FileImportTable // List of imports for file
 | 	file_imports []FileImportTable // List of imports for file
 | ||||||
| 	flags        []string //  ['-framework Cocoa', '-lglfw3']
 | 	cflags       []CFlag  // ['-framework Cocoa', '-lglfw3']
 | ||||||
| 	fn_cnt       int //atomic
 | 	fn_cnt       int //atomic
 | ||||||
| 	obfuscate    bool | 	obfuscate    bool | ||||||
| } | } | ||||||
|  | @ -78,8 +78,6 @@ mut: | ||||||
| 	scope_level     int | 	scope_level     int | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| struct Type { | struct Type { | ||||||
| mut: | mut: | ||||||
| 	mod            string | 	mod            string | ||||||
|  | @ -106,7 +104,6 @@ struct TypeNode { | ||||||
| 	typ Type | 	typ Type | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| // For debugging types
 | // For debugging types
 | ||||||
| fn (t Type) str() string { | fn (t Type) str() string { | ||||||
| 	mut s := 'type "$t.name" {' | 	mut s := 'type "$t.name" {' | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue