From 3f0f8bac49995ed7d9b0b53942d826b5129e47b7 Mon Sep 17 00:00:00 2001 From: vitalyster Date: Fri, 27 Dec 2019 11:27:19 +0300 Subject: [PATCH] windows: do not link gdi32/shell32 to console applications * read os.args from argv when we have console * dynamically load CommandLineToArgvW when we are GUI app * link gdi32/shell32 in glfw module --- make.bat | 20 ++++++++++++++------ v.v | 3 +-- vlib/builtin/cfns.v | 3 --- vlib/compiler/cc.v | 3 +++ vlib/compiler/main.v | 36 ++++++++++++++++++++++++++++++++++-- vlib/compiler/msvc.v | 2 +- vlib/glfw/glfw.v | 2 +- vlib/os/os_windows.v | 18 +++++++++++------- 8 files changed, 65 insertions(+), 22 deletions(-) diff --git a/make.bat b/make.bat index c5833f0d85..06457da86c 100644 --- a/make.bat +++ b/make.bat @@ -28,14 +28,18 @@ if not exist "%gccpath%" ( goto:msvcstrap ) -gcc -std=c99 -w -o v2.exe vc\v_win.c +gcc -std=c99 -DV_BOOTSTRAP -w -o v2.exe vc\v_win.c if %ERRORLEVEL% NEQ 0 ( echo gcc failed to compile - Create an issue at 'https://github.com/vlang' exit /b 1 ) echo Now using V to build V... -v2.exe -o v3.exe v.v +rem TODO: remove when v.c is updated +set VFLAGS=-cflags -DV_BOOTSTRAP -o v3.c v.v +v2.exe +gcc -std=c99 -DV_BOOTSTRAP -w -o v3.exe vc\v_win.c +set VFLAGS= v3.exe -o v.exe -prod v.v if %ERRORLEVEL% NEQ 0 ( echo v.exe failed to compile itself - Create an issue at 'https://github.com/vlang' @@ -70,17 +74,21 @@ if exist "%InstallDir%\Common7\Tools\vsdevcmd.bat" ( set ObjFile=.v.c.obj -cl.exe /nologo /w /volatile:ms /Fo%ObjFile% /O2 /MD vc\v_win.c user32.lib kernel32.lib advapi32.lib shell32.lib /link /NOLOGO /OUT:v2.exe /INCREMENTAL:NO +cl.exe /nologo /w /volatile:ms /Fo%ObjFile% /O2 /MD /D_VBOOTSTRAP vc\v_win.c user32.lib kernel32.lib advapi32.lib shell32.lib /link /NOLOGO /OUT:v2.exe /INCREMENTAL:NO if %ERRORLEVEL% NEQ 0 ( echo cl.exe failed to build V goto :compileerror ) echo rebuild from source (twice, in case of C definitions changes) -v2.exe -cc msvc -o v3.exe v.v -v3.exe -cc msvc -o v.exe -prod v.v +rem TODO: remove when v.c is updated +set VFLAGS=-cc msvc -cflags /DV_BOOTSTRAP -o v3.c v.v +v2.exe +cl.exe /nologo /w /volatile:ms /Fo%ObjFile% /O2 /MD /D_VBOOTSTRAP v3.c user32.lib kernel32.lib advapi32.lib shell32.lib /link /NOLOGO /OUT:v3.exe /INCREMENTAL:NO +set VFLAGS= +v3.exe -cc msvc -o v -prod v.v if %ERRORLEVEL% NEQ 0 ( - echo V failed to build itself + echo V failed to build itself with error %ERRORLEVEL% goto :compileerror ) diff --git a/v.v b/v.v index 384472dcc4..bb0d7f56e0 100644 --- a/v.v +++ b/v.v @@ -119,8 +119,7 @@ fn v_command(command string, args []string) { // v.gen_doc_html_for_module(args.last()) } else { - println('v $command: unknown command') - println('Run "v help" for usage.') + panic('v $command: unknown command\nRun "v help" for usage.') } } exit(0) diff --git a/vlib/builtin/cfns.v b/vlib/builtin/cfns.v index ceccfa720b..916c820a06 100644 --- a/vlib/builtin/cfns.v +++ b/vlib/builtin/cfns.v @@ -324,9 +324,6 @@ fn C._fullpath() int fn C.GetCommandLine() voidptr -fn C.CommandLineToArgvW() &voidptr - - fn C.LocalFree() diff --git a/vlib/compiler/cc.v b/vlib/compiler/cc.v index b43448964e..431f3d9aa2 100644 --- a/vlib/compiler/cc.v +++ b/vlib/compiler/cc.v @@ -263,6 +263,9 @@ fn (v mut V) cc() { if v.os == .mac { a << '-mmacosx-version-min=10.7' } + if v.os == .windows { + a << '-municode' + } cflags := v.get_os_cflags() // add .o files a << cflags.c_options_only_object_files() diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index e861b1baae..2351f50298 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -557,10 +557,42 @@ pub fn (v mut V) generate_main() { } pub fn (v mut V) gen_main_start(add_os_args bool) { - v.cgen.genln('int main(int argc, char** argv) { ') + if (v.os == .windows) { + if 'glfw' in v.table.imports { + v.cgen.genln('#ifdef V_BOOTSTRAP') + v.cgen.genln('int main(int argc, char** argv) { ') + v.cgen.genln('#else') + // GUI application + v.cgen.genln('int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmd_line, int show_cmd) { ') + v.cgen.genln(' typedef LPWSTR*(WINAPI *cmd_line_to_argv)(LPCWSTR, int*);') + v.cgen.genln(' HMODULE shell32_module = LoadLibrary(L"shell32.dll");') + v.cgen.genln(' cmd_line_to_argv CommandLineToArgvW = (cmd_line_to_argv)GetProcAddress(shell32_module, "CommandLineToArgvW");') + v.cgen.genln(' int argc;') + v.cgen.genln(' wchar_t** argv = CommandLineToArgvW(cmd_line, &argc);') + v.cgen.genln(' os__args = os__init_os_args_wide(argc, argv);') + v.cgen.genln('#endif') + } else { + v.cgen.genln('#ifdef V_BOOTSTRAP') + v.cgen.genln('int main(int argc, char** argv) { ') + v.cgen.genln('#else') + // Console application + v.cgen.genln('int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) { ') + v.cgen.genln('#endif') + } + } else { + v.cgen.genln('int main(int argc, char** argv) { ') + } v.cgen.genln(' init();') if add_os_args && 'os' in v.table.imports { - v.cgen.genln(' os__args = os__init_os_args(argc, (byteptr*)argv);') + if v.os == .windows { + v.cgen.genln('#ifdef V_BOOTSTRAP') + v.cgen.genln(' os__args = os__init_os_args(argc, (byteptr*)argv);') + v.cgen.genln('#else') + v.cgen.genln(' os__args = os__init_os_args_wide(argc, argv);') + v.cgen.genln('#endif') + } else { + v.cgen.genln(' os__args = os__init_os_args(argc, (byteptr*)argv);') + } } v.generate_hotcode_reloading_main_caller() v.cgen.genln('') diff --git a/vlib/compiler/msvc.v b/vlib/compiler/msvc.v index 94611e8282..1c0a50274e 100644 --- a/vlib/compiler/msvc.v +++ b/vlib/compiler/msvc.v @@ -246,7 +246,7 @@ pub fn (v mut V) cc_msvc() { // Emily: // Not all of these are needed (but the compiler should discard them if they are not used) // these are the defaults used by msbuild and visual studio - mut real_libs := ['kernel32.lib', 'user32.lib', 'gdi32.lib', 'winspool.lib', 'comdlg32.lib', 'advapi32.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib', 'uuid.lib', 'odbc32.lib', 'odbccp32.lib'] + mut real_libs := ['kernel32.lib', 'user32.lib', 'advapi32.lib'] sflags := v.get_os_cflags().msvc_string_flags() real_libs << sflags.real_libs inc_paths := sflags.inc_paths diff --git a/vlib/glfw/glfw.v b/vlib/glfw/glfw.v index 45a76d77de..c10d09d99e 100644 --- a/vlib/glfw/glfw.v +++ b/vlib/glfw/glfw.v @@ -21,7 +21,7 @@ import gl #flag freebsd -I/usr/local/include #flag freebsd -Wl,-L/usr/local/lib,-lglfw #flag linux -lglfw -#flag windows -lglfw3 +#flag windows -lgdi32 -lshell32 -lglfw3 #include // #flag darwin -framework Carbon // #flag darwin -framework Cocoa diff --git a/vlib/os/os_windows.v b/vlib/os/os_windows.v index 9da24bf0bf..236f941542 100644 --- a/vlib/os/os_windows.v +++ b/vlib/os/os_windows.v @@ -74,15 +74,19 @@ mut: bInheritHandle bool } -fn init_os_args(argc int, argv &byteptr) []string { +fn init_os_args(argc int, argv &byteptr) []string { mut args := []string - mut args_list := &voidptr(0) - mut args_count := 0 - args_list = C.CommandLineToArgvW(C.GetCommandLine(), &args_count) - for i := 0; i < args_count; i++ { - args << string_from_wide(&u16(args_list[i])) + for i := 0; i < argc; i++ { + args << string(argv[i]) + } + return args +} + +fn init_os_args_wide(argc int, argv &byteptr) []string { + mut args := []string + for i := 0; i < argc; i++ { + args << string_from_wide(&u16(argv[i])) } - C.LocalFree(args_list) return args }