Hi,
On Windows, for a Perl built with mingw gcc where the gcc version is
greater than 4.4, the perl5xx.dll may be linked to libstdc++ in addition
to libgcc. It depends on how the gcc toolchain was built and how Perl
was built. Dynamic linking to libstdc++ is not an uncommon case. I
expect the next releases of Strawberry Perl may use a dynamically linked
libstdc++.
The attached patch copies the methods used to load libgcc with the
addition of a check to see if perl5xx.dll is actually linked to libstdc++.
Regards
Mark
Index: myldr/boot.c
===================================================================
--- myldr/boot.c (revision 1354)
+++ myldr/boot.c (working copy)
@@ -30,6 +30,9 @@
#ifdef LOAD_MY_LIBGCC
#include "my_libgcc.c"
#endif
+#ifdef LOAD_MY_LIBSTDCPP
+#include "my_libstdcpp.c"
+#endif
/* Note: these two defines must be negative so as not to collide with
* any real file descriptor */
@@ -190,6 +193,18 @@
#endif
+#ifdef LOAD_MY_LIBSTDCPP
+ /* extract libgcc DLL into stmpdir */
+ i = my_mkfile( argv[0], stmpdir, name_load_my_libstdcpp,
size_load_my_libstdcpp, &my_file );
+ if ( i != MKFILE_ALREADY_EXISTS ) {
+ if ( i == MKFILE_ERROR ) DIE;
+ if ( write_chunks(i, chunks_load_my_libstdcpp) == -1 ) DIE;
+ if ( close(i) == -1 ) DIE;
+ chmod(my_file, 0755);
+ }
+
+#endif
+
/* save original argv[] into environment variables PAR_ARGV_# */
sprintf(buf, "%i", argc);
par_setenv("PAR_ARGC", buf);
Index: myldr/Makefile.PL
===================================================================
--- myldr/Makefile.PL (revision 1354)
+++ myldr/Makefile.PL (working copy)
@@ -209,12 +214,16 @@
# may depend on some libgcc*.dll (Strawberry Perl 5.12 is an example).
# This libgcc*.dll has to be included into with any packed executbale
# in the same way as libperl*.dll itself, otherwise a packed executable
-# won't run when libgcc*.dll isn't installed.
+# won't run when libgcc*.dll isn't installed. Perl may also depend
+# on libstc++ but we can only know this by checking perl5xx.dll
+
my $libgcc;
+my $libstdcpp;
+
if ($dynperl and $^O eq 'MSWin32'
and defined $Config{gccversion} # gcc version 4.x or above was used
and $Config{gccversion} =~ m{\A(\d+)}ms && $1 >= 4) {
- # look for a libgcc_*.dll
+ # look for a libgcc_*.dll
# - in the same directory as the perl executable itself
# - in the same directory as gcc (only useful if it's an absolute path)
# - in PATH
@@ -222,22 +231,46 @@
File::Basename::dirname($^X),
File::Basename::dirname($cc),
File::Spec->path;
+
+ # check if we need libstdc. Just because it is present in gcc tools does
+ # not mean Perl is linked to it
+
+ my @dumplines = qx(objdump -x $libperl);
+
+ for ( @dumplines ) {
+ if( /^\s+DLL Name: (libstdc++)(.+\.dll)\s+$/ ) {
+ my $libstdcname = $1 . $2;
+ # look for a libgcc_*.dll
+ # - in the same directory as the perl executable itself
+ # - in the same directory as gcc (only useful if it's
an absolute path)
+ # - in PATH
+
+ ($libstdcpp) = map { glob(File::Spec->catfile($_,
$libstdcname)) }
+
File::Basename::dirname($^X),
+
File::Basename::dirname($cc),
+ File::Spec->path;
+ last;
+ }
+ }
}
$libgcc ||= "";
+$libstdcpp ||= "";
my $my_stuff = "my_par.c my_libperl.c";
if ($libgcc) {
$cflags .= " -DLOAD_MY_LIBGCC";
$my_stuff .= " my_libgcc.c";
}
+if ($libstdcpp) {
+ $cflags .= " -DLOAD_MY_LIBSTDCPP";
+ $my_stuff .= " my_libstdcpp.c";
+}
-
my @strippedparl = qw( Static.pm );
push @strippedparl, qw( Dynamic.pm ) if $dynperl;
my @parl_exes = $parl_exe;
push @parl_exes, $parldyn_exe if $dynperl;
-
# Determine whether we can find a config.h. If yes, include it in
# usernamefrompwuid.h. If not, set I_PWD to undefined in that header.
# -- Steffen
@@ -251,7 +284,6 @@
}
close PWOUT;
-
WriteMakefile(
NAME => "par$exe",
SKIP => [qw(static static_lib dynamic dynamic_lib test)],
@@ -346,6 +378,9 @@
my_libgcc.c:
\$(PERLRUN) $f2c -c $chunk_size $libgcc \$@ load_my_libgcc
+
+my_libstdcpp.c:
+ \$(PERLRUN) $f2c -c $chunk_size $libstdcpp \$@ load_my_libstdcpp
Dynamic.pm: Dynamic.in $par_exe
\$(PERLRUN) encode_append.pl Dynamic.in $par_exe Dynamic.pm