2001-01-24 20:36:24 +01:00
|
|
|
<chapter id="winelib-introduction">
|
|
|
|
<title id="introduction.title">Winelib Introduction</title>
|
|
|
|
|
2003-07-22 00:13:19 +02:00
|
|
|
<sect1 id="winelib-whatis">
|
2001-01-24 20:36:24 +01:00
|
|
|
<title>What is Winelib?</title>
|
|
|
|
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
Winelib is a development toolkit which allows you to compile your
|
2001-01-24 20:36:24 +01:00
|
|
|
Windows applications on Unix.
|
|
|
|
</para>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
compiler (and even these are used when compiling Wine).
|
|
|
|
</para>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
Thanks to the above, Winelib supports most C and C++ 32bit source code,
|
|
|
|
resource and message files, and can generate graphical or console
|
2001-01-24 20:36:24 +01:00
|
|
|
applications as well as dynamic libraries.
|
|
|
|
</para>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
you in this task.
|
|
|
|
</para>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2003-07-09 21:50:14 +02:00
|
|
|
Unix environment than is allowed by running an unmodified Windows
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
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>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2003-05-13 06:48:11 +02:00
|
|
|
pretty much uncharted territory. It would be more reasonable to
|
|
|
|
target one of the more mundane i386-based platforms first.
|
2001-01-24 20:36:24 +01:00
|
|
|
</para>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
The main difference is that the compiler becomes much more important.
|
2003-05-13 06:48:11 +02:00
|
|
|
It is highly recommended that you use gcc, g++, and the GNU binutils.
|
|
|
|
The more recent your gcc compiler the better.
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
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?
|
2002-07-23 22:55:17 +02:00
|
|
|
Well, it really depends on the complexity of your application but
|
2001-01-24 20:36:24 +01:00
|
|
|
here are some issues that are shared by all applications:
|
|
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
work with and probably not what you intended.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
then the case of the filenames in your include statements may be
|
2001-01-24 20:36:24 +01:00
|
|
|
wrong: maybe they include 'Windows.h' instead of 'windows.h'.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
your include statements may use '\' instead of '/'. '\' is not
|
|
|
|
recognized by Unix compilers while '/' is recognized in both
|
2001-01-24 20:36:24 +01:00
|
|
|
environments.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
you will need to perform the usual Dos to Unix text file conversion
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
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>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
and generate autoconf-based Makefiles.
|
|
|
|
</para>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
Let's suppose that Wine/Winelib has been installed in the
|
2001-01-24 20:36:24 +01:00
|
|
|
<filename class="Directory">/usr/local/wine</filename>
|
2002-07-23 22:55:17 +02:00
|
|
|
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 (note the dot indicating
|
|
|
|
current directory at the end of the first command):
|
2001-01-24 20:36:24 +01:00
|
|
|
</para>
|
|
|
|
<programlisting>
|
2001-09-27 01:08:45 +02:00
|
|
|
$ winemaker --lower-uppercase .
|
2001-01-24 20:36:24 +01:00
|
|
|
$ ./configure --with-wine=/usr/local/wine
|
|
|
|
$ make
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
But of course things are not always that simple which is why we have
|
2001-01-24 20:36:24 +01:00
|
|
|
this guide at all.
|
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
|
2002-08-09 02:58:27 +02:00
|
|
|
<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 winemine application from the Wine source tree
|
|
|
|
suits well for testing purposes. It can be found in the programs
|
|
|
|
subdirectory. winemine is a simple application, but has a few C,
|
|
|
|
header and resource files.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Run <command>make clean</command> in the
|
|
|
|
winemine source directory if it contains results of previous builds.
|
|
|
|
Create a separate directory with name winemine2, so it won't conflict
|
|
|
|
with the Wine copy of the application. Copy the sources of winemine
|
|
|
|
(files *.c, *.h, *.rc) to this directory. Now run the commands,
|
|
|
|
mentioned above from the winemine2 directory:
|
|
|
|
</para>
|
|
|
|
<programlisting>
|
|
|
|
$ winemaker --lower-uppercase .
|
|
|
|
$ ./configure --with-wine=/usr/local/wine
|
|
|
|
$ make
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
You are done! Now you can start the application as
|
|
|
|
<command>./winemine2</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.com</email>
|
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
|
2001-01-24 20:36:24 +01:00
|
|
|
<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>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
these directories; especially as they tend to be quite big.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>cd <root_dir></option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
libraries with a single <command>make</command> command.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>Making the source writable</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
version control system you're already covered.
|
|
|
|
</para>
|
2001-10-02 19:48:16 +02:00
|
|
|
<para>
|
|
|
|
If you have already modified your source files and you want
|
|
|
|
to make sure that winemaker will not make further changes to
|
2002-07-23 22:55:17 +02:00
|
|
|
them then you can use the --nosource-fix option to protect
|
2001-10-02 19:48:16 +02:00
|
|
|
them.
|
|
|
|
</para>
|
2001-01-24 20:36:24 +01:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>Running winemaker</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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.
|
2001-01-24 20:36:24 +01:00
|
|
|
</para>
|
|
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>--lower-uppercase</option></term>
|
|
|
|
<term><option>--lower-all</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
still have to rename some files.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>--nobackup</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
option.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>--dll</option></term>
|
|
|
|
<term><option>--console</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
then you will need to use the corresponding option.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>--mfc</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
This option tells winemaker that you are building an MFC
|
2001-01-24 20:36:24 +01:00
|
|
|
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>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
<literal>-I\$(WINELIB_INCLUDE_ROOT)/msvcrt</literal>.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
|
|
<para>
|
|
|
|
So your command may finally look like:
|
2001-09-27 01:08:45 +02:00
|
|
|
<literal>winemaker --lower-uppercase -Imylib/include .</literal>
|
2001-01-24 20:36:24 +01:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term id="renaming"><option>File renaming</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
(2.13) and make (3.79).
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>Source modifications and makefile generation</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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:
|
2001-01-24 20:36:24 +01:00
|
|
|
<command>diff -uw hello.c.bak hello.c</command>
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>Running the configure script</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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>
|
2001-01-24 20:36:24 +01:00
|
|
|
respectively.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term><option>Running make</option></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
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
|
2001-01-24 20:36:24 +01:00
|
|
|
read this guide further to:
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
review the <filename>Makefile.in</filename> files to
|
|
|
|
adjust the default compilation and link options set by
|
|
|
|
winemaker. See the <xref linkend="source-analysis"
|
2003-07-09 21:50:14 +02:00
|
|
|
endterm="source-analysis.title"> section for some hints.
|
2001-01-24 20:36:24 +01:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-07-23 22:55:17 +02:00
|
|
|
fix the portability issues in your sources. See
|
|
|
|
<xref linkend="portability-issues"
|
2001-01-24 20:36:24 +01:00
|
|
|
endterm="portability-issues.title"> for more details.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
2001-10-02 19:48:16 +02:00
|
|
|
<para>
|
|
|
|
If you find yourself modifying the Makefile.in to specify the
|
|
|
|
location of the Wine header or library files then go back to
|
|
|
|
the previous step (the configure script) and use the various
|
|
|
|
--with-wine-* options to specify where they are.
|
|
|
|
</para>
|
2001-01-24 20:36:24 +01:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
|
|
</sect2>
|
|
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
Local variables:
|
|
|
|
mode: sgml
|
2003-04-19 04:50:57 +02:00
|
|
|
sgml-parent-document:("winelib-user.sgml" "book" "chapter" "")
|
2001-01-24 20:36:24 +01:00
|
|
|
End:
|
|
|
|
-->
|