From 38f05d4ac59aa799f947ae1fb4671acafcc283cb Mon Sep 17 00:00:00 2001 From: Dimenus Date: Wed, 1 Nov 2017 14:33:14 -0500 Subject: WIN32: Linking with the CRT at runtime. (#570) Disclaimer: Forgive me if my format sucks, I've never submitted a PR before! Fixes: #517 I added a few things to allow zig to link with the CRT properly both statically and dynamically. In Visual Studio 2017, Microsoft changed how the c-runtime is factored again. With this change, they also added a COM interface to allow you to query the respective Visual Studio instance for two of them. This does that and also falls back on a registry query for 2015 support. If you're using a Visual Studio instance older than 2015, you'll have to use the existing options available with the zig compiler. Changes are listed below along with a general description of the changes. all_types.cpp: The separate variables for msvc/kern32 have been removed and all win32 libc directory paths have been combined into a ZigList since we're querying more than two directories and differentiating one from another doesn't matter to lld. analyze.cpp: The existing functions were extended to support querying libc libs & libc headers at runtime. codegen.cpp/hpp: Microsoft uses the new 'Universal C Runtime' name now. Doesn't matter from a functionality standpoint. I left the compiler switches as is to not introduce any breaking changes. link.cpp: We're linking 4 libs and generating another in order to support the UCRT. Dynamic: msvcrt/d, vcruntime/d, ucrt/d, legacy_stdio_definitions.lib Static: libcmt/d, libvcruntime/d libucrt/d, legacy_stdio_definitions.lib main.cpp: Update function call names. os.cpp/hpp: COM/Registry interface for querying Windows UCRT/SDK. Sources: [Windows CRT](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features) [VS 2015 Breaking Changes](https://msdn.microsoft.com/en-us/library/bb531344.aspx) --- src/analyze.cpp | 86 ++++++++++++++++++++++++++------------------------------- 1 file changed, 39 insertions(+), 47 deletions(-) (limited to 'src/analyze.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 89ce5df6b4..4d971465da 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2015 Andrew Kelley * * This file is part of zig, which is MIT licensed. @@ -3371,65 +3371,57 @@ bool handle_is_ptr(TypeTableEntry *type_entry) { } void find_libc_include_path(CodeGen *g) { +#ifdef ZIG_OS_WINDOWS if (!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) { + if (g->win_sdk == nullptr) { + if (os_find_windows_sdk(&g->win_sdk)) { + zig_panic("Unable to determine Windows SDK path."); + } + } + + if (g->zig_target.os == ZigLLVM_Win32) { + if (os_get_win32_ucrt_include_path(g->win_sdk, g->libc_include_dir)) { + zig_panic("Unable to determine libc include path."); + } + } + } + return; +#endif + // TODO find libc at runtime for other operating systems + if(!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) { zig_panic("Unable to determine libc include path."); } } void find_libc_lib_path(CodeGen *g) { #ifdef ZIG_OS_WINDOWS - if (!g->msvc_lib_dir && g->zig_target.os == ZigLLVM_Win32) { - Buf *msvc_lib_dir; - if (g->zig_target.arch.arch == ZigLLVM_arm) { - msvc_lib_dir = buf_create_from_str("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\arm"); - } else if (g->zig_target.arch.arch == ZigLLVM_x86_64) { - msvc_lib_dir = buf_create_from_str("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64"); - } else if (g->zig_target.arch.arch == ZigLLVM_x86) { - msvc_lib_dir = buf_create_from_str("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib"); - } else { - zig_panic("unable to determine msvc lib path"); - } - Buf *test_path = buf_alloc(); - os_path_join(msvc_lib_dir, buf_create_from_str("vcruntime.lib"), test_path); - bool result; - int err; - if ((err = os_file_exists(test_path, &result))) { - result = false; - } - if (result) { - g->msvc_lib_dir = msvc_lib_dir; - } else { - zig_panic("Unable to determine msvc lib path."); + if (g->zig_target.os == ZigLLVM_Win32) { + if (g->win_sdk == nullptr) { + if (os_find_windows_sdk(&g->win_sdk)) { + zig_panic("Unable to determine Windows SDK path."); + } } - } - if (!g->kernel32_lib_dir && g->zig_target.os == ZigLLVM_Win32) { - Buf *kernel32_lib_dir; - if (g->zig_target.arch.arch == ZigLLVM_arm) { - kernel32_lib_dir = buf_create_from_str( - "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\arm"); - } else if (g->zig_target.arch.arch == ZigLLVM_x86_64) { - kernel32_lib_dir = buf_create_from_str( - "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x64"); - } else if (g->zig_target.arch.arch == ZigLLVM_x86) { - kernel32_lib_dir = buf_create_from_str( - "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x86"); - } else { - zig_panic("unable to determine kernel32 lib path"); + Buf* vc_lib_dir = buf_alloc(); + if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) { + zig_panic("Unable to determine vcruntime path."); } - Buf *test_path = buf_alloc(); - os_path_join(kernel32_lib_dir, buf_create_from_str("kernel32.lib"), test_path); - bool result; - int err; - if ((err = os_file_exists(test_path, &result))) { - result = false; + + Buf* ucrt_lib_path = buf_alloc(); + if (os_get_win32_ucrt_lib_path(g->win_sdk, ucrt_lib_path, g->zig_target.arch.arch)) { + zig_panic("Unable to determine ucrt path."); } - if (result) { - g->kernel32_lib_dir = kernel32_lib_dir; - } else { - zig_panic("Unable to determine kernel32 lib path."); + + Buf* kern_lib_path = buf_alloc(); + if (os_get_win32_kern32_path(g->win_sdk, kern_lib_path, g->zig_target.arch.arch)) { + zig_panic("Unable to determine kernel32 path."); } + + g->libc_lib_dirs_list.append(vc_lib_dir); + g->libc_lib_dirs_list.append(ucrt_lib_path); + g->libc_lib_dirs_list.append(kern_lib_path); } + return; #endif // later we can handle this better by reporting an error via the normal mechanism -- cgit v1.2.3