How to Build the WWW Libraries for Windows

# Building on Windows

When building the W3C Reference Library on a Windows platform (Windows 3.1, 95, or NT), you can decide on a set of different options to be enabled or disabled. This document describes the set of DLLs and how they can be built. C compilers on Windows platforms often have a notion of projects that define what files to include in the compilation and where to put the output. This document does not describe the process of creating projects as it depends on the compiler that you are using but refers you to your C compiler manuals.

1. Interleaved vs Asynchronous Sockets
2. Console vs Windows Application
3. Static vs Dynamic Library

## Interleaved vs Asynchronous Sockets

Non-blocking network access can either be done using multiplexed I/O or asynchronous I/O. Multiplexed I/O is based on an eventloop with a `select()` system call. The `select()` system call is a function that scans a set of BSD like socket descriptors and returns when one or more sockets are ready for either network read or write. Asynchronous I/O is based on signals instead of a `select()` call. Each time a socket is ready for a network operation, for example read, a signal is generated. This signal can then be caught by the application in an signal handler. Using the `select()` call is called reactive whereas using signals is called pro-active.

The W3C Reference Library supports both approaches under Windows, and therefore you must choose which model you prefer. The choice can depend on what type of application you are using and what other libraries you are using.

### Interleaved I/O Using select()

In this mode the Event Manager registers all active sockets and passes them to a `select()` call which then processes the registered sockets. When `select()` returns the Event Manager dispatches the appropriate handlers as the sockets get ready.

What to do: Undefine WWW_WIN_ASYNC as a preprocessor directive when generating the project for the Library. Please make sure that all DLLs are compiled without this flag.

### Asynchronous I/O based using Signals

Here the Event Manager registers all active sockets using `WSAAsyncSelect` which is part of the WinSock API. When `AsyncSelect()` which is the asynchronous equivalent to the `select()` returns, the Event Manager dispatches the results of the `AsyncSelect()`. As the asynchronous select call needs a windows handle, the Library creates a hidden window in the Library initialization function. This window is not to be used explicitly by the application and the Library closes the window when exiting.

What to do: Define WWW_WIN_ASYNC as preprocessor directives when generating the project for the Library.

## Console vs Windows Application

A Windows application can use either a character based command line interface, or a graphic windows interface. Many MS-DOS applications do run as a simple command line tool which doesn't use GUI at all. Under Win32, there is a notion of a console application. This means that all user interaction happens through a standard DOS shell interface, with a FILE pointer like that in Unix. This does not exist under Win16, where a Windows window is required.

The Library supports both the console and the windows interface, and again you must choose what version you prefer. This is often something you have to decide as you are creating the project.

### Windows Application

If you want to make a windows application then this is the mode to use. Eric Prud'hommeaux has provided a Windows application wrapper for the W3C Line Mode Browser which you can use in order to build the browser as a Windows application. This is found in www.c. Three other modules, scroll.c and lib.c provide the window for the application.

What to do: Define _WINDOWS as preprocessor directives when generating the project for the Library.

### Console Application

The console option is available only in Win32 in which case all user interaction happens through the Win32 console window. This model strongly resembles a Unix vt100 terminal interface.

What to do: Define _CONSOLE as preprocessor directives when generating the project for the Library.

## Static vs Dynamic Libraries

Windows has a concept of both static and dynamic libraries, the latter also known as DLLs. It is out of scope here to describe the difference between DLLs and static libraries, but as DLLs is based on a lot more flexible memory model it is almost always the best solution for Windows applications.

The W3C Reference Library support both models in that if can be built as either one big static library or as a set of small DLLs. As mentioned, it is in almost all cases recommended to build DLLs instead of static libraries, and on Win16 it is required because a static library is too big.

### Static Library

The libraries may be build as one large static library. This is how libwww is implemented on Unix platforms. Subsequent references to the various DLLs may all be assumed to refer to the staticly linked libwww. Care has been taken to insure that there are no #define conflicts where one library would want a #define that would interfere with the modules in other libraries. When building a static library, see the following sections on Select Options and Input/Output Options, accumulate all the #defines that are required, and build the whole libwww with those #defines.

