- Split Winelib User Guide into smaller files for easier maintenance
and better integration with make_winehq. - Add some Winelib docs from Jon Griffiths. - Fix a <sect2> problem in running.sgml.
This commit is contained in:
parent
9c446a13cd
commit
1828e59352
|
@ -35,7 +35,14 @@ BOOK_SRCS = \
|
|||
registry.sgml \
|
||||
running.sgml \
|
||||
tools.sgml \
|
||||
wine-doc.sgml
|
||||
wine-doc.sgml \
|
||||
winelib-bindlls.sgml \
|
||||
winelib-intro.sgml \
|
||||
winelib-mfc.sgml \
|
||||
winelib-pkg.sgml \
|
||||
winelib-porting.sgml \
|
||||
winelib-toolkit.sgml \
|
||||
winelib-user.sgml
|
||||
|
||||
BOOK_TARGETS = \
|
||||
$(BOOKNAME)/index.html \
|
||||
|
|
|
@ -101,8 +101,8 @@ Options:
|
|||
|
||||
<sect1 id="command-line-options">
|
||||
<title>Command-Line Options</title>
|
||||
|
||||
<sect2 id="config-parameter">
|
||||
<sect2>
|
||||
<title>--debugmsg [channels]</title>
|
||||
<para>
|
||||
Wine isn't perfect, and many Windows applications still
|
||||
|
|
|
@ -38,6 +38,14 @@
|
|||
<!-- *** Entities for Wine Developer Guide *** -->
|
||||
<!entity winelib-user SYSTEM "winelib-user.sgml">
|
||||
|
||||
<!-- *** Entities for Winelib User Guide *** -->
|
||||
<!entity winelib-intro SYSTEM "winelib-intro.sgml">
|
||||
<!entity winelib-porting SYSTEM "winelib-porting.sgml">
|
||||
<!entity winelib-toolkit SYSTEM "winelib-toolkit.sgml">
|
||||
<!entity winelib-mfc SYSTEM "winelib-mfc.sgml">
|
||||
<!entity winelib-bindlls SYSTEM "winelib-bindlls.sgml">
|
||||
<!entity winelib-packaging SYSTEM "winelib-pkg.sgml">
|
||||
|
||||
<!-- *** Entities for Wine Packager Guide *** -->
|
||||
<!entity packaging SYSTEM "packaging.sgml">
|
||||
|
||||
|
@ -114,7 +122,19 @@
|
|||
|
||||
|
||||
<!-- *** Winelib User Guide *** -->
|
||||
&winelib-user;
|
||||
<book id="index-winelib">
|
||||
<bookinfo>
|
||||
<title>Winelib User's Guide</title>
|
||||
</bookinfo>
|
||||
|
||||
&winelib-intro;
|
||||
&winelib-porting;
|
||||
&winelib-toolkit;
|
||||
&winelib-mfc;
|
||||
&winelib-bindlls;
|
||||
&winelib-packaging;
|
||||
|
||||
</book>
|
||||
|
||||
<!-- *** Wine Packager Guide *** -->
|
||||
<book id="index-pkg">
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<chapter id="bindlls">
|
||||
<title id="bindlls.title">Dealing with binary only dlls</title>
|
||||
<sect1 id="bindlls-intro">
|
||||
<title id="binary-dlls-intro.title">Introduction</title>
|
||||
<para>
|
||||
describe the problem,
|
||||
use an example and reuse it in the following sections...
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-spec">
|
||||
<title id="bindlls-spec.title">Writing the spec file</title>
|
||||
<para>
|
||||
give an example...
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-cxx-apis">
|
||||
<title id="bindlls-cxx-apis.title">How to deal with C++ APIs</title>
|
||||
<para>
|
||||
names are mangled, how to demangle them, how to call them
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-wrapper">
|
||||
<title id="bindlls-wrapper.title">Writing the wrapper</title>
|
||||
<para>
|
||||
give an example
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -0,0 +1,382 @@
|
|||
<chapter id="winelib-introduction">
|
||||
<title id="introduction.title">Winelib Introduction</title>
|
||||
|
||||
<sect1>
|
||||
<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 runnning 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 an uncharted territory. It would be more reasonable to
|
||||
first 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 'Windows.h' instead of 'windows.h'.
|
||||
</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 autoconf-based Makefiles.
|
||||
</para>
|
||||
<para>
|
||||
Let's suppose that Wine/Winelib has been installed in the
|
||||
<filename class="Directory">/usr/local/wine</filename>
|
||||
directory, and 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:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ winemaker --lower-uppercase
|
||||
$ ./configure --with-wine=/usr/local/wine
|
||||
$ 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-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>
|
||||
</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.
|
||||
</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 the configure script</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Before you run <command>make</command> you must run the
|
||||
autoconf <command>configure</command> script. The goal of this
|
||||
step is to analyze your system and generate customized
|
||||
makefiles from the <filename>Makefile.in</filename> files. This
|
||||
is also when you have to tell where Winelib resides on your
|
||||
system. If wine is installed in a single directory or you have
|
||||
the Wine sources compiled somewhere then you can just run
|
||||
<command>./configure --with-wine=/usr/local/bin</command>
|
||||
or <command>./configure --with-wine=~/wine</command>
|
||||
respectively.
|
||||
</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.in</filename> files to
|
||||
adjust the default compilation and link options set by
|
||||
winemaker. 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:("wine-doc.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -0,0 +1,168 @@
|
|||
<chapter id="mfc">
|
||||
<title id="mfc.title">Dealing with the MFC</title>
|
||||
|
||||
<sect1 id="mfc-introduction">
|
||||
<title id="mfc-introduction.title">Introduction</title>
|
||||
<para>
|
||||
To use the MFC in a Winelib application you will first have to
|
||||
recompile the MFC with Winelib. In theory it should be possible to
|
||||
write a wrapper for the Windows MFC as described in
|
||||
<xref linkend="bindlls" endterm="bindlls.title">. But in practice
|
||||
it does not seem to be a realistic approach for the MFC:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
the huge number of APIs makes writing the wrapper a big task in
|
||||
itself.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
furthermore the MFC contain a huge number of APIs which are tricky
|
||||
to deal with when making a wrapper.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
even once you have written the wrapper you will need to modify
|
||||
the MFC headers so that the compiler does not choke on them.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
a big part of the MFC code is actually in your application in
|
||||
the form of macros. This means even more of the MFC headers have
|
||||
to actually work to in order for you to be able to compile an
|
||||
MFC based application.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
This is why this guide includes a section dedicated to helping you
|
||||
compile the MFC with Winelib.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="mfc-legal-issues">
|
||||
<title id="mfc-legal-issues.title">Legal issues</title>
|
||||
<para>
|
||||
(Extracted from the HOWTO-Winelib written by Wilbur Dale
|
||||
<wilbur.dale@lumin.nl>)
|
||||
</para>
|
||||
<para>
|
||||
The purpose of this section is to make you aware of potential legal
|
||||
problems. Be sure to read your licenses and to consult your lawyers.
|
||||
In any case you should not consider the remainder of this section to
|
||||
be authoritative since it has not been written by a lawyer.
|
||||
</para>
|
||||
<para>
|
||||
Well, let's try to have a look at the situation anyway.
|
||||
</para>
|
||||
<para>
|
||||
During the compilation of your program, you will be combining code
|
||||
from several sources: your code, Winelib code, Microsoft MFC code,
|
||||
and possibly code from other vendor sources. As a result, you must
|
||||
ensure that the licenses of all code sources are obeyed. What you are
|
||||
allowed and not allowed to do can vary depending on how you compile
|
||||
your program and if you will be distributing it. For example, if you
|
||||
are releasing your code under the GPL, you cannot link your code to
|
||||
MFC code because the GPL requires that you provide ALL sources to your
|
||||
users. The MFC license forbids you from distributing the MFC source so
|
||||
you cannot both distribute your program and comply with the GPL
|
||||
license. On the other hand, if your code is released under the LGPL,
|
||||
you cannot statically link your program to the MFC and distribute it,
|
||||
but you can dynamically link your LGPL code and the MFC library and
|
||||
distribute it.
|
||||
</para>
|
||||
<para>
|
||||
Wine/Winelib is distributed under an X11-like license. It places few
|
||||
restrictions on the use and distribution of Wine/Winelib code. I doubt
|
||||
the Wine license will cause you any problems. On the other hand, MFC
|
||||
is distributed under a very restrictive license and the restrictions
|
||||
vary from version to version and between service packs. There are
|
||||
basically three aspects you must be aware of when using the MFC.
|
||||
</para>
|
||||
<para>
|
||||
First you must legally get MFC source code on your computer. The MFC
|
||||
source code comes as a part of Visual Studio. The license for
|
||||
Visual Studio implies it is a single product that can not
|
||||
be broken up into its components. So the cleanest way to get MFC on
|
||||
your system is to buy Visual Studio and install it on a dual boot
|
||||
Linux box.
|
||||
</para>
|
||||
<para>
|
||||
Then you must check that you are allowed to recompile MFC on a
|
||||
non-Microsoft operating system! This varies with the version of MFC.
|
||||
The MFC license from Visual Studio 6.0 reads in part:
|
||||
</para>
|
||||
<blockquote>
|
||||
<para>
|
||||
1.1 General License Grant. Microsoft grants to you as an
|
||||
individual, a personal, nonexclusive license to make and use
|
||||
copies of the SOFTWARE PRODUCT for the sole purposes of designing,
|
||||
developing, and testing your software product(s) that are designed
|
||||
to operate in conjunction with any Microsoft operating system
|
||||
product. [Other unrelated stuff deleted.]
|
||||
</para>
|
||||
</blockquote>
|
||||
<para>
|
||||
So it appears you cannot even compile MFC for Winelib using this
|
||||
license. Fortunately the Visual Studio 6.0 service pack 3 license
|
||||
reads (the Visual Studio 5.0 license is similar):
|
||||
</para>
|
||||
<blockquote>
|
||||
<para>
|
||||
1.1 General License Grant. Microsoft grants to you as an
|
||||
individual, a personal, nonexclusive license to make and use
|
||||
copies of the SOFTWARE PRODUCT for the purpose of designing,
|
||||
developing, and testing your software product(s). [Other unrelated
|
||||
stuff deleted]
|
||||
</para>
|
||||
</blockquote>
|
||||
<para>
|
||||
So under this license it appears you can compile MFC for Winelib.
|
||||
</para>
|
||||
<para>
|
||||
Finally you must check whether you have the right to distribute an
|
||||
MFC library. Check the relevant section of the license on
|
||||
<quote>redistributables and your redistribution rights</quote>. The
|
||||
license seems to specify that you only have the right to distribute
|
||||
binaries of the MFC library if it has no debug information and if
|
||||
you distribute it with an application that provides significant
|
||||
added functionality to the MFC library.
|
||||
<!-- FIXME: quote relevant sections of EULA in above paragraph. -->
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="mfc-compiling">
|
||||
<title id="mfc-compiling.title">Compiling the MFC</title>
|
||||
<para>
|
||||
Things to disable,
|
||||
why we have to disable them (lack of Wine support),
|
||||
where things don't compile,
|
||||
why,
|
||||
how to solve it,
|
||||
what to put in the Makefile,
|
||||
maybe try to point to a place with a ready-made makefile...
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="mfc-using">
|
||||
<title id="mfc-using.title">Using the MFC</title>
|
||||
<para>
|
||||
</para>
|
||||
<para>
|
||||
Specific winemaker options,
|
||||
the configure options,
|
||||
the initialization problem...
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -0,0 +1,15 @@
|
|||
<chapter id="packaging">
|
||||
<title id="packaging.title">Packaging your Winelib application</title>
|
||||
<para>
|
||||
Selecting which libraries to deliver,
|
||||
how to avoid interference with other Winelib applications,
|
||||
how to play nice with other Winelib applications
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -0,0 +1,396 @@
|
|||
<chapter id="portability-issues">
|
||||
<title id="portability-issues.title">Portability issues</title>
|
||||
|
||||
<sect1 id="anon">
|
||||
<title id="anon.title">Anonymous unions/structs</title>
|
||||
<para>
|
||||
Anonymous structs and unions support depends heavily on the compiler.
|
||||
The best support is provided by gcc/g++ 2.96 and later. But these
|
||||
versions of gcc come from the development branch so you may want to
|
||||
hold off before using them in production. g++ 2.95 supports anonymous
|
||||
unions but not anonymous structs and gcc 2.95 supports neither. Older
|
||||
versions of gcc/g++ have no support for either.
|
||||
since it is anonymous unions that are the most frequent in the
|
||||
windows headers, you should at least try to use gcc/g++ 2.95.
|
||||
</para>
|
||||
<para>
|
||||
But you are stuck with a compiler that does not support anonymous
|
||||
structs/unions all is not lost. The Wine headers should detect this
|
||||
automatically and define <varname>NONAMELESSUNION</varname> /
|
||||
<varname>NONAMELESSSTRUCT</varname>. Then any anonymous union will
|
||||
be given a name
|
||||
<literal>u</literal> or <literal>u2</literal>, <literal>u3</literal>,
|
||||
etc. to avoid name clashes. You will then have to modify your code to
|
||||
include those names where appropriate.
|
||||
</para>
|
||||
<para>
|
||||
The name that Wine adds to anonymous unions should match that used
|
||||
by the Windows headers. So all you have to do to compile your
|
||||
modified code in Windows is to explicitly define the
|
||||
<varname>NONAMELESSUNION</varname> macro. Note that it would be wise
|
||||
to also explicitly define this macro on in your Unix makefile
|
||||
(<filename>Makefile.in</filename>) to make sure your code will
|
||||
compile even if the compiler does support anonymous unions.
|
||||
</para>
|
||||
<para>
|
||||
Things are not as nice when dealing with anonymous structs.
|
||||
Unfortunately the Windows headers make no provisions for compilers
|
||||
that do not support anonymous structs. So you will need to be more
|
||||
subtle when modifying your code if you still want it to compile in
|
||||
Windows. Here's a way to do it:
|
||||
</para>
|
||||
<programlisting>
|
||||
#ifdef WINELIB
|
||||
#define ANONS .s
|
||||
#else
|
||||
#define ANONS
|
||||
#endif
|
||||
|
||||
. . .
|
||||
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
printf("Processor architecture=%d\n",si ANONS .wProcessorArchitecture);
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
You may put the <literal>#define</literal> directive directly in the
|
||||
source if only few files are impacted. Otherwise it's probably best
|
||||
to put it in one of your project's widely used headers.
|
||||
Fortunately usage of an anonymous struct is much rarer than usage of
|
||||
an anonymous union so these modifications should not be too much work.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="unicode">
|
||||
<title id="unicode.title">Unicode</title>
|
||||
|
||||
<para>
|
||||
Because gcc and glibc use 4 byte unicode characters, the
|
||||
compiler intrinsic <literal>L"foo"</literal> generates unicode
|
||||
strings which cannot be used by Winelib (Win32 code expects 16
|
||||
bit unicode characters). There are 3 workarounds for this:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the latest gcc version (2.9.7 or later), and pass the
|
||||
<parameter>-fshort-wchar</parameter> option to every file
|
||||
that is built.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the <function>__TEXT("foo")</function> macro, define
|
||||
<constant>WINE_UNICODE_REWRITE</constant> for each file
|
||||
that is built, and add
|
||||
<parameter>-fwritable-strings</parameter> to the compiler
|
||||
command line. You should replace all occurances of
|
||||
<type>wchar_t</type> with <type>WCHAR</type> also, since
|
||||
<type>wchar_t</type> is the native (32 bit) type. These
|
||||
changes allow Wine to modify the native unicode strings
|
||||
created by the compiler in place, so that they are 16 bit
|
||||
by the time any functions get to use them. This scheme
|
||||
works with older versions of gcc (2.95.x+).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the compiler default, but don't call any Win32 unicode
|
||||
functions without converting the strings first!
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
If you are using Unicode and you want to be able to use
|
||||
standard library calls (e.g. <function>wcslen</function>,
|
||||
<function>wsprintf</function>) as well as Win32 unicode calls
|
||||
(API functions ending in W, or having
|
||||
<constant>_UNICODE</constant> defined), then you should use
|
||||
the msvcrt runtime library instead of glibc. The functions in
|
||||
glibc will not work correctly with 16 bit strings.
|
||||
</para>
|
||||
<para>
|
||||
If you need a Unicode string even when
|
||||
_<constant>UNICODE</constant> isn't defined, use
|
||||
<function>WINE_UNICODE_TEXT("foo")</function>. This will need
|
||||
to be wrapped in <function>#ifdef WINELIB</function> to
|
||||
prevent breaking your source for windows compiles.
|
||||
</para>
|
||||
<para>
|
||||
To prevent warnings when declaring a single unicode character
|
||||
in C, use <function>(WCHAR)L'x'</function>, rather than
|
||||
<function>__TEXT('x')</function>. This works on Windows also.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="C-library">
|
||||
<title id="C-library.title">C library</title>
|
||||
|
||||
<!-- *** Is all of this covered now? Make sure before deleting ***
|
||||
<para>
|
||||
Winelib currently only supports on C library: that of your
|
||||
compiler. three solutions: native, mixed or msvcrt except we
|
||||
only have native right now, using the native C library ->
|
||||
different behavior: fopen, O_TEXT, unicode support,
|
||||
reimplement msvcrt
|
||||
</para>
|
||||
-->
|
||||
|
||||
<para>
|
||||
There are 3 choices available to you regarding which C library
|
||||
to use:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the glibc native C library.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the msvcrt C library.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use a custom mixture of both.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
Note that under Wine, the crtdll library is implemented using
|
||||
msvcrt, so there is no benefit in trying to use it.
|
||||
</para>
|
||||
<para>
|
||||
Using glibc in general has the lowest overhead, but this is
|
||||
really only important for file I/O. Many of the functions in
|
||||
msvcrt are simply resolved to glibc, so in reality options 2
|
||||
and 3 are fairly similar choices.
|
||||
</para>
|
||||
<para>
|
||||
To use glibc, you don't need to make changes to your
|
||||
application; it should work straight away. There are a few
|
||||
situations in which using glibc is not possible:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Your application uses Win32 and C library unicode
|
||||
functions.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Your application uses MS specific calls like
|
||||
<function>beginthread()</function>,
|
||||
<function>loadlibrary()</function>, etc.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You rely on the precise semantics of the calls, for
|
||||
example, returning <literal>-1</literal> rather than
|
||||
non-zero. More likely, your application will rely on calls
|
||||
like <function>fopen()</function> taking a Windows path
|
||||
rather than a Unix one.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
In these cases you should use msvcrt to provide your C runtime
|
||||
calls. To do this, add a line:
|
||||
</para>
|
||||
|
||||
<programlisting>import msvcrt.dll</programlisting>
|
||||
|
||||
<para>
|
||||
to your applications <filename>.spec</filename> file. This
|
||||
will cause <command>winebuild</command> to resolve your c
|
||||
library calls to <filename>msvcrt.dll</filename>. Many simple
|
||||
calls which behave the same have been specified as
|
||||
non-importable from msvcrt; in these cases
|
||||
<command>winebuild</command> will not resolve them and the
|
||||
standard linker <command>ld</command> will link to the glibc
|
||||
version instead.
|
||||
</para>
|
||||
<para>
|
||||
In order to avoid warnings in C (and potential errors in C++)
|
||||
from not having prototypes, you may need to use a set of MS
|
||||
compatable header files. These are scheduled for inclusion
|
||||
into Wine but at the time of writing are not available. Until
|
||||
they are, you can try prototyping the functions you need, or
|
||||
just live with the warnings.
|
||||
</para>
|
||||
<para>
|
||||
If you have a set of include files (or when they are available
|
||||
in Wine), you need to use the <parameter>-isystem
|
||||
"include_path"</parameter> flag to gcc to tell it to use your
|
||||
headers in preference to the local system headers.
|
||||
</para>
|
||||
<para>
|
||||
To use option 3, add the names of any symbols that you don't
|
||||
want to use from msvcrt into your applications
|
||||
<filename>.spec</filename> file. For example, if you wanted
|
||||
the MS specific functions, but not file I/O, you could have a
|
||||
list like:
|
||||
</para>
|
||||
|
||||
<programlisting>@ignore = ( fopen fclose fwrite fread fputs fgets )</programlisting>
|
||||
<para>
|
||||
Obviously, the complete list would be much longer. Remember
|
||||
too that some functions are implemented with an underscore in
|
||||
their name and <function>#define</function>d to that name in
|
||||
the MS headers. So you may need to find out the name by
|
||||
examing <filename>dlls/msvcrt/msvcrt.spec</filename> to get
|
||||
the correct name for your <function>@ignore</function> entry.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="porting-compiling">
|
||||
<title id="porting-compiling.title">Compiling Problems</title>
|
||||
<para>
|
||||
If you get undefined references to Win32 API calls when
|
||||
building your application: if you have a VC++
|
||||
<filename>.dsp</filename> file, check it for all the
|
||||
<filename>.lib</filename> files it imports, and add them to
|
||||
your applications <filename>.spec</filename>
|
||||
file. <command>winebuild</command> gives you a warning for
|
||||
unused imports so you can delete the ones you don't need
|
||||
later. Failing that, just import all the DLL's you can find in
|
||||
the <filename>dlls/</filename> directory of the Wine source
|
||||
tree.
|
||||
</para>
|
||||
<para>
|
||||
If you are missing GUIDs at the link stage, add
|
||||
<parameter>-lwine_uuid</parameter> to the link line.
|
||||
</para>
|
||||
<para>
|
||||
gcc is more strict than VC++, especially whan compiling
|
||||
C++. This may require you to add casts to your C++ to prevent
|
||||
overloading abiguities between similar types (such as two
|
||||
overloads that take int and char respectively).
|
||||
</para>
|
||||
<para>
|
||||
If you come across a difference between the Windows headers
|
||||
and Wine's that breaks compilation, try asking for help on
|
||||
<email>wine-devel@winehq.com</email>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="init-problems">
|
||||
<title id="init-problems.title">Initialization problems</title>
|
||||
<para>
|
||||
Initialization problems occur when the application calls the Win32 API
|
||||
before Winelib has been initialized. How can this happen?
|
||||
</para>
|
||||
<para>
|
||||
Winelib is initialized by the application's <function>main</function>
|
||||
before it calls the regular <function>WinMain</function>. But, in C++,
|
||||
the constructors of static class variables are called before the
|
||||
<function>main</function> (by the module's initializer). So if such
|
||||
a constructor makes calls to the Win32 API, Winelib will not be
|
||||
initialized at the time of the call and you may get a crash. This
|
||||
problem is much more frequent in C++ because of these class
|
||||
constructors but could also, at least in theory, happen in C if you
|
||||
were to specify an initializer making calls to Winelib. But of
|
||||
course, now that you are aware of this problem you won't do it :-).
|
||||
</para>
|
||||
<para>
|
||||
Further compounding the problem is the fact that Linux's (GNU's?)
|
||||
current dynamic library loader does not call the module
|
||||
initializers in their dependency order. So even if Winelib were to
|
||||
have its own initializer there would be no garantee that it would be
|
||||
called before the initializer of the library containing this static
|
||||
variable. Finally even if the variable is in a library that your
|
||||
application links with, that library's initializer may be called
|
||||
before Winelib has been initialized. One such library is the MFC.
|
||||
</para>
|
||||
<para>
|
||||
The current workaround is to move all the application's code in a
|
||||
library and to use a small Winelib application to dynamically load
|
||||
this library. Tus the initialization sequence becomes:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
the wrapper application starts.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
its empty initializer is run.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
its <function>main</function> is run. Its first task is to
|
||||
initialize Winelib.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
it then loads the application's main library, plus all its
|
||||
dependent libraries.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
which triggers the execution of all these libraries initializers
|
||||
in some unknown order. But all is fine because Winelib has
|
||||
already been initialized anyway.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
finally the main function calls the <function>WinMain</function>
|
||||
of the application's library.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
This may sound complex by Winemaker makes it simple. Just specify
|
||||
<option>--wrap</option> or <option>--mfc</option> on the command line
|
||||
and it will adapt its makefiles to build the wrapper and the
|
||||
application library.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="com-support">
|
||||
<title id="com-support.title">VC's native COM support</title>
|
||||
<para>
|
||||
don't use it,
|
||||
guide on how to replace it with normal C++ code (yes, how???):
|
||||
extracting a .h and .lib from a COM dll
|
||||
Can '-fno-rtti' be of some use or even required?
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="SEH">
|
||||
<title id="SEH.title">SEH</title>
|
||||
<para>
|
||||
how to modify the syntax so that it works both with gcc's macros and Wine's macros,
|
||||
is it even possible?
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="others">
|
||||
<title id="others.title">Others</title>
|
||||
<para>
|
||||
-fpermissive and -fno-for-scope,
|
||||
maybe other options
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -0,0 +1,976 @@
|
|||
<chapter id="winelib-toolkit">
|
||||
<title id="winelib-toolkit.title">The Winelib development toolkit</title>
|
||||
|
||||
<sect1 id="winemaker">
|
||||
<title id="winemaker.title">Winemaker</title>
|
||||
|
||||
<sect2 id="vc-projects">
|
||||
<title id="vc-projects.title">Support for Visual C++ projects</title>
|
||||
<para>
|
||||
Unfortunately Winemaker does not support the Visual C++ project
|
||||
files, ...yet. Supporting Visual C++ project files (the
|
||||
<filename>.dsp</filename> and some <filename>.mak</filename> files
|
||||
for older versions of Visual C++) is definitely on
|
||||
the list of important Winemaker improvements as it will allow it to
|
||||
properly detect the defines to be used, any custom include path, the
|
||||
list of libraries to link with, and exactly which source files to use
|
||||
to build a specific target. All things that the current version of
|
||||
Winemaker has to guess or that you have to tell it as will become
|
||||
clear in the next section.
|
||||
</para>
|
||||
<para>
|
||||
When the time comes Winemaker, and its associated build system, will
|
||||
need some extensions to support:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
per file defines and include paths. Visual C++ projects allow
|
||||
the user to specify compiler options for each individual file
|
||||
being compiled. But this is probably not very frequent so it
|
||||
might not be that important.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
multiple configurations. Visual C++ projects usually have at
|
||||
least a 'Debug' and a 'Release' configuration which are compiled
|
||||
with different compiler options. How exactly we deal with these
|
||||
configurations remains to be determined.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="source-analysis">
|
||||
<title id="source-analysis.title">Winemaker's source analysis</title>
|
||||
<para>
|
||||
Winemaker can do its work even without a Windows makefile or a
|
||||
Visual Studio project to start from (it would not know what to do
|
||||
with a windows makefile anyway). This involves doing many educated
|
||||
guesses which may be wrong. But by and large it works. The purpose
|
||||
of this section is to describe in more details how winemaker
|
||||
proceeds so that you can better understand why it gets things
|
||||
wrong and how to fix it/avoid it.
|
||||
</para>
|
||||
<para>
|
||||
At the core winemaker does a recursive traversal of
|
||||
your source tree looking for targets (things to build) and source
|
||||
files. Let's start with the targets.
|
||||
</para>
|
||||
<para>
|
||||
First are executables and dlls. Each time it finds one of these in
|
||||
a directory, winemaker puts it in the list of things to build and
|
||||
will later generate a <filename>Makefile.in</filename> file in this
|
||||
directory. Note that Winemaker also knows about the commonly used
|
||||
<filename>Release</filename> and <filename>Debug</filename>
|
||||
directories, so it will attribute the executables and libraries
|
||||
found in these to their parent directory. When it finds an
|
||||
executable or a dll winemaker is happy because these give it more
|
||||
information than the other cases described below.
|
||||
</para>
|
||||
<para>
|
||||
If it does not find any executable or dll winemaker will look for
|
||||
files with a <filename>.mak</filename> extension. If they are not
|
||||
disguised Visual C++ projects (and currently even if they are),
|
||||
winemaker will assume that a target by that name should be built
|
||||
in this directory. But it will not know whether this target is an
|
||||
executable or a library. So it will assume it is of the default
|
||||
type, i.e. a graphical application, which you can override by using
|
||||
the <option>--cuiexe</option> and <option>--dll</option> options.
|
||||
</para>
|
||||
<para>
|
||||
Finally winemaker will check to see if there is a file called
|
||||
<filename>makefile</filename>. If there is, then it will assume
|
||||
that there is exactly one target to build for this directory. But
|
||||
it will not know the name or type of this target. For the type it
|
||||
will do as in the above case. And for the name it will use the
|
||||
directory's name. Actually, if the directory starts with
|
||||
<filename>src</filename> winemaker will try to make use of the name
|
||||
of the parent directory instead.
|
||||
</para>
|
||||
<para>
|
||||
Once the target list for a directory has been established,
|
||||
winemaker will check whether it contains a mix of executables and
|
||||
libraries. If it is so, then winemaker will make it so that each
|
||||
executable is linked with all the libraries of that directory.
|
||||
</para>
|
||||
<para>
|
||||
If the previous two steps don't produce the expected results (or
|
||||
you think they will not) then you should put winemaker in
|
||||
interactive mode (see <xref linkend="interactive"
|
||||
endterm="interactive.title">). This will allow you to specify the
|
||||
target list (and more) for each directory.
|
||||
</para>
|
||||
<para>
|
||||
In each directory winemaker also looks for source files: C, C++
|
||||
or resource files. If it also found targets to build in this
|
||||
directory it will then try to assign each source file to one of
|
||||
these targets based on their names. Source files that do not seem
|
||||
to match any specific target are put in a global list for this
|
||||
directory, see the <literal>EXTRA_xxx</literal> variables in the
|
||||
<filename>Makefile.in</filename>, and linked with each of the
|
||||
targets. The assumption here is that these source files contain
|
||||
common code which is shared by all the targets.
|
||||
If no targets were found in the directory where these files are
|
||||
located, then they are assigned to the parent's directory. So if a
|
||||
target is found in the parent directory it will also 'inherit' the
|
||||
source files found in its subdirectories.
|
||||
</para>
|
||||
<para>
|
||||
Finally winemaker also looks for more exotic files like
|
||||
<filename>.h</filename> headers, <filename>.inl</filename> files
|
||||
containing inline functions and a few others. These are not put in
|
||||
the regular source file lists since they are not compiled directly.
|
||||
But winemaker will still remember them so that they are processed
|
||||
when the time comes to fix the source files.
|
||||
</para>
|
||||
<para>
|
||||
Fixing the source files is done as soon as winemaker has finished
|
||||
its recursive directory traversal. The two main tasks in this step
|
||||
are fixing the CRLF issues and verifying the case of the include
|
||||
statements.
|
||||
</para>
|
||||
<para>
|
||||
Winemaker makes a backup of each source file (in such a way that
|
||||
symbolic links are preserved), then reads it fixing the CRLF
|
||||
issues and the other issues as it goes. Once it has finished
|
||||
working on a file it checks whether it has done any non
|
||||
CRLF-related modification and deletes the backup file if it did
|
||||
not (or if you used <option>--nobackup</option>).
|
||||
</para>
|
||||
<para>
|
||||
Checking the case of the include statements (of any form,
|
||||
including files referenced by resource files), is done in the
|
||||
context of that source file's project. This way winemaker can use
|
||||
the proper include path when looking for the file that is included.
|
||||
If winemaker fails to find a file in any of the directories of the
|
||||
include path, it will rename it to lowercase on the basis that it
|
||||
is most likely a system header and that all system headers names
|
||||
are lowercase (this can be overriden by using
|
||||
<option>--nolower-include</option>).
|
||||
</para>
|
||||
<para>
|
||||
Finally winemaker generates the <filename>Makefile.in</filename>
|
||||
files and other support files (wrapper files, spec files,
|
||||
<filename>configure.in</filename>,
|
||||
<filename>Make.rules.in</filename>). From the above description
|
||||
you can guess at the items that winemaker may get wrong in
|
||||
this phase: macro definitions, include path, library path,
|
||||
list of libraries to import. You can deal with these issues by
|
||||
using winemaker's <option>-D</option>, <option>-I</option>,
|
||||
<option>-L</option> and <option>-i</option> options if they are
|
||||
homogeneous enough between all your targets. Otherwise you may
|
||||
want to use winemaker's <link linkend="interactive">interactive
|
||||
mode</link> so that you can specify different settings for each
|
||||
project / target.
|
||||
</para>
|
||||
<para>
|
||||
For instance, one of the problems you are likely to encounter is
|
||||
that of the <varname>STRICT</varname> macro. Some programs will
|
||||
not compile if <varname>STRICT</varname> is not turned on, and
|
||||
others will not compile if it is. Fortunately all the files in a
|
||||
given source tree use the same setting so that all you have to do
|
||||
is add <literal>-DSTRICT</literal> on winemaker's command line
|
||||
or in the <filename>Makefile.in</filename> file(s).
|
||||
</para>
|
||||
<para>
|
||||
Finally the most likely reasons for missing or duplicate symbols
|
||||
are:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The target is not being linked with the right set of libraries.
|
||||
You can avoid this by using winemaker's <option>-L</option> and
|
||||
<option>-i</option> options or adding these libraries to the
|
||||
<filename>Makefile.in</filename> file.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Maybe you have multiple targets in a single directory and
|
||||
winemaker guessed wrong when trying to match the source files
|
||||
with the targets. The only way to fix this kind of problem is
|
||||
to edit the <filename>Makefile.in</filename> file manually.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Winemaker assumes you have organized your source files
|
||||
hierarchically. If a target uses source files that are in a
|
||||
sibling directory, e.g. if you link with
|
||||
<filename>../hello/world.o</filename> then you will get missing
|
||||
symbols. Again the only solution is to manually edit the
|
||||
<filename>Makefile.in</filename> file.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="interactive">
|
||||
<title id="interactive.title">The interactive mode</title>
|
||||
<para>
|
||||
what is it,
|
||||
when to use it,
|
||||
how to use it
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="Makefile.in">
|
||||
<title id="Makefile.in.title">The Makefile.in files</title>
|
||||
<para>
|
||||
The <filename>Makefile.in</filename> is your makefile. More
|
||||
precisely it is the template from which the actual makefile will
|
||||
be generated by the <filename>configure</filename> script. It also
|
||||
relies on the <filename>Make.rules</filename> file for most of
|
||||
the actual logic. This way it only contains a relatively simple
|
||||
description of what needs to be built, not the complex logic of
|
||||
how things are actually built.
|
||||
</para>
|
||||
<para>
|
||||
So this is the file to modify if you want to customize things.
|
||||
Here's a detailed description of its content:
|
||||
</para>
|
||||
<programlisting>
|
||||
### Generic autoconf variables
|
||||
|
||||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = .
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
</programlisting>
|
||||
<para>
|
||||
The above is part of the standard autoconf boiler-plate. These
|
||||
variables make it possible to have per-architecture directories for
|
||||
compiled files and other similar goodies (But note that this kind
|
||||
of functionality has not been tested with winemaker generated
|
||||
<filename>Makefile.in</filename> files yet).
|
||||
</para>
|
||||
<programlisting>
|
||||
SUBDIRS =
|
||||
DLLS =
|
||||
EXES = hello
|
||||
</programlisting>
|
||||
<para>
|
||||
This is where the targets for this directory are listed. The names
|
||||
are pretty self-explanatory. <varname>SUBDIRS</varname> is usually
|
||||
only present in the top-level makefile. For libraries you should
|
||||
put the full Unix name, e.g. <literal>libfoo.so</literal>.
|
||||
</para>
|
||||
<programlisting>
|
||||
### Global settings
|
||||
|
||||
DEFINES = -DSTRICT
|
||||
INCLUDE_PATH =
|
||||
LIBRARY_PATH =
|
||||
LIBRARIES =
|
||||
</programlisting>
|
||||
<para>
|
||||
This section contains the global compilation settings: they apply
|
||||
to all the targets in this makefile. The <varname>LIBRARIES</varname>
|
||||
variable allows you to specify additional Unix libraries to link with.
|
||||
Note that you would normally not specify Winelib libraries there. To
|
||||
link with a Winelib library, one uses the 'import' statement of the
|
||||
<link linkend="spec-file">spec files</link>. The exception is when you
|
||||
have not explicitly exported the functions of a Winelib library. One
|
||||
library you are likely to find here is <literal>mfc</literal> (note,
|
||||
the '-l' is omitted).
|
||||
</para>
|
||||
<para>
|
||||
The other variable
|
||||
names should be self-explanatory. You can also use three additional
|
||||
variables that are usually not present in the file:
|
||||
<varname>CEXTRA</varname>, <varname>CXXEXTRA</varname> and
|
||||
<varname>WRCEXTRA</varname> which allow you to specify additional
|
||||
flags for, respectively, the C compiler, the C++ compiler and the
|
||||
resource compiler. Finally note that all these variable contain
|
||||
the option's name except <varname>IMPORTS</varname>. So you should
|
||||
put <literal>-DSTRICT</literal> in <varname>DEFINES</varname> but
|
||||
<literal>winmm</literal> in <varname>IMPORTS</varname>.
|
||||
</para>
|
||||
<para>
|
||||
Then come one section per target, each describing the various
|
||||
components that target is made of.
|
||||
</para>
|
||||
<programlisting>
|
||||
### hello sources and settings
|
||||
|
||||
hello_C_SRCS = hello.c
|
||||
hello_CXX_SRCS =
|
||||
hello_RC_SRCS =
|
||||
hello_SPEC_SRCS = hello.spec
|
||||
</programlisting>
|
||||
<para>
|
||||
Each section will start with a comment indicating the name of the
|
||||
target. Then come a series of variables prefixed with the name of
|
||||
that target. Note that the name of the prefix may be slightly
|
||||
different from that of the target because of restrictions on the
|
||||
variable names.
|
||||
</para>
|
||||
<para>
|
||||
The above variables list the sources that are used togenerate the
|
||||
target. Note that there should only be one resource file in
|
||||
<varname>RC_SRCS</varname>, and that <varname>SPEC_SRCS</varname>
|
||||
will always contain a single spec file.
|
||||
</para>
|
||||
<programlisting>
|
||||
hello_LIBRARY_PATH =
|
||||
hello_LIBRARIES =
|
||||
hello_DEPENDS =
|
||||
</programlisting>
|
||||
<para>
|
||||
The above variables specify how to link the target. Note that they
|
||||
add to the global settings we saw at the beginning of this file.
|
||||
</para>
|
||||
<para>
|
||||
<varname>DEPENDS</varname>, when present, specifies a list of other
|
||||
targets that this target depends on. Winemaker will automatically
|
||||
fill this field, and the <varname>LIBRARIES</varname> field, when an
|
||||
executable and a library are built in the same directory.
|
||||
</para>
|
||||
<para>
|
||||
The reason why winemaker also links with libraries in the Unix sense
|
||||
in the case above is because functions will not be properly exported.
|
||||
Once you have exported all the functions in the library's spec file
|
||||
you should remove them from the <varname>LIBRARIES</varname> field.
|
||||
</para>
|
||||
<programlisting>
|
||||
hello_OBJS = $(hello_C_SRCS:.c=.o) \
|
||||
$(hello_CXX_SRCS:.cpp=.o) \
|
||||
$(EXTRA_OBJS)
|
||||
</programlisting>
|
||||
<para>
|
||||
The above just builds a list of all the object files that
|
||||
correspond to this target. This list is later used for the link
|
||||
command.
|
||||
</para>
|
||||
<programlisting>
|
||||
### Global source lists
|
||||
|
||||
C_SRCS = $(hello_C_SRCS)
|
||||
CXX_SRCS = $(hello_CXX_SRCS)
|
||||
RC_SRCS = $(hello_RC_SRCS)
|
||||
SPEC_SRCS = $(hello_SPEC_SRCS)
|
||||
</programlisting>
|
||||
<para>
|
||||
This section builds 'summary' lists of source files. These lists are
|
||||
used by the <filename>Make.rules</filename> file.
|
||||
</para>
|
||||
<programlisting>
|
||||
### Generic autoconf targets
|
||||
|
||||
all: $(DLLS) $(EXES:%=%.so)
|
||||
|
||||
@MAKE_RULES@
|
||||
|
||||
install::
|
||||
for i in $(EXES); do $(INSTALL_PROGRAM) $$i $(bindir); done
|
||||
for i in $(EXES:%=%.so) $(DLLS); do $(INSTALL_LIBRARY) $$i $(libdir); done
|
||||
|
||||
uninstall::
|
||||
for i in $(EXES); do $(RM) $(bindir)/$$i;done
|
||||
for i in $(EXES:%=%.so) $(DLLS); do $(RM) $(libdir)/$$i;done
|
||||
</programlisting>
|
||||
<para>
|
||||
The above first defines the default target for this makefile. Here
|
||||
it consists in trying to build all the targets. Then it includes
|
||||
the <filename>Make.rules</filename> file which contains the build
|
||||
logic, and provides a few more standard targets to install /
|
||||
uninstall the targets.
|
||||
</para>
|
||||
<programlisting>
|
||||
### Target specific build rules
|
||||
|
||||
$(hello_SPEC_SRCS:.spec=.tmp.o): $(hello_OBJS)
|
||||
$(LDCOMBINE) $(hello_OBJS) -o $@
|
||||
-$(STRIP) $(STRIPFLAGS) $@
|
||||
|
||||
$(hello_SPEC_SRCS:.spec=.spec.c): $(hello_SPEC_SRCS:.spec) $(hello_SPEC_SRCS:.spec=.tmp.o) $(hello_RC_SRCS:.rc=.res)
|
||||
$(WINEBUILD) -fPIC $(hello_LIBRARY_PATH) $(WINE_LIBRARY_PATH) -sym $(hello_SPEC_SRCS:.spec=.tmp.o) -o $@ -spec $(hello_SPEC_SRCS)
|
||||
|
||||
hello.so: $(hello_SPEC_SRCS:.spec=.spec.o) $(hello_OBJS) $(hello_DEP
|
||||
ENDS)
|
||||
$(LDSHARED) $(LDDLLFLAGS) -o $@ $(hello_OBJS) $(hello_SPEC_SRCS:.spec=.spec.o) $(hello_LIBRARY_PATH) $(hello_LIBRARIES:%=-l%) $(DLL_LINK) $(LIBS)
|
||||
test -e hello || $(LN_S) $(WINE) hello
|
||||
</programlisting>
|
||||
<para>
|
||||
Then come additional directives to link the executables and
|
||||
libraries. These are pretty much standard and you should not need
|
||||
to modify them.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="Make.rules.in">
|
||||
<title id="Make.rules.in.title">The Make.rules.in file</title>
|
||||
<para>
|
||||
What's in the Make.rules.in...
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="configure.in">
|
||||
<title id="configure.in.title">The configure.in file</title>
|
||||
<para>
|
||||
What's in the configure.in...
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="wrc">
|
||||
<title id="wrc.title">Compiling resource files: WRC</title>
|
||||
<para>
|
||||
To compile resources you should use the Wine Resource Compiler,
|
||||
wrc for short, which produces a binary <filename>.res</filename>
|
||||
file. This resource file is then used by winebuild when compiling
|
||||
the spec file (see <xref linkend="spec-file"
|
||||
endterm="spec-file.title">).
|
||||
</para>
|
||||
<para>
|
||||
Again the makefiles generated by winemaker take care of this for you.
|
||||
But if you were to write your own makefile you would put something
|
||||
like the following:
|
||||
</para>
|
||||
<programlisting>
|
||||
WRC=$(WINE_DIR)/tools/wrc/wrc
|
||||
|
||||
WINELIB_FLAGS = -I$(WINE_DIR)/include -DWINELIB -D_REENTRANT
|
||||
WRCFLAGS = -r -L
|
||||
|
||||
.SUFFIXES: .rc .res
|
||||
|
||||
.rc.res:
|
||||
$(WRC) $(WRCFLAGS) $(WINELIB_FLAGS) -o $@ $<
|
||||
</programlisting>
|
||||
<para>
|
||||
There are two issues you are likely to encounter with resource files.
|
||||
</para>
|
||||
<para>
|
||||
The first problem is with the C library headers. WRC does not know
|
||||
where these headers are located. So if an RC file, of a file it
|
||||
includes, references such a header you will get a 'file not found'
|
||||
error from wrc. Here are a few ways to deal with this:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The solution traditionally used by the Winelib headers is to
|
||||
enclose the offending include statement in an
|
||||
<literal>#ifndef RC_INVOKED</literal> statement where
|
||||
<varname>RC_INVOKED</varname> is a macro name which is
|
||||
automatically defined by wrc.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Alternately you can add one or more <option>-I</option> directive
|
||||
to your wrc command so that it finds you system files. For
|
||||
instance you may add <literal>-I/usr/include
|
||||
-I/usr/lib/gcc-lib/i386-linux/2.95.2/include</literal> to cater
|
||||
to both C and C++ headers. But this supposes that you know where
|
||||
these header files reside which decreases the portability of your
|
||||
makefiles to other platforms (unless you automatically detect all
|
||||
the necessary directories in the autoconf script).
|
||||
</para>
|
||||
<para>
|
||||
Or you could use the C/C++ compiler to perform the preprocessing.
|
||||
To do so, simply modify your makefile as follows:
|
||||
</para>
|
||||
<programlisting>
|
||||
.rc.res:
|
||||
$(CC) $(CC_OPTS) -DRC_INVOKED -E -x c $< | $(WRC) -N $(WRCFLAGS) $(WINELIB_FLAGS) -o $@
|
||||
|
||||
</programlisting>
|
||||
<!-- FIXME: does this still cause problems for the line numbers? -->
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
The second problem is that the headers may contain constructs that
|
||||
WRC fails to understand. A typical example is a function which return
|
||||
a 'const' type. WRC expects a function to be two identifiers followed
|
||||
by an opening parenthesis. With the const this is three identifiers
|
||||
followed by a parenthesis and thus WRC is confused (note: WRC should
|
||||
in fact ignore all this like the windows resource compiler does).
|
||||
The current work-around is to enclose offending statement(s) in an
|
||||
<literal>#ifndef RC_INVOKED</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Using GIF files in resources is problematic. For best results,
|
||||
convert them to BMP and change your <filename>.res</filename>
|
||||
file.
|
||||
</para>
|
||||
<para>
|
||||
If you use common controls/dialogs in your resource files, you
|
||||
will need to add <function>#include <commctrl.h></function>
|
||||
after the <function>#include <windows.h></function> line,
|
||||
so that <command>wrc</command> knows the values of control
|
||||
specific flags.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="wmc">
|
||||
<title id="wmc.title">Compiling message files: WMC</title>
|
||||
<para>
|
||||
how does one use it???
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="spec-file">
|
||||
<title id="spec-file.title">The Spec file</title>
|
||||
|
||||
<sect2 id="spec-intro">
|
||||
<title id="spec-intro.title">Introduction</title>
|
||||
<para>
|
||||
In Windows the program's life starts either when its
|
||||
<function>main</function> is called, for console applications, or
|
||||
when its <function>WinMain</function> is called, for windows
|
||||
applications in the 'windows' subsystem. On Unix it is always
|
||||
<function>main</function> that is called. Furthermore in Winelib it
|
||||
has some special tasks to accomplish, such as initializing Winelib,
|
||||
that a normal <function>main</function> does not have to do.
|
||||
</para>
|
||||
<para>
|
||||
Furthermore windows applications and libraries contain some
|
||||
information which are necessary to make APIs such as
|
||||
<function>GetProcAddress</function> work. So it is necessary to
|
||||
duplicate these data structures in the Unix world to make these
|
||||
same APIs work with Winelib applications and libraries.
|
||||
</para>
|
||||
<para>
|
||||
The spec file is there to solve the semantic gap described above.
|
||||
It provides the <function>main</function> function that initializes
|
||||
Winelib and calls the module's <function>WinMain</function> /
|
||||
<function>DllMain</function>, and it contains information about
|
||||
each API exported from a Dll so that the appropriate tables can be
|
||||
generated.
|
||||
</para>
|
||||
<para>
|
||||
A typical spec file will look something like this:
|
||||
</para>
|
||||
<screen>
|
||||
name hello
|
||||
type win32
|
||||
mode guiexe
|
||||
init WinMain
|
||||
rsrc resource.res
|
||||
|
||||
import winmm.dll
|
||||
</screen>
|
||||
<para>
|
||||
And here are the entries you will probably want to change:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>name</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is the name of the Win32 module. Usually this is the
|
||||
same as that of the application or library (but without the
|
||||
'lib' and the '.so').
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>mode</term>
|
||||
<term>init</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>mode</literal> defines whether what you are
|
||||
building is a library, <literal>dll</literal>, a console
|
||||
application, <literal>cuiexe</literal> or a regular
|
||||
graphical application <literal>guiexe</literal>. Then
|
||||
<literal>init</literal> defines what is the entry point of
|
||||
that module. For a library this is customarily set to
|
||||
<literal>DllMain</literal>, for a console application this
|
||||
is <literal>main</literal> and for a graphical application
|
||||
this is <literal>WinMain</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>import</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Add an 'import' statement for each library that this
|
||||
executable depends on. If you don't, these libraries will
|
||||
not get initialized in which case they may very well not
|
||||
work (e.g. winmm).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>rsrc</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This item specifies the name of the compiled resource file
|
||||
to link with your module. If your resource file is called
|
||||
<filename>hello.rc</filename> then the wrc compilation step
|
||||
(see <xref linkend="wrc" endterm="wrc.title">) will generate
|
||||
a file called <filename>hello.res</filename>. This is the
|
||||
name you must provide here. Note that because of this you
|
||||
cannot compile the spec file before you have compiled the
|
||||
resource file. So you should put a rule like the following
|
||||
in your makefile:
|
||||
</para>
|
||||
<programlisting>
|
||||
hello.spec.c: hello.res
|
||||
</programlisting>
|
||||
<para>
|
||||
If your project does not have a resource file then you must
|
||||
omit this entry altogether.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>@</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This entry is not shown above because it is not always
|
||||
necessary. In fact it is only necessary to export functions
|
||||
when you plan to dynamically load the library with
|
||||
<function>LoadLibrary</function> and then do a
|
||||
<function>GetProcAddress</function> on these functions.
|
||||
This is not necessary if you just plan on linking with the
|
||||
library and calling the functions normally. For more details
|
||||
about this see: <xref linkend="spec-reference"
|
||||
endterm="spec-reference.title">.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="spec-compiling">
|
||||
<title id="spec-compiling.title">Compiling it</title>
|
||||
<para>
|
||||
Compiling a spec file is a two step process. It is first
|
||||
converted into a C file by winebuild, and then compiled into an
|
||||
object file using your regular C compiler. This is all taken
|
||||
care of by the winemaker generated makefiles of course. But
|
||||
here's what it would like if you had to do it by hand:
|
||||
</para>
|
||||
<screen>
|
||||
WINEBUILD=$(WINE_DIR)/tools/winebuild
|
||||
|
||||
.SUFFIXES: .spec .spec.c .spec.o
|
||||
|
||||
.spec.spec.c:
|
||||
$(WINEBUILD) -fPIC -o $@ -spec $<
|
||||
|
||||
.spec.c.spec.o:
|
||||
$(CC) -c -o $*.spec.o $<
|
||||
</screen>
|
||||
<para>
|
||||
Nothing really complex there. Just don't forget the
|
||||
<literal>.SUFFIXES</literal> statement, and beware of the tab if
|
||||
you copy this straight to your Makefile.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="spec-reference">
|
||||
<title id="spec-reference.title">More details</title>
|
||||
<para>
|
||||
(Extracted from tools/winebuild/README)
|
||||
<!-- FIXME: this seems to be rather outdated and sometimes even incorrect, check with the source! -->
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here is a more detailed description of the spec file's format.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
# comment text
|
||||
</programlisting>
|
||||
<para>
|
||||
Anything after a '#' will be ignored as comments.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
name NAME
|
||||
type win16|win32 <--- the |'s mean it's one or the other
|
||||
</programlisting>
|
||||
<para>
|
||||
These two fields are mandatory. <literal>name</literal>
|
||||
defines the name of your module and <literal>type</literal>
|
||||
whether it is a Win16 or Win32 module. Note that for Winelib
|
||||
you should only be using Win32 modules.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
file WINFILENAME
|
||||
</programlisting>
|
||||
<para>
|
||||
This field is optional. It gives the name of the Windows file that
|
||||
is replaced by the builtin. <literal><name>.DLL</literal>
|
||||
is assumed if none is given. This is important for kernel, which
|
||||
lives in the Windows file <filename>KRNL386.EXE</filename>.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
heap SIZE
|
||||
</programlisting>
|
||||
<para>
|
||||
This field is optional and specific to Win16 modules. It defines
|
||||
the size of the module local heap. The default is no local heap.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
mode dll|cuiexe|guiexe
|
||||
</programlisting>
|
||||
<para>
|
||||
This field is optional. It specifies specifies whether it is the
|
||||
spec file for a dll or the main exe. This is only valid for Win32
|
||||
spec files.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
init FUNCTION
|
||||
</programlisting>
|
||||
<para>
|
||||
This field is optional and specific to Win32 modules. It
|
||||
specifies a function which will be called when the dll is loaded
|
||||
or the executable started.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
import DLL
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance names a dll that this module depends on (only for
|
||||
Win32 modules at the present).
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
rsrc RES_FILE
|
||||
</programlisting>
|
||||
<para>
|
||||
This field is optional. If present it specifies the name of the
|
||||
.res file containing the compiled resources. See <xref
|
||||
linkend="wrc" endterm="wrc.title"> for details on compiling a
|
||||
resource file.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]])
|
||||
2 byte Variable(-1 0xff 0 0)
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines data storage at the ordinal specified. You
|
||||
may store items as bytes, 16-bit words, or 32-bit words.
|
||||
<literal>ORDINAL</literal> is replaced by the ordinal number
|
||||
corresponding to the variable. <literal>VARTYPE</literal> should
|
||||
be <literal>byte</literal>, <literal>word</literal> or
|
||||
<literal>long</literal> for 8, 16, or 32 bits respectively.
|
||||
<literal>EXPORTNAME</literal> will be the name available for
|
||||
dynamic linking. <literal>DATA</literal> can be a decimal number
|
||||
or a hex number preceeded by "0x". The example defines the
|
||||
variable <literal>Variable</literal> at ordinal 2 and containing
|
||||
4 bytes.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL equate EXPORTNAME DATA
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines an ordinal as an absolute value.
|
||||
<literal>ORDINAL</literal> is replaced by the ordinal number
|
||||
corresponding to the variable. <literal>EXPORTNAME</literal> will
|
||||
be the name available for dynamic linking.
|
||||
<literal>DATA</literal> can be a decimal number or a hex number
|
||||
preceeded by "0x".
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL FUNCTYPE EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) HANDLERNAME
|
||||
100 pascal CreateWindow(ptr ptr long s_word s_word s_word s_word
|
||||
word word word ptr)
|
||||
WIN_CreateWindow
|
||||
101 pascal GetFocus() WIN_GetFocus()
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines a function entry point. The prototype
|
||||
defined by <literal>EXPORTNAME ([ARGTYPE [ARGTYPE [...]]])</literal>
|
||||
specifies the name available for dynamic linking and the format
|
||||
of the arguments. <literal>"ORDINAL</literal>" is replaced
|
||||
by the ordinal number corresponding to the function, or
|
||||
<literal>@</literal> for automatic ordinal allocation (Win32 only).
|
||||
</para>
|
||||
<para>
|
||||
<literal>FUNCTYPE</literal> should be one of:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>pascal16</term>
|
||||
<listitem><para>for a Win16 function returning a 16-bit value</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>pascal</term>
|
||||
<listitem><para>for a Win16 function returning a 32-bit value</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>register</term>
|
||||
<listitem><para>for a function using CPU register to pass arguments</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>interrupt</term>
|
||||
<listitem><para>for a Win16 interrupt handler routine</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>stdcall</term>
|
||||
<listitem><para>for a normal Win32 function</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>cdecl</term>
|
||||
<listitem><para>for a Win32 function using the C calling convention</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>varargs</term>
|
||||
<listitem><para>for a Win32 function taking a variable number of arguments</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
<literal>ARGTYPE</literal> should be one of:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>word</term>
|
||||
<listitem><para>for a 16 bit word</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>long</term>
|
||||
<listitem><para>a 32 bit value</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>ptr</term>
|
||||
<listitem><para>for a linear pointer</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>str</term>
|
||||
<listitem><para>for a linear pointer to a null-terminated string</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>s_word</term>
|
||||
<listitem><para>for a 16 bit signed word</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>segptr</term>
|
||||
<listitem><para>for a segmented pointer</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>segstr</term>
|
||||
<listitem><para>for a segmented pointer to a null-terminated string</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
Only <literal>ptr</literal>, <literal>str</literal> and
|
||||
<literal>long</literal> are valid for Win32 functions.
|
||||
<literal>HANDLERNAME</literal> is the name of the actual Wine
|
||||
function that will process the request in 32-bit mode.
|
||||
</para>
|
||||
<para>
|
||||
The two examples define an entry point for the
|
||||
<function>CreateWindow</function> and <function>GetFocus</function>
|
||||
calls respectively. The ordinals used are just examples.
|
||||
</para>
|
||||
<para>
|
||||
To declare a function using a variable number of arguments in
|
||||
Win16, specify the function as taking no arguments. The arguments
|
||||
are then available with CURRENT_STACK16->args. In Win32, specify
|
||||
the function as <literal>varargs</literal> and declare it with a
|
||||
'...' parameter in the C file. See the wsprintf* functions in
|
||||
<filename>user.spec</filename> and
|
||||
<filename>user32.spec</filename> for an example.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL stub EXPORTNAME
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines a stub function. It makes the ordinal
|
||||
available for dynamic linking, but will terminate execution with
|
||||
an error message if the function is ever called.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL extern EXPORTNAME SYMBOLNAME
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines an entry that simply maps to a Wine symbol
|
||||
(variable or function); <literal>EXPORTNAME</literal> will point
|
||||
to the symbol <literal>SYMBOLNAME</literal> that must be defined
|
||||
in C code. This type only works with Win32.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL forward EXPORTNAME SYMBOLNAME
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines an entry that is forwarded to another entry
|
||||
point (kind of a symbolic link). <literal>EXPORTNAME</literal>
|
||||
will forward to the entry point <literal>SYMBOLNAME</literal>
|
||||
that must be of the form <literal>DLL.Function</literal>. This
|
||||
type only works with Win32.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="linking">
|
||||
<title id="linking.title">Linking it all together</title>
|
||||
<!-- FIXME: This is outdated -->
|
||||
<para>
|
||||
To link an executable you need to link together: your object files,
|
||||
the spec file, any Windows libraries that your application depends
|
||||
on, gdi32 for instance, and any additional library that you use. All
|
||||
the libraries you link with should be available as '.so' libraries.
|
||||
If one of them is available only in '.dll' form then consult
|
||||
<xref linkend="bindlls" endterm="bindlls.title">.
|
||||
</para>
|
||||
<para>
|
||||
It is also when attempting to link your executable that you will
|
||||
discover whether you have missing symbols or not in your custom
|
||||
libraries. On Windows when you build a library, the linker will
|
||||
immediately tell you if a symbol it is supposed to export is
|
||||
undefined. In Unix, and in Winelib, this is not the case. The symbol
|
||||
will silently be marked as undefined and it is only when you try to
|
||||
produce an executable that the linker will verify all the symbols are
|
||||
accounted for.
|
||||
</para>
|
||||
<para>
|
||||
So before declaring victory when first converting a library to
|
||||
Winelib, you should first try to link it to an executable (but you
|
||||
would have done that to test it anyway, right?). At this point you
|
||||
may discover some undefined symbols that you thought were implemented
|
||||
by the library. Then, you to the library sources and fix it. But you
|
||||
may also discover that the missing symbols are defined in, say,
|
||||
gdi32. This is because you did not link the said library with gdi32.
|
||||
One way to fix it is to link this executable, and any other that also
|
||||
uses your library, with gdi32. But it is better to go back to your
|
||||
library's makefile and explicitly link it with gdi32.
|
||||
</para>
|
||||
<para>
|
||||
As you will quickly notice, this has unfortunately not been
|
||||
(completely) done for Winelib's own libraries. So if an application
|
||||
must link with ole32, you will also need to link with advapi32,
|
||||
rpcrt4 and others even if you don't use them directly. This can be
|
||||
annoying and hopefully will be fixed soon (feel free to submit a
|
||||
patch).
|
||||
</para>
|
||||
<!-- FIXME: try to give some sort of concrete example -->
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue