Re: [Module-build-general] [PATCH] Compiling under Windows
Status: Beta
Brought to you by:
kwilliams
|
From: Randy W. S. <Ra...@Th...> - 2003-02-26 00:53:39
|
On 2/24/2003 12:56 PM, Ken Williams wrote:
> That can wait until the future. To do this cleanly, I think we could
> create a module like ExtUtils::C with classes like ExtUtils::C::Compiler
> and ExtUtils::C::Linker that Module::Build could just use
> transparently. Its purpose would be to compile and link things that
> will be linked in with Perl modules (not a general tool for arbitrary C
> code), using the same interface regardless of platform.
>
> We could use that module in other situations too, like in the testing
> code for ExtUtils::ParseXS.
>
> Probably the code you've written for Win32 and the code I wrote for Unix
> would be a good start toward such a module. But given that the module
> doesn't exist yet, we'll just have to wait. =)
I've been thinking very seriously about writing those modules. My
problem is the more I think about it the more ambitious the design
becomes. I'm more inclined at the moment to design them as a framework
not limited to 'C' and 'XS', so that Inline::* modules could make use of
the framework if desired. Instead of ExtUtils::C::Linker, there would be
something like:
my $cc = new ExtUtils::Compiler(
LANG => 'C',
FLAGS => ...
);
$cc->compile( source => 'source.c', output => 'source.o' );
In other words, it would operate like 'gcc' does, where it is a
front-end driver for any number of different compilers.
> Also, I think a "uses-a" or "has-a" relationship to the compiler/linker
> would make more sense than the "is-a" relationship that's now in the
> M::B::P::Windows.pm code, but I understand that this was probably an
> easier way to get things written.
I agree, in fact the first implementation actually used an aggregate
relationship instead of inheritance. In fact there is still a relic of
that design in there. In the constructor, you see:
my $cc_driver = "Module::Build::Platform::Windows::$cf->{ccname}";
unshift @ISA, $cc_driver;
the next line used the be something like
$self->{config}{cc_driver} = eval "new $cc_driver";
The problem was that it would have taken more code to implement mostly
duplicating code already in M::B or storing a backref to the caller
(which I generally prefer to avoid), and that really didn't seem to make
sense within the context of M::B.
>> Outstanding issues:
>>
>> The 'runthrough.t' test sometimes fails in random places at random
>> times. This is true with or without the modifications I've made.
>> Sometimes 2 tests fail, sometimes 5, sometimes ??, most of the time
>> none--It's completly unpredictable. It happens after ./build
>> (real)clean as often as it happens after back to back runs of ./build
>> test. I have not yet had a chance to look into it, but I'm pretty
>> certain of the cause. Windows seems to be extremely sensitive about
>> file operations. Sometimes a file gets locked (not always the same one
>> in this case), and it can no longer be accessed. This usually means
>> that a file handle was not explicitly closed or a tied file was not
>> untied, etc.
>
>
> Yes, there were a couple of places I had to deal with this problem for
> the Win32 folks. Are you using the latest CVS version of M::B, or the
> CPAN version? The CVS version fixed a few things, but it's likely there
> are more instances of this problem lurking. Is there any way to get an
> error message to tell you what file is in contention?
In my notes, I put down the names of two of the files: 'Sample.pm' &
'MANIFEST'. There may be others; I admit that I mostly ignored the
errors at the time because I was focusing on the compiling/linking tests
and I didn't want to get sidetracked. I'll take a closer look at this.
>> Another place I ran into problems with locked files is with the
>> 'system()' call. My first stab at getting M::B to work was basically a
>> copy, paste, and edit of the 'compile_c()' and 'link_c()' routines in
>> Base.pm, with branches all over the place to handle differences in
>> compiler syntax. When passing a LIST to system(), It would compile,
>> but the next call to system() to invoke the linker would fail with an
>> 'access denied' error. If I joined the list into a single string it
>> would work (don't ask how long it took me to track that down to the
>> system() call).
>
>
> Ack - I'm really trying to avoid system(STRING) calls, because I really
> don't want shell metachars involved anywhere. Differences in shell
> behavior can open up a whole new can of worms I'm trying to avoid.
>
>
>> At some point I decided to revisit the issue to figure out exactly
>> what was happening, unfortunatelly changing back to the LIST form now
>> works as expected--It has never failed with that error again. This was
>> after I restructured the code, so I can only assume... bah, I won't
>> assume anything.....
>
>
> We'll just keep our eye on it, I guess.
This is something else I wanted to revisit. If I'm not mistaken this may
actually be a Perl bug that was in 5.6.1, but has since been fixed. At
least I think I remember some problem being fixed in the system() call.
>> Most of the time it is invoked with just the name of the module being
>> built, but sometimes it's neccessary to pass in lists of
>> functions/variables. I thought it would be best to leave it to you as
>> to how the user will pass the information through. As it is, it
>> should work for most modules, and a small change to 'sub prelink()'
>> telling it where to get the user supplied options will allow it to
>> work those modules that need that extra functionality.
>>
>
> Okay, so people could override prelink_c() in their own subclasses?
I guess it could be argued either way: subclassing or passing arguments
to M::B's constructor. If subclassing, users need to know that on some
platforms that there is a prelink operation, and that it generally
involves a call ExtUtils::Mksymlists. They will have to reference that
documentation to see what arguments they need to pass. If it were just
parameters passed to M::B's constructor, It would arguably simplify the
interface and documentation, at least from the users perspective.
However, design-wise it shifts responsiblities in the wrong direction;
the reason there is a seperate module for Mksymlists in the first place
is to move that responsiblity out of the package used for building modules.
The way I wrote the prelink_c() routine should allow you easily go in
either direction as you prefer.
Randy.
|