mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
add MSVC C backend support; fix live code reloading on Windows; other Windows fixes
This commit is contained in:

committed by
Alexander Medvednikov

parent
3cf8e18cf6
commit
e25ea7f9dd
123
compiler/main.v
123
compiler/main.v
@ -29,7 +29,7 @@ fn modules_path() string {
|
||||
}
|
||||
|
||||
const (
|
||||
SupportedPlatforms = ['windows', 'mac', 'linux', 'freebsd', 'openbsd', 'netbsd', 'dragonfly']
|
||||
SupportedPlatforms = ['windows', 'mac', 'linux', 'freebsd', 'openbsd', 'netbsd', 'dragonfly', 'msvc']
|
||||
ModPath = modules_path()
|
||||
)
|
||||
|
||||
@ -41,6 +41,7 @@ enum OS {
|
||||
openbsd
|
||||
netbsd
|
||||
dragonfly
|
||||
msvc
|
||||
}
|
||||
|
||||
enum Pass {
|
||||
@ -189,9 +190,22 @@ fn (v mut V) compile() {
|
||||
#include <inttypes.h> // int64_t etc
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
//#include <WinSock2.h>
|
||||
//#include <WinSock2.h>
|
||||
#ifdef _MSC_VER
|
||||
// On MSVC these are the same (as long as /volatile:ms is passed)
|
||||
#define _Atomic volatile
|
||||
#endif
|
||||
|
||||
void pthread_mutex_lock(HANDLE *m) {
|
||||
WaitForSingleObject(*m, INFINITE);
|
||||
}
|
||||
|
||||
void pthread_mutex_unlock(HANDLE *m) {
|
||||
ReleaseMutex(*m);
|
||||
}
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
@ -246,12 +260,22 @@ int load_so(byteptr);
|
||||
void reload_so();
|
||||
void init_consts();')
|
||||
|
||||
if v.pref.is_so {
|
||||
cgen.genln('pthread_mutex_t live_fn_mutex;')
|
||||
}
|
||||
if v.pref.is_live {
|
||||
cgen.genln('pthread_mutex_t live_fn_mutex = PTHREAD_MUTEX_INITIALIZER;')
|
||||
if v.os != .windows && v.os != .msvc {
|
||||
if v.pref.is_so {
|
||||
cgen.genln('pthread_mutex_t live_fn_mutex;')
|
||||
}
|
||||
if v.pref.is_live {
|
||||
cgen.genln('pthread_mutex_t live_fn_mutex = PTHREAD_MUTEX_INITIALIZER;')
|
||||
}
|
||||
} else {
|
||||
if v.pref.is_so {
|
||||
cgen.genln('HANDLE live_fn_mutex;')
|
||||
}
|
||||
if v.pref.is_live {
|
||||
cgen.genln('HANDLE live_fn_mutex = 0;')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
imports_json := v.table.imports.contains('json')
|
||||
// TODO remove global UI hack
|
||||
@ -386,8 +410,24 @@ string _STR_TMP(const char *fmt, ...) {
|
||||
so_name := file_base + '.so'
|
||||
// Need to build .so file before building the live application
|
||||
// The live app needs to load this .so file on initialization.
|
||||
vexe := os.args[0]
|
||||
os.system('$vexe -o $file_base -shared $file')
|
||||
mut vexe := os.args[0]
|
||||
|
||||
if os.user_os() == 'windows' {
|
||||
vexe = vexe.replace('\\', '\\\\')
|
||||
}
|
||||
|
||||
mut msvc := ''
|
||||
if v.os == .msvc {
|
||||
msvc = '-os msvc'
|
||||
}
|
||||
|
||||
mut debug := ''
|
||||
|
||||
if v.pref.is_debug {
|
||||
debug = '-debug'
|
||||
}
|
||||
|
||||
os.system('$vexe $msvc $debug -o $file_base -shared $file')
|
||||
cgen.genln('
|
||||
|
||||
void lfnmutex_print(char *s){
|
||||
@ -397,7 +437,10 @@ void lfnmutex_print(char *s){
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
')
|
||||
|
||||
if v.os != .windows && v.os != .msvc {
|
||||
cgen.genln('
|
||||
#include <dlfcn.h>
|
||||
void* live_lib=0;
|
||||
int load_so(byteptr path) {
|
||||
@ -412,8 +455,28 @@ int load_so(byteptr path) {
|
||||
return 0;
|
||||
}
|
||||
')
|
||||
for so_fn in cgen.so_fns {
|
||||
cgen.genln('$so_fn = dlsym(live_lib, "$so_fn"); ')
|
||||
for so_fn in cgen.so_fns {
|
||||
cgen.genln('$so_fn = dlsym(live_lib, "$so_fn"); ')
|
||||
}
|
||||
}
|
||||
else {
|
||||
cgen.genln('
|
||||
void* live_lib=0;
|
||||
int load_so(byteptr path) {
|
||||
char cpath[1024];
|
||||
sprintf(cpath, "./%s", path);
|
||||
if (live_lib) FreeLibrary(live_lib);
|
||||
live_lib = LoadLibraryA(cpath);
|
||||
if (!live_lib) {
|
||||
puts("open failed");
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
')
|
||||
|
||||
for so_fn in cgen.so_fns {
|
||||
cgen.genln('$so_fn = (void *)GetProcAddress(live_lib, "$so_fn"); ')
|
||||
}
|
||||
}
|
||||
|
||||
cgen.genln('return 1;
|
||||
@ -434,8 +497,17 @@ void reload_so() {
|
||||
|
||||
//v -o bounce -shared bounce.v
|
||||
sprintf(new_so_base, ".tmp.%d.${file_base}", _live_reloads);
|
||||
#ifdef _WIN32
|
||||
// We have to make this directory becuase windows WILL NOT
|
||||
// do it for us
|
||||
os__mkdir(string_all_before_last(tos2(new_so_base), tos2("/")));
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
sprintf(new_so_name, "%s.dll", new_so_base);
|
||||
#else
|
||||
sprintf(new_so_name, "%s.so", new_so_base);
|
||||
sprintf(compile_cmd, "$vexe -o %s -shared $file", new_so_base);
|
||||
#endif
|
||||
sprintf(compile_cmd, "$vexe $msvc -o %s -shared $file", new_so_base);
|
||||
os__system(tos2(compile_cmd));
|
||||
|
||||
if( !os__file_exists(tos2(new_so_name)) ) {
|
||||
@ -443,13 +515,17 @@ void reload_so() {
|
||||
continue;
|
||||
}
|
||||
|
||||
lfnmutex_print("reload_so locking...");
|
||||
pthread_mutex_lock(&live_fn_mutex);
|
||||
lfnmutex_print("reload_so locking...");
|
||||
pthread_mutex_lock(&live_fn_mutex);
|
||||
lfnmutex_print("reload_so locked");
|
||||
|
||||
live_lib = 0; // hack: force skipping dlclose/1, the code may be still used...
|
||||
load_so(new_so_name);
|
||||
load_so(new_so_name);
|
||||
#ifndef _WIN32
|
||||
unlink(new_so_name); // removing the .so file from the filesystem after dlopen-ing it is safe, since it will still be mapped in memory.
|
||||
#else
|
||||
_unlink(new_so_name);
|
||||
#endif
|
||||
//if(0 == rename(new_so_name, "${so_name}")){
|
||||
// load_so("${so_name}");
|
||||
//}
|
||||
@ -485,7 +561,8 @@ void reload_so() {
|
||||
'./' + v.out_name
|
||||
}
|
||||
$if windows {
|
||||
cmd = v.out_name
|
||||
cmd = v.out_name
|
||||
cmd = cmd.replace('/', '\\')
|
||||
}
|
||||
if os.args.len > 3 {
|
||||
cmd += ' ' + os.args.right(3).join(' ')
|
||||
@ -569,8 +646,6 @@ fn (c &V) cc_windows_cross() {
|
||||
}
|
||||
println('Done!')
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn (v mut V) cc() {
|
||||
// Cross compiling for Windows
|
||||
@ -580,6 +655,11 @@ fn (v mut V) cc() {
|
||||
return
|
||||
}
|
||||
}
|
||||
if v.os == .msvc {
|
||||
cc_msvc(v)
|
||||
return
|
||||
}
|
||||
|
||||
linux_host := os.user_os() == 'linux'
|
||||
v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name')
|
||||
mut a := [v.pref.cflags, '-w'] // arguments for the C compiler
|
||||
@ -752,7 +832,7 @@ fn (v &V) v_files_from_dir(dir string) []string {
|
||||
if file.ends_with('_test.v') {
|
||||
continue
|
||||
}
|
||||
if file.ends_with('_win.v') && v.os != .windows {
|
||||
if file.ends_with('_win.v') && (v.os != .windows && v.os != .msvc) {
|
||||
continue
|
||||
}
|
||||
if file.ends_with('_lin.v') && v.os != .linux {
|
||||
@ -761,7 +841,7 @@ fn (v &V) v_files_from_dir(dir string) []string {
|
||||
if file.ends_with('_mac.v') && v.os != .mac {
|
||||
continue
|
||||
}
|
||||
if file.ends_with('_nix.v') && v.os == .windows {
|
||||
if file.ends_with('_nix.v') && (v.os == .windows || v.os == .msvc) {
|
||||
continue
|
||||
}
|
||||
res << '$dir/$file'
|
||||
@ -1004,6 +1084,7 @@ fn new_v(args[]string) *V {
|
||||
case 'openbsd': _os = .openbsd
|
||||
case 'netbsd': _os = .netbsd
|
||||
case 'dragonfly': _os = .dragonfly
|
||||
case 'msvc': _os = .msvc
|
||||
}
|
||||
}
|
||||
builtins := [
|
||||
|
Reference in New Issue
Block a user