Euphoria
Ticket #731:
_WIN32_IE not defined with gcc 4.6.1 minGW
-
Reported by
ne1uno
Dec 01, 2011
be_runtime.c: In function 'eu_startup':
be_runtime.c:4823:7: warning: assignment from incompatible pointer type [enabled by default]
be_runtime.c:4843:3: error: unknown type name 'INITCOMMONCONTROLSEX'
be_runtime.c:4848:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
#ifdef EWINDOWS
#if defined(EMINGW) && INTPTR_MAX == INT32_MAX
// some versions of MinGW don't define this
#if __GNUC__ < 5 && __GNUC_MINOR__ < 6
#define _WIN32_IE 0x0400
#endif
#endif
#include <windows.h>
#include <commctrl.h>
#endif
looks like gcc 461 from nuwen isn't defining
_WIN32_IE 0x0400
builds & tests ok when comment out the #if and let _WIN32_IE be defined
I built last week w/gcc 4.6.0 from nuwen* and was ok. no idea why it would have changed.
nuwen is a popular packager of minGW & msys.
rather than checking for gcc version
#if !defined(_WIN32_IE)
#define _WIN32_IE 0x0400
#endif
//untested
this would enable trials with other values of
_WIN32_IE too
Details
1. Comment by mattlewis
Dec 02, 2011
This is a somewhat frustrating aspect of MinGW headers. I had issues doing a defined check with 64-bit headers (IIRC). We probably need to have an autoconf-like process that checks to see if it's really there or not during configuration. I've seen different things across versions, cross vs native compilers and target architectures.
2. Comment by SDPringle
Dec 02, 2011
Better to check if _WIN32_IE is defined. If it is undefine it and ten define it to what it has to be.
3. Comment by ne1uno
Dec 03, 2011
undefine it and ten define it to what it has to be.
it could be 0x500 or something else all euphoria needs is minimum 0x400 to include the parts it uses from the headers.
check for minimum of 0x400 but not force 0x400 if it is higher.
4. Comment by mattlewis
Dec 03, 2011
You cannot simply look for its existence inside of the source code. If it's not defined in windows.h, then it needs to be defined prior to windows.h. And if you define it to a value different than what is already defined in windows.h, then you'll get an error.
This is why I suggest an autoconf-like process where we actually compile a simple test program that can detect the value:
int main(){
#ifdef _WIN32_IE__
return 0;
#else
return 1;
#endif
}
Not that this is exactly the best way to do it, but something like that.
5. Comment by ne1uno
Dec 03, 2011
cross compiler headers must be broken then, you must be able to set various IE and WINVER defines. many projects do this to set the minimum windows supported.
maybe there is an update available?
6. Comment by ne1uno
Dec 03, 2011
forgot you can't edit comments in tickets,
a check is still the best way.
part of the problem may be the win64 headers are trying to be more compatible with msvc defines.
7. Comment by mattlewis
Dec 03, 2011
Yes, it seems to be an inconsistency across different versions. Checking the version seemed the most obvious (though ugly) thing to do at the time. Actually, I'm not certain that it was a cross compiler.
I think there were also problems with the particular version or something. We'd been setting it to 4 or whatever, and something wanted 5, or something.
8. Comment by mattlewis
Dec 04, 2011
OK, I rediscovered the problem, in "x86_64-w64-mingw32-gcc (GCC) 4.6.1" and "i686-w64-mingw32-gcc (GCC) 4.6.1", inside of commctrl.h I find this:
#ifndef _WINRESRC_
#ifndef _WIN32_IE
#define _WIN32_IE 0x0501
#else
/* FIXME: This really must be 0x0501 !!! */
#if (_WIN32_IE < 0x0500)
#error _WIN32_IE setting conflicts
#endif
#endif
#endif
These versions do not define _WIN32_IE, however, they do define WINVER, which I believe is used to determine the value of _WIN32_IE:
// gcc bug.c -o bug
#include <stdio.h>
#include <windows.h>
struct symtab_entry typedef _symtab_entry;
int main( int x ){
#ifdef WINVER
printf("WINVER: 0x%0004x\n", WINVER );
#else
puts("NO WINVER");
#endif
#ifdef __WIN32_IE
printf("_WIN32_IE 0x%04x\n", _WIN32_IE);
#else
puts("no _WIN32_IE");
#endif
return 0;
}
This results in:
$ x86_64-w64-mingw32-gcc -o bug.exe bug.c && ~/wine64/wine bug.exe
WINVER: 0x0502
no _WIN32_IE
$ i686-w64-mingw32-gcc -o bug.exe bug.c && ~/wine64/wine bug.exe
WINVER: 0x0502
no _WIN32_IE
So the correct thing to do appears to be to use WINVER to define this.
9. Comment by mattlewis
Dec 04, 2011
See: hg:euphoria/rev/854ddc6ffa77
changeset: 5306:854ddc6ffa77 branch: 4.0 tag: tip user: Matt Lewis date: Sun Dec 04 14:55:27 2011 -0500 files: source/be_runtime.c description:
- use WINVER to define _WIN32_IE
- maybe fixes ticket 731
10. Comment by ne1uno
Dec 04, 2011
_WIN32_IE and WINVER can be 0x501 for win64 haven't seen, don't expect to see a win9 x64 fork.
11. Comment by ne1uno
Dec 05, 2011
configure needs a WINVER option, otherwise WINVER and _WIN32_IE will be set to whatever system doing the build or source distribution.
could this be affecting sockets too?
12. Comment by mattlewis
Dec 05, 2011
Hmm, good point. I suppose we need to know how MinGW headers deal with WINVER. And maybe this is an argument against dropping Watcom.