Compiling Binutils error: ‘TARGET_ALIAS’ undeclared (first use in this function) [Work-Around]

Hello Folks

      There is an obscure bug that pops up when you compile binutils. Basically the compilation will fail with the following error:

gcc -DHAVE_CONFIG_H -I.  -I. -I. -I../bfd -I./config -I./../include -I./.. -I./../bfd -DLOCALEDIR="\"/opt/gcc-4.9.3/install/share/locale\""   -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -g -O2 -MT  as.o -MD -MP -MF .deps/as.Tpo -c -o as.o as.c
as.c: In function ‘print_version_id’:
as.c:224:14: error: ‘TARGET_ALIAS’ undeclared (first use in this function)
     VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
              ^
as.c:224:14: note: each undeclared identifier is reported only once for each function it appears in
as.c: In function ‘parse_args’:
as.c:635:5: error: ‘TARGET_ALIAS’ undeclared (first use in this function)
     TARGET_ALIAS);
     ^
as.c:649:44: error: ‘TARGET_CANONICAL’ undeclared (first use in this function)
    fprintf (stderr, _("canonical = %s
"), TARGET_CANONICAL);
                                            ^
as.c:650:43: error: ‘TARGET_CPU’ undeclared (first use in this function)
    fprintf (stderr, _("cpu-type = %s
"), TARGET_CPU);
                                           ^
Makefile:896: recipe for target 'as.o' failed


      Searching the internet others have ran into the same problem however there does not seem to be a solution. I was lucky enough to figure out the problem and track it down. Basically the error is in how gcc resolves duplicate header files. It is suppose to include the local version but instead it includes another version. The fix is based on renaming the other version to force gcc to select the correct header file. I am posting a work around here just so others can overcome this problem for the time being.
  1. run configure as normal

  2. run ‘make’ it will fail in the gas directory

  3. run ‘mv bfd/config.h bfd/config.h.bak’ this forces the compilation to select the correct config.h

  4. run ‘cd gas/’

  5. run ‘make’

  6. run ‘cd …’

  7. run ‘make’ this will rebuild bfd, but it will skip over gas and avoid the error… however it will then descend into binutils and run into the same error…

  8. run ‘mv bfd/config.h bfd/config.h.bak’

  9. run ‘cd binutils/’

  10. run ‘make’

  11. run ‘cd …’

  12. run ‘make’ this will rebuild bfd, but it will skip over gas and binutils… this time everything else compiles without error

     This error seems to only occur when compiling with newer  versions of gcc. The default gcc in Suse 13.2 is 4.8.3 and it will produce there error furthermore it is only inevitable more distro's will be  shipping with updated versions of gcc, so this bug will become more common. This could be a bug with either gcc or binutils. I have informed the binutils people, I am hoping they can help me figure out if it is a binutils or gcc problem. Once I know better I will have it posted to the correct bug fix system. So in time it should be resolved permanently, in the mean time use the work-around I provided.
    

Take Care
Mike

PS in case you want to know more of the nitty-gritty details:


user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> gcc --version
gcc (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064]
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> ./configure --prefix=/opt/gcc-4.9.3/install --with-mpc=/opt/gcc-4.9.3/install --with-mpfr=/opt/gcc-4.9.3/install --with-gmp=/opt/gcc-4.9.3/install --with-cloog=/opt/gcc-4.9.3/install --with-isl=/opt/gcc-4.9.3/install --enable-gold=yes --enable-ld=yes --disable-libquadmath --disable-libquadmath-support --enable-lto


... <snipped>...



user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> make

... <snipped>...

gcc -DHAVE_CONFIG_H -I.  -I. -I. -I../bfd -I./config -I./../include -I./.. -I./../bfd -DLOCALEDIR="\"/opt/gcc-4.9.3/install/share/locale\""   -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -g -O2 -MT  as.o -MD -MP -MF .deps/as.Tpo -c -o as.o as.c
as.c: In function ‘print_version_id’:
as.c:224:14: error: ‘TARGET_ALIAS’ undeclared (first use in this function)
     VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
              ^
as.c:224:14: note: each undeclared identifier is reported only once for each function it appears in
as.c: In function ‘parse_args’:
as.c:635:5: error: ‘TARGET_ALIAS’ undeclared (first use in this function)
     TARGET_ALIAS);
     ^
as.c:649:44: error: ‘TARGET_CANONICAL’ undeclared (first use in this function)
    fprintf (stderr, _("canonical = %s
"), TARGET_CANONICAL);
                                            ^
as.c:650:43: error: ‘TARGET_CPU’ undeclared (first use in this function)
    fprintf (stderr, _("cpu-type = %s
"), TARGET_CPU);
                                           ^
Makefile:896: recipe for target 'as.o' failed

... <snipped>...

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> cd gas
user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/gas>  gcc -DHAVE_CONFIG_H -I.  -I. -I. -I../bfd -I./config -I./../include  -I./.. -I./../bfd -DLOCALEDIR="\"/opt/gcc-4.9.3/install/share/locale\""   -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -g -O2 -MT  as.o -MD -MP -MF .deps/as.Tpo -c -o as.o as.c --save-temps


... <same error> ...


user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/gas> head as.i -n 20
# 1 "as.c"
# 1 "/opt/gcc-4.9.3/binutils/binutils-2.25/gas//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "as.c"
# 34 "as.c"
# 1 "as.h" 1
# 37 "as.h"
# 1 "./../include/alloca-conf.h" 1
# 16 "./../include/alloca-conf.h"
# 1 "../bfd/config.h" 1                                     <------------- This is the WRONG config.h
# 17 "./../include/alloca-conf.h" 2



user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/gas> mv ../bfd/config.h ../bfd/config.h.bak
user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/gas> make

... <everything compiles perfectly> ...

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/gas> cd ..
user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> make


... <bfd is recompiled which restores bfd/config.h > ...


... <then I get the following error in binutils:> ...

gcc -DHAVE_CONFIG_H -I.  -I. -I. -I../bfd -I./../bfd -I./../include -DLOCALEDIR="\"/opt/gcc-4.9.3/install/share/locale\"" -Dbin_dummy_emulation=bin_vanilla_emulation   -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -g -O2 -MT  bucomm.o -MD -MP -MF .deps/bucomm.Tpo -c -o bucomm.o bucomm.c
bucomm.c: In function ‘set_default_bfd_target’:
bucomm.c:159:24: error: ‘TARGET’ undeclared (first use in this function)
   const char *target = TARGET;
                        ^
bucomm.c:159:24: note: each undeclared identifier is reported only once for each function it appears in
Makefile:932: recipe for target 'bucomm.o' failed


... <snipped> ...


user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> cd binutils
user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/binutils> gcc -DHAVE_CONFIG_H -I.  -I. -I. -I../bfd -I./../bfd -I./../include -DLOCALEDIR="\"/opt/gcc-4.9.3/install/share/locale\"" -Dbin_dummy_emulation=bin_vanilla_emulation   -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -g -O2 -MT  bucomm.o -MD -MP -MF .deps/bucomm.Tpo -c -o bucomm.o bucomm.c  --save-temps


... <same error> ...

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/binutils> head bucomm.i -n 20
# 1 "bucomm.c"
# 1 "/opt/gcc-4.9.3/binutils/binutils-2.25/binutils//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "bucomm.c"
# 24 "bucomm.c"
# 1 "sysdep.h" 1
# 23 "sysdep.h"
# 1 "./../include/alloca-conf.h" 1
# 16 "./../include/alloca-conf.h"
# 1 "../bfd/config.h" 1                                     <------------- Once again an indirect include through alloca-conf.h selects the wrong config.h
# 17 "./../include/alloca-conf.h" 2

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/binutils> mv ../bfd/config.h ../bfd/config.h.bak
user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/binutils> gcc -DHAVE_CONFIG_H -I.  -I. -I. -I../bfd -I./../bfd -I./../include -DLOCALEDIR="\"/opt/gcc-4.9.3/install/share/locale\"" -Dbin_dummy_emulation=bin_vanilla_emulation   -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -g -O2 -MT  bucomm.o -MD -MP -MF .deps/bucomm.Tpo -c -o bucomm.o bucomm.c  --save-temps


... <no errors> ...

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/binutils> head bucomm.i -n 20
# 1 "bucomm.c"
# 1 "/opt/gcc-4.9.3/binutils/binutils-2.25/binutils//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "bucomm.c"
# 24 "bucomm.c"
# 1 "sysdep.h" 1
# 23 "sysdep.h"
# 1 "./../include/alloca-conf.h" 1
# 16 "./../include/alloca-conf.h"
# 1 "./config.h" 1 3                                         <---- now the correct 'config.h' is included
# 17 "./../include/alloca-conf.h" 2


user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/binutils> make


... <everything compiles without error> ...

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25/binutils> cd ..
user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> make


... <everything compiles without error> ...

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> make check

... <all tests pass> ...

user@host:/opt/gcc-4.9.3/binutils/binutils-2.25> make install

... <everything is installed> ...https://ssl.gstatic.com/ui/v1/icons/mail/images/cleardot.gif




Or you could grab binutils 2.25 patched from:


http://download.opensuse.org/repositories/devel:/gcc/openSUSE_13.2/

yes for most users the repository version will work fine… however if you want more control on how your tool chain is built then you will have to compile it yourself and voila you will need this work-around. Typically a manual compile is needed for cross compiling… in my case I need special tool chain options to run some of the code optimizations I need for HPC…

Just an update for those that need to compile their own tool-chains…

I have been looking deeper into this issue and the problem is due to a bug in how the C pre-processor includes files from environment variables

In my case C_INCLUDE_PATH was “:/path/to/other/stuff”

The problem is the colon at the beginning. This is interpreted as an empty path which is further interpreted as ‘./’. The bug in ‘cpp’ is that this over-writes the precedence according to “-I./” flags. This bug occurs whenever there is an empty path (e.g. “:” “/path/to/other/stuff:” etc.).

I did not check other environment variables but you should also check

CPATH
CPLUS_INCLUDE_PATH

I have posted this bug to the gcc folks. It is fairly minor and obscure so I have no expectation on it getting fixed soon.

Regardless the better resolution is to ensure that either ‘./’ or an empty path is not in the following environment variables:

CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH

Take Care
Mike