MPS issue job001096

TitleThe MPS is not a Windows DLL
Assigned userDavid Jones
DescriptionConfigura would like a DLL. See [1]

See <> [6] for requirements

See mps/branch/2004-12-15/dll for implementation.
AnalysisSee [2]

State of Play

2005-01-28 DRJ

Proceeding as outlined in [5].

2004-12-16 DRJ

Added mps.dll target to commpost.nmk. Realised that this may be
wrong name as that means that the import library for the mps.dll
dll will be mps.lib which conflicts with (is the same as) the
name of the static mps library. This is why we see things like
SPONGDLL.DLL. [2005-02-08 DRJ: This is now mpsdy.dll]

mps.dll does not build properly. Specifically:

D:\home\drj\\project\mps\branch\2004-12-15\dll\code>nmake /f
w3i3mv.nmk VARIETY=we mps.dll

Microsoft (R) Program Maintenance Utility Version 6.00.8168.0
Copyright (C) Microsoft Corp 1988-1998. All rights reserved.

mpm.obj : error LNK2001: unresolved external symbol _mps_lib_get_EOF
mpm.obj : error LNK2001: unresolved external symbol _mps_lib_fputs
mpm.obj : error LNK2001: unresolved external symbol _mps_lib_fputc
global.obj : error LNK2001: unresolved external symbol _mps_clock
global.obj : error LNK2001: unresolved external symbol _mps_clocks_per_sec
dbgpool.obj : error LNK2001: unresolved external symbol _mps_lib_assert_fail
w3i3mv\we\mps.dll : fatal error LNK1120: 6 unresolved externals
NMAKE : fatal error U1077: 'link' : return code '0x460'
NMAKE : fatal error U1077: 'C:\PROGRA~1\MICROS~3\VC98\BIN\NMAKE.EXE' : return code '0x2'

Looks like we need to tell the linker that these symbols
will be provided by someone else.

You see phrases like this in the MSDN doc: "However, when a DLL
exports to a program that it also imports from, whether directly
or indirectly, you must use LIB to create one of the import
libraries. When LIB creates an import library, it also creates
an export file. You must use the export file when linking one of
the DLLs."

We are in that situation. mps.dll exports symbols (to the
client program) and also imports symbols, namely the plinth
functions. So I need an export file. So I need to use LIB.

2004-12-15 DRJ

According to [2] we need to use /LD when compiling .c to .obj
and /link /dll when linking.

It looks like we will need to ship a .DLL and a .LIB (the import
library against which client programs will link).

Zlib have a good DLL war story, See [4].

Configura use (when compiling and linking the DLL objects):
/W3 /WX /Gf /Gy /Gs /G6 /Zi /ML /LD

Which, according to,
is decoded as follows:

W3 warning level 3
WX warnings as errors
Gf pool strings (read-write), note, GF is read-only pooled. Cool.
Gy function level linking
Gs stack probe control (use without a decimal number undocumented)
G6 optimised for Pentium Pro, II, III, P4.
Zi produce a PDB for debug info
ML instruct linker to link to LIBC.lib
LD create a DLL

/LD and /ML being the crucial options.

On Exporting Symbols

When the DLL is built the exported symbols need to be
identified. There are 3 ways to do this (from MSDN):

1) The __declspec(dllexport) keyword in the source code

2) An EXPORTS statement in a .def file

3) An /EXPORT specification in a LINK command

Method 1) involves modifying the source code which is
distasteful. 2) seems like the way to go.

We need to create a .DEF file which has an EXPORTS statement.
Like this:

.def file:


The .def files is specifies to the linker using the /DEF option.

and so on.
Generating this list seems a bit tedious. /Zg might be useful
or not, it seems it only generates prototypes for defined

Maybe we can generate the list on a suitable GNU enabled unix
platform. After all the list of exported symbols (from mps.h)
isn't going to change (much?) between different platforms.

Investigating gcc


