diff --git a/ext/DynaLoader/DynaLoader_pm.PL b/ext/DynaLoader/DynaLoader_pm.PL index 002569f98c74..6c8ad3ca4d5d 100644 --- a/ext/DynaLoader/DynaLoader_pm.PL +++ b/ext/DynaLoader/DynaLoader_pm.PL @@ -88,7 +88,7 @@ package DynaLoader; # Tim.Bunce@ig.co.uk, August 1994 BEGIN { - $VERSION = '1.50'; + $VERSION = '1.51'; } EOT @@ -245,6 +245,70 @@ if ($ENV{PERL_BUILD_EXPAND_CONFIG_VARS} && $ENV{PERL_BUILD_EXPAND_ENV_VARS}) { EOT } +# Filter out PATH elements that do not exist (anymore) and filter duplicates +# e.g. /usr/lib64/gcc/x86_64-suse-linux/7/include-fixed might refer to +# the compiler path when perl was built and the current installed +# copiler updated to version 8 or higher +{ my %seen; + @dl_library_path = grep { -d && !$seen{$_}++} @dl_library_path; +} + +# In a 64bit environment, force 64bit locations *before* 32bit locations. +# This will move /usr/lib64 in front of /usr/lib and /lib64 in front of +# /lib. This is important if a module uses $Config{libpth} to find a +# library to load, like FFI::CheckLib does. If a library is installed in +# both locations, it is likely to pick the wrong one if the order is not +# showing the correct architecture first +# As this clutch only looks at trailing 64, it will have no impact on +# locations differing completely, as /usr/lib vs /usr/lib/i386-linux-gnu/ +# like on debian. +# Example: +# $Config{libpth} = join " " => qw( +# /usr/local/lib +# /usr/lib64/gcc/x86_64-suse-linux/7/include-fixed +# /usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/lib +# /usr/lib +# /pro/local/lib +# /lib/../lib64 +# /usr/lib/../lib64 +# /lib +# /lib64 +# /usr/lib64 +# /usr/local/lib64 +# ); +if ($Config{ptrsize} == 8) { + my (@libpth, %p); + # Group all libs to the base of with or without trailing 64 + # --> with above example @libpth becomes qw( + # /usr/local/lib + # /usr/lib64/gcc/x86_64-suse-linux/7/include-fixed + # /usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/lib + # /usr/lib + # /pro/local/lib + # /lib/../lib + # /usr/lib/../lib + # /lib + # /lib + # /usr/lib + # /usr/local/lib + # and %p becomes (only first part shown) + # { "/lib" => [ + # "/lib", + # "/lib64" + # ], + # "/lib/../lib" => [ + # "/lib/../lib64" + # ], + for (@dl_library_path) { + my $p = s/64$//r; + push @libpth => $p; + push @{$p{$p}} => $_; + } + # Then join them back in the original (base) order (preserved in @libpth) + # where the trailing sorts after the non-trailing 64, hence reverse sort + @dl_library_path = map { reverse sort @{delete $p{$_} || []} } @libpth; +} + if ( $Config::Config{d_libname_unique} ) { printf OUT <<'EOT', length($Config::Config{dlext}) + 1; sub mod2fname { diff --git a/pod/perldelta.pod b/pod/perldelta.pod index aa261d289fef..1ec5ebaadf3e 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -149,6 +149,17 @@ L has been upgraded from version 1.29 to 1.30. One warning in F averted (rt.cpan.org #133952). +=item * + +L has been upgraded from version 1.50 to 1.51. + +@DynaLoader::dl_library_path will now save only existing PATH elements where +duplicates are filtered. + +If $Conf{ptrsize} == 8 (64bit builds), @dl_library_path will sort 64bit +locations in front of 32bit locations. This will force-mode /lib64 in +front of /lib and /usr/lib64 in front of /usr/lib. + =back =head2 Removed Modules and Pragmata