jdv has asked for the wisdom of the Perl Monks concerning the following question:

Based on CPAN Testers reports, I see that an XS-based module I just uploaded is failing (actually, "UNKNOWN" status) on some platforms because of unsupported compiler options or missing libraries. Specifically, the C++ library being bound requires support for C++11 and POSIX threads during compilation. I think it would be better to specifically check for this in the Build.PL script and give a more informative error message before exiting cleanly (i.e. test ignored, the same result as for other types of platform incompatibility).

What I am thinking of is adding something like this to the top of Build.PL:

use File::Temp qw/tempfile/; my ($fh_1, $fn_1) = tempfile('cXXXX', SUFFIX=>'.cpp', UNLINK => 1); my ($fh_2, $fn_2) = tempfile('oXXXX', SUFFIX=>'.out', UNLINK => 1); print {$fh_1} "int main() {}\n"; close $fh_1; if( system("cc -o $fn_2 --std=c++11 -lpthread $fn_1") ) { warn "Unsupported compiler or missing library (must be C+11 complian +t and have POSIX thread support)\n"; exit(0); # will be ignored by CPAN Testers as having unmet dependenc +ies }
My question is whether there is a better or more standardized way of doing this testing. I'm aware of Devel::CheckLib which could be used to check for pthreads but not for C++11 support (that I know). Thanks for any advice.

Replies are listed 'Best First'.
Re: Check compiler features before building XS module
by Anonymous Monk on Jan 04, 2016 at 19:03 UTC

    What module?

    I think it would be better to specifically check for this in the Build.PL script and give a more informative error message before exiting cleanly (i.e. test ignored, the same result as for other types of platform incompatibility).

    Don't exit cleanly , let the compiler try to do its thing

    Your system call could easily fail because of shell interpolation, and if you exit, compiler never gets a chance

    Also %Config

      What module?

      Compress::DSRC

      Don't exit cleanly , let the compiler try to do its thing

      Based on my interpretation of the CPAN Testers FAQ, if Build.PL returns 0 before generating the Build script, it is treated as an incompatible system (similar to unsatisified minimum Perl version, etc) and the test attempt is ignored. It seems to me that if the system doesn't have a compatible compiler, this would be the desired response. This is basically the behavior of Devel::CheckLib as I understand it.

      Your system call could easily fail because of shell interpolation, and if you exit, compiler never gets a chance

      I definitely don't want to prevent otherwise successful installs, and my solution is probably not ideal. It does still seem, though, like the proper behaviour would be to check for a compatible compiler as a prerequisite and exit as above if none was found. This would make the testing results more meaningful and possibly be helpful to an end-user trying to troubleshoot.

      Also %Config

      This gives details on how Perl was compiled, correct? That might not be with the same compiler that would be used to build the module, although I could be wrong here.

        Well, Compress-DSRC-0.002/Build.PL uses Module::Build::WithXSpp which uses ExtUtils::CppGuess

        It is those modules that need enhancing not your Build.PL, so you can simply tell them you want C++11, without having to use extra_compiler_flags -std=c++11 or ... in your Build.PL

        But speaking generically,

        Yes, %Config is where you're supposed to retrieve the compiler name, compiler options..... used to build perl, they're going to be used to build your module as well

        If a user is going to use a different compiler, hes going to override %Config with ExtUtils::FakeConfig ...

        Sure, print an extra message to make it easy for user to understand that it probably won't work; compiler messages can be hard to understand

        But you shouldn't prevent the compiler from trying

        Only the compiler knows for sure if it supports C++11

        Best option is to let the compiler try