Chip Salzenberg wrote:
> According to Ron Blaschke:

>> - The parrot library should be named C<parrot.lib> and
>> C<parrot${MAJOR}${MINOR}.dll> on Windows

> OK, but will Windows allow delimiter(s) on the DLL name?  Without
> them, there's an ambiguity (is "parrot110.dll" 1.10 or 11.0?).

> Also, Parrot release numbers currently have three parts.  Closer to
> release you could change the Win32 DLL name to be based only on the
> top two, since changes in the third number will not involve any issues
> of binary compatibility[*], but at least during early development it
> would be a Good Idea to include all three.

The idea was mainly stolen from other projects, guess it's some sort
of convention on Windows.  Eg, Microsoft Visual C++ 7.1 distributes
its C Runtime as F<msvcrt71.dll>.  The ICU data library 3.0 is named
F<icudt30.dll>, Perl 5.8.6 called F<perl58.dll>. Adding all three
parts, with dots, will work nicely, too, I guess.


>> - The dynamic parrot library C<parrot01.dll> should be in the same
>> directory as C<parrot.exe>, or otherwise it must be a)explicity loaded
>> or b)the directory added to the PATH environment.

> OK.  I haven't done much Windows software work since Win98; what's the
> standard way of making a command (e.g. "parrot") available from [a]
> the Win32 command line and [b] the Win32 spawn interface?  The old
> hack of adding PATH statements to autoexec.bat doesn't work any more.
> Or so I'm told.  :-)

Not sure I get your question right, but libraries are mostly located
in the same directory as the executable, which is called "private DLL"
or "side-by-side installation."  The reason for this is that Windows
favours this location, it is the first place Windows looks for the
library (even before the system directory).

>> - Paths and/or linkage instructions should be updated accordingly, eg
>> F<lib/Parrot/Test.pm>
[snip]
>>             # use shared library version if available
>>             if( -e $libparrot_dynamic ) {
>>                 $libparrot = '-Lblib/lib -lparrot';
>>             } else {
>>                 $libparrot = $libparrot_root.$PConfig{a};
>>             }

> I think I see where you're going with this, but why test for existence
> of the dll??  If a given Parrot instance included a libparrot.dll at
> build time, then assume it's there; otherwise, assume it's not.  The
> only way these assumptions could be wrong is (1) we have a bug or (2)
> the filesystem being modified in unsupported ways.  I'm not interested
> in papering over either of those cases.

Sorry, I should have been more explicit on this.  Above code is taken
from the current Parrot::Test, and I think we both agree that it's not
the best way to do things.  This, and the dynclasses tests, were the
reason I proposed the dynamic/static decision on Configure time.  I've
stumbled over above code as I needed to get linkage of F<t/src/*.t>
tests right, for which C<$libparrot = 'blib/lib/libparrot.lib'> was
necessary.

>> - 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.

> By "added" you mean in the .h, or the .c, or both?  And if both, will
> the same macro with the same definition work for both places?

Sorry again.  Guess I've been pondering these issues too long, and
think way too much in Win32 terms.

A "common" Windows idiom is to add the following to the header.
#if defined(PARROT_EXPORTS)
#define PARROT_API __declspec(dllexport)
#else
#define PARROT_API __declspec(dllimport)
#endif

Symbols that should be exported get tagged on declaration.
PARROT_API void f();
PARROT_API int i;

Then, C<PARROT_EXPORTS> is defined during compilation of the library,
which yields C<__declspec(dllexport)>, and not defined during usage of
the library, yielding C<__declspec(dllimport)>.

As there are several headers for parrot, I'd guess we'd have a
F<include/parrot/api.h> which defines above, and used as necessary.

There would be another way to get functions exported, namely by
providing an C<EXPORTS> section in a separate module definition file,
which would contain a list of all functions to be exported.  The
module definition file would be another argument to the linker.  This
would not work with the current implementation, as data is accessed as
well, eg C<Parrot_base_vtables>, where C<__declspec> is the only way
to get hold of.


>> - 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.

> Looking at this from the point of view of a third-party PMC author,
> might "PARROT_EXPORT" be closer to the relevant idea?  From the
> interface design perspective, does it matter whether I'm writing a
> "DYNCLASS" or something else?

It's a matter of what is inside or outside of a library, I guess.  For
a dynclass, parrot is on the outside, that's why I thought of a
different macro.  That is, when compiling a dynclass, parrot's symbols
must be imported, and that of the dynclass exported. Am I making any
sense, or am I getting all confused here?

>> - After I changed the linkage, some dynclasses failed, during access
>> of C<Parrot_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?
> Absolutely.  I don't want to speak for Leo, but: "Patches welcome."

Hope someone else, who's deeper in the core, can tackle this one.


>> - I'm not sure where IMCC belongs.  I'd guess it goes into libparrot.
>> But F<imcc/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?

> On the one hand, IMCC doesn't really help you _run_ code, so I'm not
> inclined to see it part of libparrot.  On the other hand, I haven't
> grokked the entire code base organization, so I could be Greatly
> Missing The Point.

> On the gripping hand, if you'd like to experiment with putting IMCC
> into libparrot, bison's "-p prefix" option seems relevant: "Rename the
> external symbols used in the parser so that they start with prefix
> instead of yy."  Maybe "-p Parrot_imcc_"?

I have left things as-is while getting linkage correctly.  That is,
most of IMCC is currently part of libparrot (only F<main.c> is not).
In the beginning, I thought IMCC is part of the parrot executable, but
reality left me puzzled, so I thought I'll leave the decision to you.
;-)

Ron


Reply via email to