From 97c6568c2744efe2ee45ff6db27d6b6541a4f79d Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Thu, 10 Jul 2025 05:53:17 -0400 Subject: [PATCH] DynaLoader.pm on Win32 bake in Config.pm (PERL_BUILD_EXPAND_CONFIG_VARS) It seems $ENV{PERL_BUILD_EXPAND_CONFIG_VARS} is a long forgotten by POSIX Perl build config option. Apparantly there is a belief that DynaLoader.pm is a dual-life on CPAN, and 30 different versions of stable Perls must share 1 non-arch DynaLoader.pm file on Linux. On Win32, the $Config{vars} that DynaLoader.pm wants, are not, and make no sense to be end user interp build time configurable. There is no file extension for shlibs except .dll on Win32. No .aout vs .so vs .sl drama. $Config{libpth} telling DynaLoader to pass a .o/.obj/.a/.lib file to LoadLibraryEx() is out of scope of this commit. - Decoding $Config::Config{libpth} into actual paths on Win32 is complicated, $Config::Config{libpth} is 1 or more paths, separated by " " space, if the individual path needs to escape a " " space like "C:\Program Files", the path is wrapped in '"' quotes. So use an outside tool Text::ParseWords to parse the string, since /win32/config_sh.PL's sub mungepath {} created the string inside $Config::Config{libpth} specifically for Text::ParseWords to parse it under Text::ParseWords logic - add "length($ldlibpthname) &&" b/c on Win32 $ldlibpthname is empty string - >>>to_string($Config{'dlsrc'}), ")\n;" ;<<< looks like a typo for a ; on a line by itself, fix it - add binmode(OUT) on Win32 for anti-CRLF inside DynaLoader.pm, less bytes to read and parse off the disk at perl proc startup --- ext/DynaLoader/DynaLoader_pm.PL | 38 +++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/ext/DynaLoader/DynaLoader_pm.PL b/ext/DynaLoader/DynaLoader_pm.PL index 5506dd315e40..b5dcdfda4806 100644 --- a/ext/DynaLoader/DynaLoader_pm.PL +++ b/ext/DynaLoader/DynaLoader_pm.PL @@ -67,8 +67,16 @@ sub expand_os_specific { $s; } +# On Win32, there are no values from Config.pm that ever need to be changed +# between WinPerl builds, or major interp versions, or by end users. +# libpth points to CC's .a/.lib not a dir of .dlls. LoadLibraryEx() will not +# accept .obj .o .a and .lib files. +# ldlibpthname = '' path_sep = ';' dlext = 'dll' so = 'dll' dlsrc = 'dl_win32.xs' +my $expand_config_vars = $^O eq 'MSWin32' ? 1 : $ENV{PERL_BUILD_EXPAND_CONFIG_VARS}; + unlink "DynaLoader.pm" if -f "DynaLoader.pm"; open OUT, '>', "DynaLoader.pm" or die $!; +binmode(OUT) if $^O eq 'MSWin32'; print OUT <<'EOT'; # Generated from DynaLoader_pm.PL, this file is unique for every OS @@ -90,7 +98,7 @@ package DynaLoader; # Tim.Bunce@ig.co.uk, August 1994 BEGIN { - our $VERSION = '1.57'; + our $VERSION = '1.58'; } # Note: in almost any other piece of code "our" would have been a better @@ -103,7 +111,7 @@ use vars qw(@dl_library_path @dl_resolve_using @dl_require_symbols EOT -if (!$ENV{PERL_BUILD_EXPAND_CONFIG_VARS}) { +if (!$expand_config_vars) { print OUT "use Config;\n"; } @@ -128,11 +136,11 @@ sub dl_load_flags { 0x00 } EOT -if ($ENV{PERL_BUILD_EXPAND_CONFIG_VARS}) { +if ($expand_config_vars) { print OUT "(\$dl_dlext, \$dl_so, \$dlsrc) = (", to_string($Config{'dlext'}), ",", to_string($Config{'so'}), ",", - to_string($Config{'dlsrc'}), ")\n;" ; + to_string($Config{'dlsrc'}), ");\n" ; } else { print OUT <<'EOT'; @@ -162,15 +170,26 @@ my $do_expand = <<$^O-eq-VMS>>1<<|$^O-eq-VMS>>0<>; EOT -my $cfg_dl_library_path = <<'EOT'; +my $cfg_dl_library_path; + +if ($^O eq 'MSWin32') { + require Text::ParseWords; + my @w32libpths = Text::ParseWords::parse_line('\s+', 1, $Config::Config{libpth}); + @w32libpths = map({if (substr($_, 0, 1) eq '"') {$_ =~ tr/"/'/;} $_;} @w32libpths); + my $w32libpths = join(',',@w32libpths); + $cfg_dl_library_path = "push(\@dl_library_path, $w32libpths);"; +} +else { + $cfg_dl_library_path = <<'EOT'; push(@dl_library_path, split(' ', $Config::Config{libpth})); EOT +} sub dquoted_comma_list { join(", ", map {'"'.quotemeta($_).'"'} @_); } -if ($ENV{PERL_BUILD_EXPAND_CONFIG_VARS}) { +if ($expand_config_vars) { eval $cfg_dl_library_path; if (!$ENV{PERL_BUILD_EXPAND_ENV_VARS}) { my $dl_library_path = dquoted_comma_list(@dl_library_path); @@ -196,7 +215,7 @@ my $ldlibpthname; my $ldlibpthname_defined; my $pthsep; -if ($ENV{PERL_BUILD_EXPAND_CONFIG_VARS}) { +if ($expand_config_vars) { $ldlibpthname = to_string($Config::Config{ldlibpthname}); $ldlibpthname_defined = to_string(defined $Config::Config{ldlibpthname} ? 1 : 0); $pthsep = to_string($Config::Config{path_sep}); @@ -215,6 +234,7 @@ EOT my $env_dl_library_path = <<'EOT'; if ($ldlibpthname_defined && + length($ldlibpthname) && exists $ENV{$ldlibpthname}) { push(@dl_library_path, split(/$pthsep/, $ENV{$ldlibpthname})); } @@ -228,7 +248,7 @@ if ($ldlibpthname_defined && } EOT -if ($ENV{PERL_BUILD_EXPAND_CONFIG_VARS} && $ENV{PERL_BUILD_EXPAND_ENV_VARS}) { +if ($expand_config_vars && $ENV{PERL_BUILD_EXPAND_ENV_VARS}) { eval $env_dl_library_path; } else { @@ -241,7 +261,7 @@ $env_dl_library_path EOT } -if ($ENV{PERL_BUILD_EXPAND_CONFIG_VARS} && $ENV{PERL_BUILD_EXPAND_ENV_VARS}) { +if ($expand_config_vars && $ENV{PERL_BUILD_EXPAND_ENV_VARS}) { my $dl_library_path = dquoted_comma_list(@dl_library_path); print OUT <