implemented runtime abi detetction for windows

This commit is contained in:
emekoi 2019-08-01 17:51:53 -05:00
parent e68fee3984
commit f15ec9a59b
3 changed files with 32 additions and 18 deletions

View File

@ -1125,29 +1125,27 @@ Error os_get_cwd(Buf *out_cwd) {
#endif
}
#if defined(ZIG_OS_WINDOWS)
#define is_wprefix(s, prefix) \
(wcsncmp((s), (prefix), sizeof(prefix) / sizeof(WCHAR) - 1) == 0)
static bool is_stderr_cyg_pty(void) {
HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
if (stderr_handle == INVALID_HANDLE_VALUE)
bool ATTRIBUTE_MUST_USE os_is_cygwin_pty(int fd) {
#if defined(ZIG_OS_WINDOWS)
HANDLE handle = (HANDLE)_get_osfhandle(fd);
// Cygwin/msys's pty is a pipe.
if (handle == INVALID_HANDLE_VALUE || GetFileType(handle) != FILE_TYPE_PIPE) {
return false;
}
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
FILE_NAME_INFO *nameinfo;
WCHAR *p = NULL;
// Cygwin/msys's pty is a pipe.
if (GetFileType(stderr_handle) != FILE_TYPE_PIPE) {
return 0;
}
nameinfo = (FILE_NAME_INFO *)allocate<char>(size);
FILE_NAME_INFO *nameinfo = (FILE_NAME_INFO *)allocate<char>(size);
if (nameinfo == NULL) {
return 0;
return false;
}
// Check the name of the pipe:
// '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master'
if (GetFileInformationByHandleEx(stderr_handle, FileNameInfo, nameinfo, size)) {
if (GetFileInformationByHandleEx(handle, FileNameInfo, nameinfo, size)) {
nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0';
p = nameinfo->FileName;
if (is_wprefix(p, L"\\cygwin-")) { /* Cygwin */
@ -1180,12 +1178,14 @@ static bool is_stderr_cyg_pty(void) {
}
free(nameinfo);
return (p != NULL);
}
#else
return false
#endif
}
bool os_stderr_tty(void) {
#if defined(ZIG_OS_WINDOWS)
return _isatty(_fileno(stderr)) != 0 || is_stderr_cyg_pty();
return _isatty(_fileno(stderr)) != 0 || os_is_cygwin_pty(_fileno(stderr));
#elif defined(ZIG_OS_POSIX)
return isatty(STDERR_FILENO) != 0;
#else
@ -1486,7 +1486,7 @@ WORD original_console_attributes = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BL
void os_stderr_set_color(TermColor color) {
#if defined(ZIG_OS_WINDOWS)
if (is_stderr_cyg_pty()) {
if (os_stderr_tty()) {
set_color_posix(color);
return;
}

View File

@ -11,6 +11,7 @@
#include "list.hpp"
#include "buffer.hpp"
#include "error.hpp"
#include "target.hpp"
#include "zig_llvm.h"
#include "windows_sdk.h"
@ -152,6 +153,8 @@ Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf
Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
Error ATTRIBUTE_MUST_USE os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
bool ATTRIBUTE_MUST_USE os_is_cygwin_pty(int fd);
Error ATTRIBUTE_MUST_USE os_self_exe_shared_libs(ZigList<Buf *> &paths);
#endif

View File

@ -506,7 +506,7 @@ void get_native_target(ZigTarget *target) {
&oformat);
target->os = get_zig_os_type(os_type);
target->is_native = true;
if (target->abi == ZigLLVM_UnknownEnvironment) {
if (target->os == OsWindows || target->abi == ZigLLVM_UnknownEnvironment) {
target->abi = target_default_abi(target->arch, target->os);
}
if (target_is_glibc(target)) {
@ -1504,6 +1504,16 @@ bool target_is_single_threaded(const ZigTarget *target) {
return target_is_wasm(target);
}
static ZigLLVM_EnvironmentType target_get_win32_abi() {
FILE* files[] = { stdin, stdout, stderr, nullptr };
for (int i = 0; files[i] != nullptr; i++) {
if (os_is_cygwin_pty(_fileno(files[i]))) {
return ZigLLVM_GNU;
}
}
return ZigLLVM_MSVC;
}
ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
if (arch == ZigLLVM_wasm32 || arch == ZigLLVM_wasm64) {
return ZigLLVM_Musl;
@ -1544,8 +1554,9 @@ ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
case OsHurd:
return ZigLLVM_GNU;
case OsUefi:
case OsWindows:
return ZigLLVM_MSVC;
case OsWindows:
return target_get_win32_abi();
case OsLinux:
case OsWASI:
return ZigLLVM_Musl;