Question

I´m doing my master thesis and I´m having problems configuring the cross compiler. I´ve read lots of articles, faq, tutorial, etc.., but I still think I´m missing something, maybe very stupid and basilar, but without that I can´t have a clear vision of everything and I can´t make it all work…so please feel free to explain me everything. Let´s go to the problem.

I´m using SoClib to design a NoC with many MIPS and many RAMs and I want to load different applications in every RAM, to make every MIPS read from only one RAM. I managed to do that using very simple applications (like hello word with interrupts…) so now I was trying to realize a JPEG decoder to use in a more intense way the MIPS. The problem is that the cross compiler I´m using can´t find the basic stdio functions and so cannot compile the application for the mips. So basically I didn´t managed to install a working full cross compiler.

1) Let´s start with the cross compiler installed with SoClib: Here there is the guide I´ve followed to install it: http://www.soclib.fr/trac/dev/wiki/CrossCompiler Now from what I´ve read this is not a full cross compiler. I´ve only installed a first stage gcc that can generate elf code for the mips but that can´t use any C function. With that one, I should compile a C library to create a new cross compiler. So it´s normal that it is not working, although that doesn´t answer to the question: why “Hello world” was working if it uses a printf and includes stdio.h? The answer should be that I´ve seen that SoClib has his header stdio.h with very few function realized (printf is there) so I can´t use the standard C library with that compiler.

2) Because of that I´ve decided to install a full cross compiler and I´ve read so many guides that I will only post the two I´ve used in practice: http://www.cse.iitb.ac.in/grc/gcc-workshop-11/downloads/slides/gccw11-config-build.pdf from page 108 (before explains the problems with cross compiling) It uses EGLIBC. The only difference is that I´ve used as target “mipsel-elf”. If I´ve understood correctly, this method requires a 3 stage cross compiler, because eglibc can´t be fully compiled with the first stage cross compiler. Now the problem is that I can´t succeed in installing eglibc with the first stage cross compiler (it fails at page 122). I´have attached the log. I think problems starts when it says: “mipsel-elf-gcc: error: unrecognized option ´-V´” and “mipsel-elf-gcc: fatal error: no input files compilation terminated”. Seems that I´ve some problem with the compiler and all finishes with an unsupported platform…but it should work because I´ve copied the eglibc/ports directory like the guide says…

3) I´ve tried another guide that uses newlib instead of eglibc: http://www(dot)cygwin(dot)com/ml/crossgcc/2005-08/msg00114/l-cross-ltr.pdf This guide creates only a 2 stage cross compiler. I think it´s because newlib can be fully compiled with the first stage compiler…am I right? Anyway I get the same problem. I can´t compile newlib and I get similar errors (log attached).

So that´s my problem and here I put some doubt I´ve had trying to resolve it.

4) Can the problem be the target=mipsel-elf? I know from the gnu documentation that the name to configure gnu should be: cpu-manufacturer-os (or cpu-manufacturer-kernel-os) but I´ve read that mipsel-elf is accepted. The elf should be because I don´t want to load an OS on my NoC platform and here the second doubt…

5) Can the problem be the OS thing? The guides uses linux kernel headers…maybe with a mipsel-elf target I shouldn´t configure binutils –with-sysroot? But sounds me strange…what should change?

6) Yet another probably stupid question. The stdio and generally C functions, doesn´t need an OS right? Because all these problems are making me doubt on the basics…so I should be able to run a JPEG decoding C application with a mipsel-elf cross compiler right?

Every consideration, advice and help will be appreciated. If you have some documents about these arguments please let me know, I would like to learn and become more confident in this field. Thanks

eglibc log:

configure:2426: $? = 0
configure:2433: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -v >&5
Using built-in specs.
COLLECT_GCC=/home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc
COLLECT_LTO_WRAPPER=/home/bertone/programmazione/crosscompiler/mips/install/libexec/gcc/mipsel-elf/4.6.2/lto-wrapper
Target: mipsel-elf
Configured with: ../../../../../Scaricati/src/gcc-4.6.2/configure --target=mipsel-elf --prefix=/home/bertone/programmazione/crosscompiler/mips/install --without-headers --with-newlib --disable-shared --disable-threads --disable-libssp --disable-libgomp --disable-libmudflap --enable-languages=c --disable-werror
Thread model: single
gcc version 4.6.2 (GCC) 
configure:2437: $? = 0
configure:2444: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -V >&5
mipsel-elf-gcc: error: unrecognized option '-V'
mipsel-elf-gcc: fatal error: no input files
compilation terminated.
configure:2448: $? = 1
configure:2452: checking for suffix of object files
configure:2478: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -c   conftest.c >&5
configure:2482: $? = 0
configure:2507: result: o
configure:2511: checking whether we are using the GNU C compiler
configure:2540: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -c   conftest.c >&5
configure:2547: $? = 0
configure:2564: result: yes
configure:2573: checking whether /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc accepts -g
configure:2603: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -c -g  conftest.c >&5
configure:2610: $? = 0
configure:2711: result: yes
configure:2728: checking for /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc option to accept ISO C89
configure:2802: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc  -c -g -O2  conftest.c >&5
conftest.c:9:19: fatal error: stdio.h: No such file or directory
compilation terminated.
configure:2809: $? = 1
configure: failed program was:
| /* confdefs.h.  */
| #define PACKAGE_NAME "GNU C Library"
| #define PACKAGE_TARNAME "glibc"
| #define PACKAGE_VERSION "(see version.h)"
| #define PACKAGE_STRING "GNU C Library (see version.h)"
| #define PACKAGE_BUGREPORT "http://sourceware.org/bugzilla/"
| /* end confdefs.h.  */
| #include <stdarg.h>
| #include <stdio.h>
| #include <sys/types.h>
| #include <sys/stat.h>
| /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
| struct buf { int x; };
| FILE * (*rcsopen) (struct buf *, struct stat *, int);
| static char *e (p, i)
|      char **p;
|      int i;
| {
|   return p[i];
| }
| static char *f (char * (*g) (char **, int), char **p, ...)
| {
|   char *s;
|   va_list v;
|   va_start (v,p);
|   s = g (p, va_arg (v,int));
|   va_end (v);
|   return s;
| }
| 
| /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
|    function prototypes and stuff, but not '\xHH' hex character constants.
|    These don't provoke an error unfortunately, instead are silently treated
|    as 'x'.  The following induces an error, until -std is added to get
|    proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
|    array size at least.  It's necessary to write '\x00'==0 to get something
|    that's true only with -std.  */
| int osf4_cc_array ['\x00' == 0 ? 1 : -1];
| 
| /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
|    inside strings and character constants.  */
| #define FOO(x) 'x'
| int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
| 
| int test (int i, double x);
| struct s1 {int (*f) (int a);};
| struct s2 {int (*f) (double a);};
| int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
| int argc;
| char **argv;
| int
| main ()
| {
| return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
|   ;
|   return 0;
| }
configure:2802: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -qlanglvl=extc89 -c -g -O2  conftest.c >&5
mipsel-elf-gcc: error: unrecognized

option '-qlanglvl=extc89' configure:2809: $? = 1

NEWLIB log

