Bug 22941 - binutils build fails if intl/plural.y is newer than intl/plural.c
Summary: binutils build fails if intl/plural.y is newer than intl/plural.c
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.31
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 24029 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-03-08 23:56 UTC by Ryan Prichard
Modified: 2022-07-22 04:36 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2018-03-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ryan Prichard 2018-03-08 23:56:03 UTC
binutils has the same non-deterministic build problem that was reported in https://sourceware.org/bugzilla/show_bug.cgi?id=22432. (Aside: various other projects appear to have the same pair of files, e.g. gdb, gcc, e2fsprogs, ...)

When I build binutils for Linux, it uses gettext from libc, but when I cross-compile for Windows, it instead used its bundled libintl. If I check out binutils source on a normal Linux desktop, the intl/plural.c and intl/plural.y typically have equal mtimes and ctimes, so the build system uses the intl/plural.c file (generated by Bison 1.35) and the build succeeds.

If I instead use a WSL (Windows-Subsystem-for-Linux) environment, the intl/plural.y is typically newer than intl/plural.c (slower filesystem?), and the build system regenerates plural.c (using e.g. Bison 3.0.4). With the regenerated file, the build fails.

Build errors:

    bison -y --name-prefix=__gettext --output plural.c ../../intl/plural.y
    ../../intl/plural.y:46.1-12: warning: deprecated directive, use ‘%pure-parser’ [-Wdeprecated]
     %pure_parser
     ^^^^^^^^^^^^
    rm -f plural.h
    x86_64-w64-mingw32-gcc -c  -g -O2 -D__USE_MINGW_ACCESS -DHAVE_CONFIG_H  -I. -I../../intl plural.c
    In file included from ../../intl/plural.y:35:0:
    ../../intl/plural-exp.h:102:23: error: conflicting types for ‘libintl_gettextparse’
     # define PLURAL_PARSE libintl_gettextparse
                           ^
    ../../intl/plural.y:40:25: note: in expansion of macro ‘PLURAL_PARSE’
     # define __gettextparse PLURAL_PARSE
                             ^~~~~~~~~~~~
    plural.c:184:5: note: in expansion of macro ‘__gettextparse’
     int __gettextparse (void);
         ^~~~~~~~~~~~~~
    ../../intl/plural-exp.h:102:23: note: previous declaration of ‘libintl_gettextparse’ was here
     # define PLURAL_PARSE libintl_gettextparse
                           ^
    ../../intl/plural-exp.h:114:12: note: in expansion of macro ‘PLURAL_PARSE’
     extern int PLURAL_PARSE PARAMS ((void *arg));
                ^~~~~~~~~~~~
    ../../intl/plural-exp.h:102:23: error: conflicting types for ‘libintl_gettextparse’
     # define PLURAL_PARSE libintl_gettextparse
                           ^
    ../../intl/plural.y:40:25: note: in expansion of macro ‘PLURAL_PARSE’
     # define __gettextparse PLURAL_PARSE
                             ^~~~~~~~~~~~
    plural.c:63:25: note: in expansion of macro ‘__gettextparse’
     #define yyparse         __gettextparse
                             ^~~~~~~~~~~~~~
    plural.c:1129:1: note: in expansion of macro ‘yyparse’
     yyparse (void)
     ^~~~~~~
    ../../intl/plural-exp.h:102:23: note: previous declaration of ‘libintl_gettextparse’ was here
     # define PLURAL_PARSE libintl_gettextparse
                           ^
    ../../intl/plural-exp.h:114:12: note: in expansion of macro ‘PLURAL_PARSE’
     extern int PLURAL_PARSE PARAMS ((void *arg));
                ^~~~~~~~~~~~
    plural.c: In function ‘libintl_gettextparse’:
    plural.c:64:25: error: too few arguments to function ‘__gettextlex’
     #define yylex           __gettextlex
                             ^
    plural.c:1298:16: note: in expansion of macro ‘yylex’
           yychar = yylex (&yylval);
                    ^~~~~
    plural.c:64:25: note: declared here
     #define yylex           __gettextlex
                             ^
    ../../intl/plural.y:69:12: note: in expansion of macro ‘yylex’
     static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
                ^~~~~
    ../../intl/plural.y:178:29: error: ‘arg’ undeclared (first use in this function)
          ((struct parse_args *) arg)->res = $1;
                                 ^~~
    ../../intl/plural.y:178:29: note: each undeclared identifier is reported only once for each function it appears in
    Makefile:133: recipe for target 'plural.o' failed
    make[2]: *** [plural.o] Error 1
    make[2]: Leaving directory '/usr/local/google/home/rprichard/android/binutils-gdb/out/intl'
    Makefile:6574: recipe for target 'all-intl' failed
    make[1]: *** [all-intl] Error 2
    make[1]: Leaving directory '/usr/local/google/home/rprichard/android/binutils-gdb/out'
    Makefile:856: recipe for target 'all' failed
    make: *** [all] Error 2


