                              Wine Documentation                               
Prev                                                                       Next
-------------------------------------------------------------------------------

Chapter 3. The Winelib development toolkit

3.1. Winemaker

3.1.1. Support for Visual C++ projects

Unfortunately Winemaker does not support the Visual C++ project files, ...yet.
Supporting Visual C++ project files (the .dsp and some .mak 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.

When the time comes Winemaker, and its associated build system, will need some
extensions to support:

  * 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.
   
  * 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.
   
3.1.2. Winemaker's source analysis

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.

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.

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
Makefile.in file in this directory. Note that Winemaker also knows about the
commonly used Release and Debug 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.

If it does not find any executable or dll winemaker will look for files with a
.mak 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 --cuiexe and --dll
options.

Finally winemaker will check to see if there is a file called makefile. 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 src winemaker will try
to make use of the name of the parent directory instead.

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.

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 The
interactive mode). This will allow you to specify the target list (and more)
for each directory.

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 EXTRA_xxx variables in the Makefile.in, 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.

Finally winemaker also looks for more exotic files like .h headers, .inl 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.

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.

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 --nobackup).

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 --nolower-include).

Finally winemaker generates the Makefile.in files and other support files
(wrapper files, spec files, configure.in, Make.rules.in). From the above
description you can guess at the items that winemaker may get wrong in this
phase: macro definitions, include path, library path, list of libraries to
import. You can deal with these issues by using winemaker's -D, -I, -L and -i
options if they are homogeneous enough between all your targets. Otherwise you
may want to use winemaker's interactive mode so that you can specify different
settings for each project / target.

For instance, one of the problems you are likely to encounter is that of the
STRICT macro. Some programs will not compile if STRICT 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 -DSTRICT on
winemaker's command line or in the Makefile.in file(s).

Finally the most likely reasons for missing or duplicate symbols are:

  * The target is not being linked with the right set of libraries. You can
    avoid this by using winemaker's -L and -i options or adding these libraries
    to the Makefile.in file.
   
  * 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 Makefile.in file manually.
   
  * 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 ../hello/world.o then you will get missing symbols. Again the only
    solution is to manually edit the Makefile.in file.
   
3.1.3. The interactive mode

what is it, when to use it, how to use it

3.1.4. The Makefile.in files

The Makefile.in is your makefile. More precisely it is the template from which
the actual makefile will be generated by the configure script. It also relies
on the Make.rules 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.

So this is the file to modify if you want to customize things. Here's a
detailed description of its content:

### Generic autoconf variables

TOPSRCDIR             = @top_srcdir@
TOPOBJDIR             = .
SRCDIR                = @srcdir@
VPATH                 = @srcdir@
        

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 Makefile.in files yet).

SUBDIRS               =
DLLS                  =
EXES                  = hello
        

This is where the targets for this directory are listed. The names are pretty
self-explanatory. SUBDIRS is usually only present in the top-level makefile.
For libraries you should put the full Unix name, e.g. libfoo.so.

### Global settings

DEFINES               = -DSTRICT
INCLUDE_PATH          =
LIBRARY_PATH          =
LIBRARIES             =
        

This section contains the global compilation settings: they apply to all the
targets in this makefile. The 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
'import' statement of the spec files. The exception is when you have not
explicitly exported the functions of a Winelib library. One library you are
likely to find here is mfc (note, the '-l' is omitted).

The other variable names should be self-explanatory. You can also use three
additional variables that are usually not present in the file: CEXTRA, CXXEXTRA
and WRCEXTRA 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 IMPORTS. So you should put
-DSTRICT in DEFINES but winmm in IMPORTS.

Then come one section per target, each describing the various components that
target is made of.

### hello sources and settings

hello_C_SRCS          = hello.c
hello_CXX_SRCS        =
hello_RC_SRCS         =
hello_SPEC_SRCS       = hello.spec
        

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.

The above variables list the sources that are used togenerate the target. Note
that there should only be one resource file in RC_SRCS, and that SPEC_SRCS will
always contain a single spec file.

hello_LIBRARY_PATH    =
hello_LIBRARIES       =
hello_DEPENDS         =
        

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.

DEPENDS, when present, specifies a list of other targets that this target
depends on. Winemaker will automatically fill this field, and the LIBRARIES
field, when an executable and a library are built in the same directory.

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 LIBRARIES field.

hello_OBJS            = $(hello_C_SRCS:.c=.o) \
                        $(hello_CXX_SRCS:.cpp=.o) \
                        $(EXTRA_OBJS)
        

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.

### Global source lists

C_SRCS                = $(hello_C_SRCS)
CXX_SRCS              = $(hello_CXX_SRCS)
RC_SRCS               = $(hello_RC_SRCS)
SPEC_SRCS             = $(hello_SPEC_SRCS)
        

This section builds 'summary' lists of source files. These lists are used by
the Make.rules file.

### 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
        

The above first defines the default target for this makefile. Here it consists
in trying to build all the targets. Then it includes the Make.rules file which
contains the build logic, and provides a few more standard targets to install /
uninstall the targets.

### 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
        

Then come additional directives to link the executables and libraries. These
are pretty much standard and you should not need to modify them.

3.1.5. The Make.rules.in file

What's in the Make.rules.in...

3.1.6. The configure.in file

What's in the configure.in...

-------------------------------------------------------------------------------
Prev                                 Home                                  Next
Others                                Up              Compiling resource files:
                                                                            WRC