What to do: Undefine WWW_WIN_DLL as preprocessor directives when generating the project for the Library. Please note, that it is not recommended to staticly link to the libraries if you are building a Win16 application as it creates segment size problems.

### Dynamic Libraries (DLLs)

The libwww can also be built as a set of DLLs that follows the modular architecture of the Library. This enables the application programmer to choose exactly what functionality should be enabled in the application. The boundaries between these DLLs are based on module interdependency and some assumptions regarding which modules may be replaced by the application. Unlike static linking, dynamic linking requires that all the modules in a DLL be replaced at once. This is because the DLL needs all internal references to be resolved at build time.

What to do: Define WWW_WIN_DLL as preprocessor directives when generating the project for the Library.

### Special Windows DLL

In addition to platform independent modules, there is a small Windows specific DLL which implements the trace message generation. The DLL is called `windll.dll` and contains also the definition of the global trace flag definition.

- windll.c - DLLMain to ALL DLLs.
- wwwdll.c - instances of PTTYPrint and WWW_TraceFlag. This is included in wwwdll so that it can export the variables to the rest of the DLLs.
- wwwdll.def, wwwutils.def, wwwcore.def - def (exports) files for the DLLs of the same names.

What to do: Include the windll.dll as a part of your project and make sure that it is built as the first DLL.

### Exporting Functions from DLLs

The functions exported from a DLL are listed in the EXPORTS section of a .def file. These can be found in the windows directory. These may also be build by the makeDefs.pl perl script, see the description below. You can use the def files as a basis for generating the DLL projects for your compiler.

What to do: Generate the DLLs according to the def files so the exported interface is identical to the set of functions defined in the actual c files included in the DLL.

## Make Files and Projects

Unfortunately, make files are not easily shared among different C compilers on Windows which complicates the distribution. We can not support all of them but we can give some hints which may help you to get going.

### Microsoft Visual C++ 4.0

In the distribution file you can find a complete Microsoft Visual C++ 4.0 Project that builds the W3C Reference Library as a set of DLLs as described in the Library Internals.

### Microsoft Visual C++ 2.0

You can also find a set of Microsoft 2.0 make files in the windows directory of the distribution file. However, as version 2.0 does not support having one single Make file, you must compile the set described by the following list of DLLs in the order they are listed. Please note that these files may be slightly out of date as we do not update them as often as the MSVC 4.0 files.

### Microsoft Visual C++ 1.x

A problem with the MSVC 1.5 compiler is that it doesn't get the dependencies right. It includes all `#include` directives even tough that some of these directives are for Unix only and the include files don't exist on windows. The only way to get around this is to manually edit the project make files generated by MSVC 1.x and take out the dependencies of files that are not intended for the Windows platform. Compiling on a 16 bit platform may also cause some trouble as we don't really support that.

### Borland C Compiler

The Borland C compiler has a different DLL interface where you need to use the reserved word `export` in front of all methods and data objects to be exported from a DLL. This is not currently the case but you can use the makexprt.pl Perl script to change the Library code.

### Other Compilers

You can often use this project as the basis for porting the make file. The DLL description also various from compiler to compiler which can cause that you can't use the DLL def files directly. We try to make as generic solutions as possible but have limited resources to provide projects for multiple compilers.

### makeDefs.pl

makeDefs.pl is a perl 4 script which takes a list of modules and generates a list of exports from them. The module list may be taken from the appropriate header file for the library, e.g. wwwutils.dll uses wwwutils.def which is made from WWWUtils.html. The file list assumes nothing except the module file names with no extensions so each line that says: #include "some file.h" should be translated to some file. As of the time of this writing, there were to ways in which the library header files must be modified to give an accurate list of the modules in a library. In WWWCore.html, HTReq.h should translate to HTReqMan and in WWWUtils.html, HTUtils.h should be removed from the list.