Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 1 | What is this? |
| 2 | ------------ |
| 3 | |
| 4 | This note is a short description of |
| 5 | |
| 6 | * How to port Wine to your favourite operating system |
| 7 | * Why you probably shouldn't use "#ifdef MyOS" |
| 8 | * What to do instead. |
| 9 | |
| 10 | This document does not say a thing about how to port Wine to non-386 |
| 11 | operating systems, though. You would need a CPU emulator. Let's get |
| 12 | Wine into a better shape on 386 first, OK? |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | Why "#ifdef MyOS" is probably a mistake. |
| 18 | --------------------------------------- |
| 19 | |
| 20 | Operating systems change. Maybe yours doesn't have the "foo.h" |
| 21 | header, but maybe a future version will have it. If you want |
| 22 | to "#include <foo.h>", it doesn't matter what operating system |
| 23 | you are using; it only matters whether "foo.h" is there. |
| 24 | |
| 25 | Furthermore, operating systems change names or "fork" into |
| 26 | several ones. An "#ifdef MyOs" will break over time. |
| 27 | |
| 28 | If you use the feature of Autoconf, the Gnu auto-configuration |
| 29 | utility wisely, you will help future porters automatically |
| 30 | because your changes will test for _features_, not names of |
| 31 | operating systems. A feature can be many things: |
| 32 | |
| 33 | * existance of a header file |
| 34 | * existance of a library function |
| 35 | * existance of libraries |
| 36 | * bugs in header files, library functions, the compiler, ... |
| 37 | * (you name it) |
| 38 | |
| 39 | You will need Gnu Autoconf, which you can get from your |
| 40 | friendly Gnu mirror. This program takes Wine's "configure.in" |
| 41 | file and produces a "configure" shell script that users use to |
| 42 | configure Wine to their system. |
| 43 | |
| 44 | There _are_ exceptions to the "avoid #ifdef MyOS" rule. Wine, |
| 45 | for example, needs the internals of the signal stack -- that |
| 46 | cannot easily be described in terms of features. |
| 47 | |
| 48 | Let's now turn to specific porting problems and how to solve |
| 49 | them. |
| 50 | |
| 51 | |
| 52 | |
| 53 | MyOS doesn't have the `foo.h' header! |
| 54 | ------------------------------------ |
| 55 | |
| 56 | This first step is to make Autoconf check for this header. |
| 57 | In configure.in you add a segment like this in the section |
| 58 | that checks for header files (search for "header files"): |
| 59 | |
| 60 | AC_CHECK_HEADER(foo.h, AC_DEFINE(HAVE_FOO_H)) |
| 61 | |
| 62 | If your operating system supports a header file with the |
| 63 | same contents but a different name, say bar.h, add a check |
| 64 | for that also. |
| 65 | |
| 66 | Now you can change |
| 67 | |
| 68 | #include <foo.h> |
| 69 | |
| 70 | to |
| 71 | |
| 72 | #ifdef HAVE_FOO_H |
| 73 | #include <foo.h> |
| 74 | #elif defined (HAVE_BAR_H) |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 75 | #include <bar.h> |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 76 | #endif |
| 77 | |
| 78 | If your system doesn't have a corresponding header file even |
| 79 | though it has the library functions being used, you might |
| 80 | have to add an "#else" section to the conditional. Avoid |
| 81 | this if you can. |
| 82 | |
| 83 | You will also need to add "#undef HAVE_FOO_H" (etc.) to |
| 84 | include/config.h.in |
| 85 | |
| 86 | Finish up with "make configure" and "./configure". |
| 87 | |
| 88 | |
| 89 | MyOS doesn't have the `bar' function! |
| 90 | ------------------------------------ |
| 91 | |
| 92 | A typical example of this is the `memmove'. To solve this |
| 93 | problem you would add `memmove' to the list of functions |
| 94 | that Autoconf checks for. In configure.in you search for |
| 95 | AC_CHECK_FUNCS and add `memmove'. (You will notice that |
| 96 | someone already did this for this particular function.) |
| 97 | |
| 98 | Secondly, you will also need to add "#undef HAVE_BAR" |
| 99 | to include/config.h.in |
| 100 | |
| 101 | The next step depends on the nature of the missing function. |
| 102 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 103 | Case 1: It's easy to write a complete implementation of the |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 104 | function. (`memmove' belongs to this case.) |
| 105 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 106 | You add your implementation in misc/port.c surrounded by |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 107 | "#ifndef HAVE_MEMMOVE" and "#endif". |
| 108 | |
| 109 | You might have to add a prototype for your function. If so, |
| 110 | include/miscemu.h might be the place. Don't forget to protect |
| 111 | that definition by "#ifndef HAVE_MEMMOVE" and "#endif" also! |
| 112 | |
Douglas Ridgway | 692389d | 1998-11-22 16:56:44 +0000 | [diff] [blame] | 113 | Case 2: A general implementation is hard, but Wine is only using |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 114 | a special case. |
| 115 | |
| 116 | An example is the various "wait" calls used in SIGNAL_child |
| 117 | from loader/signal.c. Here we have a multi-branch case on |
| 118 | features: |
| 119 | |
| 120 | #ifdef HAVE_THIS |
| 121 | ... |
| 122 | #elif defined (HAVE_THAT) |
| 123 | ... |
| 124 | #elif defined (HAVE_SOMETHING_ELSE) |
| 125 | ... |
| 126 | #endif |
| 127 | |
| 128 | Note that this is very different from testing on operating |
| 129 | systems. If a new version of your operating systems comes |
| 130 | out and adds a new function, this code will magically start |
| 131 | using it. |
| 132 | |
| 133 | Finish up with "make configure" and "./configure". |
| 134 | |
| 135 | |