ouptut of -fdump-translation-unit looks parsable.


 awk '
   $2=="function_decl" && $7=="srcp:" && $8 ~ /^mps\.h:/ {print $4
   $2=="identifier_node"{print $1,$4 >"name"}
 ' mps.h.tu
 join fun name >join

Warning: gcc mps.h produces an _evil_ mps.h.gch file which will
silently corrupt future compilations. Work out how to suppress
that. Need to do this for other header files too (pool class
header files).


On Object Files

If we really do need different options when compiling .c to
.obj (/LD) then we need a different platform (or possibly
variety). It's like another axis in the platform space, perhaps
a bit like the different ABI options that some UNIX platforms
(EG IRIX 6) have.

I have a vague memory that we used to give object files to
DylanWorks so that they could build their own DLL, I don't think
that we treated the object files in any special way (and there's
no evidence that I've found in the build system that we treated
them either).

RHSK 2005-10-12
Design (from [6]):

.des.functions: Code can call MPS functions directly.

.des.functions.linker: All we need to do is export MPS functions
from a DLL, and the OS will link all calling code for us.

.des.functions.mps-dll: We choose to make a separate MPS DLL,
which exports all MPS functions.

.des.functions.mps-dll.plinth: In order to keep this separate MPS
DLL client-agnostic, it requires the client to manually register
all mpslib.h callbacks. See <manual/supplement/dll-notes/>.

.note.mps-only.nonreq: Now that the MPS is a separate DLL, it
could support Configura code that wants the MPS but not anything
else from CMSupport.dll. But this is not a requirement (we just
happened to get it 'for free').

.des.macros: Code needs to be able to use MPS facilities that are
currently implemented as C macros, such as mps_reserve().

.des.macros.include: Code that calls MPS should #include mps.h.
(Where client code is shielded from knowledge of MPS details by, for
example, a collection class, the class should of course perform this
#include too).
How foundcustomer
Evidence[1] Configura say they would like a DLL:
[2] More useful discussion and some command line options:
[3] MSDN Linker doc, EXPORT statements in .def files. Note that
this link will probably not work by the time you use it because
MSDN gets reorganised a lot.
[4] Zlib DLL war story.
[5] drj's suggested design of a callback interface:
[6] rhsk's wrap-up of requirements and design:
Observed in1.104.0
Created byDavid Jones
Created on2004-12-15 11:52:01
Last modified byGareth Rees
Last modified on2013-03-19 11:22:18
History2004-12-15 DRJ Created.
2005-02-08 DRJ Updated.
2005-10-12 RHSK Closed. Noted design here. Mailed wrap-up [6] to Configura.


Change Effect Date User Description
179602 closed 2012-09-21 09:46:50 Richard Brooksby Adding baseline Visual Studio project for building the MPS.
Only the amcss test is included for W3I3MV so far.
155369 closed 2005-10-12 11:20:38 Richard Kistruck MPS: comments only: add licence text; add: works with gcc 3.3, not 4.0
155267 open 2005-10-06 12:23:07 Richard Kistruck build-notes: make text+k; add Windows section; now /Gs /GZ (for DLL)
155265 open 2005-10-06 12:15:10 Richard Kistruck dll-notes: make it a proper doc: add intro etc; corrections and clarity.
155264 open 2005-10-06 11:42:11 Richard Kistruck MPS DLL notes
155259 open 2005-10-05 18:37:41 Richard Kistruck add copyright and licence notices
144811 open 2005-02-16 11:36:22 David Jones MPS: Windows linker problem.
144809 open 2005-02-16 11:20:41 David Jones MPS: Bug in linker line
144807 open 2005-02-16 11:10:42 David Jones MPS: removing windows compiler warning
144799 open 2005-02-16 10:19:55 David Jones MPS: removing mpm.h from mpslibcb.c
143481 open 2005-02-08 12:45:47 David Jones MPS: mpsplcb.lib target
143475 open 2005-02-08 12:34:31 David Jones MPS: Updated generated file w3gen.def
143474 open 2005-02-08 12:32:49 David Jones MPS: Documented procedure for rebuilding w3gen.def
143471 open 2005-02-08 12:22:54 David Jones MPS: new files in windows makefiles
143314 open 2005-02-07 14:50:11 David Jones MPS: mpslib via client callbacks. mpslib.c
134030 open 2004-12-16 17:01:58 David Jones mps: more dll tweaking. Still broken.
134028 open 2004-12-16 16:58:49 David Jones MPS: Adjusting list of exported functions.
134017 open 2004-12-16 16:03:00 David Jones MPS: Adding mps.dll target. Does not work (yet).
133985 open 2004-12-16 12:17:13 David Jones MPS: expgen script to generate a list of exported symbols. And
its output.