Stupid DynaLoader Tricks
In MacPerl, there's a neat little hack to make certain functions always available. Essentially, bootstrap is called for the MacPerl, OSA, and XL packages explicitly in runperl.c:
Normally, one could just do a conditional bootstrap, but this is complicated by the fact that a bootsrap OSA (we skip XL for Mac OS X) will look for a dynamic library named "OSA.$dl_dlext". But we don't have that. So instead, we first bootstrap MacPerl, and then find the file that was used for MacPerl -- don't load the file, it's already been loaded -- and use that to install our OSA::boostrap, before finally calling it.
It's possible I am overcomplicating things or doing something wrong, but hey, it works ...
av_push(PL_preambleav, newSVpv("BEGIN { bootstrap MacPerl; bootstrap OSA; bootstrap XL; }",0));All three packages are statically linked, and are a "part of" the MacPerl package (that is, they get compiled into the same static library file). When porting this to Mac OS X, it causes problems: in MacPerl.pm, no bootstrap is done because it is not necessary, having already been done.
Normally, one could just do a conditional bootstrap, but this is complicated by the fact that a bootsrap OSA (we skip XL for Mac OS X) will look for a dynamic library named "OSA.$dl_dlext". But we don't have that. So instead, we first bootstrap MacPerl, and then find the file that was used for MacPerl -- don't load the file, it's already been loaded -- and use that to install our OSA::boostrap, before finally calling it.
It's possible I am overcomplicating things or doing something wrong, but hey, it works
# bootstrap MacPerl is already implicitly done by your MacPerl binary
unless ($^O eq 'MacOS') {
# use Config;
# my $dl_dlext = $Config::Config{'dlext'};
my $dl_dlext = 'bundle';
require DynaLoader;
push @ISA, 'DynaLoader';
bootstrap MacPerl;
# because OSA is in MacPerl.bundle, not OSA.bundle
my $file = "auto/MacPerl/MacPerl.$dl_dlext";
foreach (@INC) {
$dir = "$_/auto/MacPerl";
next unless -d $dir;
my $try = "$dir/MacPerl.$dl_dlext";
last if $file = -f $try && $try;
}
for my $mod (qw(OSA)) {
my($xs, $symref);
for (@DynaLoader::dl_librefs) {
last if $symref = DynaLoader::dl_find_symbol($_, "boot_$mod");
}
next unless $symref;
$xs = DynaLoader::dl_install_xsub("${mod}::bootstrap", $symref, $file);
&$xs($mod);
}
}
Now Playing: Ribbon In The Sky - Stevie Wonder (Original Musiquarium I, Vol I)
Leave a comment