Re: [Module-build-general] Re: redirecting system() to a file, or ways to avoid it
Status: Beta
Brought to you by:
kwilliams
From: Ken W. <ke...@ma...> - 2002-11-27 03:57:11
|
On Wednesday, November 27, 2002, at 11:33 AM, Michael G Schwern wrote: > SF.net hates me, so I'll just post straight to you. > > > On Wed, Nov 27, 2002 at 12:13:23AM +1100, Ken Williams wrote: >> In Module::Build, very little is done by the external system, but some >> things still are. One little thorn in its side is ExtUtils::xsubpp - >> which, despite living in @INC and having two colons in its name, is a >> script, not a module. In order to parse .xs files, this >> script needs to >> be called and its output redirected to a file. > > I hereby disavow all responsiblity for xsubpp, Amen. > > You might want to look at the ExtUtils::MM_Unix->tool_xsubpp > method to see > how MakeMaker locates xsubpp and the typemap file. Will do. I'm already finding that stuff, but maybe I need to be more complicated. > > >> That's not usually a very hard task, but I've decided to use the >> multi-arg form of system() whenever possible, so that I don't have to >> handle argument quoting issues on all the platforms of the world. But >> the multi-arg form of system() doesn't let me do output >> redirects (which >> probably weren't portable across platforms anyway with single-arg >> system()). > > In general `someprogram some args > some_file` is plenty > portable, even on > VMS. And that should be all you need. > `$^X path/to/xsubpp -some -args foo.xs > some_tmp_file` Hm, I guess I'll do that if none of the other easy solutions work. As I mentioned, for every system() call or fork() I can get rid of, Texas Instruments will donate $50,000 to the Make-A-Wish Foundation. Who am I to deny all those wishes? > What isn't portable is any piping or redirecting STDERR. > > If you look at the new code in ExtUtils::MM_Unix->find_perl() > you'll see we > supress STDERR by temporarily closing it. > http://makemaker.org/src/ExtUtils-MakeMaker- > snap/lib/ExtUtils/MM_Unix.pm > > # To avoid using the unportable 2>&1 to supress STDERR, > # we close it before running the command. > close STDERR if $stderr_duped; > $val = `"$abs" -e "require $ver; print qq{VER_OK\n}"`; > open STDERR, '>&STDERR_COPY' if $stderr_duped; > > Closing STDERR outright seems portable. Tying STDERR and/or > STDOUT to a > file may be unreliable in certain versions of Perl. Okay, thanks for the tip. In this case I'll probably just want STDERR to go to the terminal, but for future cases I may need to suppress it. > >> So I'm trying to think of the best alternative. Choices include: >> >> 1) Wrap all of the xsubpp code into a subroutine, set @ARGV, open >> STDOUT to a file, and call the subroutine. >> >> 2) Same as 1), but just do() the xsubpp file instead of making it a >> subroutine. > > #1 would work. Something like: > > sub xsubpp { > my($self, $file) = @_; > local @ARGV = ($file); > > open(SAVE_STDOUT, '>&STDOUT'); > tie *STDOUT, to memory; > > do ExtUtils::xsubpp; > > open(STDOUT, '>&SAVE_STDOUT'); > > return $whatever_you_captured; > } Unfortunately, ExtUtils::xsubpp does an exit(), so I'd also have to override *CORE::GLOBAL::exit. And I'm getting some errors like "ValidProtoString() called too early to check prototype", which I think means that this code doesn't like being called embeddedly. Or maybe I can just prototype those subroutines in advance. >> 4) Go back in time and re-implement ExtUtils::xsubpp as a bare-bones >> wrapper around an ExtUtils::ParseXS module. Module::Build can >> just call >> functions in ExtUtils::ParseXS, then. >> >> 5) Don't go back in time, but create an ExtUtils::ParseXS module >> nonetheless, which *future* versions of xsubpp could use as guts. >> Create a Module::Build dependency on ExtUtils::ParseXS and don't call >> xsubpp. > > I'd like that. It's looking more likely. >> 6) Borg all the xsubpp code into Module::Build where I can >> control it. > > The stuff in xsubpp is supposed to be very version specific, > that's why we > don't ship it with the CPAN version of ExtUtils::MakeMaker. Oof, so an ExtUtils::ParseXS module would have to take version info into account? Sounds hairy. Maybe a 'diff' of it from perl version to perl version would enlighten. Is it also *platform* specific? >> Even though 1) and 2) are pretty ugly, I'm leaning toward doing one of >> them, if they'd work. 3) looks non-fun, and the further away >> I can get >> Module::Build and system() from each other, the better. 4) >> and 5) would >> be a lot of work, but probably the best from an architectural point of >> view. 4) would be really cool, actually. Note that 5) would >> create the >> first non-5.6-core dependency in Module::Build, though. And 6) seems >> like a bad idea. >> >> There's also: >> >> 7) Just write it as a single-arg, ad hoc system() call, don't worry >> about cross-platform issues, make those MacOS bastards live without XS >> compilation a little while longer, and only fix the quoting >> when someone >> tells me it's broken on VMS and Amiga, and Win95. > > I think it'll work on MacPerl since any XS compiling requires > the MPW shell. > MacPerl might also just emulate `perl ...`. hmmm... -Ken |