diff --git a/src/all_types.hpp b/src/all_types.hpp index a5244b87b8..894deca930 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1461,6 +1461,8 @@ struct CodeGen { Buf *libc_lib_dir; Buf *libc_static_lib_dir; Buf *libc_include_dir; + Buf *msvc_lib_dir; + Buf *kernel32_lib_dir; Buf *zig_lib_dir; Buf *zig_std_dir; Buf *zig_c_headers_dir; diff --git a/src/analyze.cpp b/src/analyze.cpp index 3bb4fe6511..292943a6e6 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3359,6 +3359,61 @@ void find_libc_include_path(CodeGen *g) { } 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->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 *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; + } + if (result) { + g->kernel32_lib_dir = kernel32_lib_dir; + } else { + zig_panic("Unable to determine kernel32 lib path."); + } + } +#endif + // later we can handle this better by reporting an error via the normal mechanism if (!g->libc_lib_dir || buf_len(g->libc_lib_dir) == 0) { zig_panic("Unable to determine libc lib path."); diff --git a/src/codegen.cpp b/src/codegen.cpp index 2ffb2c49c2..c8e339b8e3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -117,6 +117,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out g->libc_lib_dir = buf_create_from_str(""); g->libc_static_lib_dir = buf_create_from_str(""); g->libc_include_dir = buf_create_from_str(""); + g->msvc_lib_dir = nullptr; + g->kernel32_lib_dir = nullptr; g->each_lib_rpath = false; } else { // native compilation, we can rely on the configuration stuff @@ -127,6 +129,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR); g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR); g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR); + g->msvc_lib_dir = nullptr; // find it at runtime + g->kernel32_lib_dir = nullptr; // find it at runtime #ifdef ZIG_EACH_LIB_RPATH g->each_lib_rpath = true; #endif @@ -228,6 +232,14 @@ void codegen_set_libc_include_dir(CodeGen *g, Buf *libc_include_dir) { g->libc_include_dir = libc_include_dir; } +void codegen_set_msvc_lib_dir(CodeGen *g, Buf *msvc_lib_dir) { + g->msvc_lib_dir = msvc_lib_dir; +} + +void codegen_set_kernel32_lib_dir(CodeGen *g, Buf *kernel32_lib_dir) { + g->kernel32_lib_dir = kernel32_lib_dir; +} + void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker) { g->dynamic_linker = dynamic_linker; } diff --git a/src/codegen.hpp b/src/codegen.hpp index 549891b107..f4c7f6a8c7 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -31,6 +31,8 @@ void codegen_set_out_name(CodeGen *codegen, Buf *out_name); void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir); void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir); void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir); +void codegen_set_msvc_lib_dir(CodeGen *codegen, Buf *msvc_lib_dir); +void codegen_set_kernel32_lib_dir(CodeGen *codegen, Buf *kernel32_lib_dir); void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker); void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); void codegen_set_windows_unicode(CodeGen *g, bool municode); diff --git a/src/link.cpp b/src/link.cpp index 0a25471d3c..f2f21fd746 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -397,6 +397,14 @@ static void construct_linker_job_coff(LinkJob *lj) { lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&lj->out_file)))); + if (g->libc_link_lib != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); + + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); + } + if (lj->link_in_crt) { const char *lib_str = g->is_static ? "lib" : ""; const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; @@ -441,11 +449,6 @@ static void construct_linker_job_coff(LinkJob *lj) { lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir))); } - if (g->libc_link_lib != nullptr) { - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); - } - for (size_t i = 0; i < g->link_objects.length; i += 1) { lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); } diff --git a/src/main.cpp b/src/main.cpp index 6695ae4225..a9a1d5a8da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,6 +59,8 @@ static int usage(const char *arg0) { " --each-lib-rpath add rpath for each used dynamic library\n" " --libc-lib-dir [path] directory where libc crt1.o resides\n" " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n" + " --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides\n" + " --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides\n" " --library [lib] link against lib\n" " --library-path [dir] add a directory to the library search path\n" " --linker-script [path] use a custom linker script\n" @@ -279,6 +281,8 @@ int main(int argc, char **argv) { const char *libc_lib_dir = nullptr; const char *libc_static_lib_dir = nullptr; const char *libc_include_dir = nullptr; + const char *msvc_lib_dir = nullptr; + const char *kernel32_lib_dir = nullptr; const char *zig_install_prefix = nullptr; const char *dynamic_linker = nullptr; ZigList clang_argv = {0}; @@ -518,6 +522,10 @@ int main(int argc, char **argv) { libc_static_lib_dir = argv[i]; } else if (strcmp(arg, "--libc-include-dir") == 0) { libc_include_dir = argv[i]; + } else if (strcmp(arg, "--msvc-lib-dir") == 0) { + msvc_lib_dir = argv[i]; + } else if (strcmp(arg, "--kernel32-lib-dir") == 0) { + kernel32_lib_dir = argv[i]; } else if (strcmp(arg, "--zig-install-prefix") == 0) { zig_install_prefix = argv[i]; } else if (strcmp(arg, "--dynamic-linker") == 0) { @@ -728,6 +736,10 @@ int main(int argc, char **argv) { codegen_set_libc_static_lib_dir(g, buf_create_from_str(libc_static_lib_dir)); if (libc_include_dir) codegen_set_libc_include_dir(g, buf_create_from_str(libc_include_dir)); + if (msvc_lib_dir) + codegen_set_msvc_lib_dir(g, buf_create_from_str(msvc_lib_dir)); + if (kernel32_lib_dir) + codegen_set_kernel32_lib_dir(g, buf_create_from_str(kernel32_lib_dir)); if (dynamic_linker) codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker)); codegen_set_verbose(g, verbose);