Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Re: Defining an XS symbol in the Makefile.PL

by jcb (Chaplain)
on Aug 18, 2019 at 05:20 UTC ( #11104630=note: print w/replies, xml ) Need Help??

in reply to Defining an XS symbol in the Makefile.PL

Normally, I would suggest adding backslashes, but I do not know exactly how many layers of quoting this would need.

Perl has a neat feature: the custom quote operators. I suggest:

WriteMakefile( .... DEFINE => q['-DMY_FORMAT="%.16e"'], .... );

... which should put the entire parameter in "shell" single quotes.

Another option is to follow the method used by GNU autoconf and write out a "config.h" file with '#define MY_FORMAT "%.16e"' in it somewhere.

Replies are listed 'Best First'.
Re^2: Defining an XS symbol in the Makefile.PL
by afoken (Canon) on Aug 18, 2019 at 06:24 UTC
    ... which should put the entire parameter in "shell" single quotes

    Ah, "the shell", my pet problem.

    You are assuming that putting something in single quotes will prevent any shell from interpreting it. Sorry, but that assumption is wrong. Both the old ( and the standard shell (cmd.exe) on Windows don't handle single quotes that way.

    Generating a header file to be included by the C/XS code seems to be the more portable approach.


    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Generating a header file to be included by the C/XS code seems to be the more portable approach

      That's probably sort of what I'm doing - and my initial post oversimplified things.
      See this Scalar-List-Utils bug report for a better picture.

      The real issue is that MY_FORMAT needs to be defined to "%.17" (if NV is 64 bit), to be defined to "%.21" (if NV is 80 bit), to be defined to "%.36" (if NV is 128 bit).
      It's quite easy during the Makefile.PL processing to determine which it needs to be - and surely the simplest thing to do is to just have the Makefile.PL define MY_FORMAT to the correct string.
      But you're right ... and jcb's suggestion (along with several variations thereof) is not working.

      At the moment, the Makefile.PL is doing:
      .... if($Config{nvsize} == 8) { $nvtype = 'LU_NV_IS_64_BIT' } # double o +r 8-byte long double elsif(length(sqrt 2) > 25) { $nvtype = 'LU_NV_IS_128_BIT' } # IEEE lon +g double or __float128 else { $nvtype = 'LU_NV_IS_80_BIT' } # extended + precision long double $defines .= " -D$nvtype"; .... WriteMakefile ( .... DEFINE => $defines, .... );
      And the XS file is rewritten to redefine the symbol to the appropriate value:
      #if defined(LU_NV_IS_64_BIT) #define MY_FORMAT "%.17" #elif defined(LU_NV_IS_80_BIT) #define MY_FORMAT "%.21" #else #define MY_FORMAT "%.36" #endif
      It's working fine .... but I feel that I should be able to define MY_FORMAT directly within the Makefile.PL and avoid having to add that preprocessing to the XS file ??


        Actually, what you are actually doing is probably a better option. Getting strings through varying shell quoting rules is asking for trouble.

        And that leads to another option:

        in Makefile.PL:

        if($Config{nvsize} == 8) { $nvbits = 64 } elsif(length(sqrt 2) > 25) { $nvbits = 128 } else { $nvbits = 80 } $defines .= ' -DLU_NV_BITS='.$nvbits;

        in XS code:

        #if LU_NV_BITS == 64 #define MY_FORMAT "%.17" #elif LU_NV_BITS == 80 #define MY_FORMAT "%.21" #elif LU_NV_BITS == 128 #define MY_FORMAT "%.36" #else #error "LU_NV_BITS not set" #endif

        Passing a numeric parameter through the shell does not require quoting at all.

        You could also just pass the number of digits you want, but converting that back to a string in the C preprocessor requires macro tricks documented in the GNU CPP manual.

      It has been a while since I have developed on Windows, but if I recall correctly, the special variant if $^O eq 'MSWin32' is:

      WriteMakefile( .... DEFINE => q["-DMY_FORMAT=""%.16e"""], .... );

      Since Makefile.PL is actually a Perl program, these can be combined as:

      WriteMakefile( .... DEFINE => $^O eq 'MSWin32' ? q["-DMY_FORMAT=""%.16e"""] : q['-DMY_FO +RMAT="%.16e"'], .... );

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11104630]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2019-10-15 11:14 GMT
Find Nodes?
    Voting Booth?