| <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, 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.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 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.in</> 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 -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> |
| |
| <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> |
| <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> |
| (Extracted from tools/winebuild/README) |
| </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> |
| <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 as 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> |
| <!-- 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: |
| --> |