From 6365f5a9f3f60c1a65f91dcf2926fefee4228b21 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 26 Feb 2019 17:17:20 -0500 Subject: [PATCH] introduce sys_include_dir for when sys/* files are not with stdlib.h --- src/codegen.cpp | 12 ++--- src/libc_installation.cpp | 96 ++++++++++++++++++++++++++++++++------- src/libc_installation.hpp | 1 + src/translate_c.cpp | 11 ++--- 4 files changed, 92 insertions(+), 28 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 58682cdd88..78bd037839 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8181,14 +8181,13 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { args.append(buf_ptr(g->zig_c_headers_dir)); if (g->libc != nullptr) { - if (buf_len(&g->libc->msvc_lib_dir) != 0) { - Buf *include_dir = buf_sprintf("%s" OS_SEP ".." OS_SEP ".." OS_SEP "include", buf_ptr(&g->libc->msvc_lib_dir)); - args.append("-isystem"); - args.append(buf_ptr(include_dir)); - } - args.append("-isystem"); args.append(buf_ptr(&g->libc->include_dir)); + + if (!buf_eql_buf(&g->libc->include_dir, &g->libc->sys_include_dir)) { + args.append("-isystem"); + args.append(buf_ptr(&g->libc->sys_include_dir)); + } } if (g->zig_target->is_native) { @@ -8848,6 +8847,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length); if (g->libc) { cache_buf(ch, &g->libc->include_dir); + cache_buf(ch, &g->libc->sys_include_dir); cache_buf(ch, &g->libc->crt_dir); cache_buf(ch, &g->libc->lib_dir); cache_buf(ch, &g->libc->static_lib_dir); diff --git a/src/libc_installation.cpp b/src/libc_installation.cpp index 5591aa1bbb..2a8aade6a5 100644 --- a/src/libc_installation.cpp +++ b/src/libc_installation.cpp @@ -12,6 +12,7 @@ static const char *zig_libc_keys[] = { "include_dir", + "sys_include_dir", "crt_dir", "lib_dir", "static_lib_dir", @@ -34,6 +35,7 @@ static bool zig_libc_match_key(Slice name, Slice value, bool * static void zig_libc_init_empty(ZigLibCInstallation *libc) { *libc = {}; buf_init_from_str(&libc->include_dir, ""); + buf_init_from_str(&libc->sys_include_dir, ""); buf_init_from_str(&libc->crt_dir, ""); buf_init_from_str(&libc->lib_dir, ""); buf_init_from_str(&libc->static_lib_dir, ""); @@ -46,7 +48,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget Error err; zig_libc_init_empty(libc); - bool found_keys[array_length(zig_libc_keys)] = {}; // zig_libc_keys_len + bool found_keys[array_length(zig_libc_keys)] = {}; Buf *contents = buf_alloc(); if ((err = os_fetch_file_path(libc_file, contents, false))) { @@ -76,12 +78,13 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget Slice value = SplitIterator_rest(&line_it); bool match = false; match = match || zig_libc_match_key(name, value, found_keys, 0, &libc->include_dir); - match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->crt_dir); - match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->lib_dir); - match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->static_lib_dir); - match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->msvc_lib_dir); - match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->kernel32_lib_dir); - match = match || zig_libc_match_key(name, value, found_keys, 6, &libc->dynamic_linker_path); + match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->sys_include_dir); + match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->crt_dir); + match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->lib_dir); + match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->static_lib_dir); + match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->msvc_lib_dir); + match = match || zig_libc_match_key(name, value, found_keys, 6, &libc->kernel32_lib_dir); + match = match || zig_libc_match_key(name, value, found_keys, 7, &libc->dynamic_linker_path); } for (size_t i = 0; i < zig_libc_keys_len; i += 1) { @@ -100,6 +103,13 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget return ErrorSemanticAnalyzeFail; } + if (buf_len(&libc->sys_include_dir) == 0) { + if (verbose) { + fprintf(stderr, "sys_include_dir may not be empty\n"); + } + return ErrorSemanticAnalyzeFail; + } + if (buf_len(&libc->crt_dir) == 0) { if (!target_is_darwin(target)) { if (verbose) { @@ -195,13 +205,40 @@ static Error zig_libc_find_kernel32_lib_dir(ZigLibCInstallation *self, ZigWindow static Error zig_libc_find_native_msvc_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) { if (sdk->msvc_lib_dir_ptr == nullptr) { if (verbose) { - fprintf(stderr, "Unable to determine vcruntime path\n"); + fprintf(stderr, "Unable to determine vcruntime.lib path\n"); } return ErrorFileNotFound; } buf_init_from_mem(&self->msvc_lib_dir, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len); return ErrorNone; } +static Error zig_libc_find_native_msvc_include_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) { + Error err; + if (sdk->msvc_lib_dir_ptr == nullptr) { + if (verbose) { + fprintf(stderr, "Unable to determine vcruntime.h path\n"); + } + return ErrorFileNotFound; + } + Buf search_path = BUF_INIT; + buf_init_from_mem(&search_path, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len); + buf_append_str(&search_path, "\\..\\..\\include"); + + Buf *vcruntime_path = buf_sprintf("%s\\vcruntime.h", buf_ptr(&search_path)); + bool exists; + if ((err = os_file_exists(vcruntime_path, &exists))) { + exists = false; + } + if (exists) { + self->sys_include_dir = search_path; + return ErrorNone; + } + + if (verbose) { + fprintf(stderr, "Unable to determine vcruntime.h path\n"); + } + return ErrorFileNotFound; +} #else static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, bool verbose) { const char *cc_exe = getenv("CC"); @@ -253,18 +290,38 @@ static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, b while (*search_path == ' ') { search_path += 1; } - Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path); - bool exists; - if ((err = os_file_exists(stdlib_path, &exists))) { - exists = false; + + if (buf_len(&self->include_dir) == 0) { + Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path); + bool exists; + if ((err = os_file_exists(stdlib_path, &exists))) { + exists = false; + } + if (exists) { + buf_init_from_str(&self->include_dir, search_path); + } } - if (exists) { - buf_init_from_str(&self->include_dir, search_path); + if (buf_len(&self->sys_include_dir) == 0) { + Buf *stdlib_path = buf_sprintf("%s/sys/errno.h", search_path); + bool exists; + if ((err = os_file_exists(stdlib_path, &exists))) { + exists = false; + } + if (exists) { + buf_init_from_str(&self->sys_include_dir, search_path); + } + } + if (buf_len(&self->include_dir) != 0 && buf_len(&self->sys_include_dir) != 0) { return ErrorNone; } } if (verbose) { - fprintf(stderr, "unable to determine libc include path: stdlib.h not found in '%s' search paths\n", cc_exe); + if (buf_len(&self->include_dir) == 0) { + fprintf(stderr, "unable to determine libc include path: stdlib.h not found in '%s' search paths\n", cc_exe); + } + if (buf_len(&self->sys_include_dir) == 0) { + fprintf(stderr, "unable to determine libc include path: sys/errno.h not found in '%s' search paths\n", cc_exe); + } } return ErrorFileNotFound; } @@ -345,8 +402,12 @@ static Error zig_libc_find_native_dynamic_linker_posix(ZigLibCInstallation *self void zig_libc_render(ZigLibCInstallation *self, FILE *file) { fprintf(file, "# The directory that contains `stdlib.h`.\n" - "# On POSIX, can be found with: `cc -E -Wp,-v -xc /dev/null`\n" + "# On POSIX, include directories be found with: `cc -E -Wp,-v -xc /dev/null`\n" "include_dir=%s\n" + "# The system-specific include directory. May be the same as `include_dir`.\n" + "# On Windows it's the directory that includes `vcruntime.h`.\n" + "# On POSIX it's the directory that includes `sys/errno.h`.\n" + "sys_include_dir=%s\n" "\n" "# The directory that contains `crt1.o`.\n" "# On POSIX, can be found with `cc -print-file-name=crt1.o`.\n" @@ -377,6 +438,7 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file) { "\n" , buf_ptr(&self->include_dir), + buf_ptr(&self->sys_include_dir), buf_ptr(&self->crt_dir), buf_ptr(&self->lib_dir), buf_ptr(&self->static_lib_dir), @@ -395,6 +457,8 @@ Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) { ZigWindowsSDK *sdk; switch (zig_find_windows_sdk(&sdk)) { case ZigFindWindowsSdkErrorNone: + if ((err = zig_libc_find_native_msvc_include_dir(self, sdk, verbose))) + return err; if ((err = zig_libc_find_native_msvc_lib_dir(self, sdk, verbose))) return err; if ((err = zig_libc_find_kernel32_lib_dir(self, sdk, &native_target, verbose))) diff --git a/src/libc_installation.hpp b/src/libc_installation.hpp index 7a1fb37d67..167f9ee834 100644 --- a/src/libc_installation.hpp +++ b/src/libc_installation.hpp @@ -17,6 +17,7 @@ // Must be synchronized with zig_libc_keys struct ZigLibCInstallation { Buf include_dir; + Buf sys_include_dir; Buf crt_dir; Buf lib_dir; Buf static_lib_dir; diff --git a/src/translate_c.cpp b/src/translate_c.cpp index c38de6bf8c..a0db339065 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4815,14 +4815,13 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const clang_argv.append(buf_ptr(codegen->zig_c_headers_dir)); if (codegen->libc != nullptr) { - if (buf_len(&codegen->libc->msvc_lib_dir) != 0) { - Buf *include_dir = buf_sprintf("%s" OS_SEP ".." OS_SEP ".." OS_SEP "include", buf_ptr(&codegen->libc->msvc_lib_dir)); - clang_argv.append("-isystem"); - clang_argv.append(buf_ptr(include_dir)); - } - clang_argv.append("-isystem"); clang_argv.append(buf_ptr(&codegen->libc->include_dir)); + + if (!buf_eql_buf(&codegen->libc->include_dir, &codegen->libc->sys_include_dir)) { + clang_argv.append("-isystem"); + clang_argv.append(buf_ptr(&codegen->libc->sys_include_dir)); + } } // windows c runtime requires -D_DEBUG if using debug libraries