1
0
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:
Emily Hudson 2019-07-24 14:00:26 +01:00 committed by Alexander Medvednikov
parent 0bbefca875
commit 32aae80a64
5 changed files with 108 additions and 104 deletions

4
.gitignore vendored
View File

@ -7,3 +7,7 @@
*.exe *.exe
*.o *.o
.*.c .*.c
*.obj
*.pdb

View File

@ -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)
} }

View File

@ -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

View File

@ -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,80 +537,94 @@ 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))
continue;
best_path = bstr_inst_path;
}
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"); L"\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
SysFreeString(bstr_inst_path);
FILE *f; FILE *f;
errno_t open_result = _wfopen_s(&f, tools_filename, L"rt"); errno_t open_result = _wfopen_s(&f, tools_filename, L"rt");
free(tools_filename); free(tools_filename);
if (open_result != 0) if (open_result != 0)
continue; return false;
if (!f) if (!f)
continue; return false;
LARGE_INTEGER tools_file_size; LARGE_INTEGER tools_file_size;
HANDLE file_handle = (HANDLE)_get_osfhandle(_fileno(f)); HANDLE file_handle = (HANDLE)_get_osfhandle(_fileno(f));
BOOL success = GetFileSizeEx(file_handle, &tools_file_size); BOOL success = GetFileSizeEx(file_handle, &tools_file_size);
if (!success) { if (!success) {
fclose(f); fclose(f);
continue; return false;
} }
uint64_t version_bytes = uint64_t version_bytes =
(tools_file_size.QuadPart + 1) * (tools_file_size.QuadPart + 1) *
2; // Warning: This multiplication by 2 presumes there is no 2; // Warning: This multiplication by 2 presumes there is no
// variable-length encoding in the wchars (wacky characters in the // variable-length encoding in the wchars (wacky characters in the file
// file could betray this expectation). // could betray this expectation).
wchar_t *version = (wchar_t *)malloc(version_bytes); wchar_t *version = (wchar_t *)malloc(version_bytes);
wchar_t *read_result = fgetws(version, version_bytes, f); wchar_t *read_result = fgetws(version, version_bytes, f);
fclose(f); fclose(f);
if (!read_result) if (!read_result)
continue; return false;
wchar_t *version_tail = wcschr(version, '\n'); wchar_t *version_tail = wcschr(version, '\n');
if (version_tail) if (version_tail)
*version_tail = 0; // Stomp the data, because nobody cares about it. *version_tail = 0; // Stomp the data, because nobody cares about it.
wchar_t *library_path = wchar_t *library_path =
concat4(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x64"); concat4(best_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x64");
wchar_t *library_file = wchar_t *library_file = concat2(
concat2(library_path, library_path, L"\\vcruntime.lib"); // @Speed: Could have library_path
L"\\vcruntime.lib"); // @Speed: Could have library_path point to // point to this string, with a smaller
// this string, with a smaller count, to // count, to save on memory flailing!
// save on memory flailing!
if (os_file_exists(library_file)) { if (os_file_exists(library_file)) {
wchar_t *link_exe_path = concat4(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", wchar_t *link_exe_path = concat4(best_path, L"\\VC\\Tools\\MSVC\\", version,
version, L"\\bin\\Hostx64\\x64"); L"\\bin\\Hostx64\\x64");
free(version);
result->vs_exe_path = link_exe_path; result->vs_exe_path = link_exe_path;
result->vs_library_path = library_path; result->vs_library_path = library_path;
found_visual_studio_2017 = true; found_visual_studio_2017 = true;
break;
} }
free(version); free(version);
SysFreeString(best_path);
/* /*
Ryan Saunderson said: Ryan Saunderson said:
"Clang uses the 'SetupInstance->GetInstallationVersion' / "Clang uses the 'SetupInstance->GetInstallationVersion' /
ISetupHelper->ParseVersion to find the newest version and then reads the ISetupHelper->ParseVersion to find the newest version and then reads the
tools file to define the tools path - which is definitely better than tools file to define the tools path - which is definitely better than what
what i did." i did." So... @Incomplete: Should probably pick the newest version...
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;

View File

@ -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)