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 {
|
||||
fullargs := env_vflags_and_os_args()
|
||||
mut cflags := get_cmdline_cflags(fullargs)
|
||||
mut cflags := get_cmdline_multiple_values(fullargs,'-cflags')
|
||||
$if !windows {
|
||||
cflags += ' -fPIC'
|
||||
cflags << '-fPIC'
|
||||
}
|
||||
if '-m32' in fullargs {
|
||||
cflags += ' -m32'
|
||||
cflags << '-m32'
|
||||
}
|
||||
return cflags
|
||||
return cflags.join(' ')
|
||||
}
|
||||
|
||||
fn get_cmdline_cflags(args []string) string {
|
||||
mut cflags := ''
|
||||
fn get_cmdline_multiple_values(args []string, optname string) []string {
|
||||
mut flags := []string
|
||||
for ci, cv in args {
|
||||
if cv == '-cflags' {
|
||||
cflags += args[ci + 1] + ' '
|
||||
if cv == optname {
|
||||
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 {
|
||||
|
|
|
@ -19,10 +19,18 @@ pub fn (c &CFlag) str() string {
|
|||
// get flags for current os
|
||||
fn (v &V) get_os_cflags() []CFlag {
|
||||
mut flags := []CFlag
|
||||
mut ctimedefines := []string
|
||||
if v.compile_defines.len > 0 {
|
||||
ctimedefines << v.compile_defines
|
||||
}
|
||||
|
||||
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) {
|
||||
flags << flag
|
||||
}
|
||||
if flag.os in ctimedefines {
|
||||
flags << flag
|
||||
}
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
@ -66,7 +74,7 @@ fn (table &Table) has_cflag(cflag CFlag) bool {
|
|||
|
||||
// parse the flags to (table.cflags) []CFlag
|
||||
// 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', ]
|
||||
flag_orig := cflag.trim_space()
|
||||
mut flag := flag_orig
|
||||
|
@ -74,7 +82,10 @@ fn (table mut Table) parse_cflag(cflag string, mod string) ?bool {
|
|||
return true
|
||||
}
|
||||
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 {
|
||||
return none
|
||||
}
|
||||
|
|
|
@ -351,7 +351,11 @@ fn os_name_to_ifdef(name string) string {
|
|||
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 {
|
||||
'.v'{
|
||||
''
|
||||
|
|
|
@ -20,6 +20,7 @@ fn (p mut Parser) comp_time() {
|
|||
}
|
||||
name := p.check_name()
|
||||
p.fspace()
|
||||
|
||||
if name in supported_platforms {
|
||||
ifdef_name := os_name_to_ifdef(name)
|
||||
if name == 'mac' {
|
||||
|
@ -99,6 +100,9 @@ fn (p mut Parser) comp_time() {
|
|||
else if name == '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 {
|
||||
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('@VMOD', v_modules_path)
|
||||
// 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)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -749,7 +749,7 @@ fn (p mut Parser) verify_fn_before_call(f &Fn) {
|
|||
// p.tok == fn_name
|
||||
fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type string) {
|
||||
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 {
|
||||
p.cgen.nogen = true
|
||||
}
|
||||
|
|
|
@ -76,6 +76,10 @@ pub mut:
|
|||
gen_parser_idx map[string]int
|
||||
cached_mods []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 {
|
||||
|
@ -117,7 +121,6 @@ pub mut:
|
|||
// This is on by default, since a vast majority of users do not
|
||||
// work on the builtin module itself.
|
||||
// generating_vh bool
|
||||
comptime_define string // -D vfmt for `if $vfmt {`
|
||||
fast bool // use tcc/x64 codegen
|
||||
enable_globals bool // allow __global for low level code
|
||||
// is_fmt bool
|
||||
|
@ -251,7 +254,20 @@ pub fn (v mut V) compile() {
|
|||
else {
|
||||
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)
|
||||
|
||||
if !v.pref.is_bare {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
return res
|
||||
|
@ -905,8 +934,6 @@ pub fn new_v(args []string) &V {
|
|||
vgen_buf.writeln('module vgen\nimport strings')
|
||||
joined_args := args.join(' ')
|
||||
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 dir := args.last()
|
||||
if 'run' in args {
|
||||
|
@ -1031,7 +1058,11 @@ pub fn new_v(args []string) &V {
|
|||
exit(1)
|
||||
}
|
||||
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_name := os.filename(rdir)
|
||||
if '-bare' in args {
|
||||
|
@ -1073,7 +1104,6 @@ pub fn new_v(args []string) &V {
|
|||
cflags: cflags
|
||||
ccompiler: find_c_compiler()
|
||||
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib'))
|
||||
comptime_define: comptime_define
|
||||
// is_fmt: comptime_define == 'vfmt'
|
||||
|
||||
user_mod_path: user_mod_path
|
||||
|
@ -1104,7 +1134,9 @@ pub fn new_v(args []string) &V {
|
|||
vroot: vroot
|
||||
pref: pref
|
||||
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"')
|
||||
}
|
||||
path_platform = path_ending
|
||||
path_pcguard = platform_postfix_to_ifdefguard(path_ending)
|
||||
path_pcguard = v.platform_postfix_to_ifdefguard(path_ending)
|
||||
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))
|
||||
p = {
|
||||
p |
|
||||
|
|
Loading…
Reference in New Issue