The rest of this post will be of NO INTEREST AT ALL to anyone who usually reads my blog. It may be of no interest at all to anyone in fact. It's aimed at hardcode Linux/Arduino hackers, with the hope they'll be able to reproduce,and improve on my results (its also essentially my notes, so I can reproduce the build!). This in turn makes Sniff on Yun even cooler!
If you're looking for cool educational computing stuff please just scoll past this.
The main catch to this is that there's no C compiler. Huh? a Unix machine without a C compiler? Well there is a C compiler somewhere, but not one which runs on the Yun. To generate code to run on the Linux side, you need to cross compile it on a different machine. To make matters worse it needs to be Debian Linux! Not that I've got anything against Debian, but it is quite specific...
Step 1: Install Debian in a VirtualBox VM.
I don't have a Debian machine (or a regular Linux machine for that matter - got a FreeBSD box, and a bunch of Mac's - no the Pi does not count. This is taking several days on a Quad i7!). In any case its nice to have a clean install, just to be safe so I used VirtualBox on the Mac and installed the latest Debian.apt-get install git subversion build-essential asciidoc \ fastjar flex gawk libgtk2.0-dev intltool zlib1g-dev \ genisoimage libncurses5-dev libssl-dev ruby sdcc unzip \ bison libboost-dev libxml-parser-perl libusb-dev bin86 \ bcc sharutils openjdk-7-jdk mercurial cvs bzrThe instructions for building on Debian can be found on github but they have a couple of glitches. the first is that it suggest installing the "npm" package. This doesn't exist in my version of Debian. I used the list above, and it worked fine...
Step 3: Clone the Repo
This works as per the instructs
Step 4: Build The YUN Linux OS
The again following the instructions on github don't quite work. They sort of work, but then it randomly crashes out. Restarting it seemed to "solve" the problem. It looks like a race condition, as the build tries to use multiple processes to build elements in parallel. I used the command:
make -j 1 V=s
which seemed to solve the problem. The build is still running after about 24 hours, which is actually a good thing!
Step 5: Check GCC cross compiler
At some point long before the build is complete it will make a working version of gcc that runs on Debian, but generates programs for the Yun!
To use it you need to add it to your PATH, and set up STAGING_DIR so that it can find includes and libs:
export PATH=$PATH:$HOME/Open-Wrt-yun/staging_dir/toolchain*/bin
export STAGING_DIR=$HOME/Open-Wrt-yun/staging_dir
Once you can compile a program:
mips-openwrt-linux-uclibc-gcc hello.c
produces a MIPS executable. You can move this over to the YUN with scp, then ssh and run it!!!!!
Step 6: add "cc"
This long and tangled process doesn't generate "cc" only "gcc". At some point we're going to need both (even though they're the same) so:
cd $HOME/Open-Wrt-yun/staging_dir/toolchain*/bin
ln -s mips-openwrt-linux-uclibc-gcc mips-openwrt-linux-uclibc-cc
Step 7: Download GCC
I went for 4.6.4... the cross compiler is 4.6.2, so I figured I'd stick with 4.6, but take a couple of bug fixes.
Download it and unpack it. Then download the "extra" bits it needs.
cd gcc-4.6.4 ./contrib/download_prerequisites cd .. mkdir objdir cd objdir
This also makes a directory to do the actual build in.
Step 8: Build GCC to RUN on Mips
$PWD/../gcc-4.6.4/configure --host=mips-openwrt-linux-uclibc --target=mips-openwrt-linux-uclibc --prefix=/gcc --enable-languages=c,c++
(we;re just building c and c++ as anything more will break later on) and finally
make
This will crash after a couple of minutes: It turns out theres a REAL bug which affects gcc4.4 and later: it means we need to change mpfr/ mpfr-longlong.h.
#if defined (__mips) && W_TYPE_SIZE == 32
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype __ll = (UDItype)(u) * (v); \
+ w1 = __ll >> 32; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("multu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
-#else
+#endif
+#if !defined (umul_ppmm)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("multu %2,%3\n\tmflo %0\n\tmfhi %1" \
: "=d" (w0), "=d" (w1) : "d" (u), "d" (v))
@@ -1034,10 +1043,20 @@
#endif /* __mips */
At some point during the build of the standard C++ library you'll get an error about fenv.h being missing. This isn't needed so find the relevant include file, and just comment out the include.
Step 9: Install
make install
to "install" it on the Debian machine - if course this doesn't work, but it makes the files. It's set to install in /gcc, so once that's done, tar it up and scp it to the Yun.
You also need binutils. You can either build them (exactly the same way as we built gcc, using the same configure options), or install the pre-built package. I tried both... Not sure if they both work, but I ended up building it myself, and copying it over with gcc.
Step 10: Add the Libraries
You've now got a compiler, but you need includes and libs. Fortunatly we've already built them as part of the OpenWRT build (which has now failed completely trying to make a JavaScript VM - I guess you do need npm for that bit). Copy include and lib from them OpenWRT build on Debian onto the Yun, and put them in /gcc
Step 11: Fix the Libraries
No idea what's going on here, but a bunch of really important files ended up in the wrong place. Fix it with:
cd /gcc/lib/gcc/mips-openwrt-linux-uclibc/4.6.4
for i in ../*.o ../*.a
do
ln -s $i .
done
Step 12: Enjoy!
export PATH=/gcc/bin:$PATH
gcc hello.c
./a.out
You'll get a warning about hard and soft floats. Looks like there's a config error in the compiler, as the Yun doesn't have an FPU, which is going to break a lot of stuff. I need to go back around and start over to fix this, but in the mean time
gcc -msoft-float xxx.c
./a.out
You'll get a warning about hard and soft floats. Looks like there's a config error in the compiler, as the Yun doesn't have an FPU, which is going to break a lot of stuff. I need to go back around and start over to fix this, but in the mean time
gcc -msoft-float xxx.c
is a pretty good work around.
Step 1A: Alterative Approach
I deliberately built it to live in the /gcc folder, so you could tar it all up and make it easy to install:You can download it here.
Gunzip and untag it so that its in /gcc. You'll either need to have turned on the "overlay" expanded file store (so the SD card is holding everything -recommended), or unpack it to the SD, and add a link. Add /gcc/bin to your path.
You might also want to install make with:
opkg update
opkg install make
Conclusion and Disclaimer
It's currently almost completely untested - I've compiled hello world! It works. It could do with being improved. There's a couple of bodges in there, but this is really a proof of concept, and a stop gap until someone integrates all this into the proper build. You can compile C on the Yun, and while the above process is pretty tortured, I managed to get it working in a couple of days. An experienced Linino/OpenWRT/GCC+ hacker should be able to make sense of my notes, and produce something better in a fraction of the time.Hopefully now we can get past the "it can't be done"stage, and actually make this thing useful...