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