  <chapter id="porting">
    <title>Porting Wine to new Platforms</title>
    <para>Porting Wine to different (UNIX-based) operating systems...</para>

    <sect1 id="wine-porting">
      <title>Porting</title>

      <para>
        written by ???
      </para>
      <para>
        (Extracted from <filename>wine/documentation/how-to-port</filename>)
      </para>

      <sect2>
        <title>What is this?</title>

        <para>
          This note is a short description of:
        </para>

        <itemizedlist>
          <listitem>
            <para>How to port Wine to your favourite operating system</para>
          </listitem>
          <listitem>
            <para>Why you probably shouldn't use <symbol>#ifdef MyOS</symbol></para>
          </listitem>
          <listitem>
            <para>What to do instead.</para>
          </listitem>
        </itemizedlist>

        <para>
          This document does not say a thing about how to port Wine to
          non-386 operating systems, though.  You would need a CPU
          emulator.  Let's get Wine into a better shape on 386 first,
          OK?
        </para>
      </sect2>

      <sect2>
        <title>Why <symbol>#ifdef MyOS</symbol> is probably a mistake.</title>

        <para>
          Operating systems change.  Maybe yours doesn't have the
          <filename>foo.h</filename> header, but maybe a future
          version will have it.  If you want to <symbol>#include
            &lt;foo.h&gt;</symbol>, it doesn't matter what operating
          system you are using; it only matters whether
          <filename>foo.h</filename> is there.
        </para>
        <para>
          Furthermore, operating systems change names or "fork" into
          several ones.  An <symbol>#ifdef MyOs</symbol> will break
          over time.
        </para>
        <para>
          If you use the feature of <command>autoconf</command> -- the
          Gnu auto-configuration utility -- wisely, you will help
          future porters automatically because your changes will test
          for <emphasis>features</emphasis>, not names of operating
          systems.  A feature can be many things:
        </para>

        <itemizedlist>
          <listitem>
            <para>existance of a header file</para>
          </listitem>
          <listitem>
            <para>existance of a library function</para>
          </listitem>
          <listitem>
            <para>existance of libraries</para>
          </listitem>
          <listitem>
            <para>bugs in header files, library functions, the compiler, ...</para>
          </listitem>
          <listitem>
            <para>(you name it)</para>
          </listitem>
        </itemizedlist>
        <para>
          You will need Gnu Autoconf, which you can get from your
          friendly Gnu mirror.  This program takes Wine's
          <filename>configure.in</filename> file and produces a
          <filename>configure</filename> shell script that users use
          to configure Wine to their system.
        </para>
        <para>
          There <emphasis>are</emphasis> exceptions to the "avoid
          <symbol>#ifdef MyOS</symbol>" rule. Wine, for example, needs
          the internals of the signal stack -- that cannot easily be
          described in terms of features.
        </para>
        <para>
          Let's now turn to specific porting problems and how to solve
          them.
        </para>
      </sect2>

      <sect2>
        <title>MyOS doesn't have the <filename>foo.h</filename> header!</title>

        <para>
          This first step is to make <command>autoconf</command> check
          for this header. In <filename>configure.in</filename> you
          add a segment like this in the section that checks for
          header files (search for "header files"):
        </para>
        <programlisting>
AC_CHECK_HEADER(foo.h, AC_DEFINE(HAVE_FOO_H))
        </programlisting>
        <para>
          If your operating system supports a header file with the
          same contents but a different name, say
          <filename>bar.h</filename>, add a check for that also.
        </para>
        <para>
          Now you can change
        </para>
        <programlisting>
#include &lt;foo.h&gt;
        </programlisting>
        <para>
          to
        </para>
        <programlisting>
#ifdef HAVE_FOO_H
#include &lt;foo.h&gt;
#elif defined (HAVE_BAR_H)
#include &lt;bar.h&gt;
#endif
        </programlisting>
        <para>
          If your system doesn't have a corresponding header file even
          though it has the library functions being used, you might
          have to add an <symbol>#else</symbol> section to the
          conditional.  Avoid this if you can.
        </para>
        <para>
          You will also need to add <symbol>#undef HAVE_FOO_H</symbol>
          (etc.) to <filename>include/config.h.in</filename>
        </para>
        <para>
          Finish up with <command>make configure</command> and
          <command>./configure</command>.
        </para>
      </sect2>

      <sect2>
        <title>MyOS doesn't have the <function>bar</function> function!</title>

        <para>
          A typical example of this is the
          <function>memmove</function> function.  To solve this
          problem you would add <function>memmove</function> to the
          list of functions that <command>autoconf</command> checks
          for.  In <filename>configure.in</filename> you search for
          <function>AC_CHECK_FUNCS</function> and add
          <function>memmove</function>.  (You will notice that someone
          already did this for this particular function.)
        </para>
        <para>
          Secondly, you will also need to add <symbol>#undef
            HAVE_BAR</symbol> to
          <filename>include/config.h.in</filename>
        </para>
        <para>
          The next step depends on the nature of the missing function.
        </para>

        <variablelist>
          <varlistentry>
            <term>Case 1:</term>
            <listitem>
              <para>
                It's easy to write a complete implementation of the
                function.  (<function>memmove</function> belongs to
                this case.)
              </para>
              <para>
                You add your implementation in
                <filename>misc/port.c</filename> surrounded by
                <symbol>#ifndef HAVE_MEMMOVE</symbol> and
                <symbol>#endif</symbol>.
              </para>
              <para>
                You might have to add a prototype for your function.
                If so, <filename>include/miscemu.h</filename> might be the place.  Don't
                forget to protect that definition by <symbol>#ifndef
                  HAVE_MEMMOVE</symbol> and <symbol>#endif</symbol> also!
              </para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>Case 2:</term>
            <listitem>
              <para>
                A general implementation is hard, but Wine is only
                using a special case.
              </para>
              <para>
                An example is the various <function>wait</function>
                calls used in <function>SIGNAL_child</function> from
                <filename>loader/signal.c</filename>.  Here we have a
                multi-branch case on features:
              </para>
              <programlisting>
