This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Can't build m68k-elf target with gcc-3.4.3 and newlib-1.13.0(clock_t conflict)


Josep Sabater wrote:

I am writing because I am trying to build a toolchain (using gcc-3.4.3
and newlib-1.13.0) for a Coldfire and I am experimenting some problems
with 'clock_t' definition.

Let me explain the scenario:

1) I have previously unzip newlib src and gcc src into the following dirs:

/home/jsabater/newlib-1.13.0
/home/jsabater/gcc-3.4.3

2) And added a link to newlib src in gcc dir, to have newlib installed
with gcc, as follows:

cd xxx/gcc-3.4.3
mkdir newlib
ln -sf ../newlib-1.13.0/newlib newlib

3) After that, I am running gcc configure as follows:

${GCC_SOURCE_PATH}/configure --target=m68k-elf \
 --prefix=$PREFIX --with-newlib --enable-languages=c,c++ \
 --with-gnu-ld --with-gnu-as --disable-threads

This seems to be the method suggested by the Cygnus guys with their past in-sync source trees, when starting from absolute scratch...

 The GCC manual then doesn't assume/suggest anyone to start from
scratch when building GCC. All the "system" targets (which can have
native GCCs) are assumed to have their C libraries already built and
tested. And all the "embedded" targets (which don't have native GCCs)
are assumed to have at least their C headers available and easy to
copy and install. In the newlib case this is true and the
'--with-newlib' tries to enable people to get their GCCs made when
having only the generic target headers from the newlib sources
preinstalled, copied with a single 'cp -r' like command...

 So the very basic newbie-level know-how required here is where to
install the target C library, its libraries and headers. This can
be compared with a car owner knowing where to put the gasoline and
the lubricating oil in a car... Or a wood-cutter to know these
things about the chain-saw (I have at least once mixed these because
the two saws I use have changed their places). Ok, everyone is assumed
to know where to put the target headers and libraries in a cross-GCC
because every cross-GCC uses just the same standard, so if one has
100 cross-GCCs, they all use just the same install convention. But
please don't ask why, but I have a wacky thought that people really
don't know where to put those target headers and libraries in a cross-
GCC... Not even the GCC developers. If  one must tell this thing 100's
of times, that is too much.

 In any case it should be enough to just copy the newlib headers to
their proper place and then configure GCC using the '--with-newlib'
and then build the complete GCC with all the libiberty and libstdc++
extra libraries. And then consider to build newlib if one yet hadn't
that, made by the earlier rock-solid GCC. The just-built GCC can be
an experimental 'dot zero' (like '3.0', '4.0') level GCC and it not
being suitable to build something as critical as the standard C
library routines...

4) And my latest attemps ends as follows:

/home/jsabater/build-gcc/gcc/xgcc
> -B/home/jsabater/build-gcc/gcc/ -nostdinc
> -B/home/jsabater/build-gcc/m68k-elf/m68000/newlib/
> -isystem /home/jsabater/build-gcc/m68k-elf/m68000/newlib/targ-include

These are stuff from the $build tree...

> -isystem /home/jsabater/gcc-3.4.3/newlib/libc/include

This is the place for the generic headers in the newlib headers...

-B/usr/local/m68k-elf/m68k-elf/bin/

The target binutils should be here for the new GCC to use...


-B/usr/local/m68k-elf/m68k-elf/lib/

The target libraries should be here if they would exist...


-isystem /usr/local/m68k-elf/m68k-elf/include
> -isystem /usr/local/m68k-elf/m68k-elf/sys-include

 The target headers should be in the 'include' one by the GCC manual,
but the GCC developers think they should be in the 'sys-include' !!!
Or was it vice versa or aren't the system headers (sys-include) just
the same thing as the standard headers (include)? If I can mix gasoline
and oil sometimes, maybe the GCC developoers should be allowed to mix
the stabdard and the system headers sometimes... Or should they? That
is the question writes Shakespeare in Hamlet...

 The '--with-newlib' triggers the new GCC to search from the $build
