show an info message if a C compiler is not installed
parent
e31d892598
commit
9e19472c33
|
@ -38,11 +38,10 @@
|
||||||
- declarative ui with hot reload (similar to swiftui)
|
- declarative ui with hot reload (similar to swiftui)
|
||||||
- "building a simple blog with vweb" tutorial + youtube video
|
- "building a simple blog with vweb" tutorial + youtube video
|
||||||
+ fix interfaces
|
+ fix interfaces
|
||||||
- merge v.c and v_win.c
|
|
||||||
+ fast.vlang.io
|
+ fast.vlang.io
|
||||||
+ bare metal support
|
+ bare metal support
|
||||||
+ inline assembly
|
+ inline assembly
|
||||||
+ x64 machine code generation (ELF)
|
+ x64 machine code generation (ELF)
|
||||||
- require explicit C.fn definitions, add all missing definitions
|
+ require explicit C.fn definitions, add all missing definitions
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
|
fn test_fn() {
|
||||||
|
println('test fn')
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println('x64 test')
|
println('x64 test')
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
println('Hello world from V x64 machine code generator!')
|
println('Hello world from V x64 machine code generator!')
|
||||||
}
|
}
|
||||||
println('Hello again!')
|
println('Hello again!')
|
||||||
|
test_fn()
|
||||||
|
println('dne')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_fn() {
|
|
||||||
println('test fn')
|
|
||||||
}
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn test_split() {
|
||||||
assert vals.len == 2
|
assert vals.len == 2
|
||||||
assert vals[0] == 'volt/twitch.v'
|
assert vals[0] == 'volt/twitch.v'
|
||||||
assert vals[1] == '34'
|
assert vals[1] == '34'
|
||||||
// /////////
|
// /////////
|
||||||
s = '2018-01-01z13:01:02'
|
s = '2018-01-01z13:01:02'
|
||||||
vals = s.split('z')
|
vals = s.split('z')
|
||||||
assert vals.len == 2
|
assert vals.len == 2
|
||||||
|
@ -491,13 +491,13 @@ fn test_raw() {
|
||||||
lines := raw.split('\n')
|
lines := raw.split('\n')
|
||||||
assert lines.len == 1
|
assert lines.len == 1
|
||||||
println('raw string: "$raw"')
|
println('raw string: "$raw"')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_escape() {
|
fn test_escape() {
|
||||||
// TODO
|
// TODO
|
||||||
//a := 10
|
//a := 10
|
||||||
//println("\"$a")
|
//println("\"$a")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_atoi() {
|
fn test_atoi() {
|
||||||
assert '234232'.int() == 234232
|
assert '234232'.int() == 234232
|
||||||
|
@ -506,8 +506,8 @@ fn test_atoi() {
|
||||||
for n in -10000 .. 100000 {
|
for n in -10000 .. 100000 {
|
||||||
s := n.str()
|
s := n.str()
|
||||||
assert s.int() == n
|
assert s.int() == n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_raw_inter() {
|
fn test_raw_inter() {
|
||||||
world := 'world'
|
world := 'world'
|
||||||
|
@ -523,6 +523,6 @@ fn test_c_r() {
|
||||||
println('$c')
|
println('$c')
|
||||||
r := 50
|
r := 50
|
||||||
println('$r')
|
println('$r')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
fn todo() {
|
fn todo() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_mingw_installed() bool {
|
fn no_mingw_installed() bool {
|
||||||
$if !windows {
|
$if !windows {
|
||||||
|
@ -48,16 +48,16 @@ fn (v mut V) cc() {
|
||||||
} else {
|
} else {
|
||||||
println('Failed.')
|
println('Failed.')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret := os.system('$vjs_path -o $v.out_name $v.dir')
|
ret := os.system('$vjs_path -o $v.out_name $v.dir')
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
println('Done. Run it with `node $v.out_name`')
|
println('Done. Run it with `node $v.out_name`')
|
||||||
println('JS backend is at a very early stage.')
|
println('JS backend is at a very early stage.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// v.out_name_c may be on a different partition than v.out_name
|
// v.out_name_c may be on a different partition than v.out_name
|
||||||
os.mv_by_cp(v.out_name_c, v.out_name) or { panic(err) }
|
os.mv_by_cp(v.out_name_c, v.out_name) or { panic(err) }
|
||||||
exit(0)
|
exit(0)
|
||||||
|
@ -116,7 +116,7 @@ fn (v mut V) cc() {
|
||||||
}
|
}
|
||||||
} $else {
|
} $else {
|
||||||
verror('-fast is only supported on Linux right now')
|
verror('-fast is only supported on Linux right now')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//linux_host := os.user_os() == 'linux'
|
//linux_host := os.user_os() == 'linux'
|
||||||
v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name')
|
v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name')
|
||||||
|
@ -127,11 +127,11 @@ fn (v mut V) cc() {
|
||||||
}
|
}
|
||||||
if v.pref.is_bare {
|
if v.pref.is_bare {
|
||||||
a << '-static -ffreestanding -nostdlib $vdir/vlib/os/bare/bare.S'
|
a << '-static -ffreestanding -nostdlib $vdir/vlib/os/bare/bare.S'
|
||||||
}
|
}
|
||||||
if v.pref.build_mode == .build_module {
|
if v.pref.build_mode == .build_module {
|
||||||
// Create the modules & out directory if it's not there.
|
// Create the modules & out directory if it's not there.
|
||||||
mut out_dir := if v.dir.starts_with('vlib') {
|
mut out_dir := if v.dir.starts_with('vlib') {
|
||||||
'$v_modules_path${os.path_separator}cache${os.path_separator}$v.dir'
|
'$v_modules_path${os.path_separator}cache${os.path_separator}$v.dir'
|
||||||
} else {
|
} else {
|
||||||
'$v_modules_path${os.path_separator}$v.dir'
|
'$v_modules_path${os.path_separator}$v.dir'
|
||||||
}
|
}
|
||||||
|
@ -158,14 +158,14 @@ fn (v mut V) cc() {
|
||||||
}
|
}
|
||||||
optimization_options = '-O3 -fno-strict-aliasing -flto'
|
optimization_options = '-O3 -fno-strict-aliasing -flto'
|
||||||
}
|
}
|
||||||
|
|
||||||
if debug_mode {
|
if debug_mode {
|
||||||
a << debug_options
|
a << debug_options
|
||||||
}
|
}
|
||||||
if v.pref.is_prod {
|
if v.pref.is_prod {
|
||||||
a << optimization_options
|
a << optimization_options
|
||||||
}
|
}
|
||||||
|
|
||||||
if debug_mode && os.user_os() != 'windows'{
|
if debug_mode && os.user_os() != 'windows'{
|
||||||
a << ' -rdynamic ' // needed for nicer symbolic backtraces
|
a << ' -rdynamic ' // needed for nicer symbolic backtraces
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ fn (v mut V) cc() {
|
||||||
for imp in v.table.imports {
|
for imp in v.table.imports {
|
||||||
if imp.contains('vweb') { continue } // not working
|
if imp.contains('vweb') { continue } // not working
|
||||||
if imp == 'webview' { continue }
|
if imp == 'webview' { continue }
|
||||||
|
|
||||||
imp_path := imp.replace('.', os.path_separator)
|
imp_path := imp.replace('.', os.path_separator)
|
||||||
path := '$v_modules_path${os.path_separator}cache${os.path_separator}vlib${os.path_separator}${imp_path}.o'
|
path := '$v_modules_path${os.path_separator}cache${os.path_separator}vlib${os.path_separator}${imp_path}.o'
|
||||||
//println('adding ${imp_path}.o')
|
//println('adding ${imp_path}.o')
|
||||||
|
@ -207,11 +207,11 @@ fn (v mut V) cc() {
|
||||||
os.cp('$vdir/thirdparty/ui/ui.o', path) or { panic('error copying ui files') }
|
os.cp('$vdir/thirdparty/ui/ui.o', path) or { panic('error copying ui files') }
|
||||||
os.cp('$vdir/thirdparty/ui/ui.vh', v_modules_path +
|
os.cp('$vdir/thirdparty/ui/ui.vh', v_modules_path +
|
||||||
'/vlib/ui.vh') or { panic('error copying ui files') }
|
'/vlib/ui.vh') or { panic('error copying ui files') }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
os.system('$vexe build module vlib${os.path_separator}$imp_path')
|
os.system('$vexe build module vlib${os.path_separator}$imp_path')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if path.ends_with('vlib/ui.o') {
|
if path.ends_with('vlib/ui.o') {
|
||||||
a << '-framework Cocoa -framework Carbon'
|
a << '-framework Cocoa -framework Carbon'
|
||||||
}
|
}
|
||||||
|
@ -256,10 +256,10 @@ fn (v mut V) cc() {
|
||||||
|
|
||||||
// add .o files
|
// add .o files
|
||||||
a << cflags.c_options_only_object_files()
|
a << cflags.c_options_only_object_files()
|
||||||
|
|
||||||
// add all flags (-I -l -L etc) not .o files
|
// add all flags (-I -l -L etc) not .o files
|
||||||
a << cflags.c_options_without_object_files()
|
a << cflags.c_options_without_object_files()
|
||||||
|
|
||||||
a << libs
|
a << libs
|
||||||
// Without these libs compilation will fail on Linux
|
// Without these libs compilation will fail on Linux
|
||||||
// || os.user_os() == 'linux'
|
// || os.user_os() == 'linux'
|
||||||
|
@ -275,7 +275,7 @@ fn (v mut V) cc() {
|
||||||
if v.os == .js && os.user_os() == 'linux' {
|
if v.os == .js && os.user_os() == 'linux' {
|
||||||
a << '-lm'
|
a << '-lm'
|
||||||
}
|
}
|
||||||
|
|
||||||
args := a.join(' ')
|
args := a.join(' ')
|
||||||
start:
|
start:
|
||||||
todo()
|
todo()
|
||||||
|
@ -309,14 +309,16 @@ start:
|
||||||
if v.pref.ccompiler.contains('tcc') {
|
if v.pref.ccompiler.contains('tcc') {
|
||||||
v.pref.ccompiler = 'cc'
|
v.pref.ccompiler = 'cc'
|
||||||
goto start
|
goto start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verror('C compiler error, while attempting to run: \n' +
|
verror('C compiler error, while attempting to run: \n' +
|
||||||
'-----------------------------------------------------------\n' +
|
'-----------------------------------------------------------\n' +
|
||||||
'$cmd\n' +
|
'$cmd\n' +
|
||||||
'-----------------------------------------------------------\n' +
|
'-----------------------------------------------------------\n' +
|
||||||
'Probably your C compiler is missing. \n' +
|
'Probably your C compiler is missing. \n' +
|
||||||
'Please reinstall it, or make it available in your PATH.')
|
'Please reinstall it, or make it available in your PATH.\n\n' +
|
||||||
|
missing_compiler_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.pref.is_debug {
|
if v.pref.is_debug {
|
||||||
|
@ -368,7 +370,7 @@ start:
|
||||||
$if windows {
|
$if windows {
|
||||||
println('-compress does not work on Windows for now')
|
println('-compress does not work on Windows for now')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret := os.system('strip $v.out_name')
|
ret := os.system('strip $v.out_name')
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
println('strip failed')
|
println('strip failed')
|
||||||
|
@ -379,16 +381,16 @@ start:
|
||||||
println('upx failed')
|
println('upx failed')
|
||||||
$if mac {
|
$if mac {
|
||||||
println('install upx with `brew install upx`')
|
println('install upx with `brew install upx`')
|
||||||
}
|
}
|
||||||
$if linux {
|
$if linux {
|
||||||
println('install upx\n' +
|
println('install upx\n' +
|
||||||
'for example, on Debian/Ubuntu run `sudo apt install upx`')
|
'for example, on Debian/Ubuntu run `sudo apt install upx`')
|
||||||
}
|
}
|
||||||
$if windows {
|
$if windows {
|
||||||
// :)
|
// :)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -430,7 +432,7 @@ fn (c mut V) cc_windows_cross() {
|
||||||
println('Unzip it afterwards.\n')
|
println('Unzip it afterwards.\n')
|
||||||
println('winroot.zip contains all library and header files needed '+
|
println('winroot.zip contains all library and header files needed '+
|
||||||
'to cross-compile for Windows.')
|
'to cross-compile for Windows.')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
mut obj_name := c.out_name
|
mut obj_name := c.out_name
|
||||||
obj_name = obj_name.replace('.exe', '')
|
obj_name = obj_name.replace('.exe', '')
|
||||||
|
@ -463,7 +465,7 @@ fn (c mut V) cc_windows_cross() {
|
||||||
|
|
||||||
fn (c &V) build_thirdparty_obj_files() {
|
fn (c &V) build_thirdparty_obj_files() {
|
||||||
for flag in c.get_os_cflags() {
|
for flag in c.get_os_cflags() {
|
||||||
if flag.value.ends_with('.o') {
|
if flag.value.ends_with('.o') {
|
||||||
rest_of_module_flags := c.get_rest_of_module_cflags( flag )
|
rest_of_module_flags := c.get_rest_of_module_cflags( flag )
|
||||||
if c.pref.ccompiler == 'msvc' {
|
if c.pref.ccompiler == 'msvc' {
|
||||||
build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags)
|
build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags)
|
||||||
|
@ -512,3 +514,16 @@ fn get_cmdline_cflags(args []string) string {
|
||||||
}
|
}
|
||||||
return cflags
|
return cflags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn missing_compiler_info() string {
|
||||||
|
$if windows {
|
||||||
|
return 'https://github.com/vlang/v/wiki/Installing-a-C-compiler-on-Windows'
|
||||||
|
}
|
||||||
|
$if linux {
|
||||||
|
return 'On Debian/Ubuntu, run `sudo apt install build-essential`'
|
||||||
|
}
|
||||||
|
$if mac {
|
||||||
|
return 'Install command line XCode tools with `xcode-select --install`'
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
|
@ -512,6 +512,9 @@ fn (p mut Parser) fn_decl() {
|
||||||
f.defer_text[f.scope_level] = ' ${cgen_name}_time += time__ticks() - _PROF_START;'
|
f.defer_text[f.scope_level] = ' ${cgen_name}_time += time__ticks() - _PROF_START;'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if p.pref.x64 {
|
||||||
|
p.x64.register_function_address(f.name)
|
||||||
|
}
|
||||||
p.statements_no_rcbr()
|
p.statements_no_rcbr()
|
||||||
//p.cgen.nogen = false
|
//p.cgen.nogen = false
|
||||||
// Print counting result after all statements in main
|
// Print counting result after all statements in main
|
||||||
|
@ -712,6 +715,9 @@ fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type s
|
||||||
if is_comptime_define {
|
if is_comptime_define {
|
||||||
p.cgen.nogen = true
|
p.cgen.nogen = true
|
||||||
}
|
}
|
||||||
|
if p.pref.x64 && !p.first_pass() {
|
||||||
|
p.x64.call_fn(f.name)
|
||||||
|
}
|
||||||
p.calling_c = f.is_c
|
p.calling_c = f.is_c
|
||||||
if f.is_c && !p.builtin_mod {
|
if f.is_c && !p.builtin_mod {
|
||||||
if f.name == 'free' {
|
if f.name == 'free' {
|
||||||
|
|
|
@ -15,6 +15,7 @@ mut:
|
||||||
file_size_pos i64
|
file_size_pos i64
|
||||||
main_fn_addr i64
|
main_fn_addr i64
|
||||||
code_start_pos i64 // location of the start of the assembly instructions
|
code_start_pos i64 // location of the start of the assembly instructions
|
||||||
|
fn_addr map[string]i64
|
||||||
//string_addr map[string]i64
|
//string_addr map[string]i64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +45,10 @@ pub fn new_gen(out_name string) &Gen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (g &Gen) pos() i64 {
|
||||||
|
return g.buf.len
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn (g mut Gen) write8(n int) {
|
fn (g mut Gen) write8(n int) {
|
||||||
// write 1 byte
|
// write 1 byte
|
||||||
|
@ -155,10 +160,13 @@ fn (g mut Gen) mov64(reg Register, val i64) {
|
||||||
g.write64(val)
|
g.write64(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) call(val int) {
|
fn (g mut Gen) call(addr int) {
|
||||||
//println('call val=$val')
|
//rel := g.abs_to_rel_addr(addr)
|
||||||
|
rel := 0xffffffff - int(abs(addr - g.buf.len))-1
|
||||||
|
|
||||||
|
println('call addr=$addr rel_addr=$addr pos=$g.buf.len')
|
||||||
g.write8(0xe8)
|
g.write8(0xe8)
|
||||||
g.write32(val)
|
g.write32(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) syscall() {
|
fn (g mut Gen) syscall() {
|
||||||
|
@ -228,4 +236,19 @@ fn (g mut Gen) mov(reg Register, val int) {
|
||||||
g.write32(val)
|
g.write32(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (g mut Gen) register_function_address(name string) {
|
||||||
|
addr := g.pos()
|
||||||
|
println('reg fn addr $name $addr')
|
||||||
|
g.fn_addr[name] = addr
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (g mut Gen) call_fn(name string) {
|
||||||
|
if !name.contains('__') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
addr := g.fn_addr[name]
|
||||||
|
g.call(int(addr))
|
||||||
|
println('call $name $addr')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue