Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 527 forks source link

config.h: invalid preprocessing directive `# HAS_LC_MONETARY_2008 /**/` #21803

Open dilyanpalauzov opened 4 months ago

dilyanpalauzov commented 4 months ago

I downloaded perl-5.38.2, unpacked it, ran ./Configure && make. The latter failed with

echo @`sh  cflags "optimize='-O2'" opmini.o`  -DPERL_IS_MINIPERL -DPERL_EXTERNAL_GLOB opmini.c
@cc -c -DPERL_CORE -D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -O2 -Wall -Wno-use-after-free -DPERL_IS_MINIPERL -DPERL_EXTERNAL_GLOB opmini.c
In file included from perl.h:44,
                 from op.c:163:
config.h:2892:3: error: invalid preprocessing directive #HAS_LC_MONETARY_2008
 2892 | # HAS_LC_MONETARY_2008          /**/
      |   ^~~~~~~~~~~~~~~~~~~~
make: *** [makefile:313: opmini.o] Error 1

Indeed, config.h contains # HAS_LC_MONETARY_2008 /**/ and this is invalid preprocessor input.

jkeenan commented 4 months ago

I downloaded perl-5.38.2, unpacked it, ran ./Configure && make. The latter failed with

echo @`sh  cflags "optimize='-O2'" opmini.o`  -DPERL_IS_MINIPERL -DPERL_EXTERNAL_GLOB opmini.c
@cc -c -DPERL_CORE -D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -O2 -Wall -Wno-use-after-free -DPERL_IS_MINIPERL -DPERL_EXTERNAL_GLOB opmini.c
In file included from perl.h:44,
                 from op.c:163:
config.h:2892:3: error: invalid preprocessing directive #HAS_LC_MONETARY_2008
 2892 | # HAS_LC_MONETARY_2008          /**/
      |   ^~~~~~~~~~~~~~~~~~~~
make: *** [makefile:313: opmini.o] Error 1

Indeed, config.h contains # HAS_LC_MONETARY_2008 /**/ and this is invalid preprocessor input.

Can you supply the output of:

$ uname -a
$ locale

Thanks.

dilyanpalauzov commented 4 months ago
# uname -a
Linux mail 5.10.198 #5 SMP Sun Nov 19 15:01:30 UTC 2023 x86_64 GNU/Linux
# locale
LANG=
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
jkeenan commented 4 months ago

Also, what -- if anything do you have for:

d_lc_monetary_2008=

... in ./config.sh after running sh ./Configure?

dilyanpalauzov commented 4 months ago
d_lc_monetary_2008='define'
jkeenan commented 4 months ago

On a system (Debian Linux 11) which I believe is very similar to yours, I switched locales with:

$ export LC_ALL=POSIX; locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=POSIX

I then configured perl (blead) normally: sh ./Configure -des -Dusedevel and observed:

$ grep -n 'monetary_2008' config.sh
350:d_lc_monetary_2008='define'

I then called make (gcc (Debian 10.2.1-6) 10.2.1 20210110). It completed successfully, i.e., it did not fail in compilation of opmini.c, as your case did.

That exhausts my knowledge of these issues. Time to call in the experts: @khwilliamson, @tonycoz, can you take a look? Thanks.

khwilliamson commented 4 months ago

How about the full output of config.sh

and patch Configure with this patch

Configure_patch.txt

and try again with that

dilyanpalauzov commented 4 months ago

The problem is with nm. When I execute ./Configure -Dusenm -d, then case "$d_locconv:$d_lc_monetary_2008" in in Configure is substituted with case "undef:" in. Then the patch does help.

If I call instead just ./Configure -d, then case "$d_locconv:$d_lc_monetary_2008" in Configure is replaced with case "define:" in and config.h contains #define HAS_LC_MONETARY_2008 /**/.

My statement above that config.h contains d_lc_monetary_2008='define' is not correct. It has this value, when I run ./Configure -d, but not when config.h contains # HAS_LC_MONETARY_2008 /**/

khwilliamson commented 4 months ago

On 1/7/24 08:35, Дилян Палаузов wrote:

The problem is with |nm|. When I execute |./Configure -Dusenm -d|, then |case "$d_locconv:$d_lc_monetary_2008" in| in |Configure| is substituted with |case "undef:" in|. Then the patch does help.

If I call instead just |./Configure -d|, then |case "$d_locconv:$d_lc_monetary_2008"| in |Configure| is replaced with |case "define:" in| and config.h contains |#define HAS_LC_MONETARY_2008 /**/|.

My statement above that config.h contains |d_lc_monetary_2008='define'| is not correct. It has this value, when I run |./Configure -d|, but not when config.h contains |# HAS_LC_MONETARY_2008 /**/|

— Reply to this email directly, view it on GitHub https://github.com/Perl/perl5/issues/21803#issuecomment-1880091808, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2DH6QH523WAFBDL5LPR3YNK6FDAVCNFSM6AAAAABBPYCJPGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOBQGA4TCOBQHA. You are receiving this because you were mentioned.Message ID: @.***>

Please attach config.h and config.sh with and without nm

dilyanpalauzov commented 4 months ago

I unpack perl-5.38.2.tar.gz in two directories: perl-5.38.2-with-nm and perl-5.38.2-without-nm

In perl-5.38.2-with-nm I do ./Configure -Dusenm -d config.sh-with-nm.txt config.h-with-nm.txt

In perl-5.38.2-without-nm I execute ./Configure -d config.sh-without-nm.txt config.h-without-nm.txt

khwilliamson commented 4 months ago

The files you posted with nm. Were those with or without the patch? If without, could you post the results when using the patch?

dilyanpalauzov commented 4 months ago

The config.sh/config.h files were without the patch. These are the files with the patch

config.sh-with-nm-patched.txt config.h-with-nm-patched.txt

As I mentioned above the patch does help. The major problem is that nm misbehaves.

khwilliamson commented 4 months ago

For the record, nm is failing to find the following libc functions that not using nm finds

HAS_FGETPOS HAS_FSETPOS HAS_GETTIMEOFDAY HAS_LOCALECONV HAS_MSG HAS_SEM HAS_DLADDR HAS_SHM USE_SEMCTL_SEMUN USE_SEMCTL_SEMID_DS HAS_EXP2 HAS_FMA HAS_HYPOT HAS_LC_MONETARY_2008 HAS_LGAMMA HAS_LOG2 HAS_MEMRCHR HAS_NEARBYINT HAS_RINT HAS_STRNLEN HAS_TRUNC HAS_TIME

nm finds HAS_SYS_ERRLIST that isn't found without it

khwilliamson commented 4 months ago

usenm isn't my area of expertise, but I looked around, and it is problematic to use on Linux. There is a mistrustnm variable (I'm uncertain how to specify it to get nm to behave better. Look at the file lib/Config.pod for more information. ``

tonycoz commented 4 months ago

Which linux distribution is this?

dilyanpalauzov commented 4 months ago

Can the problem be, that nm looks in libc.so.6, while exp2() is in libm.so? This is my own distribution.

dilyanpalauzov commented 4 months ago

No, this cannot be the problem, at least not for fgetpos().

dilyanpalauzov commented 4 months ago

./Configure -Dusenm generates a file libc.list, which contains

000000000010c180 T __vfprintf_chk@@GLIBC_2.3.4
0000000000053610 T _IO_vfprintf@@GLIBC_2.2.5
000000000004d130 W _IO_fprintf@@GLIBC_2.2.5
000000000010c0c0 T __fprintf_chk@@GLIBC_2.3.4
000000000004d130 T fprintf@@GLIBC_2.2.5
0000000000053610 T vfprintf@@GLIBC_2.2.5
                 U vfprintf@GLIBC_2.2.5
                 U fprintf@GLIBC_2.2.5
                 U fprintf@GLIBC_2.2.5

The ./Configure cannot find there fprintf in the ways it is searching it, so it sets nm_opt=-p and regenerates libc.list. Then libc.list contains:

log1p
log2@@GLIBC_2.29
log2@GLIBC_2.2.5
log2_finite@GLIBC_2.15
log2f128_finite@GLIBC_2.26
log2f32x
log2l
log2f64
log2l_finite@GLIBC_2.15
log2f@GLIBC_2.2.5
log2f64x
log2f128
db_log2

Then configure does grep ^log2$ libc.list which is not found, as there is no line containing only log2.

This change does fix make nm detect correctly log2:

--- Configure.orig      2024-01-14 14:16:59.220913131 +0000
+++ Configure   2024-01-14 14:18:17.760706822 +0000
@@ -6674,12 +6674,12 @@
        $contains '^fprintf$' libc.list >/dev/null 2>&1; then
                eval $xrun
 else
