I've been experimenting with dynamic linkage on Windows. As a teaser
to read on, here's how far I've got.
Before
Failed TestStat Wstat Total Fail Failed List of Failed
---
t\dynclass\foo.t 1 256 11 100.00% 1
t\dynclass\gdbmhash.t13 332813 13 100.00% 1-13
t\dynclass\pybuiltin.t6 1536 66 100.00% 1-6
t\dynclass\pyclass.t 6 1536 66 100.00% 1-6
t\dynclass\pycomplex.t1 256 11 100.00% 1
t\dynclass\pyfunc.t 4 1024 44 100.00% 1-4
t\dynclass\pyint.t 25 640025 25 100.00% 1-25
t\op\spawnw.t 2 512 32 66.67% 2-3
3 tests and 66 subtests skipped.
Failed 8/141 test scripts, 94.33% okay. 58/2263 subtests failed, 97.44% okay.
After
Failed Test Stat Wstat Total Fail Failed List of Failed
---
t\op\spawnw.t2 512 32 66.67% 2-3
3 tests and 65 subtests skipped.
Failed 1/139 test scripts, 99.28% okay. 2/2257 subtests failed, 99.91% okay.
Don't worry about spawn at the moment, it broke some week ago, and is
not related to the linkage problem.
There's quite a number of changes involved, here's my proposal of how
to change things. Choosing early on static or dynamic linkage, and
changing the library names, is not strictly necessary, but would
probably make things simpler, and Parrot feel more at home on
Windows, respectively.
- Parrot should be told during Configure to be built static
or dynamic (shared); it should probably be dynamic on most systems
- A static Parrot should not run the dynclasses tests
- The parrot library should be named Cparrot.lib and
Cparrot${MAJOR}${MINOR}.dll on Windows
- The dynamic parrot library Cparrot01.dll should be in the same
directory as Cparrot.exe, or otherwise it must be a)explicity loaded
or b)the directory added to the PATH environment.
- Paths and/or linkage instructions should be updated accordingly, eg
Flib/Parrot/Test.pm
(my $libparrot_root = $PConfig{blib_lib_libparrot_a}) =~
s/\$\(A\)//;
my $libparrot_dynamic = $libparrot_root.$PConfig{share_ext};
my $libparrot;
# use shared library version if available
if( -e $libparrot_dynamic ) {
$libparrot = '-Lblib/lib -lparrot';
} else {
$libparrot = $libparrot_root.$PConfig{a};
}
- There should be a macro PARROT_API, which hints the compiler how to
link things, on platforms that support it. Eg, on Windows it should
expand to
'__declspec(dllexport)' if a symbol should be exported (dynamic)
'__declspec(dllimport)' if a symbol should be imported (dynamic)
empty string (static)
PARROT_API must be added to each API symbol of the library.
- A similar macro must be present for each library, which means there
must be a different one for dynclasses (PARROT_DYNCLASSES_API), as the
symbols of libparrot must be imported, and the symbols of the
dynclasses exported.
I have some questions, too.
- After I changed the linkage, some dynclasses failed, during access
of CParrot_base_vtables[100]. No surprise, as the array is only
C#define PARROT_MAX_CLASSES 100
long. After I changed it to 1000, the tests passed. Why gets no one
else bitten by this? Somehow my fault? Shouldn't it be dynamically
resized?
- I'm not sure where IMCC belongs. I'd guess it goes into libparrot.
But Fimcc/main.c goes into the parrot executable. Yet, this one
depends on parser symbols (line, yyparse, yyin, yydebug, yylex), which
probably should not be exported by libparrot. Any hints?
Comments are highly appreciated, especially from the Win32 folks.
Leo, if that's okay, I'll wait for your GO before preparing and
submitting any patches.
Frohe Ostern,
Ron