binutils already requires bison to build, so it seems sensible to fix this issue the same way that glibc was already fixed:

    rprichard@cashew:~/android/binutils-gdb$ for f in $(find . -name '*.y'); do echo -- $f; find . -name $(basename ${f%.y}.c); done
    -- ./gold/yyscript.y
    -- ./intl/plural.y
    ./intl/plural.c
    ./out/intl/plural.c
    -- ./ld/ldgram.y
    -- ./ld/deffilep.y
    -- ./gas/itbl-parse.y
    -- ./gas/config/rx-parse.y
    -- ./gas/config/bfin-parse.y
    -- ./gas/config/rl78-parse.y
    -- ./gas/config/m68k-parse.y
    -- ./gdb/c-exp.y
    -- ./gdb/ada-exp.y
    -- ./gdb/m2-exp.y
    -- ./gdb/p-exp.y
    -- ./gdb/cp-name-parser.y
    -- ./gdb/rust-exp.y
    -- ./gdb/f-exp.y
    -- ./gdb/go-exp.y
    -- ./gdb/d-exp.y
    -- ./binutils/nlmheader.y
    -- ./binutils/defparse.y
    -- ./binutils/mcparse.y
    -- ./binutils/sysinfo.y
    -- ./binutils/rcparse.y
    -- ./binutils/arparse.y

Steps to cross-compile binutils:

On a Debian system, install the mingw-w64 package. This provide a GCC toolchain with the triple x86_64-w64-mingw32 (e.g. x86_64-w64-mingw32-gcc)

Run these commands:

    /path/to/configure --host=x86_64-w64-mingw32
    make
Comment 1 Jim Wilson 2018-03-09 23:26:48 UTC
I just got the same bug report for a riscv* target.  I can reproduce this failure for any target by forcing intl to build.

Steps to reproduce:
../binutils-gdb/configure
make configure-intl
edit intl/Makefile to change "all: all-no" to "all: all-yes"
touch ../binutils-gdb/intl/plural.y
make all-intl

I have bison 3.0.4.
Comment 2 Nick Clifton 2018-04-05 13:51:05 UTC
Hi Ryan,

> binutils already requires bison to build, so it seems sensible to fix this
> issue the same way that glibc was already fixed:
> 
>     rprichard@cashew:~/android/binutils-gdb$ for f in $(find . -name '*.y');
> do echo -- $f; find . -name $(basename ${f%.y}.c); done
>     -- ./gold/yyscript.y
>     -- ./intl/plural.y
>     ./intl/plural.c
>     ./out/intl/plural.c

Sorry - can you run this solution by me again ?  How does it fix the timestamps ?

Cheers
  Nick
Comment 3 Jim Wilson 2018-04-05 18:24:20 UTC
There is no fix in the PR.  The list of files is just showing that plural.c is the only bison output file in the git tree.

The glibc solution is to drop the generated file from the git tree, and always generate it at build time.  The gcc solution is to add a script that touches every generated file after checkout to fix the timestamps.  This is contrib/gcc_update.

The gcc solution could work for binutils, provided that no one ever needs to build the intl dir.

The glibc solution will not work unless we update the intl dir.  It looks like we have a 15 year old copy of the intl package, which is why it no longer works with current bison versions.  Note the 2003 import message in the ChangeLog file.  The glibc plural.y file has a 2018 copyright, the binutils copy of the file has a 2001 copyright.  So the fix here is to update intl to a recent version.
Comment 4 Andreas Schwab 2018-04-06 06:56:05 UTC
> The glibc plural.y file has a 2018 copyright,

That doesn't say much, it is routinely updated every year.  The last merge from upstream was commit 6d24885784 ("intl: Merge with gettext version 0.19.3"), from 2014.
Comment 5 Jim Wilson 2019-07-07 23:50:30 UTC
*** Bug 24029 has been marked as a duplicate of this bug. ***
Comment 6 Jim Wilson 2020-04-16 21:56:01 UTC
This is the same bug as
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92008
and a patch has been added to fix that bug.  Merging that patch into the binutils git tree should fix this bug.  There is also a config/gettext.m4 hunk that hasn't been committed yet, and might not be until after the gcc 10 branch is made.  I don't know if that part is required to complete the fix; I haven't checked.
Comment 7 Alan Modra 2022-07-22 04:36:43 UTC
I believe this has been fixed