and source trees via the previous two first '-isystem' options. This
far this good... BUT the GCC build itself expects to see the target
headers in the place seen with the last '-isystem' option. If they
are not seen there (or only the critical ones: 'limits.h', 'stdio.h',
'stdlib.h', 'string.h', 'time.h' and 'unistd.h'), the GCC build makes
dumb substitutes for them. These 'stub headers' are not working in
the newlib case.

 The only benefit got via the "combined source tree" could be
getting newlib built at the same time with the GCC parts and with
the built GCC. Getting it built with some experimental or prerelease
GCC version is quite suspectable, so I would prefer to consider
building newlib separately with the best GCC for this purpose. Ok,
using gcc-3.4.3 or the latest 'gcc-3.4', the gcc-3.4.4, sounds sane.

 But when having the newlib sources joined to the GCC sources is not
enough and one must still preinstall the target headers or parts from
them, why then not leave the newlib build to happen after the GCC
build?

In file included from
/home/jsabater/gcc-3.4.3/newlib/libc/include/sys/stat.h:9,
from
> ../../../../../../gcc-3.4.3/newlib/libc/search/hash.c:44:
/home/jsabater/build-gcc/gcc/include/time.h:12:
> error: conflicting types for 'clock_t'
> /home/jsabater/gcc-3.4.3/newlib/libc/include/sys/types.h:90:
error: previous declaration of 'clock_t' was here

If I open those conflicting files I got for
"/home/jsabater/gcc-3.4.3/newlib/libc/include/sys/types.h" the following
definition:

#ifndef __clock_t_defined
typedef _CLOCK_T_ clock_t;
#define __clock_t_defined
#endif

This is one of the proper newlib headers...


and for "/home/jsabater/build-gcc/gcc/include/time.h":

/* Fake time.h, created by GCC.
   The functions declared in this file do not necessarily exist in
   your C library. */
#ifndef __time_h
#define __time_h

#define __need_NULL
#define __need_size_t
#include <stddef.h>

typedef long time_t;
typedef long clock_t;
struct tm;

This is one of the 'fake' (as it tells!) stub headers the GCC build will generate when it doesn't 'see' the 'time.h' existing among the target headers...

Has any of you any idea about what I am doing wrong?

"Don't ask what your country can do for you, but ask what you can do for your country!", or something by J.F.K., could be said otherwise... My opinion has for a long time been that people should somehow get the GCC developers to arrange these things being easier for the builders. That the builders are always doing things wrong is not true at all...

 Generally what you did, should work too!  My reasons to suggest the
separate GCC and newlib builds comes from this method being similar
with building cross-GCCs for the "system" targets. And that the GCC
manual tells that building the target C library has generally nothing
to do with building GCC. If the C library must be built, that is a
totally different case and in many cases doing that has no sanity at
all...

> What is more, do you know how to get the whole thing working?

 Just put the critical target headers: 'limits.h', 'stdio.h',
'stdlib.h', 'string.h', 'time.h' and 'unistd.h' into the :

/usr/local/m68k-elf/m68k-elf/sys-include

where they are expected to be. Or if you are brave, put all the
target headers to be there during the GCC build. But REMEMBER to
remove them after the installation is ready because the newlib
installation will put the final 'm68k-elf' specific headers into
the :

/usr/local/m68k-elf/m68k-elf/include

 The installed GCC will search from these two but the "system
headers" will be searched before the "standard headers" and in
this case the "system headers" would then be the generic newlib
headers, not the ones with replacements and additions coming
from the :

/home/jsabater/build-gcc/m68k-elf/m68000/newlib/targ-include

in the newlib installation...

 Ok, the GCC build tries to FIX all the headers seen in the
'sys-include' for GCC, so one must be brave to let the 'fixinc'
to try to fix something which should already be suitable for GCC :-)
In the "system" target cases the native GCC builders have tested
that the GCC build fixes the '/usr/include' stuff ok, but there
is no guarantee for those targets which don't have native GCCs at
all...

 Maybe it would be better to write a 'make distclean' in the
$build directory, preinstall only the mentioned six headers
into the 'sys-include' and then reconfigure and build... And
then hopefully be happy when everything succeeds...

 In some cases the 'libiberty' build can crash because the
