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.