wine/documentation/winelib-intro.sgml

441 lines
20 KiB
Text

<chapter id="winelib-introduction">
<title id="introduction.title">Winelib Introduction</title>
<sect1 id="winelib-whatis">
<title>What is Winelib?</title>
<para>
Winelib is a development toolkit which allows you to compile your
Windows applications on Unix.
</para>
<para>
Most of Winelib's code consists of the Win32 API implementation.
Fortunately this part is 100 percent shared with Wine. The remainder
consists of Windows compatible headers and tools like the resource
compiler (and even these are used when compiling Wine).
</para>
<para>
Thanks to the above, Winelib supports most C and C++ 32bit source code,
resource and message files, and can generate graphical or console
applications as well as dynamic libraries.
</para>
<para>
What is not supported is 16bit source code as the types it depends on
(especially segmented pointers) are not supported by Unix compilers.
Also missing are some of the more exotic features of Microsoft's
compiler like native COM support and structured exception handling.
So you may need to perform some modifications in your code when
recompiling your application with Winelib. This guide is here to help
you in this task.
</para>
<para>
What you gain by recompiling your application with Winelib is the
ability to make calls to Unix APIs, directly from your
Windows source code. This allows for a better integration with the
Unix environment than is allowed by running an unmodified Windows
application running in Wine. Another benefit is that a Winelib
application can relatively easily be recompiled on a non-Intel
architecture and run there without the need for a slow software
emulation of the processor.
</para>
</sect1>
<sect1 id="winelib-requirements">
<title id="requirements.title">System requirements</title>
<para>
The requirements for Winelib are similar to those for Wine.
</para>
<para>
Basically if you can run Wine on your computer then you can run
Winelib. But the converse is not true. You can also build Winelib
and Winelib applications on platforms not supported by Wine,
typically platforms with a non i386 processor. But this is still
pretty much uncharted territory. It would be more reasonable to
target one of the more mundane i386-based platforms first.
</para>
<para>
The main difference is that the compiler becomes much more important.
It is highly recommended that you use gcc, g++, and the GNU binutils.
The more recent your gcc compiler the better.
For any serious amount of code you should not consider anything older
than gcc 2.95.2. The latest gcc snapshots contain some useful bug
fixes and much better support for anonymous structs and unions. This
can help reduce the number of changes you have to do in your code but
these are not stable releases of the compiler so you may not want to
use them in production.
</para>
</sect1>
<sect1 id="winelib-getting-started">
<title id="getting-started.title">Getting Started</title>
<sect2 id="winemaker-introduction">
<title id="winemaker-introduction.title">Winemaker introduction</title>
<para>
So what is needed to compile a Windows application with Winelib?
Well, it really depends on the complexity of your application but
here are some issues that are shared by all applications:
</para>
<itemizedlist>
<listitem>
<para>
the case of your files may be bad. For example they could be
in all caps: <filename>HELLO.C</filename>. It's not very nice to
work with and probably not what you intended.
</para>
</listitem>
<listitem>
<para>
then the case of the filenames in your include statements may be
wrong: maybe they include <filename>Windows.h</filename> instead
of <filename>windows.h</filename>.
</para>
</listitem>
<listitem>
<para>
your include statements may use '\' instead of '/'. '\' is not
recognized by Unix compilers while '/' is recognized in both
environments.
</para>
</listitem>
<listitem>
<para>
you will need to perform the usual Dos to Unix text file conversion
otherwise you'll get in trouble when the compiler considers that
your '\' is not at the end of the line since it is followed by a
pesky carriage return.
</para>
</listitem>
<listitem>
<para>
you will have to write new makefiles.
</para>
</listitem>
</itemizedlist>
<para>
The best way to take care of all these issues is to use winemaker.
</para>
<para>
Winemaker is a perl script which is designed to help you bootstrap
the conversion of your Windows projects to Winelib. In order to do
this it will go analyze your code, fixing the issues listed above
and generate straight Makefiles.
</para>
<para>
Let's suppose that you are already in the top directory of your
sources. Then converting your project to Winelib may be as simple
as just running the three commands below (note the dot indicating
current directory at the end of the first command):
</para>
<programlisting>
$ winemaker --lower-uppercase .
$ make
</programlisting>
<para>
But of course things are not always that simple which is why we have
this guide at all.
</para>
</sect2>
<sect2 id="winemaker-test">
<title id="winemaker-test.title">Test Drive</title>
<para>
Before starting to work on a big project you may want to try to port a
small application. The notepad application from the Wine source tree
suits well for testing purposes. It can be found in the programs
subdirectory. notepad is a simple application, but has a few C,
header and resource files.
</para>
<para>
Run <command>make clean</command> in the
notepad source directory if it contains results of previous builds.
Create a separate directory with name notepad2, so it won't conflict
with the Wine copy of the application. Copy the sources of notepad
(files *.c, *.h, *.rc) to this directory. Now run the commands,
mentioned above from the notepad2 directory:
</para>
<programlisting>
$ winemaker --lower-uppercase .
$ make
</programlisting>
<para>
Notice how the build fails in a resource file
(<filename>Da.rc</filename> at the time this was written).
This is because for the time being, the Wine resource compiler
(<command>windres</command>) can't cope with more than one
resource file ending up in a given executable. To get around
that limitation, the Wine developers have chosen to only have
one master resource file per application, and include the
other ones via <literal>#include</literal> statements in the
master one. The included files do not
<literal>#include</literal> the necessary files to be
compilable on their own. You will need to do the same thing
for now in your own Winelib port projects.
</para>
<para>
To fix that problem, you will need to edit the list of
resource files winemaker thought notepad used, and only keep
the master resource file. To do so, open
<filename>notepad2/Makefile</filename> in a text editor and
search for an assignment to a variable with
<literal>RC_SRCS</literal> as part of its name. It will likely
be named <literal>notepad2_exe_RC_SRCS</literal>. There will
be a list of resource files starting on the same line. Remove
them all except <filename>rsrc.rc</filename> (this is the
master one for notepad). Save your work.
</para>
<para>
Now you're ready to continue at the same point the first
<command>make</command> failed. Return to the notepad2
directory and type:
</para>
<programlisting>
$ make
</programlisting>
<para>
You are done! Now you can start the application as
<command>./notepad2</command>.
</para>
<para>
If you come across problems preparing and building this application
this probably means that winemaker utility is broken by some changes
in Wine. Try asking for help on <email>wine-devel@winehq.org</email>
</para>
</sect2>
<sect2 id="winemaker-guide">
<title id="winemaker-guide.title">Step by step guide</title>
<para>
Let's retrace the steps above in more details.
</para>
<variablelist>
<varlistentry>
<term><option>Getting the source</option></term>
<listitem>
<para>
First if you can try to get the sources together with the
executables/libraries that they build. In the current state of
winemaker having these around can help it guess what it is that
your project is trying to build. Later, when it is able to
understand Visual C++ projects, and if you use them, this will
no longer be necessary. Usually the executables and libraries
are in a <filename class="Directory">Release</filename> or
<filename class="Directory">Debug</filename> subdirectory of the
directory where the sources are. So it's best if you can
transfer the source files and either of these directories to
Linux. Note that you don't need to transfer the
<filename>.obj</filename>, <filename>.pch</filename>,
<filename>.sbr</filename> and other files that also reside in
these directories; especially as they tend to be quite big.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>cd &lt;root_dir&gt;</option></term>
<listitem>
<para>
Then go to the root directory where are your source files.
Winemaker can deal with a whole directory hierarchy at once so
you don't need to go into a leaf directory, quite the contrary.
Winemaker will automatically generate makefiles in each
directory where one is required, and will generate a global
makefile so that you can rebuild all your executables and
libraries with a single <command>make</command> command.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>Making the source writable</option></term>
<listitem>
<para>
Then make sure you have write access to your sources. It may
sound obvious, but if you copied your source files from a
CD-ROM or if they are in Source Safe on Windows, chances are
that they will be read-only.
But Winemaker needs write access so that it can fix them. You
can arrange that by running <command>chmod -R u+w .</command>.
Also you will want to make sure that you have a backup copy of
your sources in case something went horribly wrong, or more
likely, just for reference at a later point. If you use a
version control system you're already covered.
</para>
<para>
If you have already modified your source files and you want
to make sure that winemaker will not make further changes to
them then you can use the --nosource-fix option to protect
them.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>Running winemaker</option></term>
<listitem>
<para>
Then you'll run winemaker. Here are the options you will most
likely want to use. For complete list of options see
the winemaker man page.
</para>
<variablelist>
<varlistentry>
<term><option>--lower-uppercase</option></term>
<term><option>--lower-all</option></term>
<listitem>
<para>
These options specify how to deal with files, and
directories, that have an 'incorrect' case.
<option>--lower-uppercase</option> specifies they should
only be renamed if their name is all uppercase. So files
that have a mixed case, like 'Hello.c' would not be
renamed. <option>--lower-all</option> will rename any
file. If neither is specified then no file or directory
will be renamed, almost. As you will see
<link linkend="renaming">later</link> winemaker may
still have to rename some files.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--nobackup</option></term>
<listitem>
<para>
Winemaker normally makes a backup of all the files in which
it does more than the standard Dos to Unix conversion.
But if you already have (handy) copies of these files
elsewhere you may not need these so you should use this
option.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--dll</option></term>
<term><option>--console</option></term>
<listitem>
<para>
These option lets winemaker know what kind of target you are
building. If you have the windows library in your source
hierarchy then you should not need to specify
<option>--dll</option>. But if you have console executables
then you will need to use the corresponding option.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--mfc</option></term>
<listitem>
<para>
This option tells winemaker that you are building an MFC
application/library.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-Dmacro[=defn]</option></term>
<term><option>-Idir</option></term>
<term><option>-Ldir</option></term>
<term><option>-idll</option></term>
<term><option>-llibrary</option></term>
<listitem>
<para>
The <option>-i</option> specifies a Winelib library to
import via the <link linkend="spec-file">spec file</>
mechanism. Contrast this with the <option>-l</option>
which specifies a Unix library to link with. The other
options work the same way they would with a C
compiler. All are applied to all the targets found.
When specifying a directory with either
<option>-I</option> or <option>-L</option>, winemaker
will prefix a relative path with
<literal>$(TOPDIRECTORY)/</literal> so that it is valid
from any of the source directories. You can also use a
variable in the path yourself if you wish (but don't
forget to escape the '$'). For instance you could specify
<literal>-I\$(WINELIB_INCLUDE_ROOT)/msvcrt</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
So your command may finally look like:
<literal>winemaker --lower-uppercase -Imylib/include .</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term id="renaming"><option>File renaming</option></term>
<listitem>
<para>
When you execute winemaker it will first rename files to bring
their character case in line with your expectations and so that they can
be processed by the makefiles. This later category implies that
files with a non lowercase extension will be renamed so that the
extension is in lowercase. So, for instance,
<filename>HELLO.C</filename> will be renamed to
<filename>HELLO.c</filename>. Also if a file or directory name
contains a space or a dollar, then this
character will be replaced with an underscore. This is because
these characters cause problems with current versions of autoconf
(2.13) and make (3.79).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>Source modifications and makefile generation</option></term>
<listitem>
<para>
winemaker will then proceed to modify the source files so that
they will compile more readily with Winelib. As it does so it
may print warnings when it has to make a guess or identifies a
construct that it cannot correct. Finally it will generate the
autoconf-based makefiles. Once all this is done you can review
the changes that winemaker did to your files by using
<command>diff -uw</command>. For instance:
<command>diff -uw hello.c.bak hello.c</command>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>Running make</option></term>
<listitem>
<para>
This is a pretty simple step: just type <command>make</command>
and voila, you should have all your executables and libraries.
If this did not work out, then it means that you will have to
read this guide further to:
<itemizedlist>
<listitem>
<para>
review the <filename>Makefile</filename> files to
adjust what winemaker thinks are the binaries you are
trying to build and which sources should be used for
each. See the <xref linkend="source-analysis"
endterm="source-analysis.title"> section for some hints.
</para>
</listitem>
<listitem>
<para>
fix the portability issues in your sources. See
<xref linkend="portability-issues"
endterm="portability-issues.title"> for more details.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("winelib-user.sgml" "book" "chapter" "")
End:
-->