8 4901 HW Oosterhout (NB)
13 WARNING: This HOWTO is incomplete. I expect to add to it on a weekly
14 basis until it is complete.
16 =====================================================================
20 I. Introduction: Wine vs. WineLib
22 IV. File Format Conversion
24 V. Compiling A Simple Win32 Program
27 A. Windows executable and Windows DLL.
28 B. Windows executable and WineLib DLL.
29 C. WineLib executable and Windows DLL.
30 D. WineLib executable and WineLib DLL.
33 A. Using a native MFC DLL
36 =====================================================================
38 I. Introduction: Wine vs. WineLib
40 WineLib provides the Win32 API to a non-Microsoft operating
41 system. The WineLib Win32 functions use X11 functions to perform the
42 actual drawing on the screen. Wine and WineLib are based on the same
43 set of functions that implement the Win32 API. The difference between
44 Wine and WineLib is the type of executable that is loaded into memory
45 and executed. If an executable and any associated DLLs were compiled
46 for x86 hardware running the Windows 95, 98, or Windows NT (TM)
47 operating systems, then Wine can use a special binary loader to load
48 the program and the libraries into memory and execute it. WineLib on
49 the other hand allows you to take the source for such a program and
50 DLLs and compile it into the native format of a x86 Unix or Linux
51 operating system. WineLib also allows you to partially compile the
52 program and DLLs into the native format. For example, if you use a DLL
53 from a vendor to provide some functions to your program and the vendor
54 does not give you source, then you can use the Windows version of the
55 DLL to provide the functions and compile the rest of your program in
56 the native form for your system. [1]
58 Windows compilers and linkers generate executables with a different
59 structure than standard compilers. Windows has two executable formats:
60 the NE format and the PE format. The NE executable format provides for
61 two entry points and the PE format provides for three entry points
62 while a standard executable has a single entry point. Usually, a NE or
63 a PE executable will use one of the entry points for your program and
64 the other entry points will print an error message and exit. However,
65 a linker can link 16 bit objects into one or both of the alternate
66 entry points of a NE or PE executable.
68 Standard compilers assume that the function main() exists. The entry
69 point for a standard program is constructed from the C runtime
70 library, initialization code for static variables in your program, the
71 initialization code for your classes (C++), and your function main().
72 On the other hand, windows compilers assume WinMain() exists. The
73 entry point for a windows program is constructed from the C runtime
74 library, initialization code for static variables in your program, the
75 initialization code for your classes (C++), and your function
78 Since main() and WinMain() have different type signatures (parameter
79 types), WineLib provides certain aids to generate code so that your
80 program can be compiled and run as written for windows. For example,
81 WineLib generates a main() to initialize the windows API, to load any
82 necessary DLLs and then call your WinMain(). Therefore, you need to
83 learn four basic operations to compile a windows program using
84 WineLib: compiling a simple program, compiling resources, compiling
85 libraries, and compiling MFC (if you will be using MFC). Each of these
86 skills or operations are explained in later sections of this HOWTO.
88 Before you start porting your windows code to WineLib, you need to
89 consider whether you are allowed to port your program to WineLib. As
90 you compile your program using WineLib, you will be combining software
91 from several sources and you need to ensure that the licenses for the
92 components are compatible. Hence, in the next section, we will examine
96 IV. File Format Conversion
98 Before you can compile your program, you must deal with one major
99 difference between Windows and WineLib. Window sources are in DOS
100 format with carriage return / line feed at the end of each line of
101 text while WineLib files are in Unix format with only line feed at the
102 end of each line of text.
104 The main problem with the difference between Unix and DOS format
105 source files occurs with macro line continuation. A Unix compiler
106 expects a backslash (\) followed by a newline (^J) to indict that a
107 macro is continued on the next line. However, a file in DOS format will
108 have the characters backslash (\), carriage return (^M), and newline
109 (^J). The Unix compiler will interpret the backslash (\), carriage
110 return (^M), newline (^) of a file in DOS format as a quoted carriage
111 return and newline. The Unix compiler will think the line has ended
112 and the macro is completely defined. Hence, before you compile your
113 sources, you will need to convert you DOS format sources to Unix
114 format. There are several tools such as dos2unix and tr that are
115 available to convert the format.
117 FIXME: get more info on dos2unix, tr, and all other such tools and
118 give example commands. Until I do [3] is a good source.
120 FIXME: is CR/LF conversion necessary for gcc 2.95 ?
122 V. Compiling A Simple Win32 Program
124 Wine and WineLib are written in C as is the MS Win32 API; thus, if
125 have a program that calls only the Win32 API directly, you can compile
126 the program using a C compiler and link it with some of the WineLib
127 libraries. There are several simple examples of WineLib programs in
128 the directory libtest/ in the Wine source tree. We shall examine one
129 of these to show you how to compile a WineLib program.
131 The example we shall examine is hello2. If you examine hello2.c, you
132 will see it is a windows program that pops up a message box that says
133 "Hello, hello!". It can be compiled and run using a windows compiler
134 just like any other windows program. However, it can not be compiled
135 and run with a non-windows compiler. As mentioned previously, windows
136 programs have an entry point called WinMain(), while non-windows
137 compilers use an entry point of main(). Hence, we need some "glue" to
138 glue the main() entry point to the WinMain() in the windows program.
140 In WineLib, some of the glue is provided by the spec file. Spec files
141 are used in several places in Wine and WineLib to provide glue between
142 windows code and code for non-windows compilers. WineLib provides a
143 tool called winebuild in the tools/winebuild directory that converts a
144 spec file into a C file that can be compiled and linked with the
145 windows source files. ...
149 As mentioned in the introduction, Wine allows you to execute windows
150 executables and windows libraries under non-Microsoft operating
151 systems. WineLib allows you to take sources intended for the windows
152 operating system and to compile them to run as native executables
153 under a Unix/Linux operating system. With an executable and a single
154 library, there are four combinations in which to run the programs and
156 1. a Windows executable with a Windows DLL,
157 2. a Windows executable with WineLib DLL,
158 3. a WineLib executable with Windows DLL, and
159 4. a WineLib executable with WineLib DLL.
160 In this section, we will discuss each of these and discuss the steps
161 required to implement the executable/DLL combination.
163 A. Windows executable and Windows DLL
165 Running a windows executable with a windows DLL is not a WineLib
166 program: it is a Wine program. If you type
168 and the DLL is in the search path, then the windows program should run
169 using the windows DLL.
171 FIXME: find out what is the search path.
173 B. Windows executable and WineLib DLL
175 Running a windows executable with a WineLib DLL is also accomplished
176 using the Wine program. The source code for the DLL is compiled into a
177 Unix style shared library. When the windows executable "loads" the
178 DLL, Wine will use the shared library (.so file) instead.
180 At first you may wonder why you would want to run a windows executable
181 with a WineLib DLL. Such a situation implies you do not have the
182 source for the executable, but you do have the source for the
183 DLL. This is backwards from what you might expect. However, I do have
184 an example where this situation might arise.
186 Codewright is a popular editor in the windows world, and the
187 capabilities of Codewright can be extended by using DLLs. Since
188 Codewright is a commercial product, you do not have the source and
189 must use the windows executable with Wine. If you have written a DLL
190 to add functionality to Codewright, you have two choices: you can
191 compile the DLL using a windows compiler and use both a windows
192 executable and a windows DLL as in case A above, or you can use
193 WineLib and compile the DLL as a shared library (.so file). I have no
194 idea if Codewright actually runs under Wine, but this is an example of
195 why you might decide to use a windows executable and a WineLib
196 DLL. Many other editors and other programs use DLLs to extend their
199 In order for Wine to use the WineLib DLL, certain glue code is need to
200 replace the linker magic that windows compilers use. As with a simple
201 executable, the winebuild program uses a spec file to generate the glue
202 code. For example, in the spec file for the DLL will look something like
206 1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
207 2 cdecl _WINEfullName@4 ( str ) WINEfullName
208 The name is the name of the DLL. Since WineLib only supports win32,
209 the type should always be win32. The init function is the name of the
210 initialization function for the DLL. The initialization function for a
211 windows DLL is named DllMain(). You will need to rename the function
212 in the DLL source so there will not be any name clashes with the
213 DllMain() of other DLLs in you program.
215 The last two lines of the spec file above, provide the export
216 information for the DLL. For example, the line
217 1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
218 says that the function at ordinal 1 uses the cdecl calling convention
219 for the parameters. The DLL export name is _WINEbirthDay@4. The
220 function takes a single parameter that is a string. Finally, the C
221 function name to be called whenever this DLL function is called is
222 WINEbirthday. You will need a function ordinal line for each function
223 in the DLL. The export name and the ordinal can be obtained from the
224 windows program dumpbin and the windows version of the DLL. See the
225 file <wine>/tools/winebuild/README for more details on the spec file
228 During the compile process, a command like
229 winebuild -fPIC -o winedll.spec.c -spec winedll.spec
230 will be executed to create the file winedll.spec.c from information in
231 the file winedll.spec. The file winedll.spec.c and winedll.c are
232 compiled into object files and used to create the shared library.
234 In order for the program to run, a copy of the shared library must be in
235 your EXTRA_LD_LIBRARY_PATH. For example, if your wine.conf file has
237 EXTRA_LD_LIBRARY_PATH=${HOME}/wine/lib
238 then you must copy the shared library into the directory ~/wine/lib/
239 and the shared library will now be in the correct search path.
243 the program will load the shared library (.so).
245 C. WineLib executable and Windows DLL
247 Running a WineLib executable with a Windows DLL is accomplished
248 using WineLib. This situation will be common since you may have
249 purchased DLLs to use with you project and the DLL vendor may not give
250 you the source code for the DLL.
252 In order for WineLib to use the Windows DLL, certain glue code is
253 needed to replace the linker magic that windows compilers use. Part of
254 the glue code must be written by you. The basic idea of the glue code
255 is that you write a new DLL that consists of function pointers. Each
256 function in the DLL will consist of a call on a function pointer. For
258 WINEDLL_ConstString WINEDLL_INTERFACE
259 WINEfullName( WINEDLL_ConstString handle ) {
260 return (* pWINEfullName) ( handle );
262 The initialization function for the DLL will use the function
263 LoadLibrary() to load the windows DLL and initialize the function
264 pointers using the function GetProcAddress().
266 Since Wine can use either windows DLLs or Unix shared libraries (.so),
267 the LoadLibrary() function call may have unexpected results if there
268 is a winedll.dll and a winedll.so file. Hence, the windows version of
269 the DLL should be named something like hiddenWinedll.dll and the
270 shared library should be named winedll.so. Now the shared library will
271 use LoadLibrary() to load the "hidden" DLL.
273 The shared library will need a spec file. Fortunately, it is simpler
274 than case B above. The spec file will look something like
278 The name is the name of the DLL. Since WineLib only supports win32,
279 the type should always be win32. The init function is the name of the
280 initialization function for the shared library. This is the function
281 that will load the "hidden" DLL and initialize the function
282 pointers. There is no need for any function ordinals unless your
283 program calls functions by the ordinal.
285 During the compile process, a command like
286 winebuild -fPIC -o winedll.spec.c -spec winedll.spec
287 will be executed to create the file winedll.spec.c from information in
288 the file winedll.spec. The file winedll.spec.c and winedll.c are
289 compiled into object files and used to create the shared library.
291 Now that the shared library is compiled, you still need to compile
292 your program. Part of the compile process for your program will
293 consist of a spec file for your program. For example,
299 This spec file is similar to the spec file of the simple WineLib
300 example in part V above. The only difference is the import
301 specification that tells WineLib that the main program uses
302 winedll.dll. If this import line is not included, the "hidden" DLL
303 will not be loaded and the function pointers will not be initialized.
305 During the compile process, a command like
306 winebuild -fPIC -o program.spec.c -spec program.spec
307 will be executed to create the file program.spec.c from information in
308 the file program.spec. The file program.spec.c and your source code are
309 compiled into object files and used to create the executable.
311 D. WineLib executable and WineLib DLL.
313 Running a WineLib executable with a WineLib DLL is accomplished using
314 WineLib. The source for the DLL will be combined with a spec file to
315 generate the shared library. Likewise, the source for your program and
316 a spec file will be combined to create the executable. In the source
317 for the DLL, you should change the name of DllMain() to a name like
318 winedll_DllMain() so that there will not be a name clash with other
319 initialization functions for other DLLs.
321 The shared library's spec file is like case C above. The spec file
322 will look something like
326 The init function is the name of the initialization function for the
327 shared library (what you renamed DllMain to). There is no need for any
328 function ordinals unless your program calls functions by the ordinal.
330 During the compile process, a command like
331 winebuild -fPIC -o winedll.spec.c -spec winedll.spec
332 will be executed to create the file winedll.spec.c from information in
333 the file winedll.spec. The file winedll.spec.c and the source code for
334 your DLL are compiled into object files and used to create the shared
337 Compiling your program is exactly like case C above. For example, the
338 spec file for you program will look something like
345 During the compile process, a command like
346 winebuild -fPIC -o program.spec.c -spec program.spec
347 will be executed to create the file program.spec.c from information in
348 the file program.spec. The file program.spec.c and your source code are
349 compiled into object files and used to create the executable.
352 A. Using a native MFC DLL
355 FIXME: to be continued.
357 A Windows compiler does NOT generate a fake main. Instead, the
358 executable file format provides for 2 (NE) or 3 (PE) entry points.
359 One of these is your program, the other(s) are normally filled with
360 stubs that print an error message and exit. It is possible to instruct
361 the _linker_ to link 16-bit objects into one or both of the alternate
362 entry points, and create a fat binary.
364 At the C/C++ level, your statement about WinMain() is correct. Of
365 course the actual entry point first inits run time lib etc, and then
366 calls the C/C++ level entry, but that is also true for main() in the
367 standard setup. It may be important to regurgitate this info here,
368 though, because some of the fun things that can happen with multiple
369 run time libs and DLLs occur at this level.
371 Line 86: I only need to know how compile MFC if I use it... :-)
374 From: Damyan Ognyanoff <Damyan@rocketmail.com>
375 Subject: Re: Wine MFC info request
378 my MFC is from VC6.0 with SP3
379 MFC Bulid: (form afxbld_.h)
380 #define _MFC_BUILD 8447
381 #define _MFC_USER_BUILD "8447"
384 FILEVERSION 6,0,_MFC_BUILD,_MFC_RBLD
385 PRODUCTVERSION 6,0,0,0
388 1. Wine include files
390 In some of them you will find error about '__attribute__' all kinds of
391 similar errors can be fixed using proper typedefs first example :
393 typedef BOOL (CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM);
397 typedef BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM);
399 and the second kind is something like
401 TYPE* WINAPI SomeFunction(HWND param1,UINT param2);
403 The problem here is a TYPE* or TYPE& (in some of mfc files) the
404 workaround is to declare a type before:
406 typedef TYPE* TYPEPtr;
410 typedef TYPE& TYPERef;
412 and declaration will look like:
414 TYPEPtr WINAPI SomeFunction(HWND param1,UINT param2);
416 note: don't miss a 'struct' when you define struct type pointers. I
417 miss it and get a lot of problems compiling MFC:
421 typedef !!!struct!!! _TEB* P_TEB;
422 extern inline P_TEB WINAPI NtCurrentTeb(void);
425 Those conversions are semanticaly the same as above but g++ compile
426 them and generate proper code to invoke __stdcall kind of functions
428 in some of Wine/obj_XXX.h files: Wine/obj_base.h - there are a lot of
429 defines's that are used to declare a COM interfaces
431 #define ICOM_METHOD(ret,xfn) \
432 public: virtual ret (CALLBACK xfn)(void) = 0;
434 will be (for all of them that are related to C++ (watch #ifdef's
437 #define ICOM_METHOD(ret,xfn) \
438 public: virtual ret CALLBACK (xfn)(void) = 0;
440 and the second tip is an error when compiler stops on line like:
442 ICOM_DEFINE(ISomeInterfase,IUnknown)
444 watch method declarations above to find something like:
446 ICOM_METHOD1(TYPE*,MethodName, DWORD,dwParam)
448 and replace TYPE* with proper TYPEPtr type. In many cases You will see
449 void* which can be replaced simply by LPVOID.
451 qthere are several errors related to anonymous structs and unions but
452 they can be avoided with proper - #ifdef __cplusplus
454 This is all about Wine headers I think. If you find something that I
455 miss type a line of mail to me.
458 The rules are the same with some new issues:
460 virtual BOOL Method1(int param1, BOOL (CALLBACK *param2)
461 (HWND,UINT,WPARAM,LPARAM));
463 don't compile. I remove a function pointer declaration
466 typedef BOOL CALLBACK
467 (*param2Type)(HWND,UINT,WPARAM,LPARAM);
469 virtual BOOL Method1(int param1, param2Type param2);
471 I didn't apply this technique to a operator new
474 void* AFXAPI operator new(size_t nSize);
476 so i remove AFXAPI from these declarations:
478 I got some missed #defines from commctrl.h and I added
479 them form VC6.0 include.
481 these are my defines form Makefile which I used to
484 -DTWINE_NO_CMONIKER \ -- this is related to exclude
486 -D__urlmon_h__ \ -- Wine didn't have URL interfaces
487 -D_AFX_NO_OLEDB_SUPPORT \
489 -DNOWIN98 \ -- this is used to exclude all
490 unimplemented classes from commctrl
492 -D_AFX_NO_DHTML_SUPPORT \
493 -D_AFX_NO_SOCKET_SUPPORT \
494 -D_AFX_NO_SYNC_SUPPORT \
495 -D_AFX_NO_OCX_SUPPORT \
497 -D_AFX_OLD_EXCEPTIONS \
498 -D_AFX_NO_SOCKET_SUPPORT \
499 -D_AFX_NO_DEBUG_CRT \
500 -D_AFX_NO_DAO_SUPPORT \
501 -D_AFX_NO_OCC_SUPPORT \
502 -D_AFX_NO_INET_SUPPORT \
503 -D_AFX_NO_RICHEDIT_SUPPORT \
507 may be you will try to enable some of features of mfc I tested only
508 -D_AFX_NO_OCC_SUPPORT but got missing interfaces from Wine
511 - _CIP<_Interface, _IID>::~_CIP<_Interface, _IID>()
512 + _CIP<_Interface, _IID>::~_CIP()
515 - BOOL Lookup(BASE_CLASS::BASE_ARG_KEY key,
517 - { return BASE_CLASS::Lookup(key,
518 (BASE_CLASS::BASE_VALUE&)rValue); }
519 + BOOL Lookup(typename BASE_CLASS::BASE_ARG_KEY
520 key, VALUE& rValue) const
521 + { return BASE_CLASS::Lookup(key,
522 (typename BASE_CLASS::BASE_VALUE&)rValue); }
524 and all releated errors can be fixed in this way.
531 10 stdcall WinMain(long long ptr long) WinMain
534 use -rdynamic wnen link libmfc.so to get ARGV and
537 5. I didn'n build a extension dll with Wine but I suspect that there
538 will be some problems related to a chaining Runtime classes form MFC
541 6. build your app as a MODULE too.
543 7. make a loader and in it's _WinMain:
544 ... includes are here
545 iint PASCAL (*winMain)(HINSTANCE,HINSTANCE,LPSTR,int) =
547 my app uses these to manage filenames
548 VOID __cdecl (*_splitpath1)(LPCSTR path, LPSTR drive,
549 LPSTR directory, LPSTR filename, LPSTR extension ) =
551 VOID __cdecl _splitpath(LPCSTR path, LPSTR drive,
552 LPSTR directory, LPSTR filename, LPSTR extension )
555 _splitpath1(path, drive, directory, filename,
558 VOID __cdecl (*_makepath1)(LPSTR path, LPCSTR drive,
559 LPCSTR directory, LPCSTR filename, LPCSTR extension )
561 VOID __cdecl _makepath(LPSTR path, LPCSTR drive,
562 LPCSTR directory, LPCSTR filename, LPCSTR extension )
565 _makepath1(path, drive, directory, filename,
568 int PASCAL _WinMain(HINSTANCE h,HINSTANCE h1,LPSTR
571 HINSTANCE hInstance,hins,hlib,htst,hform,himag,hexe;
574 hins = LoadLibrary("CRTDLL.DLL");
575 _splitpath1 = GetProcAddress(hins,
577 _makepath1 = GetProcAddress(hins,
579 hins = LoadLibrary("COMCTL32.DLL");
580 hins = LoadLibrary("COMDLG32.DLL");
583 hins = dlopen("libmfc42.so",2);
584 hlib = LoadLibrary("mfc42");
585 himag = dlopen("libmxformatslib.so",2);
586 hform = LoadLibrary("mxformatslib");
587 hexe = dlopen("libmxpaint.so",2);
588 htst = LoadLibrary("mxpaint");
590 winMain = GetProcAddress(hlib, "WinMain");
593 retv = winMain (htst, // note the > htst
607 the spec for loader is:
613 please find attached a Makefile which i use to build