#ifdef HAVE_THIS
...
#elif defined (HAVE_THAT)
...
#elif defined (HAVE_SOMETHING_ELSE)
...
#endif
              </programlisting>
              <para>
                Note that this is very different from testing on
                operating systems.  If a new version of your operating
                systems comes out and adds a new function, this code
                will magically start using it.
              </para>
            </listitem>
          </varlistentry>
        </variablelist>
        <para>
          Finish up with <command>make configure</command> and
          <command>./configure</command>.
        </para>

      </sect2>
    </sect1>

    <sect1 id="os2-wine">
      <title>Running & Compiling WINE in OS/2</title>

      <para>
        Written by &name-robert-pouliot; <email>&email-robert-pouliot;</email>,
        January 9, 1997
      </para>
      <para>
        (Extracted from <filename>wine/documentation/wine_os2</filename>)
      </para>

      <para>
        If you want to help the port of WINE to OS/2, send me a
        message at <email>krynos@clic.net</email> I currently don't
        want beta testers. It must work before we can test it.
      </para>
      <para>
        Here is what you need to (try to) compile Wine for OS/2:
      </para>

      <itemizedlist>
        <listitem>
          <para>EMX 0.9c (fix 2)</para>
        </listitem>
        <listitem>
          <para>XFree86 3.2 OS/2 (with development libraries)</para>
        </listitem>
        <listitem>
          <para>
            <command>bash</command>, gnu <command>make</command>,
            <command>grep</command>, <command>tar</command>,
            <command>bison</command>, <command>flex</command>
          </para>
        </listitem>
        <listitem>
          <para><command>sed</command> (a working copy of)</para>
        </listitem>
        <listitem>
          <para><command>diff</command> and <command>patch</command>
            are recommended</para>
        </listitem>
        <listitem>
          <para>Lots of disk space (about 40-50 megs after EMX and XFree installed)</para>
        </listitem>
      </itemizedlist>

      <para>
        To compile:
      </para>

      <screen>
<prompt>$ </prompt><userinput>sh</userinput>
<prompt>$ </prompt><userinput>tools/make_os2.sh</userinput>
<prompt>$ </prompt><userinput>make depend</userinput>
<prompt>$ </prompt><userinput>make</userinput>
<prompt>$ </prompt><userinput>emxbind wine</userinput>
      </screen>

      <para>
        Currently:
      </para>

      <itemizedlist>
        <listitem>
          <para><command>configure</command> and <command>make depend</command> work...</para>
        </listitem>
        <listitem>
          <para><command>make</command> compiles (with a modified
            Linux <filename>mman.h</filename>), but doesn't
            link.</para>
        </listitem>
        <listitem>
          <para>signal handling is horrible... (if any)</para>
        </listitem>
        <listitem>
          <para>EMX doesn't support <function>mmap</function> (and
            related), SysV IPC and <function>stafs()</function></para>
        </listitem>
        <listitem>
          <para>
            XFree86/OS2 3.2 doesn't support
            <function>XShmQueryExtension()</function> and
            <function>XShmPixmapFormat()</function> due to the same
            lack in EMX...
          </para>
        </listitem>
      </itemizedlist>

      <para>
        What needs to be redone:
      </para>

      <itemizedlist>
        <listitem>
          <para>LDT (using <function>DosAllocSeg</function> in
            <filename>memory/ldt.c</filename>) *</para>
        </listitem>
        <listitem>
          <para>Implement <function>mmap()</function> and SysV IPC in EMX *</para>
        </listitem>
        <listitem>
          <para>File functions, </para>
        </listitem>
        <listitem>
          <para>I/O access (do it!),</para>
        </listitem>
        <listitem>
          <para>Communication (modem),</para>
        </listitem>
        <listitem>
          <para>Interrupt (if int unknown, call current RealMode one...), </para>
        </listitem>
        <listitem>
          <para>
            Verify that everything is thread safe (how does Win95/NT handle multi-thread?),
          </para>
        </listitem>
        <listitem>
          <para>
            Move X functions in some files (and make a wrapper, to use PM instead latter),
          </para>
        </listitem>
        <listitem>
          <para>Return right CPU type, </para>
        </listitem>
        <listitem>
          <para>Make winsock work</para>
        </listitem>
      </itemizedlist>

      <para>
        The good things:
      </para>

      <itemizedlist>
        <listitem>
          <para>OS/2 have DOS interrupts</para>
        </listitem>
        <listitem>
          <para>OS/2 have I/O port access</para>
        </listitem>
        <listitem>
          <para>OS/2 have multi-thread</para>
        </listitem>
        <listitem>
          <para>Merlin have Open32 (to be used later...)</para>
        </listitem>
      </itemizedlist>
    </sect1>

    </chapter>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
