Portability issues Anonymous unions/structs Anonymous structs and unions support depends heavily on the compiler. The best support is provided by gcc/g++ 2.96 and later. But these versions of gcc come from the development branch so you may want to hold off before using them in production. g++ 2.95 supports anonymous unions but not anonymous structs and gcc 2.95 supports neither. Older versions of gcc/g++ have no support for either. since it is anonymous unions that are the most frequent in the windows headers, you should at least try to use gcc/g++ 2.95. But you are stuck with a compiler that does not support anonymous structs/unions all is not lost. The Wine headers should detect this automatically and define NONAMELESSUNION / NONAMELESSSTRUCT. Then any anonymous union will be given a name u or u2, u3, etc. to avoid name clashes. You will then have to modify your code to include those names where appropriate. The name that Wine adds to anonymous unions should match that used by the Windows headers. So all you have to do to compile your modified code in Windows is to explicitly define the NONAMELESSUNION macro. Note that it would be wise to also explicitly define this macro on in your Unix makefile (Makefile.in) to make sure your code will compile even if the compiler does support anonymous unions. Things are not as nice when dealing with anonymous structs. Unfortunately the Windows headers make no provisions for compilers that do not support anonymous structs. So you will need to be more subtle when modifying your code if you still want it to compile in Windows. Here's a way to do it: #ifdef WINELIB #define ANONS .s #else #define ANONS #endif . . . { SYSTEM_INFO si; GetSystemInfo(&si); printf("Processor architecture=%d\n",si ANONS .wProcessorArchitecture); } You may put the #define directive directly in the source if only few files are impacted. Otherwise it's probably best to put it in one of your project's widely used headers. Fortunately usage of an anonymous struct is much rarer than usage of an anonymous union so these modifications should not be too much work. Unicode Because gcc and glibc use 4 byte unicode characters, the compiler intrinsic L"foo" generates unicode strings which cannot be used by Winelib (Win32 code expects 16 bit unicode characters). There are 3 workarounds for this: Use the latest gcc version (2.9.7 or later), and pass the -fshort-wchar option to every file that is built. Use the __TEXT("foo") macro, define WINE_UNICODE_REWRITE for each file that is built, and add -fwritable-strings to the compiler command line. You should replace all occurances of wchar_t with WCHAR also, since wchar_t is the native (32 bit) type. These changes allow Wine to modify the native unicode strings created by the compiler in place, so that they are 16 bit by the time any functions get to use them. This scheme works with older versions of gcc (2.95.x+). Use the compiler default, but don't call any Win32 unicode function without converting the strings first! If you are using Unicode and you want to be able to use standard library calls (e.g. wcslen, wsprintf) as well as Win32 unicode calls (API functions ending in W, or having _UNICODE defined), then you should use the msvcrt runtime library instead of glibc. The functions in glibc will not work correctly with 16 bit strings. If you need a Unicode string even when _UNICODE isn't defined, use WINE_UNICODE_TEXT("foo"). This will need to be wrapped in #ifdef WINELIB to prevent breaking your source for windows compiles. To prevent warnings when declaring a single unicode character in C, use (WCHAR)L'x', rather than __TEXT('x'). This works on Windows also. C library There are 3 choices available to you regarding which C library to use: Use the glibc native C library. Use the msvcrt C library. Use a custom mixture of both. Note that under Wine, the crtdll library is implemented using msvcrt, so there is no benefit in trying to use it. Using glibc in general has the lowest overhead, but this is really only important for file I/O. Many of the functions in msvcrt are simply resolved to glibc, so in reality options 2 and 3 are fairly similar choices. To use glibc, you don't need to make changes to your application; it should work straight away. There are a few situations in which using glibc is not possible: Your application uses Win32 and C library unicode functions. Your application uses MS specific calls like beginthread(), loadlibrary(), etc. You rely on the precise semantics of the calls, for example, returning -1 rather than non-zero. More likely, your application will rely on calls like fopen() taking a Windows path rather than a Unix one. In these cases you should use msvcrt to provide your C runtime calls. To do this, add a line: import msvcrt.dll to your applications .spec file. This will cause winebuild to resolve your c library calls to msvcrt.dll. Many simple calls which behave the same have been specified as non-importable from msvcrt; in these cases winebuild will not resolve them and the standard linker ld will link to the glibc version instead. In order to avoid warnings in C (and potential errors in C++) from not having prototypes, you may need to use a set of MS compatable header files. These are scheduled for inclusion into Wine but at the time of writing are not available. Until they are, you can try prototyping the functions you need, or just live with the warnings. If you have a set of include files (or when they are available in Wine), you need to use the -isystem "include_path" flag to gcc to tell it to use your headers in preference to the local system headers. To use option 3, add the names of any symbols that you don't want to use from msvcrt into your applications .spec file. For example, if you wanted the MS specific functions, but not file I/O, you could have a list like: @ignore = ( fopen fclose fwrite fread fputs fgets ) Obviously, the complete list would be much longer. Remember too that some functions are implemented with an underscore in their name and #defined to that name in the MS headers. So you may need to find out the name by examing dlls/msvcrt/msvcrt.spec to get the correct name for your @ignore entry. Compiling Problems If you get undefined references to Win32 API calls when building your application: if you have a VC++ .dsp file, check it for all the .lib files it imports, and add them to your applications .spec file. winebuild gives you a warning for unused imports so you can delete the ones you don't need later. Failing that, just import all the DLL's you can find in the dlls/ directory of the Wine source tree. If you are missing GUIDs at the link stage, add -lwine_uuid to the link line. gcc is more strict than VC++, especially whan compiling C++. This may require you to add casts to your C++ to prevent overloading abiguities between similar types (such as two overloads that take int and char respectively). If you come across a difference between the Windows headers and Wine's that breaks compilation, try asking for help on wine-devel@winehq.com. Initialization problems Initialization problems occur when the application calls the Win32 API before Winelib has been initialized. How can this happen? Winelib is initialized by the application's main before it calls the regular WinMain. But, in C++, the constructors of static class variables are called before the main (by the module's initializer). So if such a constructor makes calls to the Win32 API, Winelib will not be initialized at the time of the call and you may get a crash. This problem is much more frequent in C++ because of these class constructors but could also, at least in theory, happen in C if you were to specify an initializer making calls to Winelib. But of course, now that you are aware of this problem you won't do it :-). Further compounding the problem is the fact that Linux's (GNU's?) current dynamic library loader does not call the module initializers in their dependency order. So even if Winelib were to have its own initializer there would be no garantee that it would be called before the initializer of the library containing this static variable. Finally even if the variable is in a library that your application links with, that library's initializer may be called before Winelib has been initialized. One such library is the MFC. The current workaround is to move all the application's code in a library and to use a small Winelib application to dynamically load this library. Tus the initialization sequence becomes: the wrapper application starts. its empty initializer is run. its main is run. Its first task is to initialize Winelib. it then loads the application's main library, plus all its dependent libraries. which triggers the execution of all these libraries initializers in some unknown order. But all is fine because Winelib has already been initialized anyway. finally the main function calls the WinMain of the application's library. This may sound complex but Winemaker makes it simple. Just specify or on the command line and it will adapt its makefiles to build the wrapper and the application library. VC's native COM support don't use it, guide on how to replace it with normal C++ code (yes, how???): extracting a .h and .lib from a COM dll Can '-fno-rtti' be of some use or even required? SEH how to modify the syntax so that it works both with gcc's macros and Wine's macros, is it even possible? Others -fpermissive and -fno-for-scope, maybe other options