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