autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Which Perl versions Autoconf needs


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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]