On 11.02.2018 18:41 Ian MacArthur wrote:
>
>> On 11 Feb 2018, at 14:13, Albrecht Schlosser wrote:
>>
>> #define FD_ISSET ... is the key to a patch that works for me with FLTK 1.4. See attached patch mingw-winsock-fltk-1.4_v2.patch. I called it '_v2' because it's a different approach.
>>
>> I don't really like it because we need to redefine not only FD_ISSET to use "our version" but also some more function prototypes.
>>
>> This was a quick shot. A little reordering of functions and prototypes may help to make it shorter, but we have a catch-22 issue: We must #define FD_ISSET before we #include winsock2.h so we don't _know_ the correct definitions of SOCKET, fd_set, and maybe more.
>>
>> Please check yourself.
>
> I looked at that briefly, but couldn’t see any way to do it that I liked. Your way is better than what I had cobbled together. If we do this, we need something that works for the “new” mingw but is still OK with older mingw32 and mingw64 and also with MS cl and... It’s not nice.
What I did should work on all Windows platforms, but I'm not sure if we
can get data type issues, maybe we'd have to add some casts or similar.
The proposed patch would (as it stands) only be for MinGW anyway, and
the solution *should* work on old and new mingw32 and mingw64 platforms.
I did not yet test all combinations though, but I have pretty old
mingw32 and mingw64 as well as absolutely new mingw32 and mingw64 (both
included in my new MSYS2 installation).
The question is whether the "original" MinGW + MSYS has different
headers - which seems to be the case since the OP and my "new"
installation of MinGW/MSYS had the issue whereas the
mingw32/mingw64/MSYS2 installation doesn't have the issue.
> The mingw64 I have is older, and does not exhibit this behaviour - I do not know if they will switch to using this newer variant of the win32api files at some point?
I don't know how these different forks maintain their Windows headers.
ISTR that I saw comments that refer to WINE, so the common root may be
Wine or Cygwin or whatever, but what current forks do and when and how
the synchronize again (if at all) I do not know.
We should be prepared for everything...
>>>> Further (and last) question: If we'd have to add the dependency on winsock2
>>>> for MinGW builds, shouldn't we then add it to all Windows build systems,
>>>> just to keep the dependencies "the same" on all Windows platforms? Maybe it
>>>> would be confusing (at least) if programs linked with one Windows toolchain
>>>> (MinGW) depend on ws2_32.dll but others (Cygwin, Visual Studio) do not?
>>> I don't think it makes sense to have the dll linked at runtime on
>>> those toolchains that (still) support it, if we have to make the code
>>> such that it is linked at compile time for the mingw case now?
>>
>> I did this for FLTK 1.4 with conditional code (__MINGW32__) but I'd like to avoid this.
>>
>>> I couldn't claim to be happy about this, though.
>>
>> Can you explain why we _should_ load winsock2 dynamically? This is a serious question. Do you know of any systems (we still support) that lack support of winsock2 (ws2_32.dll)? So, what do we gain if we do, what do we lose if we link directly with ws2_32?
>
> TBH, I do not know of any current WinXX variant where this would be a problem; we did have issues early on, but I think those days are past now.
I checked the code (by reading) and this is what I understood (but I'm
not sure and I don't know how to test this even if I wanted):
(1) Applications that don't use Fl::add_fd() will never try to load the
winsock2 dll dynamically, hence they will be able to run w/o ws2_32.dll
w/o issues.
(2) Applications that use Fl::add_fd() will work on systems that have
ws2_32.dll, of course.
(3) Applications that use Fl::add_fd() will *crash* on systems that
don't have ws2_32.dll. There is no fallback. At least that's what I read
in the code.
Back to the question "what do we lose?": Only case (1) is worth thinking
about. Most if not all of our test/*.{fl|cxx} demo programs would work,
as well as any GUI programs that don't use sockets (with or w/o add_fd()
if they use winsock2). Programs that use old winsock or any other socket
library would no longer work because they would not find ws2_32.dll
(linked in statically) at startup.
> It still rankles though, but I now think our “best” option is to link in ws2_32 dll and be done with it...
What about linking in ws2_32.dll in FLTK 1.4 but using my proposed FLTK
1.4 patch and the S_OK patch for FLTK 1.3.5 for MinGW only?
The advantages:
(1) Only *MinGW* builds of _FLTK 1.3.5_ (and later 1.3.x) would be
affected. Hence programs that don't use sockets could still successfully
run on "old" Windows systems w/o winsock2 even if built with MinGW. This
is the best we can do for backwards compatibility and w/o breaking the
ABI (new dll dependency for most apps).
(2) We can document the change that FLTK 1.4 requires ws2_32.dll [1] on
all Windows platforms, independent of the build system (MinGW, Visual
Studio, MSYS2, Linux cross compilation, whatever).
(3) We can remove the dynamic loading of winsock functions to:
(3a) make the code more "standard" (e.g. using FD_ISSET macro)
(3b) avoid "late crash" of programs using add_fd().
(4) This will unify all Windows platform to behave in the same way.
-----
[1] additionally to comctl32.dll and other standard Windows dll's
>> I'm not against keeping it as-is (see my patch above, which should be applicable to FLTK 1.3 in a similar way), but it's kinda hackish to suppose we know all these types that would be defined by system supplied macros otherwise.
Now, after thinking about the issue and in the light of possible ABI
changes I think the "split proposal" to
- patch 1.3.5 as described above and
- change 1.4.0 to link in ws2_32 statically
would be my preferred solution. No ABI change in 1.3.5, but "future
proof standard code" in 1.4.0 and later.
If there are no other proposals, then I suggest we vote:
+1 for "split proposal" described above.
>> The SOCKET type is even worse because we define it anyway, and it is different in platforms: Linux (int) != Windows 32-bit != Windows 64-bit.
>
> Unrelated: In other work, I got caught out by MS changing their SOCKET type between 32 and 64 recently... Not helpful!
Yep, and we have STR #3271 which I don't really know how to resolve:
http://www.fltk.org/str.php?L3271
OT:
The conflict is that we have the well-documented API Fl::add_fd(int
socket, ...) and we'd break this contract (API, not "only" ABI) if we'd
change this to Fl::add_fd(FL_SOCKET, ...) where FL_SOCKET is a platform
specific type that can be 'int', 'unsigned int', and 'unsigned __int64'
(see comment #1 - #6 of STR #3271). The same would apply to remove_fd().
But if we break the API (using FL_SOCKET), how would portable user
programs be affected? Would our API be backwards compatible? How many
compiler warnings (or even errors) would we get reported?
Comments welcome, preferred in the STR or, if necessary for discussion,
maybe in a new thread?