From: Keith M. <kei...@to...> - 2005-09-29 15:46:21
|
Angus Leeming wrote: > So clearly I can write an autoconf test to see whether this file exists, > but I can't use the __W32API_VERSION directly in my own code :( No need to write one. The standard macro AC_CHECK_HEADERS([w32api.h]) will do it for you, and define HAVE_W32API_H in config.h for free! HTH. Keith. P.S. I'll post an example of a functional check tomorrow, based on the code you posted earlier. |
From: Keith M. <kei...@to...> - 2005-09-30 10:43:14
|
Angus Leeming wrote: > Anyway, the following piece of code will always compile on > MinGW yet will fail to compile against MS's Win95 header files. > > #include <windows.h> > int main() { > WIN32_FILE_ATTRIBUTE_DATA foo; > GET_FILEEX_INFO_LEVELS bar; > (void)foo; > (void)bar; > return 0; > } So, for an autoconf test, you could use something like:-- <file name="aclocal.m4" excerpt="yes"> # WIN32_AC_CHECK_TYPEDEF( MACRONAME ) # ----------------------------------- # Define HAVE_WORKING_MACRONAME to 1, in config.h, # if the C preprocessor macro MACRONAME is defined, # and serves as a typedef. # AC_DEFUN([WIN32_AC_CHECK_TYPEDEF], [AC_MSG_CHECKING([whether $1 typedef macro works]) AC_LANG_PUSH(C) AC_COMPILE_IFELSE(dnl AC_LANG_PROGRAM(dnl [[dnl #include <windows.h> ]], [[dnl $1 foo; ]]),dnl AC_DEFINE([HAVE_WORKING_$1], [1], [Define to 1, if $1 works]) AC_MSG_RESULT([yes]),dnl AC_MSG_RESULT([no])) AC_LANG_POP([C])dnl ]) </file> <file name="configure.ac" excerpt="yes"> AC_INIT AC_PREREQ([2.59]) AC_CONFIG_HEADERS([config.h]) AC_PROG_CC WIN32_AC_CHECK_TYPEDEF([WIN32_FILE_ATTRIBUTE_DATA]) WIN32_AC_CHECK_TYPEDEF([GET_FILEEX_INFO_LEVELS]) AC_OUTPUT </file> <commands> autoconf autoheader ./configure </commands> should define `HAVE_WORKING_WIN32_FILE_ATTRIBUTE_DATA' in config.h, for all but the MS/Win95 case; (not sure if you would need the `(void)foo;' from your example; the requirement is that you need just enough to make the compiler choke). You can then use:-- <example> #ifdef HAVE_WORKING_WIN32_FILE_ATTRIBUTE_DATA /* code which depends on WIN32_FILE_ATTRIBUTE_DATA */ : #else /* workaround for Win95 */ : #endif </example> Notice that I've marked the two files as "excerpted", because they will normally include much more besides this example; however, the example is completely self-contained, if you want to try it out. Disclaimer: I don't have a Win95 box, or an MS compiler, to verify if it works as advertised -- it says "yes" for both tests, as expected with MinGW on Win2K, and "no" on GNU/Linux, (even if I provide an empty windows.h, for it to find). HTH. Keith. |
From: Angus L. <le...@ly...> - 2005-09-30 11:18:19
|
Keith MARSHALL wrote: > Angus Leeming wrote: >> Anyway, the following piece of code will always compile on >> MinGW yet will fail to compile against MS's Win95 header files. >> >> #include <windows.h> >> int main() { >> WIN32_FILE_ATTRIBUTE_DATA foo; >> GET_FILEEX_INFO_LEVELS bar; >> (void)foo; >> (void)bar; >> return 0; >> } > > So, for an autoconf test, you could use something like:-- Nice! Shame that we can't use any of MS's compilers with the autotools directly :) (A cygwin tool wrapmsvc.cpp does exist, but I've never had the patience to get it up and running.) More seriously, you're accumulating a heap of useful stuff. It would make sense to add an autoconf macros repository to the MSys web site, no? (As for the (void)foo; --- well I guess whether you need it depends on the warning levels you're using on your compiler and whether you've set warning == fatal. I don't think you should assume too much :)) Angus |
From: Keith M. <kei...@to...> - 2005-10-03 09:46:43
|
Angus Leeming wrote, quoting me: >> Only if windows.h provides a definition which makes the statement >> syntactically valid, will the test pass. Do you know of any case >> where this will pass, when you believe it should fail? If so, is >> merely adding an additional `(void)foo;' sufficient to promote >> the failure? > > Hmmmm. I was thinking of things the other way around. Ie, I do have > access to the WIN32_FILE_ATTRIBUTE_DATA declaration but I'm got my > compiler set up to be pedantic in the extreme. Ie, the test would > pass but the "variable is unused" warning issued by the compiler is > sufficient to cause it to fail because I have it set to > "warning == failure". > > It's the sort of little detail that you do tend to see in generated > tests, so I guess the autoconf people have been bitten by it in the > past. Ahh. I see what you mean; with `./configure CFLAGS="-Wall -Werror"' the test would fail, even when it should pass! So... <file name="aclocal.m4" excerpt="yes"> # WIN32_AC_CHECK_TYPEDEF( MACRONAME ) # ----------------------------------- # Define HAVE_WORKING_MACRONAME to 1, in config.h, # if the C preprocessor macro MACRONAME is defined, # and serves as a typedef. # AC_DEFUN([WIN32_AC_CHECK_TYPEDEF], [AC_MSG_CHECKING([whether $1 typedef macro works]) AC_LANG_PUSH(C) AC_COMPILE_IFELSE(dnl AC_LANG_PROGRAM(dnl [[ #include <windows.h> ]], [[ $1 foo; (void) foo; ]]),dnl AC_DEFINE([HAVE_WORKING_$1], [1], [Define to 1, if $1 works]) AC_MSG_RESULT([yes]),dnl AC_MSG_RESULT([no])) AC_LANG_POP([C])dnl ]) </file> should fix the problem. Regards, Keith. |
From: Keith M. <kei...@to...> - 2005-10-03 09:57:41
|
Angus Leeming wrote: > Playing devil's advocate if I may for a while: do I *have* to > compile my code with MinGW gcc if I compile against the MinGW > w32api header files? In principle, there's nothing to stop you using MinGW's headers with some other compiler; in practice it isn't a good idea. There may well be syntactical variations, which the `foreign' compiler doesn't understand, or understands differently, and you're on your own sorting out the ensuing mess, if it `sort of' works, but does so imperfectly. Regards, Keith. |
From: Angus L. <le...@ly...> - 2005-09-29 16:58:02
|
Keith MARSHALL wrote: > Angus Leeming wrote: >> So clearly I can write an autoconf test to see whether this file exists, >> but I can't use the __W32API_VERSION directly in my own code :( > > No need to write one. The standard macro > AC_CHECK_HEADERS([w32api.h]) > will do it for you, and define HAVE_W32API_H in config.h for free! Right. However, the point I'm trying to make is that it's entirely within the MinGW team's control to #include <w32api.h> in all it's win*.h files. If they had done that then I wouldn't need to use autoconf at all to define yet another macro. I'm trying to propose a patch to Boost.Filesystem that will enable the code to run on Win95 by using the NewAPIs.h documented WANT_GETFILEATTRIBUTESEX_WRAPPER macro. The code is messy because MinGW's winapi headers and NewAPIs.h do not live well together. However, I was hoping that it would nonetheless "just work": #include <windows.h> +#if defined (WANT_GETFILEATTRIBUTESEX_WRAPPER) + +// MinGW's winapi header files and NewAPI.h do not live well together +// because NewAPIs.h redefines WIN32_FILE_ATTRIBUTE_DATA if +// WINVER < 0x04A. +# if WINVER < 0x040A && \ + defined (__W32API_MAJOR_VERSION) && \ + defined (__W32API_MINOR_VERSION) && \ + (__W32API_MAJOR_VERSION < 3 || \ + __W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION <= 3) +# define BOOST_MINGW_WINVER WINVER +# undef WINVER +# define WINVER 0x40A +# endif + +# include <NewAPIs.h> + +// Return all macro definitions to their original state. +# ifdef BOOST_MINGW_WINVER +# undef WINVER +# define WINVER BOOST_MINGW_WINVER +# undef BOOST_MINGW_WINVER +# endif +#endif As it is, I'm going to have to require Boost users who want their code to work on Win95 when compiled with MinGW to define another preprocessor macro HAVE_WIN32API_H because I can't deduce this myself. That means I'm going to have to write some documentation :( +#if defined (WANT_GETFILEATTRIBUTESEX_WRAPPER) + +// MinGW's winapi header files and NewAPI.h do not live well together +// because NewAPIs.h redefines WIN32_FILE_ATTRIBUTE_DATA if +// WINVER < 0x04A. +# if WINVER < 0x040A && defined HAVE_WIN32API_H +# include <w32api.h> +# if __W32API_MAJOR_VERSION < 3 || \ + __W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION <= 3 +# define BOOST_MINGW_WINVER WINVER +# undef WINVER +# define WINVER 0x040A +# endif +# endif + +# include <NewAPIs.h> + +// Return all macro definitions to their original state. +# ifdef BOOST_MINGW_WINVER +# undef WINVER +# define WINVER BOOST_MINGW_WINVER +# undef BOOST_MINGW_WINVER +# endif +#endif It would be nice if the MinGW source could be modified to allow its winapi headers to coexist harmoniously with NewAPIs.h. That, however, won't happen now because I was thoughtless yesterday :( The second best solution would be to make the __W32API macros visible from so that things could be made to "just work". If I ask really nicely, is there any chance that this will be done in the future? Pretty please! Kind regards, Angus |
From: Greg C. <chi...@co...> - 2005-09-29 22:06:27
|
On 2005-9-29 16:53 UTC, Angus Leeming wrote: > > Right. However, the point I'm trying to make is that it's entirely within > the MinGW team's control to #include <w32api.h> in all it's win*.h files. > If they had done that then I wouldn't need to use autoconf at all to > define yet another macro. As far as I can guess, the idea behind <w32api.h> is that the programmer should #include it explicitly if version information is wanted. Or maybe it's not really intended to be #included at all. A patch to define __W32API_VERSION __W32API_MAJOR_VERSION __W32API_MINOR_VERSION whenever a top-level msw header is #included sounds like a good idea to me, though maybe I'm missing something. To #include the present <w32api.h> in other system headers seems like the wrong way, because conflicts with macros like 'IE3' are possible. |
From: Angus L. <le...@ly...> - 2005-09-29 22:38:05
|
Greg Chicares wrote: >> Right. However, the point I'm trying to make is that it's entirely >> within the MinGW team's control to #include <w32api.h> in all it's >> win*.h files. If they had done that then I wouldn't need to use autoconf >> at all to define yet another macro. > > As far as I can guess, the idea behind <w32api.h> is that > the programmer should #include it explicitly if version > information is wanted. Or maybe it's not really intended > to be #included at all. > > A patch to define > __W32API_VERSION > __W32API_MAJOR_VERSION > __W32API_MINOR_VERSION > whenever a top-level msw header is #included sounds like > a good idea to me, though maybe I'm missing something. > > To #include the present <w32api.h> in other system headers > seems like the wrong way, because conflicts with macros > like 'IE3' are possible. Right. But to split it into <w32api_version.h> which defines only the three macros above and <w32api.h> which contains everything else that's in the present <w32api.h>? I can't see the problem and it would certainly make users' lives easier. Regards, Angus |
From: Earnie B. <ea...@pr...> - 2005-09-30 11:17:24
|
Quoting Angus Leeming <le...@ly...>: > > Right. But to split it into <w32api_version.h> which defines only the three > macros above and <w32api.h> which contains everything else that's in the > present <w32api.h>? I can't see the problem and it would certainly make > users' lives easier. > In the years of MinGW existence only you have complained so I'm not sure how many users lives other than one would be made easier. If you wish to support Windows 95 by use of many compilers you must define _WIN32_WINNT to have a value of 0x0400 before including windows.h. I think your barking up the wrong tree with trying to determine if you're using MinGW's w32api or not. It shouldn't matter. BTW, MinGW is not actively supporting features for W95 any longer. W98 is the lowest actively supported version. Earnie |
From: Earnie B. <ea...@pr...> - 2005-09-30 11:08:03
|
Quoting Greg Chicares <chi...@co...>: > On 2005-9-29 16:53 UTC, Angus Leeming wrote: >> >> Right. However, the point I'm trying to make is that it's entirely within >> the MinGW team's control to #include <w32api.h> in all it's win*.h files. >> If they had done that then I wouldn't need to use autoconf at all to >> define yet another macro. > > As far as I can guess, the idea behind <w32api.h> is that > the programmer should #include it explicitly if version > information is wanted. Or maybe it's not really intended > to be #included at all. > > A patch to define > __W32API_VERSION > __W32API_MAJOR_VERSION > __W32API_MINOR_VERSION > whenever a top-level msw header is #included sounds like > a good idea to me, though maybe I'm missing something. > > To #include the present <w32api.h> in other system headers > seems like the wrong way, because conflicts with macros > like 'IE3' are possible. > I added w32api.h to simply indicate the versioning. I later added the constants for OS and IE so that I didn't have to go look at msdn to remember the values. I suppose an argument that the windows.h file at least should include w32api.h but that is not a definitive statement and I don't have time to research the pros and cons. As for Angus' problem with code working in MinGW and not in VC the difference is the fact that our supported OS is set to 95 and VC's support OS is set to the most current version of the OS. So if Angus wants the code to build in VC he needs to set _WIN32_WINNT to 0x0400 before including windows.h. Earnie |
From: Angus L. <le...@ly...> - 2005-09-30 12:08:09
|
Earnie Boyd wrote: > I added w32api.h to simply indicate the versioning. I later added the > constants for OS and IE so that I didn't have to go look at msdn to > remember the values. I suppose an argument that the windows.h file at > least should include w32api.h but that is not a definitive statement and > I don't have time to research the pros and cons. Can I suggest splitting w32api.h into two? w32api_version.h would contian only the three __W32API_VERSION macros. It's this that would be included in the other win*.h files. I'm perfectly willing to make the patch. Just give me the nod. > As for Angus' problem with code working in MinGW and not in VC the > difference is the fact that our supported OS is set to 95 and VC's > support OS is set to the most current version of the OS. So if Angus > wants the code to build in VC he needs to set _WIN32_WINNT to 0x0400 > before including windows.h. Thanks. I've answered this in detail in my reply to your other post. Angus |
From: Angus L. <le...@ly...> - 2005-09-30 12:11:48
|
Earnie Boyd wrote: > Quoting Angus Leeming: >> Right. But to split it into <w32api_version.h> which defines only the >> three macros above and <w32api.h> which contains everything else that's >> in the present <w32api.h>? I can't see the problem and it would >> certainly make users' lives easier. > In the years of MinGW existence only you have complained so I'm not sure > how many users lives other than one would be made easier. Just in case you think I'm being hostile after our earlier conversation --- I'm not. Email isn't always an easy medium to get across such nuances. So, let me be crystal clear: I'm not complaining. I'm merely telling you of the hoops that I needed to jump through to get some code to work both with MinGW and with MSVC. I'm attempting to be proactive by also making some suggestions. > If you wish to support Windows 95 by use of many compilers you must > define _WIN32_WINNT to have a value of 0x0400 before including windows.h. Right. I knew that anyway, but thanks for the tip. However, it doesn't help in this case because (I believe that) there's a bug in the MinGW headers. See below. > I think your barking up the wrong tree with trying to determine if > you're using MinGW's w32api or not. It shouldn't matter. But that's the point: it does matter because, as things stand, MinGW's w32api headers don't live nicely with NewAPIs.h. I think that there really is a bug here: The msdn docs state that WIN32_FILE_ATTRIBUTE_DATA and GET_FILEEX_INFO_LEVELS exist only for Win98 and later: http://msdn.microsoft.com/library/en-us/fileio/fs/win32_file_attribute_data_str.asp As of __W32API_VERSION 3.3, these structures are unprotected by a preprocessor block conditioned on WINVER. That appears to be a simple oversight in the MinGW headers. > BTW, MinGW is not actively supporting features for W95 any longer. W98 > is the lowest actively supported version. <shrug>I can't force you to make the changes, but I can't see any reason not to either.<\shrug> Anyway, there's a wider point here. There are doubtless other corner cases where some small detail of the MinGW headers differ from Microsoft's. Having access to the __W32API_VERSION would make it trivially easy to work around such problems as and when they arise. Angus |
From: Earnie B. <ea...@pr...> - 2005-10-03 13:05:07
|
Quoting Angus Leeming <le...@ly...>: > I think that there really is a bug here: > > The msdn docs state that WIN32_FILE_ATTRIBUTE_DATA and > GET_FILEEX_INFO_LEVELS exist only for Win98 and later: > > http://msdn.microsoft.com/library/en-us/fileio/fs/win32_file_attribute_data_str.asp > I would be a little cautious with regard to removing items from Win95 based on this current documentation. MS now considers Windows 95 as dead and are most likely removing references to it as they update for LONGHORN. AFAIK, WIN32_FILE_ATTRIBUTE_DATA exists for Windows 95. Earnie |
From: Earnie B. <ea...@pr...> - 2005-10-03 13:09:30
|
Quoting Angus Leeming <le...@ly...>: > > Anyway, there's a wider point here. There are doubtless other corner cases > where some small detail of the MinGW headers differ from Microsoft's. > Having access to the __W32API_VERSION would make it trivially easy to work > around such problems as and when they arise. > If there are bugs in the header files, there is a bug reporting facility and a patch submission facility that can be used to help resolve the issues. As for patching w32api.h and including it in other headers, I'll leave it up to the other developers to decide. Earnie |