On Wed, 5 May 2004 13:59:14 -0400, Dan Sugalski wrote:

>>>  Another todo list task for the interested. A perl & linker thing.
>>>
>>>  Right now, through the wonders of the Unix default linking
>>>  conventions, every function in parrot gets exported whether we want
>>>  them to be or not, and generally we don't. That needs fixing.

I've spent most of today wading through Windows' linking stuff.  Here's
what I have learned:

- you always specifiy a .lib file.  It's either the real thing (static), or
a stub for the DLL (dynamic).
- For static linking, a function should be declared "as usual."
- For dynamic linking, a function should be declared with
"__declspec(dllexport)" during compilation, and "__declspec(dllimport)"
during use.  The first one tells the linker (through the object file) to
export the symbol, the latter to call the stub function for the DLL.

- For static linking the name is mangled to "_function."
- For dynamic linking the name is mangled to "__imp_function." (Seems to be
the stub code that calls the actual function in the DLL.)

- For the C library, Windows provides two versions (static: libc.lib,
dynamic: msvcrt.lib), and a preprocessor macro _DLL (defined for dynamic
linking).


So, here's what I think that should be done:
- Separate the compiler and linker flags into static and dynamic (probably
separating the common flags, too).
- When compiling the static parrot lib, PARROT_LIB_STATIC and
PARROT_EXPORTS should be defined.
- The static library should be named "libparrot.lib" on Windows.
- When using the static parrot lib, PARROT_LIB_STATIC should be defined.

- When compiling the dynamic parrot lib, PARROT_LIB_DYNAMIC and
PARROT_EXPORTS should be defined.
- The dynamic library should be named "parrot.lib" on Windows (to blend
nicely into the system).
- When using the dynamic parrot lib, PARROT_LIB_DYNAMIC should be defined.

I still think we should use the PARROT_API macro I talked about, and a
simple script to grep for them (anyone interested in it?).  On Windows we
could simply say:
/*
** config/gen/platform/win32/api.h:
*/

#if defined(PARROT_LIB_DYNAMIC)
#if defined(PARROT_EXPORTS)
#define PARROT_API __declspec(dllexport)
#else
#define PARROT_API __declspec(dllimport)
#endif /* defined(PARROT_EXPORTS) */
#elif defined(PARROT_LIB_STATIC)
#define PARROT_API
#else
#error Either PARROT_LIB_STATIC or PARROT_LIB_DYNAMIC must be defined!
#endif /* PARROT_LIB_XXX */

Other platforms might use the generated symbol files.

I've implemented some of the above things, in case anyone is interested.


Some optional things that come into mind:
- Maybe provide a PARROT_DEBUG for debug/non-debug libraries
- Compile everything into
    build/release/static        static release library (libparrot.lib on Windows)
    build/release/dynamic       release DLL (parrot.lib, parrot.dll)
    build/debug/static          static debug library (libparrotd.lib)
    build/debug/dynamic         debug DLL (parrotd.lib, parrotd.dll)


I'd love to hear other opinions on that one,
Ron

Reply via email to