-       $nm -p $* 2>/dev/null >libc.tmp
+       $nm -p --without-symbol-versions $* 2>/dev/null >libc.tmp
        $grep fprintf libc.tmp > libc.ptf
        if com="$sed -n -e 's/^.* [ADTSIW]  *_[_.]*//p' -e 's/^.* [ADTSIW] //p'";\
                eval $xscan; $contains '^fprintf$' libc.list >/dev/null 2>&1
        then
-               nm_opt='-p'
+               nm_opt='-p --without-symbol-versions'
                eval $xrun
        else
                echo " "

After applying this change, I get config.sh-nm-without-symbol-versions.txt config.h-nm-without-symbol-versions.txt

I am not saying this is an universal fix, but it gives hints where the problem is.

I am not going to work on this further, unless I am asked to try particular patches. After applying the first change here with d_lc_monetary_2008="$undef" this ticket can be closed.

khwilliamson commented 4 months ago

@Tux what do you think of dilyan's changes?

Tux commented 4 months ago

As I spotted, there are currently several nm issues.

I don't think long options are supported at all on older native nm on HP-UX, Solaris, AIX etc, so this change would break all those systems.

I also spotter truckloads of -a failures in invoking nm, so there is some digging to do in that area too

blastwave commented 1 month ago
I am baffled by the same problem on a bone stock Debian type machine : 

In file included from perl.h:44,
                 from op.c:163:
config.h:2892:3: error: invalid preprocessing directive #HAS_LC_MONETARY_2008
 2892 | # HAS_LC_MONETARY_2008          /**/
      |   ^~~~~~~~~~~~~~~~~~~~
op.c: In function ‘Perl_ck_ftst’:
op.c:12488:58: warning: format ‘%p’ expects argument of type ‘void *’, but argument 4 has type ‘SV *’ {aka ‘struct sv *’
} [-Wformat=]
12488 |                 Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "%s (did you want stat %" SVf "?)",
      |                                                          ^~~~~~~~~~~~~~~~~~~~~~~~~
12489 |                             array_passed_to_stat, name);
      |                                                   ~~~~    
      |                                                   |
      |                                                   SV * {aka struct sv *}
make: *** [makefile:317: opmini.o] Error 1

This makes no sense to me whatsoever.

The only locale type env vars I have are : 

LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
XTERM_LOCALE=en_US.UTF-8

So what is the deal here ... is there an actual patch ?
Tux commented 1 month ago

That should be either #define or #undef on line 2892. The code to set that is in Configure line 16090 and on. That code is in there since f40bbcbf5 2014-11-23 19:45:33 v5.21.6 At first glance I see no reason for it to be empty

dilyanpalauzov commented 1 month ago

If I recall correctly, you have to apply https://github.com/Perl/perl5/pull/21835 and do not pass -Dusenm to ./Configure. But it might be something different, I have forgotten the details.

Tux commented 2 weeks ago

The more I look at this, the more I am convinced that $nm should include --without-symbol-versions if that is supported, so at the detection time of $nm. The proposed patch will break all systems where (their version of) nm does not support this option. It will do very very unwanted things if the nm command does not support long options at all (I found two such systems already)

Looking in that area right now

Tux commented 2 weeks ago

--without-symbol-versions was added (in git) to nm on 2021-02-27 06:09:05. That means that all versions of nm (GNU or not) will fail this newish option for nm commands older that when that commit was released: That includes Rockylinux-9 and Raspbian-11.9 as today, which ship with nm-2.35.2

So for now it is a no-go. You could try to rewrite your patch using $sed -e s/@.*// or similar

dilyanpalauzov commented 2 weeks ago

Yes, but if the plan is to eventually split the logic in ./configure for nm in those supporting --without-symbol-versions, and those without supporting it, then the detection of the supoort for that parameter must be implemented anyway. If it should be implemented anyway long-term, it does not matter how spread the support for --withou-symbol-versions currently is.

Tux commented 2 weeks ago

Then forget that option, as the chance it will be implemented on HP-UX, AIX, Solaris, Irix and all will never happen. Think backwards and add that suggested $sed command instead of the new option to be backward compatible. That way you implement the required functionality in a backward compatible way. I d not think the plan is to add options that break huge areas of what currently is supported.