brechtsanders/winlibs_mingw

It would be cool to have Win32 threads builds still available

Closed this issue · 14 comments

My apologies for even asking since I assume this is a 100% volunteer project and you probably have better things to do, but was here any consideration to still provide Win32 threads builds of MinGW?

There is still some use for them, since even when compiling a C program that doesn't use any of the built-in threading, the POSIX MinGW build will still require libpthread for Windows to be shipped for the final program which from my experience isn't the case when using Win32 threads MinGW. And for licensing reasons, I think it could be be preferable to not require shipping pthread when it's not actually used - don't take this as legal advice, ask your lawyer, but that's what my own uninformed research suggested may be the case.

I too prefer win32 threads.

Not for legal reasons, but simply because I want my programs to be a single file.

(Though I admittedly haven't checked how MCF works.)

From a quick check, MCF seems to be LGPL which may or may not require shipping its code along with your program. Again I'm not a lawyer, but it vaguely looks like to me like based on that, it might be preferable to not ship it either for a program that just uses plain Win32 API threads, which many more windows-focused programs typically do.

It is perfectly possible to write code using Win32 API threads and compile it with a pthreads GCC+MinGW-w64 toolchain.

That is why I don't really see the need to build a GCC that uses Win32 API threads.

Are you running issues compiling things with Win32 API threads?

It is perfectly possible to write code using Win32 API threads and compile it with a pthreads GCC+MinGW-w64 toolchain.

You can, but it force-pulls in a dependency for the result last time I checked. The final binary depends on libpthread which I think is LGPL-licensed, if I recall correctly. Shipping LGPL libraries, especially when entirely unused, can be legally complicated as far as I know, not that I'm qualified to advise on details. But I never ship POSIX Threading MinGW binaries for that reason.

That doesn't make sense. If you're not using pthreads (#include <pthread.h> / -lpthread / -pthread) the executable shouldn't depend on it.

Also I was told it's allowed to ship libwinpthread-1.dll, though I don't know which licenses it's compatible with exactly.

Looking at https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-libraries/winpthreads/ it seems like it's under MIT license, which is quite liberal.

That doesn't make sense. If you're not using pthreads (#include <pthread.h> / -lpthread / -pthread) the executable shouldn't depend on it.

As far as I recall it does lead to a dependency automatically because apparently a POSIX threads MinGW libc will cause something to be pulled in already, which the Win32 threads MinGW won't do.

To be honest, I don't remember the exact reasons and whether it really pulls in LGPL, or whether it's just that making a single binary becomes a pain. But if you scroll down, winpthreads also includes this license clause: Neither the name of Lockless Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission which actually seems to be possibly GPL-incompatible, or not just MIT. In any case, this all goes away by just using MinGW32 threads gcc.

@ell1e

To be honest, I don't remember the exact reasons and whether it really pulls in LGPL, or whether it's just that making a single binary becomes a pain. But if you scroll down, winpthreads also includes this license clause: Neither the name of Lockless Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission which actually seems to be possibly GPL-incompatible, or not just MIT. In any case, this all goes away by just using MinGW32 threads gcc.

For this part I am speaking as a member of mingw-w64.

Limiting use of names (and trademarks, if any) of original authors is allowed as per bullet D in GPL section 7, so BSD 3-clause can be relicensed as GPL and is not incompatible. On the other hand, if it was BSD 4-clause then it would be incompatible, as the advertisement clause is classified by GPL as a 'further restriction' and is therefore disallowed.

If you have a program that is linked against some GPL libraries and winpthreads, you are allowed to relicense the entire program under GPL; likewise for LGPL.

In addition, if you build a program with GCC, it is sometimes unavoidable that some parts of GCC libraries (libgcc, libstdc++, etc.) get linked into your program. This applies to the win32 thread model. GCC library source code is licensed as GPL, but with an exception that mostly allows you to relicense the combination without causing a GPL violation.


And speaking of myself, thanks for reminding me about this. Licensing mcfgthread under LGPL was probably not a good idea. I have applied the GCC Runtime Library Exception so it can be used the same way as other GCC libraries: https://github.com/lhmouse/mcfgthread/releases/tag/v1.8-ga.3

Oh gosh, I apologize if I said anything wrong, that's awesome that you're a mingw-w64 member 😊

if it was BSD 4-clause then it would be incompatible, as the advertisement clause is classified by GPL as a 'further restriction'

I guess I thought the clause I quoted also sounds like an additional restriction, but I really wouldn't know if that's actually the case. I suppose it could instead just be what's usually assumed as the default, simply spelled out more clearly. I wouldn't know.

Are you running issues compiling things with Win32 API threads?

whether it's just that making a single binary becomes a pain

Some more on that: I recall fiddling around a long while with -Bstatic -lwinpthread -Bsymbolic and eventually ending up in a back and forth on a bug tracker suggesting some issue with the toolchain when I just couldn't statically pull in that one library without some linker error. Maybe it might be useful to link winpthread statically by default for POSIX threading MinGW?

That would maybe make the POSIX threading MinGW build a more painless default.

Some more on that: I recall fiddling around a long while with -Bstatic -lwinpthread -Bsymbolic and eventually ending up in a back and forth on a bug tracker suggesting some issue with the toolchain when I just couldn't statically pull in that one library without some linker error. Maybe it might be useful to link winpthread statically by default for POSIX threading MinGW?

That would maybe make the POSIX threading MinGW build a more painless default.

GCC with the posix thread model has pthread as a default library: mesonbuild/meson#13124 (comment)

It is necessary to tell GCC to not do that, because by default GCC attempts to link against the shared library, and if you provide a static library it will cause multiple definitions. I haven't tried this though:

-no-pthread -l:libwinpthread.a -lmsvcrt -lkernel32

Thanks so much for the in-depth information! I think people are more familiar with needing to specify -pthread rather than needing to use -no-pthread, so that's probably why so many get stuck on this. Maybe POSIX threading MinGW would have a better reputation otherwise.

I have to admit that after this back and forth, I see no reason anymore to use Win32 threading MinGW, assuming the build options you suggested work. But the shared libwinpthread default seems to confuse many.

I'll just say that -static-libgcc -static-libstdc++ -static -lwinpthread has always worked for me. I don't like shared DLLs on windows either, they are not good if you want to make a small standalone program that does not use an installer.

-static is an inconvenient solution in my personal opinion, because it makes it cumbersome to actually link other things shared when you want to. But right now, how to do it more granularly seems to escape most C/C++ coders when using the POSIX threads MinGW build. That's why I'm suggesting maybe winpthread should be linked statically by default.

It seems to be the case that: 1. winpthread is pretty small anyway, 2. winpthread's licensing seems to be suitable for static linking, 3. it's not the kind of library that the user is likely to want to externally upgrade/replace with a different version on their own for any application, and 4. MS Windows doesn't seem to be the kind of target platform where many software developers would be looking to want to share a libwinpthread between their different applications.

@Aerocatia

I don't like shared DLLs on windows either, they are not good if you want to make a small standalone program that does not use an installer.

I very much disagree. DLLs on Windows offer the same advantages as shared libraries on other platforms. People tend to hate DLLs on Windows and call it "DLL hell", but that's usually because it's not well understood, because on Windows all symbols must resolve (which I believe is good as it points out issues already at link time), because symbols must be explicitly exported/imported (__declspec(dllexport)/__declspec(dllimport) or using .def files), and because people mix DLLs they download and copy left and right.

If (like the https://winlibs.com/ builds) you build all dependencies in a consistent way (with the same build tools) there are no signicant issues.

This method allows perfectly for using DLL files in binary distribution of projects, small and big alike.

In fact, in my experience, for larger projects (with many dependencies that have dependencies themselves), building statically may be a lot harder (especially if dependencies don't kome with pkg-config .pc files) than shared builds (where the DLL ecosystem takes care of the dependencies of the DLLs).

@ell1e
If distributing shared pthreads DLL really is an issue for you -Bstatic -lpthread -Bdynamic is how I would make it link statically in an othewase shared build. The paramerer -Bstatic flag will tell the next libraries to link statically. The -Bdynamic is only needed if more -l arguents follow and it tells the linker to use shared libraries for them.

From my memory, the simple -Bstatic -lwinpthread -Bsymbolic sadly doesn't work. It leads to the problem mentioned above that it leads to symbol clashes. It would be nice if it could be made to work out of the box however, to make this situation less confusing.

While I don't mind shared linking of dlls and I see the benefits in larger projects, I still think it's an unfortunate default especially since winpthread.dll isn't written out, and there is no obvious info that it'll be needed or where to get it. I think it would make more sense as a conscious decision for those who see a benefit in having it separate.

I'm just saying this given the past experience of myself and many others ending up confused with this winpthread and how to statically link it, with often -static being used when it shouldn't be.

My apologies for repeating myself, I hope this input is useful.