Re: [Module-build-general] [PATCH] Compiling under Windows
Status: Beta
Brought to you by:
kwilliams
From: Randy W. S. <RandyS@ThePierianSpring.org> - 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. |