In Windows the program's life starts either when its
main is called, for console applications, or
when its WinMain is called, for windows
applications in the 'windows' subsystem. On Unix it is always
main that is called. Furthermore in Winelib it
has some special tasks to accomplish, such as initializing Winelib,
that a normal main does not have to do.
Furthermore windows applications and libraries contain some
information which are necessary to make APIs such as
GetProcAddress 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.
The spec file is there to solve the semantic gap described above.
It provides the main function that initializes
Winelib and calls the module's WinMain /
DllMain, and it contains information about
each API exported from a Dll so that the appropriate tables can be
generated.
A typical spec file will look something like this:
init WinMain
rsrc resource.res
And here are the entries you will probably want to change:
init
init defines what is the entry point of
that module. For a library this is customarily set to
DllMain, for a console application this
is main and for a graphical application
this is WinMain.
rsrc
This item specifies the name of the compiled resource file
to link with your module. If your resource file is called
hello.rc then the wrc compilation step
(see Compiling resource files: WRC) will generate
a file called hello.res. 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:
hello.spec.c: hello.res
If your project does not have a resource file then you must
omit this entry altogether.
@
Note: FIXME: You must now export functions from DLLs.
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
LoadLibrary and then do a
GetProcAddress 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: More details.
Note: 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.
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:
Here is a more detailed description of the spec file's format.
# comment text
Anything after a '#' will be ignored as comments.
init FUNCTION
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.
rsrc RES_FILE
This field is optional. If present it specifies the name of the
.res file containing the compiled resources. See Compiling resource files: WRC for details on compiling a
resource file.
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.
ORDINAL is replaced by the ordinal number
corresponding to the variable. VARTYPE should
be byte, word or
long for 8, 16, or 32 bits respectively.
EXPORTNAME will be the name available for
dynamic linking. DATA can be a decimal number
or a hex number preceded by "0x". The example defines the
variable Variable at ordinal 2 and containing
4 bytes.
ORDINAL equate EXPORTNAME DATA
This field can be present zero or more times.
Each instance defines an ordinal as an absolute value.
ORDINAL is replaced by the ordinal number
corresponding to the variable. EXPORTNAME will
be the name available for dynamic linking.
DATA can be a decimal number or a hex number
preceded by "0x".
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()
This field can be present zero or more times.
Each instance defines a function entry point. The prototype
defined by EXPORTNAME ([ARGTYPE [ARGTYPE [...]]])
specifies the name available for dynamic linking and the format
of the arguments. ORDINAL is replaced
by the ordinal number corresponding to the function, or
@ for automatic ordinal allocation (Win32 only).
FUNCTYPE should be one of:
pascal16
for a Win16 function returning a 16-bit value
pascal
for a Win16 function returning a 32-bit value
register
for a function using CPU register to pass arguments
interrupt
for a Win16 interrupt handler routine
stdcall
for a normal Win32 function
cdecl
for a Win32 function using the C calling convention
varargs
for a Win32 function taking a variable number of arguments
ARGTYPE should be one of:
word
for a 16 bit word
long
a 32 bit value
ptr
for a linear pointer
str
for a linear pointer to a null-terminated string
s_word
for a 16 bit signed word
segptr
for a segmented pointer
segstr
for a segmented pointer to a null-terminated string
wstr
for a linear pointer to a null-terminated wide
(16-bit Unicode) string
Only ptr, str,
wstr and
long are valid for Win32 functions.
HANDLERNAME is the name of the actual Wine
function that will process the request in 32-bit mode.
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.
IN: str/wstr
OUT: ptr
IN/OUT: str/wstr
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.
The two examples define an entry point for the
CreateWindow and GetFocus
calls respectively. The ordinals used are just examples.
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 varargs and declare it with a
'...' parameter in the C file. See the wsprintf* functions in
user.spec and
user32.spec for an example.
ORDINAL stub EXPORTNAME
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.
ORDINAL extern EXPORTNAME SYMBOLNAME
This field can be present zero or more times.
Each instance defines an entry that simply maps to a Wine symbol
(variable or function); EXPORTNAME will point
to the symbol SYMBOLNAME that must be defined
in C code. This type only works with Win32.
ORDINAL forward EXPORTNAME SYMBOLNAME
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). EXPORTNAME
will forward to the entry point SYMBOLNAME
that must be of the form DLL.Function. This
type only works with Win32.