mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
Windows: fix some heap corruptions, fix msvc not building with unicode flags, fix os.getwd, fix mscrazy using a less recent installation
This commit is contained in:
parent
0bbefca875
commit
32aae80a64
4
.gitignore
vendored
4
.gitignore
vendored
@ -7,3 +7,7 @@
|
|||||||
*.exe
|
*.exe
|
||||||
*.o
|
*.o
|
||||||
.*.c
|
.*.c
|
||||||
|
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
*.pdb
|
||||||
|
@ -32,25 +32,24 @@ struct MsvcResult {
|
|||||||
|
|
||||||
struct FindResult {
|
struct FindResult {
|
||||||
sdk_ver int
|
sdk_ver int
|
||||||
windows_sdk_root byteptr
|
windows_sdk_root *u16
|
||||||
windows_sdk_um_library_path byteptr
|
windows_sdk_um_library_path *u16
|
||||||
windows_sdk_ucrt_library_path byteptr
|
windows_sdk_ucrt_library_path *u16
|
||||||
vs_exe_path byteptr
|
vs_exe_path *u16
|
||||||
vs_library_path byteptr
|
vs_library_path *u16
|
||||||
}
|
}
|
||||||
|
|
||||||
fn C.find_visual_studio_and_windows_sdk() *FindResult
|
fn C.find_visual_studio_and_windows_sdk() *FindResult
|
||||||
fn C.wide_string_to_narrow_temp(byteptr) byteptr
|
|
||||||
|
|
||||||
fn find_msvc() *MsvcResult {
|
fn find_msvc() *MsvcResult {
|
||||||
$if windows {
|
$if windows {
|
||||||
r := C.find_visual_studio_and_windows_sdk()
|
r := C.find_visual_studio_and_windows_sdk()
|
||||||
|
|
||||||
windows_sdk_root := tos_clone(C.wide_string_to_narrow_temp(r.windows_sdk_root))
|
windows_sdk_root := string_from_wide(r.windows_sdk_root)
|
||||||
ucrt_lib_folder := tos_clone(C.wide_string_to_narrow_temp(r.windows_sdk_ucrt_library_path))
|
ucrt_lib_folder := string_from_wide(r.windows_sdk_ucrt_library_path)
|
||||||
um_lib_folder := tos_clone(C.wide_string_to_narrow_temp(r.windows_sdk_um_library_path))
|
um_lib_folder := string_from_wide(r.windows_sdk_um_library_path)
|
||||||
vs_lib_folder := tos_clone(C.wide_string_to_narrow_temp(r.vs_library_path))
|
vs_lib_folder := string_from_wide(r.vs_library_path)
|
||||||
exe_folder := tos_clone(C.wide_string_to_narrow_temp(r.vs_exe_path))
|
exe_folder := string_from_wide(r.vs_exe_path)
|
||||||
|
|
||||||
mut ucrt_include_folder := ucrt_lib_folder.replace('Lib', 'Include')
|
mut ucrt_include_folder := ucrt_lib_folder.replace('Lib', 'Include')
|
||||||
mut vs_include_folder := vs_lib_folder.replace('lib', 'include')
|
mut vs_include_folder := vs_lib_folder.replace('lib', 'include')
|
||||||
@ -88,7 +87,7 @@ fn find_msvc() *MsvcResult {
|
|||||||
pub fn cc_msvc(v *V) {
|
pub fn cc_msvc(v *V) {
|
||||||
r := find_msvc()
|
r := find_msvc()
|
||||||
|
|
||||||
mut a := ['-w', '/volatile:ms'] // arguments for the C compiler
|
mut a := ['-w', '/volatile:ms', '/D_UNICODE', '/DUNICODE'] // arguments for the C compiler
|
||||||
|
|
||||||
// cl.exe is stupid so these are in a different order to the ones below!
|
// cl.exe is stupid so these are in a different order to the ones below!
|
||||||
|
|
||||||
@ -274,6 +273,6 @@ fn build_thirdparty_obj_file_with_msvc(flag string) {
|
|||||||
|
|
||||||
println('$cfiles')
|
println('$cfiles')
|
||||||
|
|
||||||
res := os.exec('""$msvc.exe_path\\cl.exe" /volatile:ms /Z7 $include_string /c $cfiles /Fo"$obj_path""')
|
res := os.exec('""$msvc.exe_path\\cl.exe" /volatile:ms /Z7 $include_string /c $cfiles /Fo"$obj_path" /D_UNICODE /DUNICODE"')
|
||||||
println(res)
|
println(res)
|
||||||
}
|
}
|
@ -1,24 +1,3 @@
|
|||||||
#define MICROSOFT_CRAZINESS_IMPLEMENTATION
|
#define MICROSOFT_CRAZINESS_IMPLEMENTATION
|
||||||
|
|
||||||
#include "microsoft_craziness.h"
|
#include "microsoft_craziness.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
// Never hang around to a pointer from this function
|
|
||||||
// This is not thread safe
|
|
||||||
char *wide_string_to_narrow_temp(wchar_t *wc) {
|
|
||||||
static char buffer[10000][10];
|
|
||||||
static int counter = 0;
|
|
||||||
|
|
||||||
char *cur_buffer = buffer[counter++];
|
|
||||||
|
|
||||||
int len = wcslen(wc);
|
|
||||||
int c = wcstombs(cur_buffer, wc, len);
|
|
||||||
cur_buffer[c] = 0;
|
|
||||||
|
|
||||||
// something assert len == c
|
|
||||||
|
|
||||||
return cur_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
156
thirdparty/microsoft_craziness/microsoft_craziness.h
vendored
156
thirdparty/microsoft_craziness/microsoft_craziness.h
vendored
@ -338,6 +338,7 @@ wchar_t *find_windows_kit_root_with_key(HKEY key, wchar_t *version) {
|
|||||||
DWORD length =
|
DWORD length =
|
||||||
required_length + 2; // The +2 is for the maybe optional zero later on.
|
required_length + 2; // The +2 is for the maybe optional zero later on.
|
||||||
// Probably we are over-allocating.
|
// Probably we are over-allocating.
|
||||||
|
|
||||||
wchar_t *value = (wchar_t *)malloc(length);
|
wchar_t *value = (wchar_t *)malloc(length);
|
||||||
if (!value)
|
if (!value)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -350,8 +351,8 @@ wchar_t *find_windows_kit_root_with_key(HKEY key, wchar_t *version) {
|
|||||||
// The documentation says that if the string for some reason was not stored
|
// The documentation says that if the string for some reason was not stored
|
||||||
// with zero-termination, we need to manually terminate it. Sigh!!
|
// with zero-termination, we need to manually terminate it. Sigh!!
|
||||||
|
|
||||||
if (value[length]) {
|
if (value[required_length / 2 - 1]) {
|
||||||
value[length + 1] = 0;
|
value[required_length / 2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@ -521,6 +522,13 @@ bool find_visual_studio_2017_by_fighting_through_microsoft_craziness(
|
|||||||
if (!instances)
|
if (!instances)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// SetupInstance will return the installations in the order they were made
|
||||||
|
// - this results in 2017 being got before 2019 and we dont want this
|
||||||
|
// so get all the installations first, parse the versions and pick the best
|
||||||
|
BSTR best_path = NULL;
|
||||||
|
Version_Data best_version;
|
||||||
|
best_version.best_name = NULL;
|
||||||
|
|
||||||
bool found_visual_studio_2017 = false;
|
bool found_visual_studio_2017 = false;
|
||||||
while (1) {
|
while (1) {
|
||||||
ULONG found = 0;
|
ULONG found = 0;
|
||||||
@ -529,81 +537,95 @@ bool find_visual_studio_2017_by_fighting_through_microsoft_craziness(
|
|||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
BSTR vs_version;
|
||||||
|
hr = CALL_STDMETHOD(instance, GetInstallationVersion, &vs_version);
|
||||||
|
|
||||||
|
win10_best(vs_version, vs_version, &best_version);
|
||||||
|
|
||||||
BSTR bstr_inst_path;
|
BSTR bstr_inst_path;
|
||||||
hr = CALL_STDMETHOD(instance, GetInstallationPath, &bstr_inst_path);
|
hr = CALL_STDMETHOD(instance, GetInstallationPath, &bstr_inst_path);
|
||||||
CALL_STDMETHOD_(instance, Release);
|
CALL_STDMETHOD_(instance, Release);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wchar_t *tools_filename = concat2(
|
// Do this here to get instance->Release() called
|
||||||
bstr_inst_path,
|
if (lstrcmpW(best_version.best_name, vs_version))
|
||||||
L"\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
|
|
||||||
SysFreeString(bstr_inst_path);
|
|
||||||
|
|
||||||
FILE *f;
|
|
||||||
errno_t open_result = _wfopen_s(&f, tools_filename, L"rt");
|
|
||||||
free(tools_filename);
|
|
||||||
if (open_result != 0)
|
|
||||||
continue;
|
|
||||||
if (!f)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LARGE_INTEGER tools_file_size;
|
best_path = bstr_inst_path;
|
||||||
HANDLE file_handle = (HANDLE)_get_osfhandle(_fileno(f));
|
|
||||||
BOOL success = GetFileSizeEx(file_handle, &tools_file_size);
|
|
||||||
if (!success) {
|
|
||||||
fclose(f);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t version_bytes =
|
|
||||||
(tools_file_size.QuadPart + 1) *
|
|
||||||
2; // Warning: This multiplication by 2 presumes there is no
|
|
||||||
// variable-length encoding in the wchars (wacky characters in the
|
|
||||||
// file could betray this expectation).
|
|
||||||
wchar_t *version = (wchar_t *)malloc(version_bytes);
|
|
||||||
|
|
||||||
wchar_t *read_result = fgetws(version, version_bytes, f);
|
|
||||||
fclose(f);
|
|
||||||
if (!read_result)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wchar_t *version_tail = wcschr(version, '\n');
|
|
||||||
if (version_tail)
|
|
||||||
*version_tail = 0; // Stomp the data, because nobody cares about it.
|
|
||||||
|
|
||||||
wchar_t *library_path =
|
|
||||||
concat4(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x64");
|
|
||||||
wchar_t *library_file =
|
|
||||||
concat2(library_path,
|
|
||||||
L"\\vcruntime.lib"); // @Speed: Could have library_path point to
|
|
||||||
// this string, with a smaller count, to
|
|
||||||
// save on memory flailing!
|
|
||||||
|
|
||||||
if (os_file_exists(library_file)) {
|
|
||||||
wchar_t *link_exe_path = concat4(bstr_inst_path, L"\\VC\\Tools\\MSVC\\",
|
|
||||||
version, L"\\bin\\Hostx64\\x64");
|
|
||||||
free(version);
|
|
||||||
|
|
||||||
result->vs_exe_path = link_exe_path;
|
|
||||||
result->vs_library_path = library_path;
|
|
||||||
found_visual_studio_2017 = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(version);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Ryan Saunderson said:
|
|
||||||
"Clang uses the 'SetupInstance->GetInstallationVersion' /
|
|
||||||
ISetupHelper->ParseVersion to find the newest version and then reads the
|
|
||||||
tools file to define the tools path - which is definitely better than
|
|
||||||
what i did."
|
|
||||||
|
|
||||||
So... @Incomplete: Should probably pick the newest version...
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (best_path == NULL)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
// result->vs_root_path = _wcsdup(best_path);
|
||||||
|
|
||||||
|
wchar_t *tools_filename =
|
||||||
|
concat2(best_path,
|
||||||
|
L"\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
|
||||||
|
|
||||||
|
FILE *f;
|
||||||
|
errno_t open_result = _wfopen_s(&f, tools_filename, L"rt");
|
||||||
|
free(tools_filename);
|
||||||
|
if (open_result != 0)
|
||||||
|
return false;
|
||||||
|
if (!f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LARGE_INTEGER tools_file_size;
|
||||||
|
HANDLE file_handle = (HANDLE)_get_osfhandle(_fileno(f));
|
||||||
|
BOOL success = GetFileSizeEx(file_handle, &tools_file_size);
|
||||||
|
if (!success) {
|
||||||
|
fclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t version_bytes =
|
||||||
|
(tools_file_size.QuadPart + 1) *
|
||||||
|
2; // Warning: This multiplication by 2 presumes there is no
|
||||||
|
// variable-length encoding in the wchars (wacky characters in the file
|
||||||
|
// could betray this expectation).
|
||||||
|
wchar_t *version = (wchar_t *)malloc(version_bytes);
|
||||||
|
|
||||||
|
wchar_t *read_result = fgetws(version, version_bytes, f);
|
||||||
|
fclose(f);
|
||||||
|
if (!read_result)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wchar_t *version_tail = wcschr(version, '\n');
|
||||||
|
if (version_tail)
|
||||||
|
*version_tail = 0; // Stomp the data, because nobody cares about it.
|
||||||
|
|
||||||
|
wchar_t *library_path =
|
||||||
|
concat4(best_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x64");
|
||||||
|
wchar_t *library_file = concat2(
|
||||||
|
library_path, L"\\vcruntime.lib"); // @Speed: Could have library_path
|
||||||
|
// point to this string, with a smaller
|
||||||
|
// count, to save on memory flailing!
|
||||||
|
|
||||||
|
if (os_file_exists(library_file)) {
|
||||||
|
wchar_t *link_exe_path = concat4(best_path, L"\\VC\\Tools\\MSVC\\", version,
|
||||||
|
L"\\bin\\Hostx64\\x64");
|
||||||
|
|
||||||
|
result->vs_exe_path = link_exe_path;
|
||||||
|
result->vs_library_path = library_path;
|
||||||
|
|
||||||
|
found_visual_studio_2017 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(version);
|
||||||
|
SysFreeString(best_path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ryan Saunderson said:
|
||||||
|
"Clang uses the 'SetupInstance->GetInstallationVersion' /
|
||||||
|
ISetupHelper->ParseVersion to find the newest version and then reads the
|
||||||
|
tools file to define the tools path - which is definitely better than what
|
||||||
|
i did." So... @Incomplete: Should probably pick the newest version...
|
||||||
|
*/
|
||||||
|
|
||||||
|
failed:
|
||||||
|
|
||||||
CALL_STDMETHOD_(instances, Release);
|
CALL_STDMETHOD_(instances, Release);
|
||||||
return found_visual_studio_2017;
|
return found_visual_studio_2017;
|
||||||
}
|
}
|
||||||
|
@ -703,9 +703,9 @@ pub fn chdir(path string) {
|
|||||||
|
|
||||||
pub fn getwd() string {
|
pub fn getwd() string {
|
||||||
$if windows {
|
$if windows {
|
||||||
max := 512 // MAX_PATH * sizeof(wchar_t)
|
max := 1024 // MAX_PATH * sizeof(wchar_t)
|
||||||
buf := &u16(malloc(max))
|
buf := &u16(malloc(max))
|
||||||
if C._wgetcwd(buf, max) == 0 {
|
if C._wgetcwd(buf, max/2) == 0 {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
return string_from_wide(buf)
|
return string_from_wide(buf)
|
||||||
|
Loading…
Reference in New Issue
Block a user