| <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 <root_dir></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: | |
| --> |