Folks,
Just as I thought 'fine, I'll add the #ifdef, and get it over with', this thing comes back to haunt me. For the record, I've delete the previous thread, _and_ the io.h patch from my tree, thinking the issue was put to rest.
As you can probably guess, I have the io.h problems in wxWindows, simply because this is what I work on right now. Let me state the problem again: -- When you compile with winegcc, you get these macros: __WINE__, __WIN32__, __UNIX__ -- You want your source to compile with the native libc and/or msvcrt -- You want it portable between Wine/MinGW/Cygwin.
So, let's say I do: #ifndef __UNIX__ #include <io.h> #endif
Well, this will not work if I want to compile with msvcrt, because __UNIX__ will be defined anyway. So what do I have to test for? I have to define a new symbol (USE_MSVCRT) and test for it
#if !defined(__UNIX__) || defined(USE_MSVCRT) #include <io.h> #endif
But this is not all! For example, wxWindows includes stuff like this: #include <sys/unistd.h> #include <sys/stat.h> Since they are available in mingw, and cygwin, and in UNIX, but if I want to use msvcrt they conflit with stuff from there!
It's a mess. As you can see, the defines alone can make a grown man cry, and this is for a simple include. And I don't even know I've covered all the basis! Problem is that there are already 5 platforms: UNIX, Wine, Cygwin, MinGW, MS. And complexity grows exponentially with the number of platforms and combinations you have to test for.
This way lays madness. It is now clear to me why the Cygwin people included io.h. It's so that you can compile with or without the -mno-cygwin switch, and have everything work. The only way for that to happen without ungodly defines and tests, is to have a flat space of include files: a union of MS & Unix files. Even if they are empty! This way you can simply do:
#include <unistd.h> #include <io.h>
and you make sure you get the access() definition regardless if you use the msvcrt of the libc.
I'm not sure what to do. I was hoping to get a include/cygwin and/or a include/mingw directory so we can deal with these problems. I didn't know mingw had Unix headers as well, this complicates matters.
Any fresh ideas in this matter are highly appreciated.
Dimitrie O. Paun wrote:
#if !defined(__UNIX__) || defined(USE_MSVCRT) #include <io.h> #endif
But this is not all! For example, wxWindows includes stuff like this: #include <sys/unistd.h> #include <sys/stat.h> Since they are available in mingw, and cygwin, and in UNIX, but if I want to use msvcrt they conflit with stuff from there!
It's a mess. As you can see, the defines alone can make a grown man cry, and this is for a simple include. And I don't even know I've covered all the basis! Problem is that there are already 5 platforms: UNIX, Wine, Cygwin, MinGW, MS. And complexity grows exponentially with the number of platforms and combinations you have to test for.
This way lays madness. It is now clear to me why the Cygwin people included io.h. It's so that you can compile with or without the -mno-cygwin switch, and have everything work. The only way for that to happen without ungodly defines and tests, is to have a flat space of include files: a union of MS & Unix files. Even if they are empty! This way you can simply do:
#include <unistd.h> #include <io.h>
Applications that use autoconf surround each #include with a test for that header's presence, e.g.
#if HAVE_IO_H #include <io.h> #endif #if HAVE_UNISTD_H #include <unistd.h> #endif
That's best practice when writing applications.
When creating a platform, on the other hand, it's probably best practice to have all those headers, even if they're empty, so everyone can #include them without worrying about the #if HAVE_BLAH_H's. - Dan
"Dimitrie O. Paun" dpaun@rogers.com writes:
So, let's say I do: #ifndef __UNIX__ #include <io.h> #endif
Well, this will not work if I want to compile with msvcrt, because __UNIX__ will be defined anyway. So what do I have to test for?
I think it would work. What you have to do is something like:
#ifndef __UNIX__ #include <io.h> #else #include <unistd.h> #endif
(you could also use #ifdef _MSC_VER instead, since unistd.h should work everywhere except on MSVC)
This would require us to add a unistd.h to our msvcrt headers, but that's much less problematic than having two versions of io.h.
On January 9, 2003 12:12 pm, Alexandre Julliard wrote:
I think it would work. What you have to do is something like:
#ifndef __UNIX__ #include <io.h> #else #include <unistd.h> #endif
This so fast! :)
Remember, __UNIX__ is always defined when compiling in Wine, so we can never include io.h. Which begs the question: why do we have it in msvcrt in the first place? :)
I'd like to be able to compile an app with _and_ without the msvcrt runtime, by adding/removing the -mno-cygwin switch. The simplest thing to do would be to just:
#include <io.h> #include <unistd.h>
and when compiling with the -mno-cygwin, I get an empty/small unistd.h, and without the -mno-cygwin I get an empty/small io.h.
A include/cygwin would solve this nicely, we can simply stick in there all the cygwin extensions (like io.h, and others), and in msvcrt we can put the mingw extensions (such as unistd.h). The two includes will be mutually exclusive, and you can choose between them with the -mno-cygwin switch, the same as you do on Windows.
"Dimitrie O. Paun" dpaun@rogers.com writes:
Remember, __UNIX__ is always defined when compiling in Wine, so we can never include io.h. Which begs the question: why do we have it in msvcrt in the first place? :)
Because not all apps are cygwin apps, and pure Windows apps are of course not going to test for __UNIX__.
I'd like to be able to compile an app with _and_ without the msvcrt runtime, by adding/removing the -mno-cygwin switch.
You can do that just fine with my solution, all we need is a trivial unistd.h in the msvcrt headers. Plus this way you also have a chance to build the app under normal Unix, where you will never have io.h.
A include/cygwin would solve this nicely, we can simply stick in there all the cygwin extensions (like io.h, and others), and in msvcrt we can put the mingw extensions (such as unistd.h). The two includes will be mutually exclusive, and you can choose between them with the -mno-cygwin switch, the same as you do on Windows.
I don't think that's necessary, and we can't go around creating a new include hierarchy for every single Windows compiler out there, not to mention keeping track of all changes to the includes of all these compilers to replicate them in our environment. We need to define a portable solution that has a reasonable chance of working in all cases, even including cases that don't exist today. If it requires tweaking broken apps a bit that's acceptable.
On January 9, 2003 12:54 pm, Alexandre Julliard wrote:
You can do that just fine with my solution, all we need is a trivial unistd.h in the msvcrt headers. Plus this way you also have a chance to build the app under normal Unix, where you will never have io.h.
OK, cool. What about this patch?
On my system (RH 8.0), /usr/include/sys/unistd.h simply does
#include <unistd.h>
so it works perfectly with this addition. But is this standard? Should we just add a similar file to include/msvcrt/sys and be done with it?
ChangeLog Add a unistd.h file for mingw/Unix compatibility.
Index: include/Makefile.in =================================================================== RCS file: /var/cvs/wine/include/Makefile.in,v retrieving revision 1.79 diff -u -r1.79 Makefile.in --- include/Makefile.in 9 Jan 2003 01:09:16 -0000 1.79 +++ include/Makefile.in 9 Jan 2003 17:20:17 -0000 @@ -196,6 +196,7 @@ msvcrt/sys/types.h \ msvcrt/sys/utime.h \ msvcrt/time.h \ + msvcrt/unistd.h \ msvcrt/wchar.h \ msvcrt/wctype.h
--- /dev/null 2002-08-30 19:31:37.000000000 -0400 +++ include/msvcrt/unistd.h 2003-01-09 12:18:20.000000000 -0500 @@ -0,0 +1,2 @@ +#include <io.h> +#include <process.h>
"Dimitrie O. Paun" dpaun@rogers.com writes:
On my system (RH 8.0), /usr/include/sys/unistd.h simply does
#include <unistd.h>
so it works perfectly with this addition. But is this standard? Should we just add a similar file to include/msvcrt/sys and be done with it?
Yes, that's probably safer, and it shouldn't break anything.
On Thu, 9 Jan 2003, Dimitrie O. Paun wrote: [...]
Remember, __UNIX__ is always defined when compiling in Wine, so we can never include io.h. Which begs the question: why do we have it in msvcrt in the first place? :)
Because it's part of the Visual C++ headers for the msvcrt library. Visual C++ applications, and there's a lot of them on the Windows platform, will just do:
#include <io.h>
and thus if we want them to compile with Winelib we need to provide an io.h header.
Note: even if you don't have Visual C++, you can find this header in the MS SDK src/crt directory (with all the other msvcrt headers).