https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108408
Bug ID: 108408 Summary: libphobos: Support building on *-*-cygwin Product: gcc Version: 11.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: d Assignee: ibuclaw at gdcproject dot org Reporter: nightstrike at gmail dot com Target Milestone: --- See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99794 for reference. This PR is tracking the state of building libphobos on cygwin using 11.3, the last compiler that can be bootstrapped natively. Currently, it fails due to missing definitions for FILE, snprintf, time_t, and clock_t. I'm currently trying to add them to libphobos/libdruntime/core/stdc/stdio.d, because the path for CRuntime_Newlib is currently missing. I seem to be falling down a rabbit hole of needing to define struct after struct, so I'm trying to gather the work here in hopes that some kind soul can help. I should clarify that I'm unfamiliar with D, so what I'm putting here definitely needs someone with experience to finish the work. My hope is to just get it far enough along that others can do so. Whoever put in the gcc warning that automatically converts function pointers for you, please accept my thanks! I started by lifting the structure definitions from cygwin's newlib, which unfortunately have quite a few conditional components. I don't know how important this is if for instance a structure has: struct S { #ifdef A int a; #else void * b; }; or some variation of all manner of conditions that change the struct layout and the total size. Guidance as to whether this is the right approach or a total waste of time would be appreciated :). With what I have so far, I'm down to just the following: /cygdrive/k/gcc/src/gcc-git/libphobos/libdruntime/core/sys/posix/stdc/time.d:52:15: error: module core.sys.posix.sys.types import 'time_t' not found 52 | public import core.sys.posix.sys.types : time_t, clock_t; | ^ /cygdrive/k/gcc/src/gcc-git/libphobos/libdruntime/core/sys/posix/stdc/time.d:52:15: error: module core.sys.posix.sys.types import 'clock_t' not found 52 | public import core.sys.posix.sys.types : time_t, clock_t; | ^ /cygdrive/k/gcc/src/gcc-git/libphobos/libdruntime/core/stdc/stdio.d:1514:9: error: undefined identifier 'fpos_t', did you mean alias '_fpos_t'? 1514 | int fgetpos(FILE* stream, scope fpos_t * pos); | ^ /cygdrive/k/gcc/src/gcc-git/libphobos/libdruntime/core/stdc/stdio.d:1516:9: error: undefined identifier 'fpos_t', did you mean alias '_fpos_t'? 1516 | int fsetpos(FILE* stream, scope const fpos_t* pos); | ^ ../../../../libphobos/libdruntime/core/demangle.d:2615:16: error: module core.stdc.stdio import 'snprintf' not found, did you mean function 'core.stdc.stdio.sprintf'? 2615 | import core.stdc.stdio : snprintf; | ^ This is the diff so far: diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index c76b922a3eb..52bcc9d7cdd 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -397,6 +397,196 @@ else version (CRuntime_Microsoft) /// alias shared(_iobuf) FILE; } +else version (CRuntime_Newlib) +{ + alias long _off64_t; + alias long _fpos_t; + alias long _fpos64_t; + alias int _float_t; + + struct __sbuf { + char* _base; + int _size; + } + + struct _mbstate_t { + int _count; + union { + dchar _wch; + char[4] _wchb; + } + } + + struct _rand48 { + ushort[3] _seed; + ushort[3] _mult; + ushort _add; + } + + struct __tm { + int __tm_sec; + int __tm_min; + int __tm_hour; + int __tm_mday; + int __tm_mon; + int __tm_year; + int __tm_wday; + int __tm_yday; + int __tm_isdst; + } + + struct __lc_cats { + const void* ptr; + char* buf; + } + + struct lconv { + char* decimal_point; + char* thousands_sep; + char* grouping; + char* int_curr_symbol; + char* currency_symbol; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char int_n_cs_precedes; + char int_n_sep_by_space; + char int_n_sign_posn; + char int_p_cs_precedes; + char int_p_sep_by_space; + char int_p_sign_posn; + } + + struct __locale_t { + char[7][31 + 1] categories; // #define _LC_LAST 7, #define ENCODING_LEN 31 + extern (C) int function(_reent*, char*, wchar, _mbstate_t*) wctomb; + extern (C) int function(_reent*, wchar*, const char*, size_t, _mbstate_t*) mbtowc; + int cjk_lang; + char* ctype_ptr; + lconv lconv_member; // name collision + // #ifndef __HAVE_LOCALE_INFO__ // FIXME: Which path is enabled on cygwin by default? + char[2] mb_cur_max; + char[31 + 1] ctype_codeset; // #define ENCODING_LEN 31 + char[31 + 1] message_codeset; // #define ENCODING_LEN 31 + // #else + // struct __lc_cats lc_cat[7]; // #define _LC_LAST 7 + // #endif + } + + struct _Bigint { + _Bigint* _next; + int _k; + int _maxwds; + int _sign; + int _wds; + ulong[1] _x; + } + + struct _reent { + int _errno; + + __sFILE64* _stdin; + __sFILE64* _stdout; + __sFILE64* _stderr; + + int _inc; + char[25] _emergency; // #define _REENT_EMERGENCY_SIZE 25 + + // #ifdef _REENT_BACKWARD_BINARY_COMPAT int _reserved_1; + __locale_t* _locale; + // #ifdef _REENT_BACKWARD_BINARY_COMPAT int _reserved_0; + + extern (C) void function(_reent*) __cleanup; + + _Bigint* _p5s; + int _result_k; + _Bigint* _result; + _Bigint** _freelist; + + int _cvtlen; + char* _cvtbuf; + + union U { + struct { + // #ifdef _REENT_BACKWARD_BINARY_COMPAT unsigned int _reserved_2; + char* _strtok_last; + char[26] _asctime_buf; // #define _REENT_ASCTIME_SIZE 26 + __tm _localtime_buf; + int _gamma_signgam; + ulong _rand_next; // __extension__ unsigned long long + _rand48 _r48; + _mbstate_t _mblen_state; + _mbstate_t _mbtowc_state; + _mbstate_t _wctomb_state; + char[8] _l64a_buf; + char[24] _signal_buf; // #define _REENT_SIGNAL_SIZE 24 + int _getdate_err; + _mbstate_t _mbrlen_state; + _mbstate_t _mbrtowc_state; + _mbstate_t _mbsrtowcs_state; + _mbstate_t _wcrtomb_state; + _mbstate_t _wcsrtombs_state; + int _h_errno; + } // _reent; + // #ifdef _REENT_BACKWARD_BINARY_COMPAT + struct { + char*[30] _reserved_3; // unsigned + uint[30] _reserved_4; + } // _reserved_5; + // #endif + } // _new; + + // #ifdef _REENT_BACKWARD_BINARY_COMPAT struct _atexit *_reserved_6; + // #ifdef _REENT_BACKWARD_BINARY_COMPAT struct _atexit _reserved_7; + extern (C) void function(int)* _sig_func; + } + + struct __sFILE64 { + char* _p; // unsigned char + int _r; + int _w; + short _flags; + short _file; + __sbuf _bf; + int _lbfsize; + // ifdef _REENT_SMALL _reent* _data; + void* _cookie; + extern (C) int function(_reent*, void*, char*, int) _read; + extern (C) int function(_reent*, void*, const char*, int) _write; + extern (C) _fpos_t function(_reent*, void*, _fpos_t, int) _seek; + extern (C) int function(_reent*, void*) _close; + + __sbuf _ub; + char* _up; // unsigned char + int _ur; + + char[3] _ubuf; // unsigned char + char[1] _nbuf; // unsigned char + + __sbuf _lb; + + int _blksize; + int _flags2; + + _off64_t _offset; + extern (C) _fpos64_t function(_reent*, void*, _fpos64_t, int) _seek64; + + // #ifndef __SINGLE_THREAD__ _flock_t _lock; + _mbstate_t _mbstate; + } + + alias shared(__sFILE64) FILE; +} else version (CRuntime_Glibc) { import core.stdc.wchar_ : mbstate_t;