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

My XS module is having some problems in CPAN testing, on systems with 64-bit integers. So tonight I'll build a perl 5.10 with such integers. Our existing perl is 5.8.9, and I'd like to leave that as the standard version until 5.10.1 comes out.

My question is, what determines which include files ("EXTERN.h", "perl.h", "XSUB.h") my XS module is built with? Is it the version of perl that I run "perl Makefile.PL" (and thus ExtUtils::MakeMaker) with? Or is it the standard /usr/bin/perl or /usr/local/bin/perl? Or what?

Is this subject covered anywhere in the perl docs?

Thanks,
cmac
www.animalhead.com

Replies are listed 'Best First'.
Re: Q about module building
by ikegami (Patriarch) on Feb 27, 2009 at 01:47 UTC

    Is it the version of perl that I run "perl Makefile.PL"

    I think so. Print out the following and find out!

    #define PERL_REVISION 5 /* age */ #define PERL_VERSION 10 /* epoch */ #define PERL_SUBVERSION 0 /* generation */
Re: Q about module building
by syphilis (Archbishop) on Feb 27, 2009 at 03:12 UTC
    Is it the version of perl that I run "perl Makefile.PL"

    Yes.

    Get the right "perl" and that's all you have to worry about. Simplest way to do that is to just spell it out. That is, if this 64-bit integer build of perl is in '/home/me/perl589_64int/' just run:
    /home/me/perl589_64int/bin/perl Makefile.PL make test
    and all should be sweet. Just remember to run 'make clean' before you try to rebuild the module using a different perl - or you'll likely get some confusing 'make test' results.

    You might also like to build a perl with both long doubles and 64-bit ints (-Dusemorebits). 64-bit integers can be handled differently, depending upon whether long doubles are also available - so it's safest to have both options covered.

    Update: Just to elaborate on what I meant by 64-bit integers can be handled differently (which is not strictly correct), consider this script:
    use strict; use warnings; my $x = 2 ** 55; my $y = $x + 1; if($x == $y) {print "wow\n"} else {print "as expected\n"}
    One would naively expect that, irrespective of whether perl was built with -Duse64bitint or with -Dusemorebits, the output of that script would be "as expected". But that's not so. The -Duse64bitint build outputs "wow", and the -Dusemorebits build outputs "as expected".

    Cheers,
    Rob
      ** is handled as a floating point operation using log and exp, and 64-bit FP doesn't have the mantissa precision for the 1 to add in. Use 1<<55 instead.

      I found my problem. After carefully coding to work with 32 and 64 bit ints, I wrote lines like left_shift = 32 - right_shift; not once but 4 times!

      ANSWER MY OWN Q: stuck "LLU" after the 0x8000000000000000 and all is well

      Which brings me to a question that is REALLY off topic for Perlmonks, but if no one wants to answer it, maybe someone can suggest a place to ask the Q. For this example, UV and IV are 64 bits.
      #define BIT_WITHIN_UV_MASK 0x3F #define BIT0 ((UV)0x8000000000000000) #define BITNO_TO_BITMASK(bitno) (BIT0>>(bitno&BIT_WITHIN_UV_MASK)) SV *mm_array_fetch (mm_array *array, IV index, int prelocked) { UV uv; uv = ... sv = uv & BITNO_TO_BITMASK(index) ? &PL_sv_yes : &PL_sv_no;
      The last line gets the following warning from gcc:
      MMA.xs:463: warning: integer constant is too large for "long" type
      Thanks,
      cmac
        #define BIT0 ((UV)0x8000000000000000ULL)