When trying to build nanomsg (www.nanomsg.org or github.com/nanomsg/nanomsg on AppVeyor using mingw, I found that I was unable to build due to a number of missing or botched symbols.
_snprintf_s and the _TRUNCATE symbol are missing. Easily worked around by a test for #ifdef _MSC_VER but still really annoying.
Worse was that these symbols were missing:
WSAID_CONNECTEX, LPFN_CONNECTEX, PIPE_REJECT_REMOTE_CLIENTS, MSG_WAITALL
There may be others. I don't have a windows system of my own that I can easily test this with, as I rely mostly on AppVeyor for Windows testing and building.
A bug report describing this for nanomsg is here: https://github.com/nanomsg/nanomsg/issues/330
A failed build log, showing the failure, is here:
https://ci.appveyor.com/project/gdamore/nanomsg/build/1.0.162/job/6q0eckryp5a4pax8
(Note that the above job includes a fix for the _snprintf_s problem, in the nanomsg source base. So the errors for that are not shown.)
As a consequence of this problem, users are not able to build nanosmg using mingw. As the nanomsg author, my response to date is for people to simply use Visual Studio, which suffers none of these problems. I have no interest in adding additional spaghetti #ifdefs to check for mingw bustedness. Supporting windows at all at this point is burden enough and then some.
I don't frequent sourceforge (having long ago switched to github) - so please feel free to email me for any follow up. Personally I'm unlikely to take any action other than directing people to avoid mingw for building nanomsg until these issues are resolved and nanomsg exposes the full win32 API.
I'm intrigued: if you don't use MS-Windows yourself, why are you so keen to adopt broken-by-design APIs, such as Microsoft's so called "security enhanced"
_snprintf_s()? (The only thing that this has to do with security enhancement is that it secures an extra level of vendor lock-in for Microsoft -- it is certainly no more secure than a properly C99 conformingsnprintf()implementation, such as MinGW.org provides, and which really would be the appropriate choice here).Regarding the addition of newer MS-Windows features (requiring Vista and later):
_WIN32_WINNT, (and the bug report which you cite clearly demonstrates that neither you nor your project users understand the proper usage of that macro).So, of the symbols you identify as missing, apart from
_snprintf_s(), (which is itself specific to_WIN32_WINNT >= _WIN32_WINNT_VISTA), I can find definitive documention only forPIPE_REJECT_REMOTE_CLIENTS, (and then only to be available when you define_WIN32_WINNT >= _WIN32_WINNT_VISTA). I can also find a tentative reference forMSG_WAITALL, but with no indication as to any_WIN32_WINNTlevel which it may require; I can find nothing pertaining to any other symbol you mention, which might suffice to implement them.Finally, while you may choose to lock your users into a Microsoft proprietary product, I feel obliged to point out that, contrary to a claim within the bug report you cite, MSVC is not free. Certainly, you may acquire a copy of the express, or community edition, at no monetary cost, but this does not equate to "free", in the sense defined by the Free Software Foundation, since even these editions are encumbered by a very much non-free EULA, (which, AIUI, significantly restricts the product's usage, to the extent that it even forbids redistribution, in binary format, of any application you may build with it).
I am the maintainer of nanomsg, which is a messaging system that runs on MS Windows as well as POSIX platforms. However, we have Windows specific knowledge to make use of IOCP and so forth.
Some of my users wish to use mingw. Right now I cannot support that, because the MinGW platform does not expose symbols upon which we depend. In other words, MinGW is not a suitable replacement for VS, because I cannot compile the same code.
Regarding public docs such as _snprintf_s -- see https://msdn.microsoft.com/en-us/library/f30dzcf6.aspx
Yes, I could just use snprintf(), however, that would mean having #ifdef's for mingw. This is already spaghetti code, and I reject the idea that I need to treat mingw as yet another platform.
I'm fully aware of the free-as-in-beer vs. freedom issues. For a compiler, it only really matters to people who want or need to extend the compiler. I support the idea of freedom here, but the free-as-in-beer VS compilers are sufficient to do the job, whereas mingw is deficient. If mingw won't address those deficiencies, then how can I seriously recommend people use it? I'm interesting in using a tool to get the job done, not debating about the political regime where the tool was manufactured. (The freedom concerns are particularly pointless here, IMO, since we're using a platform -- Windows -- which itself isn't "free" as in freedom.)
If mingw is only going to support legacy Windows APIs, and not adopt any newer APIs, then I also cannot recommend it for new work. We have clear needs to support the newer APIs.
Now as to the documentation and origin of the symbols, I will say that I didn't write the code that consumes them. Indeed, I wish I didn't have any such code, because supporting Windows is an onerous burden that I'd rather leave to someone else.
HOWEVER, MSG_WAITALL is defined by POSIX/OpenGroup. http://pubs.opengroup.org/onlinepubs/009695399/functions/recv.html
I've no idea where it may be defined or not on Windows platforms. I know its on Vista and newer at least.
WSAID_CONNECTEX is briefly mentioned here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737606(v=vs.85).aspx
Additionally, LPFN_CONNECTEX is documented in that same file as such:
typedef void (*LPFN_CONNECTEX)();
So public documentation exists.
Yes, I'm aware of that, and of course we can use that as a reference to allow us to declare
_snprintf_s(), but we still must occlude the declaration within an#if _WIN32_WINNT >= _WIN32_WINNT_VISTAblock, while the MinGW default will remain as#define _WIN32_WINNT _WIN32_WINNT_NT4, so you and your users would still need to learn how to use_WIN32_WINNTproperly, and we will need to take great care that we don't expose the DLLIMPORT symbol in any way which would break backward compatibility for WinXP and earlier.MinGW is another (distinct) platform, so you are rejecting a fundamental reality.
MinGW must continue to support legacy Windows versions; this in no way precludes adding support for newer APIs, provided someone can point to suitable documentation to facilitate such additions, (and ideally, also provide appropriate patches), provided such additions can be accommodated without breaking compatibility for legacy Windows versions.
No, it is not defined by POSIX; it is required, and its purpose is described, but the actual definition is left to the system implementor. In MinGW's case, the definition needs to agree with Microsoft's, but since they don't document it, how are we to deduce the appropriate definition?
Well, obviously it should go in
<winsock.h>and<winsock2.h>, but in the absence of documentation, how are we to deduce what should go there? (In any case, I've already suggested a tentative source for an actual definition ofMSG_WAITALL, albeit lacking any indication as to whether or not it might require a_WIN32_WINNTversion guard).Mentioned, but not defined. Once again, without documentation, how are we to deduce an appropriate definition?
Yes, I saw that, but since it should surely represent a pointer to a function with the signature of
ConnectEx(), thattypedefjust looks wrong!Hardly; none of what you've pointed me to provides even the slightest inkling of how any of the associated entities should be defined.
As to why I don't use stock snprintf(), that symbol is missing from stock Windows VS builds. I agree with your Windows-only lock-in comments there, but the problem is that your approach makes me have to choose whether to support VS or mingw. If I have to choose between them, I'm going to choose to support the vendor tools. (I'm declining to provide my own implementation of snprintf -- that way lies madness.)
I don't believe btw, that applications built with VS are non-redistributable. MS does require that certain "Enterprise" level players pay licensing fees, but for everyone else the compiler is free to use, and I believe its output is not restricted.
So, you don't want to taint yourself by looking up a constant in the header file. That's fine. Your compiler, your choice. (Admittedly, it seems like a little unpragmatic approach, but if you're on a political agenda, maybe it makes sense in your world.) (I'll point out that for the constants, you could approach this programmatically by doing a printf() to print the symbolic value. Since the number gets hard coded into programs, it can't really be subject to change.)
As far as nanomsg goes, we will not be supporting mingw. You want to make mingw a unique "special snowflake" platform, by all means feel free. But I far too little time to invest in special casing mingw as a platform, particularly where the is no logical reason why any of my users can't easily use VS. There are enough "real" issues to keep me busy without trying to figure out how to make both mingw and VS users simultaenously happy.
Feel free to close this bug as "will not fix", if that's your position. I'll keep this as a link to hand out to my users when they ask or mingw support; it explains why mingw isn't a viable compiler for nanomsg's purposes.