show an info message if a C compiler is not installed

pull/2924/head
Alexander Medvednikov 2019-11-28 16:49:35 +03:00
parent e31d892598
commit 9e19472c33
6 changed files with 87 additions and 41 deletions

View File

@ -38,11 +38,10 @@
- declarative ui with hot reload (similar to swiftui)
- "building a simple blog with vweb" tutorial + youtube video
+ fix interfaces
- merge v.c and v_win.c
+ fast.vlang.io
+ bare metal support
+ inline assembly
+ x64 machine code generation (ELF)
- require explicit C.fn definitions, add all missing definitions
+ require explicit C.fn definitions, add all missing definitions

View File

@ -1,11 +1,14 @@
fn test_fn() {
println('test fn')
}
fn main() {
println('x64 test')
for _ in 0..5 {
println('Hello world from V x64 machine code generator!')
}
println('Hello again!')
test_fn()
println('dne')
}
fn test_fn() {
println('test fn')
}

View File

@ -93,7 +93,7 @@ fn test_split() {
assert vals.len == 2
assert vals[0] == 'volt/twitch.v'
assert vals[1] == '34'
// /////////
// /////////
s = '2018-01-01z13:01:02'
vals = s.split('z')
assert vals.len == 2
@ -491,13 +491,13 @@ fn test_raw() {
lines := raw.split('\n')
assert lines.len == 1
println('raw string: "$raw"')
}
}
fn test_escape() {
// TODO
//a := 10
//println("\"$a")
}
}
fn test_atoi() {
assert '234232'.int() == 234232
@ -506,8 +506,8 @@ fn test_atoi() {
for n in -10000 .. 100000 {
s := n.str()
assert s.int() == n
}
}
}
}
fn test_raw_inter() {
world := 'world'
@ -523,6 +523,6 @@ fn test_c_r() {
println('$c')
r := 50
println('$r')
}
}

View File

@ -11,8 +11,8 @@ import (
)
fn todo() {
}
}
fn no_mingw_installed() bool {
$if !windows {
@ -48,16 +48,16 @@ fn (v mut V) cc() {
} else {
println('Failed.')
exit(1)
}
}
}
}
ret := os.system('$vjs_path -o $v.out_name $v.dir')
if ret == 0 {
println('Done. Run it with `node $v.out_name`')
println('JS backend is at a very early stage.')
}
}
}
}
// 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) }
exit(0)
@ -116,7 +116,7 @@ fn (v mut V) cc() {
}
} $else {
verror('-fast is only supported on Linux right now')
}
}
}
//linux_host := os.user_os() == 'linux'
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 {
a << '-static -ffreestanding -nostdlib $vdir/vlib/os/bare/bare.S'
}
}
if v.pref.build_mode == .build_module {
// Create the modules & out directory if it's not there.
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 {
'$v_modules_path${os.path_separator}$v.dir'
}
@ -158,14 +158,14 @@ fn (v mut V) cc() {
}
optimization_options = '-O3 -fno-strict-aliasing -flto'
}
if debug_mode {
a << debug_options
}
if v.pref.is_prod {
a << optimization_options
}
if debug_mode && os.user_os() != 'windows'{
a << ' -rdynamic ' // needed for nicer symbolic backtraces
}
@ -194,7 +194,7 @@ fn (v mut V) cc() {
for imp in v.table.imports {
if imp.contains('vweb') { continue } // not working
if imp == 'webview' { continue }
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'
//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.vh', v_modules_path +
'/vlib/ui.vh') or { panic('error copying ui files') }
} else {
os.system('$vexe build module vlib${os.path_separator}$imp_path')
}
}
}
if path.ends_with('vlib/ui.o') {
a << '-framework Cocoa -framework Carbon'
}
@ -256,10 +256,10 @@ fn (v mut V) cc() {
// add .o files
a << cflags.c_options_only_object_files()
// add all flags (-I -l -L etc) not .o files
a << cflags.c_options_without_object_files()
a << libs
// Without these libs compilation will fail on Linux
// || os.user_os() == 'linux'
@ -275,7 +275,7 @@ fn (v mut V) cc() {
if v.os == .js && os.user_os() == 'linux' {
a << '-lm'
}
args := a.join(' ')
start:
todo()
@ -309,14 +309,16 @@ start:
if v.pref.ccompiler.contains('tcc') {
v.pref.ccompiler = 'cc'
goto start
}
}
}
verror('C compiler error, while attempting to run: \n' +
'-----------------------------------------------------------\n' +
'$cmd\n' +
'-----------------------------------------------------------\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 {
@ -368,7 +370,7 @@ start:
$if windows {
println('-compress does not work on Windows for now')
return
}
}
ret := os.system('strip $v.out_name')
if ret != 0 {
println('strip failed')
@ -379,16 +381,16 @@ start:
println('upx failed')
$if mac {
println('install upx with `brew install upx`')
}
}
$if linux {
println('install upx\n' +
'for example, on Debian/Ubuntu run `sudo apt install upx`')
}
}
$if windows {
// :)
}
}
}
}
}
}
@ -430,7 +432,7 @@ fn (c mut V) cc_windows_cross() {
println('Unzip it afterwards.\n')
println('winroot.zip contains all library and header files needed '+
'to cross-compile for Windows.')
exit(1)
exit(1)
}
mut obj_name := c.out_name
obj_name = obj_name.replace('.exe', '')
@ -463,7 +465,7 @@ fn (c mut V) cc_windows_cross() {
fn (c &V) build_thirdparty_obj_files() {
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 )
if c.pref.ccompiler == 'msvc' {
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
}
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 ''
}

View File

@ -512,6 +512,9 @@ fn (p mut Parser) fn_decl() {
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.cgen.nogen = false
// 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 {
p.cgen.nogen = true
}
if p.pref.x64 && !p.first_pass() {
p.x64.call_fn(f.name)
}
p.calling_c = f.is_c
if f.is_c && !p.builtin_mod {
if f.name == 'free' {

View File

@ -15,6 +15,7 @@ mut:
file_size_pos i64
main_fn_addr i64
code_start_pos i64 // location of the start of the assembly instructions
fn_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) {
// write 1 byte
@ -155,10 +160,13 @@ fn (g mut Gen) mov64(reg Register, val i64) {
g.write64(val)
}
fn (g mut Gen) call(val int) {
//println('call val=$val')
fn (g mut Gen) call(addr int) {
//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.write32(val)
g.write32(addr)
}
fn (g mut Gen) syscall() {
@ -228,4 +236,19 @@ fn (g mut Gen) mov(reg Register, val int) {
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')
}