configure:4049: $? = 0
configure:4038: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -v >&5
Using built-in specs.
COLLECT_GCC=/home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc
COLLECT_LTO_WRAPPER=/home/bertone/programmazione/crosscompiler/mips/install/libexec/gcc/mipsel-elf/4.6.2/lto-wrapper
Target: mipsel-elf
Configured with: ../../../../../Scaricati/src/gcc-4.6.2/configure --target=mipsel-elf --prefix=/home/bertone/programmazione/crosscompiler/mips/install --without-headers --with-newlib --disable-shared --disable-threads --disable-libssp --disable-libgomp --disable-libmudflap --enable-languages=c --disable-werror
Thread model: single
gcc version 4.6.2 (GCC) 
configure:4049: $? = 0
configure:4038: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -V >&5
mipsel-elf-gcc: error: unrecognized option '-V'
mipsel-elf-gcc: fatal error: no input files
compilation terminated.
configure:4049: $? = 1
configure:4038: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc -qversion >&5
mipsel-elf-gcc: error: unrecognized option '-qversion'
mipsel-elf-gcc: fatal error: no input files
compilation terminated.
configure:4049: $? = 1
configure:4069: checking for C compiler default output file name
configure:4091: /home/bertone/programmazione/crosscompiler/mips/install/bin/mipsel-elf-gcc    conftest.c  >&5
/home/bertone/programmazione/crosscompiler/mips/install/lib/gcc/mipsel-elf/4.6.2/../../../../mipsel-elf/bin/ld: cannot find crti.o: No such file or directory
/home/bertone/programmazione/crosscompiler/mips/install/lib/gcc/mipsel-elf/4.6.2/../../../../mipsel-elf/bin/ld: cannot find crtbegin.o: No such file or directory
/home/bertone/programmazione/crosscompiler/mips/install/lib/gcc/mipsel-elf/4.6.2/../../../../mipsel-elf/bin/ld: cannot find -lgcc
/home/bertone/programmazione/crosscompiler/mips/install/lib/gcc/mipsel-elf/4.6.2/../../../../mipsel-elf/bin/ld: cannot find -lgcc
/home/bertone/programmazione/crosscompiler/mips/install/lib/gcc/mipsel-elf/4.6.2/../../../../mipsel-elf/bin/ld: cannot find crtend.o: No such file or directory
/home/bertone/programmazione/crosscompiler/mips/install/lib/gcc/mipsel-elf/4.6.2/../../../../mipsel-elf/bin/ld: cannot find crtn.o: No such file or directory
collect2: ld returned 1 exit status
configure:4095: $? = 1
configure:4132: result: 
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME ""
| #define PACKAGE_TARNAME ""
| #define PACKAGE_VERSION ""
| #define PACKAGE_STRING ""
| #define PACKAGE_BUGREPORT ""
| #define PACKAGE_URL ""
| /* end confdefs.h.  */
| 
| int
| main ()
| {
| 
|   ;
|   return 0;
| }
configure:4138: error: in `/home/bertone/programmazione/crosscompiler/mips/build/newlib':
configure:4142: error: C compiler cannot create executables
Was it helpful?

Solution

First, off, do you need these stdio functions?

Can you replace these stdio functions. For example do you really really need a printf (one of the more painful ones), or might you be willing to replace those with some thing else, maybe a string_display() and hex_display() functions perhaps that are quite easy to implement and library and system independent.

Are these file I/O functions? I seem to remember one of the popular open source jpeg decoders wanted to do the file I/O for you. How hard is it really to implement an fopen() (just return with anything valid), an fread, which just keeps track of a pointer in some const data you have included in the binary, and does a mem copy, and fwrite, same deal keeps track of a pointer in an array and does a mem copy.

I have embedded jpeg decoders, mp3, etc that make system calls, both by using newlib() which makes it a bit easier but is these days very painful to build a cross compiler with, and also with replacing the system calls with different functions or by implementing simulations of those functions.

If you use the free codesourcery lite (now called codebench or something as it is mentor graphics and not codesourcery anymore) and replace the system calls with simulated ones you dont have to mess with compilers anymore.

I have some very simple mips code, but also some instructions for building the kind of gnu cross compiler I am talking about (works great if you dont have a use for system calls, C library calls, gcc library calls because you implemented everything yourself).

https://github.com/dwelch67/pic32_samples

It is not a far stretch from what I am building to a complete cross compiler. Gcc/gnu is not so stable that you can just cross compile any version from any version and have it work, likewise the cross compilers for any target from any version on any host using any version is not stable. From time to time a version of binutils+gcc+newlib for a target happen to just work. for example, at this period of time/history this worked, both on linux and with mingw on windows.

http://www.dwelch.com/ipod/gccarm.txt

but unless you use a virtual machine (vmware, etc) and install an old linux on it with an old enough build system, you wont be able to build the above.

Not long ago, and perhaps still this worked on a modern system. it is for arm but maybe it will also work for mips.

http://www.cowlark.com/2009-07-04-building-gcc/

I dont think I have any of the code posted with the mp3 and zlib and jpeg libraries used without system calls or with simulated system calls in a place where I can publish them. mallocs are easy to implement for things like zlib if you want to use zlib as a performance test or something, one time compress or decompress or both, not a general purpose thing but a controlled test environment with data in and data out. Same goes for the others controlled environment jpeg encode or decode, mp3 encode or decode (they are lossy so you cant compare input to output necessarily to verify the system produced the right result, a checksum or crc is easy though compared against a known good system/result).

If you examine the files in newlib that I null out and replace later you can see what newlib boils the stdio calls down into, you would then implement each of those functions. I have a couple of old sites that have at least dhrystone examples which pretty much just wanted a printf http://www.dwelch.com/ipod/ http://www.dwelch.com/gba/dhry.htm where you can see what I did with the newlib functions, mostly just neutered them by returning a passing value, and figuring out what newlib does when it wants to output to stdout.

Or an example of replacing some stdio calls with alternate functions resulting in something that still works. not saying it is pretty but you can play the game. https://github.com/dwelch67/stm32f4d/blob/master/adventure/

Basically what I am reading is that you have identified a problem but are only pursuing one path, solving it on the compiler side. When you could be solving it by creating an abstraction layer or shim, or by removing the offending code completely or replacing it with less offensive code. If you look at the source code for adventure above and similar era games empire, etc, even small c compilers and other code that has been ported a number of times, you can see they did exactly that, they solved the problem by making non-language, non-system specific calls in the bulk of the code, and then the last mile was to implement those calls in one or a few system specific places. Even if you were to get a gcc+newlib or gcc+glibc cross compiler you are still going to have to replace the default stdio to operating system layer with your own. (that is what the compiler side of this is as well, a large bulky abstraction layer, glibc, newlib, etc, that you still have to implement the backend).

OTHER TIPS

Why not just download the free prebuilt GCC Codesourcery Lite cross compiler toolchain for MIPS?

6) The stdio and generally C functions, doesn´t need an OS right?

Usually, libc translates stdio calls into system calls to the underlying OS, so you would need to have an OS for stdio to work. Your JPEG decoder application will work fine if it doesn't call anything that needs an OS, but you will need to create a method to get the results from each individual CPU across your NoC to the outside world.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top