'--with-newlib' handling configure script there claims that
some functions: 'asprintf()', 'strdup()' and 'vasprintf()'
aren't present in newlib !  They once weren't but it has
passed a long time since that... If you meet this case, your
homework would be to search for 'newlib' in the libiberty
config stuff ('configure*') and edit the too long function
lists for the missing ones a little shorter... The crash
will come from the 'seen' newlib header (stdlib.h) protos
clashing with the function (re-)implementations into the
'libiberty.a'...

 Although not fixing this and therefore getting duplicate
functions for these three, it can still get one nervous to
always take care which ones will be used if needing something
from the 'libiberty.a'. This problem can be avoided by configuring
and building without that '--with-newlib', but then the toolchain
should have some default real target for which to create executables.
The 'm68k-elf' is a quite unreal creature among the 'elves' but
the 'arm-elf' used to be a fake name for 'arm-angel' and all kind
of theological discussions could be done about these elves and
their real existence... But let's leave these to the hobbits to
wonder :-) In the real world it is quite newbie-level know-how
to know what happens during linking and what kind of components
('crt*.o', 'libc.a', 'libgcc.a', target board specific glue routines,
linker script,..) are required when producing an executable for
an embedded board.

I really appreciate your help. If you need additional details,
please,let me know.

I think you got enough 'details' here to succeed :-)


P.S: I have made an alternative attemp, building first a bootstrap
compiler, then compiling the newlib (no problems at all here) and
finally building the complete cross compiler obtaining the same
conflict. :-(

My third but the most obvious method, to build in one step and "just like a cross-GCC for a system target", the one suggested via the RTFM, seems to be quite rare to use because people seem to trust more to others (and younger) than RMS (Stallman). Why, has remained mainly unclear for me but maybe I too am too old and therefore believe that also we old greybeards could know something about these things although we have forgotten more than others have learned :-( Fortunately I still can produce more than 10 newlib-based toolchains a day even from absolute scratch using this 'obsolete' old method and my "very basic newbie-level know- how"...

 Generally most problems seen it the cross-GCC build area are
similar with "I'm building a car but it doesn't move anywhere,
what is missing?" And then we see someone guessing: "You maybe
have no wheels and tyres and therefore you cannot move with it"
And when the car-building is that hard, people usually prefer
to do their car buildings in the factories at their pipelines
using pre-written scripts from the car-engineers. They are then
called as "car builders" or how? But aren't the car-engineers
the real "car builders" because they know how-to build cars?

 I still prefer people to read those RMS-written instructions
in the GCC manual(s), 'gcc-2.95' and earlier ones, for producing
cross-compilers from the GCC sources. Without the given basic
know-how about crosscompilers there, it can be quite hard to
get started at all...

The following basic steps :

1. Build and install the target binutils

2. Preinstall what is available for the target C library

3. Build and install the crosscompiler

(4. Build and install the standard C library)

are the steps which every cross-GCC builder is assumed to know
because everyone is assumed to read the GCC manual first for
the cross-GCC build instructions and only after reading that
and trying the method described there but having problems, to
go to the net to search for possible bugs seen and for the
workarounds for them.  The 'build-in-one-step' method from the
Cygnus people and the (bolshevistic) 'GCC build must succeed
without anything taken from the target using the politically
correct steps', are only old and new alternatives for the base
build method. One is free to use anything AFTER knowing the
basic steps, assuming them being wrong because there are so
many who use something else, is not motivated...

 The sad fact is that these basic steps could work in the newlib
case when using '--with-newlib' if only :

1. the target headers would be searched from the '$(tooldir)/include'
   just as the GCC manual (nowadays the "GCC Internals") says,
   by the GCC build process. The RMS instructions tell that they
   must be preinstalled there and the newlib install puts them
   there. So what on earth is the problem in fixing the GCC sources
   to behave just like the manual says?

2. the bug in the libiberty configure would be fixed to expect
   newer newlib sources than something from the last millennium.
   If someone still uses them, would it be a catastrophe to leave
   the 'asprintf()', 'strdup()' and 'vasprintf()' away from the
   produced 'libiberty.a'?  Or would it be too hard to dig out the
   newlib version from the sources and then add or not add those
   functions into libiberty?

 The step 2 is always obligatory but most people seem to leave it
away... This lengthty preach should have told why it is obligatory.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]