| <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</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</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 overridden by using | |
| <option>--nolower-include</option>). | |
| </para> | |
| <para> | |
| Finally winemaker generates the <filename>Makefile</filename> | |
| files. From the above description | |
| you can guess at the items that winemaker may get wrong in | |
| this phase: macro definitions, include path, DLL path, DLLs to | |
| import, library path, libraries to link with. You can deal with | |
| these issues by using winemaker's <option>-D</>, <option>-P</>, | |
| <option>-i</>, <option>-I</>, <option>-L</> and <option>-l</> | |
| 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</filename> file(s). | |
| </para> | |
| <para> | |
| Finally the most likely reasons for missing or duplicate symbols | |
| are: | |
| </para> | |
| <itemizedlist> | |
| <listitem> | |
| <para> | |
| The target is not importing the right set of DLLs, or is not | |
| being linked with the right set of libraries. You can avoid | |
| this by using winemaker's <option>-P</>, <option>-i</>, | |
| <option>-L</option> and <option>-l</> options or adding these | |
| DLLs and libraries to the <filename>Makefile</> 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</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</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"> | |
| <title id="Makefile.title">The Makefile files</title> | |
| <para> | |
| The <filename>Makefile</filename> is your makefile. | |
| 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</filename> files yet). | |
| </para> | |
| <programlisting> | |
| SUBDIRS = | |
| DLLS = | |
| EXES = hello.exe | |
| </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 and | |
| executables, specify the full name, including the '.dll' or '.exe' | |
| extension. Note that these names must be in all lowercase. | |
| </para> | |
| <programlisting> | |
| ### Global settings | |
| DEFINES = -DSTRICT | |
| INCLUDE_PATH = | |
| DLL_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</> | |
| 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 <varname>DLLS</> | |
| variables of the Makefile. The exception is for C++ libraries where | |
| you currently don't have a choice but to link with them in the | |
| Unix sense. One library you are likely to find here is | |
| <literal>mfc</> (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. | |
| </para> | |
| <para> | |
| Then come one section per target, each describing the various | |
| components that target is made of. | |
| </para> | |
| <programlisting> | |
| ### hello.exe sources and settings | |
| hello_exe_C_SRCS = hello.c | |
| hello_exe_CXX_SRCS = | |
| hello_exe_RC_SRCS = | |
| hello_exe_SPEC_SRCS = | |
| </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 usually be empty for executables, and will contain a single | |
| spec file for libraries. | |
| </para> | |
| <programlisting> | |
| hello_exe_DLL_PATH = | |
| hello_exe_DLLS = | |
| hello_exe_LIBRARY_PATH = | |
| hello_exe_LIBRARIES = | |
| hello_exe_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> | |
| The <varname>DLLS</> field is where you would enumerate the list of | |
| DLLs that executable imports. It should contain the full DLL name | |
| including the '.dll' extension, but not the '-l' option. | |
| </para> | |
| <para> | |
| <varname>DEPENDS</>, when present, specifies a list of other | |
| targets that this target depends on. Winemaker will automatically | |
| fill this field when an executable and a library are built in the | |
| same directory. | |
| </para> | |
| <programlisting> | |
| hello_exe_OBJS = $(hello_exe_C_SRCS:.c=.o) \ | |
| $(hello_exe_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_exe_C_SRCS) | |
| CXX_SRCS = $(hello_exe_CXX_SRCS) | |
| RC_SRCS = $(hello_exe_RC_SRCS) | |
| SPEC_SRCS = $(hello_exe_SPEC_SRCS) | |
| </programlisting> | |
| <para> | |
| This section builds 'summary' lists of source files. These lists are | |
| used by the <filename>Make.rules</filename> file. | |
| </para> | |
| <note><para> | |
| FIXME:The following is not up-to-date. | |
| </para></note> | |
| <programlisting> | |
| ### Generic autoconf targets | |
| all: $(DLLS:%=%.so) $(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 -f 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> | |
| </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> | |
| init WinMain | |
| rsrc resource.res | |
| </screen> | |
| <para> | |
| And here are the entries you will probably want to change: | |
| </para> | |
| <variablelist> | |
| <varlistentry> | |
| <term>init</term> | |
| <listitem> | |
| <para> | |
| <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>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> | |
| <note><para> | |
| FIXME: You must now export functions from DLLs. | |
| </para></note> | |
| <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> | |
| <note><para> | |
| FIXME: This section is very outdated and does not correctly | |
| describe the current use of winebuild and spec files. In | |
| particular, with recent versions of winebuild most of the | |
| information that used to be in the spec files is now specified on | |
| the command line. | |
| </para></note> | |
| <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> | |
| 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> | |
| 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> | |
| 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 preceded 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 | |
| preceded 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> | |
| <varlistentry> | |
| <term>wstr</term> | |
| <listitem> | |
| <para> | |
| for a linear pointer to a null-terminated wide | |
| (16-bit Unicode) string | |
| </para> | |
| </listitem> | |
| </varlistentry> | |
| </variablelist> | |
| <para> | |
| Only <literal>ptr</literal>, <literal>str</literal>, | |
| <literal>wstr</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> | |
| Strings should almost always map to str, | |
| wide strings - wstr. | |
| As the general rule it depends on whether the | |
| parameter is IN, OUT or IN/OUT. | |
| </para> | |
| <itemizedlist> | |
| <listitem> | |
| <para> | |
| IN: str/wstr | |
| </para> | |
| </listitem> | |
| <listitem> | |
| <para> | |
| OUT: ptr | |
| </para> | |
| </listitem> | |
| <listitem> | |
| <para> | |
| IN/OUT: str/wstr | |
| </para> | |
| </listitem> | |
| </itemizedlist> | |
| <para> | |
| It is for debug messages. If the parameter is OUT | |
| it might not be initialized and thus it should not | |
| be printed as a string. | |
| </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> | |
| <note><para> | |
| FIXME:The following is not up-to-date. | |
| </para></note> | |
| <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:("winelib-user.sgml" "book" "chapter" "") | |
| End: | |
| --> |