compiler: support for custom flags
[if custom]fn..{} , #flag custom, $if custom {}pull/3195/head^2
parent
42b1660c7e
commit
6e130cd446
|
@ -486,24 +486,47 @@ fn find_c_compiler_default() string {
|
||||||
|
|
||||||
fn find_c_compiler_thirdparty_options() string {
|
fn find_c_compiler_thirdparty_options() string {
|
||||||
fullargs := env_vflags_and_os_args()
|
fullargs := env_vflags_and_os_args()
|
||||||
mut cflags := get_cmdline_cflags(fullargs)
|
mut cflags := get_cmdline_multiple_values(fullargs,'-cflags')
|
||||||
$if !windows {
|
$if !windows {
|
||||||
cflags += ' -fPIC'
|
cflags << '-fPIC'
|
||||||
}
|
}
|
||||||
if '-m32' in fullargs {
|
if '-m32' in fullargs {
|
||||||
cflags += ' -m32'
|
cflags << '-m32'
|
||||||
}
|
}
|
||||||
return cflags
|
return cflags.join(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cmdline_cflags(args []string) string {
|
fn get_cmdline_multiple_values(args []string, optname string) []string {
|
||||||
mut cflags := ''
|
mut flags := []string
|
||||||
for ci, cv in args {
|
for ci, cv in args {
|
||||||
if cv == '-cflags' {
|
if cv == optname {
|
||||||
cflags += args[ci + 1] + ' '
|
flags << args[ci + 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cflags
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_defines(defines []string) ([]string,[]string) {
|
||||||
|
// '-d abc -d xyz=1 -d qwe=0' should produce:
|
||||||
|
// compile_defines: ['abc','xyz']
|
||||||
|
// compile_defines_all ['abc','xyz','qwe']
|
||||||
|
mut compile_defines := []string
|
||||||
|
mut compile_defines_all := []string
|
||||||
|
for dfn in defines {
|
||||||
|
dfn_parts := dfn.split('=')
|
||||||
|
if dfn_parts.len == 1 {
|
||||||
|
compile_defines << dfn
|
||||||
|
compile_defines_all << dfn
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if dfn_parts.len == 2 {
|
||||||
|
compile_defines_all << dfn_parts[0]
|
||||||
|
if dfn_parts[1] == '1' {
|
||||||
|
compile_defines << dfn_parts[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return compile_defines, compile_defines_all
|
||||||
}
|
}
|
||||||
|
|
||||||
fn missing_compiler_info() string {
|
fn missing_compiler_info() string {
|
||||||
|
|
|
@ -19,10 +19,18 @@ pub fn (c &CFlag) str() string {
|
||||||
// get flags for current os
|
// get flags for current os
|
||||||
fn (v &V) get_os_cflags() []CFlag {
|
fn (v &V) get_os_cflags() []CFlag {
|
||||||
mut flags := []CFlag
|
mut flags := []CFlag
|
||||||
|
mut ctimedefines := []string
|
||||||
|
if v.compile_defines.len > 0 {
|
||||||
|
ctimedefines << v.compile_defines
|
||||||
|
}
|
||||||
|
|
||||||
for flag in v.table.cflags {
|
for flag in v.table.cflags {
|
||||||
if flag.os == '' || (flag.os == 'linux' && v.os == .linux) || (flag.os == 'darwin' && v.os == .mac) || (flag.os == 'freebsd' && v.os == .freebsd) || (flag.os == 'windows' && v.os == .windows) {
|
if flag.os == '' || (flag.os == 'linux' && v.os == .linux) || (flag.os == 'darwin' && v.os == .mac) || (flag.os == 'freebsd' && v.os == .freebsd) || (flag.os == 'windows' && v.os == .windows) {
|
||||||
flags << flag
|
flags << flag
|
||||||
}
|
}
|
||||||
|
if flag.os in ctimedefines {
|
||||||
|
flags << flag
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
@ -66,7 +74,7 @@ fn (table &Table) has_cflag(cflag CFlag) bool {
|
||||||
|
|
||||||
// parse the flags to (table.cflags) []CFlag
|
// parse the flags to (table.cflags) []CFlag
|
||||||
// Note: clean up big time (joe-c)
|
// Note: clean up big time (joe-c)
|
||||||
fn (table mut Table) parse_cflag(cflag string, mod string) ?bool {
|
fn (table mut Table) parse_cflag(cflag string, mod string, ctimedefines []string) ?bool {
|
||||||
allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L', ]
|
allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L', ]
|
||||||
flag_orig := cflag.trim_space()
|
flag_orig := cflag.trim_space()
|
||||||
mut flag := flag_orig
|
mut flag := flag_orig
|
||||||
|
@ -74,7 +82,10 @@ fn (table mut Table) parse_cflag(cflag string, mod string) ?bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
mut fos := ''
|
mut fos := ''
|
||||||
if flag.starts_with('linux') || flag.starts_with('darwin') || flag.starts_with('freebsd') || flag.starts_with('windows') {
|
mut allowed_os_overrides := ['linux','darwin','freebsd','windows']
|
||||||
|
allowed_os_overrides << ctimedefines
|
||||||
|
for os_override in allowed_os_overrides {
|
||||||
|
if !flag.starts_with( os_override ) { continue }
|
||||||
pos := flag.index(' ') or {
|
pos := flag.index(' ') or {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,7 +351,11 @@ fn os_name_to_ifdef(name string) string {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
fn platform_postfix_to_ifdefguard(name string) string {
|
fn (v &V) platform_postfix_to_ifdefguard(name string) string {
|
||||||
|
if name.starts_with('custom '){
|
||||||
|
cdefine := name.replace('custom ','')
|
||||||
|
return '#ifdef CUSTOM_DEFINE_${cdefine}'
|
||||||
|
}
|
||||||
s := match name {
|
s := match name {
|
||||||
'.v'{
|
'.v'{
|
||||||
''
|
''
|
||||||
|
|
|
@ -20,6 +20,7 @@ fn (p mut Parser) comp_time() {
|
||||||
}
|
}
|
||||||
name := p.check_name()
|
name := p.check_name()
|
||||||
p.fspace()
|
p.fspace()
|
||||||
|
|
||||||
if name in supported_platforms {
|
if name in supported_platforms {
|
||||||
ifdef_name := os_name_to_ifdef(name)
|
ifdef_name := os_name_to_ifdef(name)
|
||||||
if name == 'mac' {
|
if name == 'mac' {
|
||||||
|
@ -99,6 +100,9 @@ fn (p mut Parser) comp_time() {
|
||||||
else if name == 'clang' {
|
else if name == 'clang' {
|
||||||
p.comptime_if_block('__clang__')
|
p.comptime_if_block('__clang__')
|
||||||
}
|
}
|
||||||
|
else if p.v.compile_defines_all.len > 0 && name in p.v.compile_defines_all {
|
||||||
|
p.comptime_if_block('CUSTOM_DEFINE_${name}')
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
println('Supported platforms:')
|
println('Supported platforms:')
|
||||||
println(supported_platforms)
|
println(supported_platforms)
|
||||||
|
@ -209,7 +213,7 @@ fn (p mut Parser) chash() {
|
||||||
flag = flag.replace('@VLIB_PATH', p.pref.vlib_path)
|
flag = flag.replace('@VLIB_PATH', p.pref.vlib_path)
|
||||||
flag = flag.replace('@VMOD', v_modules_path)
|
flag = flag.replace('@VMOD', v_modules_path)
|
||||||
// p.log('adding flag "$flag"')
|
// p.log('adding flag "$flag"')
|
||||||
_ = p.table.parse_cflag(flag, p.mod) or {
|
_ = p.table.parse_cflag(flag, p.mod, p.v.compile_defines_all ) or {
|
||||||
p.error_with_token_index(err, p.cur_tok_index() - 1)
|
p.error_with_token_index(err, p.cur_tok_index() - 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -749,7 +749,7 @@ fn (p mut Parser) verify_fn_before_call(f &Fn) {
|
||||||
// p.tok == fn_name
|
// p.tok == fn_name
|
||||||
fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type string) {
|
fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type string) {
|
||||||
p.verify_fn_before_call(f)
|
p.verify_fn_before_call(f)
|
||||||
is_comptime_define := f.comptime_define != '' && f.comptime_define != p.pref.comptime_define
|
is_comptime_define := f.comptime_define != '' && !(f.comptime_define in p.v.compile_defines )
|
||||||
if is_comptime_define {
|
if is_comptime_define {
|
||||||
p.cgen.nogen = true
|
p.cgen.nogen = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,10 @@ pub mut:
|
||||||
gen_parser_idx map[string]int
|
gen_parser_idx map[string]int
|
||||||
cached_mods []string
|
cached_mods []string
|
||||||
module_lookup_paths []string
|
module_lookup_paths []string
|
||||||
|
|
||||||
|
// -d vfmt and -d another=0 for `$if vfmt { will execute }` and `$if another { will NOT get here }`
|
||||||
|
compile_defines []string // just ['vfmt']
|
||||||
|
compile_defines_all []string // contains both: ['vfmt','another']
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Preferences {
|
struct Preferences {
|
||||||
|
@ -117,7 +121,6 @@ pub mut:
|
||||||
// This is on by default, since a vast majority of users do not
|
// This is on by default, since a vast majority of users do not
|
||||||
// work on the builtin module itself.
|
// work on the builtin module itself.
|
||||||
// generating_vh bool
|
// generating_vh bool
|
||||||
comptime_define string // -D vfmt for `if $vfmt {`
|
|
||||||
fast bool // use tcc/x64 codegen
|
fast bool // use tcc/x64 codegen
|
||||||
enable_globals bool // allow __global for low level code
|
enable_globals bool // allow __global for low level code
|
||||||
// is_fmt bool
|
// is_fmt bool
|
||||||
|
@ -251,7 +254,20 @@ pub fn (v mut V) compile() {
|
||||||
else {
|
else {
|
||||||
cgen.genln('#include <stdint.h>')
|
cgen.genln('#include <stdint.h>')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.compile_defines_all.len > 0 {
|
||||||
|
cgen.genln('')
|
||||||
|
cgen.genln('// All custom defines : ' + v.compile_defines_all.join(','))
|
||||||
|
cgen.genln('// Turned ON custom defines: ' + v.compile_defines.join(','))
|
||||||
|
for cdefine in v.compile_defines {
|
||||||
|
cgen.genln('#define CUSTOM_DEFINE_${cdefine}')
|
||||||
|
}
|
||||||
|
cgen.genln('//')
|
||||||
|
cgen.genln('')
|
||||||
|
}
|
||||||
|
|
||||||
cgen.genln(c_builtin_types)
|
cgen.genln(c_builtin_types)
|
||||||
|
|
||||||
if !v.pref.is_bare {
|
if !v.pref.is_bare {
|
||||||
cgen.genln(c_headers)
|
cgen.genln(c_headers)
|
||||||
}
|
}
|
||||||
|
@ -638,6 +654,19 @@ pub fn (v &V) v_files_from_dir(dir string) []string {
|
||||||
if file.ends_with('_c.v') && v.os == .js {
|
if file.ends_with('_c.v') && v.os == .js {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if v.compile_defines_all.len > 0 && file.contains('_d_') {
|
||||||
|
mut allowed := false
|
||||||
|
for cdefine in v.compile_defines {
|
||||||
|
file_postfix := '_d_${cdefine}.v'
|
||||||
|
if file.ends_with(file_postfix) {
|
||||||
|
allowed = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !allowed {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
res << filepath.join(dir,file)
|
res << filepath.join(dir,file)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
@ -905,8 +934,6 @@ pub fn new_v(args []string) &V {
|
||||||
vgen_buf.writeln('module vgen\nimport strings')
|
vgen_buf.writeln('module vgen\nimport strings')
|
||||||
joined_args := args.join(' ')
|
joined_args := args.join(' ')
|
||||||
target_os := get_arg(joined_args, 'os', '')
|
target_os := get_arg(joined_args, 'os', '')
|
||||||
comptime_define := get_arg(joined_args, 'd', '')
|
|
||||||
// println('comptimedefine=$comptime_define')
|
|
||||||
mut out_name := get_arg(joined_args, 'o', 'a.out')
|
mut out_name := get_arg(joined_args, 'o', 'a.out')
|
||||||
mut dir := args.last()
|
mut dir := args.last()
|
||||||
if 'run' in args {
|
if 'run' in args {
|
||||||
|
@ -1031,7 +1058,11 @@ pub fn new_v(args []string) &V {
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
mut out_name_c := get_vtmp_filename(out_name, '.tmp.c')
|
mut out_name_c := get_vtmp_filename(out_name, '.tmp.c')
|
||||||
cflags := get_cmdline_cflags(args)
|
cflags := get_cmdline_multiple_values(args, '-cflags').join(' ')
|
||||||
|
|
||||||
|
defines := get_cmdline_multiple_values(args, '-d')
|
||||||
|
compile_defines, compile_defines_all := parse_defines( defines )
|
||||||
|
|
||||||
rdir := os.realpath(dir)
|
rdir := os.realpath(dir)
|
||||||
rdir_name := os.filename(rdir)
|
rdir_name := os.filename(rdir)
|
||||||
if '-bare' in args {
|
if '-bare' in args {
|
||||||
|
@ -1073,7 +1104,6 @@ pub fn new_v(args []string) &V {
|
||||||
cflags: cflags
|
cflags: cflags
|
||||||
ccompiler: find_c_compiler()
|
ccompiler: find_c_compiler()
|
||||||
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib'))
|
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib'))
|
||||||
comptime_define: comptime_define
|
|
||||||
// is_fmt: comptime_define == 'vfmt'
|
// is_fmt: comptime_define == 'vfmt'
|
||||||
|
|
||||||
user_mod_path: user_mod_path
|
user_mod_path: user_mod_path
|
||||||
|
@ -1105,6 +1135,8 @@ pub fn new_v(args []string) &V {
|
||||||
pref: pref
|
pref: pref
|
||||||
mod: mod
|
mod: mod
|
||||||
vgen_buf: vgen_buf
|
vgen_buf: vgen_buf
|
||||||
|
compile_defines: compile_defines
|
||||||
|
compile_defines_all: compile_defines_all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,10 +155,22 @@ fn (v mut V) new_parser_from_file(path string) Parser {
|
||||||
println('warning: use "$p" file name instead of "$path"')
|
println('warning: use "$p" file name instead of "$path"')
|
||||||
}
|
}
|
||||||
path_platform = path_ending
|
path_platform = path_ending
|
||||||
path_pcguard = platform_postfix_to_ifdefguard(path_ending)
|
path_pcguard = v.platform_postfix_to_ifdefguard(path_ending)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.compile_defines.len > 0 {
|
||||||
|
for cdefine in v.compile_defines {
|
||||||
|
custom_path_ending := '_d_${cdefine}.v'
|
||||||
|
if path.ends_with(custom_path_ending){
|
||||||
|
path_platform = custom_path_ending
|
||||||
|
path_pcguard = v.platform_postfix_to_ifdefguard('custom $cdefine')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mut p := v.new_parser(new_scanner_file(path))
|
mut p := v.new_parser(new_scanner_file(path))
|
||||||
p = {
|
p = {
|
||||||
p |
|
p |
|
||||||
|
|
Loading…
Reference in New Issue