|
From: | Jacob Bachmeyer |
Subject: | Re: Which Perl versions Autoconf needs |
Date: | Thu, 30 Mar 2023 14:10:55 -0500 |
User-agent: | Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.22) Gecko/20090807 MultiZilla/1.8.3.4e SeaMonkey/1.1.17 Mnenhy/0.7.6.0 |
Gavin Smith wrote:
On Wed, Mar 29, 2023 at 09:29:30PM -0500, Jacob Bachmeyer wrote:Do we need a direct configure test for "has Perl module"? AC_PERL_MODULE([Digest::SHA]) would need to execute `$PERL -e "require Digest::SHA"` and consider Digest::SHA available if that returns success. Using Perl's -M option works for most modules, but a few (such as Devel::Cover) produce effects beyond the perl process when import is called, so simply evaluating "require" is less likely to cause weirdness. (Theoretically, a module could do something when loaded with require, but those kinds of side effects are strongly discouraged. Devel::Cover creates a coverage database in the current directory when import is called, but does nothing when loaded with "require".)It would likely be possible to implement whatever tests were desired. For example, the Texinfo package has several occurences of checks for Perl modules. Some of them occur at run-time, some at configure-time, and some are fatal and some are non-fatal. Here's an example of a configure check in configure.ac: AC_MSG_CHECKING([Perl version for tests requiring unicode collation]) if $PERL -e "use 5.018_001; use Unicode::Collate" >/dev/null 2>&1; then perl_unicode_collation_requirement='yes' else perl_unicode_collation_requirement='no' fi AC_MSG_RESULT($perl_unicode_collation_requirement) PERL_UNICODE_COLLATE_OK=$perl_unicode_collation_requirement AC_SUBST([PERL_UNICODE_COLLATE_OK])
This is a fair example of a case where a Perl version could be a legitimate requirement, since Perl's Unicode support has often been incomplete or buggy and is deeply intertwined into the Perl core. However, while that is relevant for Texinfo, which must actually process text in many alphabets (and in this case, I am guessing, perform proper collation for building indexes), Automake and Autoconf deal primarily in ASCII and secondarily in octet strings, such that the details of Unicode support are irrelevant, and even the Perl 5.6 Unicode support is adequate.
This is also a fair start for an expansion for an AC_PERL_MODULE macro. To continue with the example I used earlier:
AC_MSG_CHECKING([for Perl module Digest::SHA]) if $PERL -e 'require Digest::SHA' >/dev/null 2>&1; then perl_module_Digest_SHA='yes' else perl_module_Digest_SHA='no' fi AC_MSG_RESULT($perl_module_Digest_SHA) PERL_MODULE_DIGEST_SHA=$perl_module_Digest_SHA AC_SUBST([PERL_MODULE_DIGEST_SHA])The perl_* and PERL_* shell variable names can be obtained using the patsubst ([::] -> [_]) and translit ([a-z] -> [A-Z]) GNU m4 builtins. We probably should use the cache, so the expansion becomes: (I think)
AC_CACHE_CHECK([for Perl module Digest::SHA], [ac_cv_perl_module_Digest_SHA],
[if $PERL -e 'require Digest::SHA' >/dev/null 2>&1; then ac_cv_perl_module_Digest_SHA='yes' else ac_cv_perl_module_Digest_SHA='no' fi]) PERL_MODULE_DIGEST_SHA=$ac_cv_perl_module_Digest_SHA AC_SUBST([PERL_MODULE_DIGEST_SHA])
An example of a run-time check (for the Archive::Zip module, in the EPUB output code): eval { require Archive::Zip; };my $archive_zip_loading_error = $@;
This discussion got started with a compile-time check (note that perl compiles the program to an in-memory intermediate form immediately before running it) that I wrote for Automake:
BEGIN { eval { require Time::HiRes; import Time::HiRes qw(stat) } }This is a bit of an odd duck, because the semantics of importing Time::HiRes::stat are to effectively replace the builtin stat operator with an XSUB that returns timestamps with fractional seconds included. As a consequence, while the result must be established before the rest of the module is compiled, failing to import Time::HiRes::stat leaves an obvious fallback: the original stat builtin that only gives integer timestamps, which Automake now uses instead of failing if Time::HiRes is not available.
Note that the run-time check you cite is (as I understand) subtly wrong under most versions of perl, where edge cases exist that can allow an exception to be caught, yet $@ remains undefined. I have never actually seen this happen and I do not remember exactly what the supposed edge cases are off the top of my head or if the edge cases were ever entirely eliminated, but seem to recall that the only way to be certain is to set a variable after the operation that can throw, like this:
my $archive_zip_loaded = 0; eval { require Archive::Zip; $archive_zip_loaded = 1 }; my $archive_zip_loading_error = $@;Later code then looks for more details in $archive_zip_loading_error iff $archive_zip_loaded has remained false. The issues with $@ may have been fixed at some point, but I typically use this "flag variable" method as a defensive programming practice, since it works under all versions of perl and is obviously correct upon inspection. This was not an issue for importing Time::HiRes::stat in Automake, since the goal there was simply to get the high-resolution timestamps if available.
-- Jacob
[Prev in Thread] | Current Thread | [Next in Thread] |