Monday, November 25, 2013

Mono 3.2.3 on Synology DS210

This is my guide to building Mono on the Synology DS box with the ARM chipset. If you just want the binaries, they are here: Mono 3.2.3 binaries for Synology DS210.

To use it run (installs in /opt/mono3.2.3):

wget ""
tar -C / xf mono-3.2.3-bin.tar.bz2

Then sprinkle a few symlinks:
ln -s /opt/mono-3.2.3/bin/mono /opt/bin/mono
ln -s /opt/mono-3.2.3/bin/mcs /opt/bin/mcs
ln -s /opt/mono-3.2.3/bin/gmcs /opt/bin/gmcs

If you want to compile Mono 3.2.3 yourself, the guide follows here. 

First step is to grab and extract the Mono source:
wget ""
tar xf mono-3.2.3.tar.bz2
cd mono-3.2.3

Then simply run the configure script:
./configure --prefix=/opt/mono-3.2.3

And you should be able to compile, but if you try, you get errors like:
undefined reference to `__sync_add_and_fetch_4'
undefined reference to `__sync_val_compare_and_swap_8'

This is because Mono uses a newer GCC and the methods are not in the old GCC found on Synology, and the cross compile tools version is also too old. Fortunately there is a trick which I adopted from here. I use a newer version of GCC, and the relevant file has moved, so these are the steps:
wget ""
tar xf gcc-4.8.2.tar.bz2 gcc-4.8.2/libgcc/config/arm/
cd gcc-4.8.2/libgcc/config/arm/
sed -i -e 's/define HIDDEN.*/define HIDDEN/' linux-atomic.c
gcc -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c linux-atomic.c  -fPIC -DPIC -o linux-atomic.o
cd ../../../../
mv gcc-4.8.2/libgcc/config/arm/*.o .

Now you have the missing methods in the object files so they can be linked into the binaries, except the __sync_val_compare_and_swap_8 method. This method can be obtained from the linux-atomic-64bit.c file in libgcc as well. But it depends on the kernel function call "__kernel_cmpxchg64", which is not included in the kernel running on Synology. Fortunately there is a fallback method, which we can activate by editing mono/utils/atomic.h. Somewhere around the top, just insert this line:

This will make the compilation fall back to a mutex based method instead of using the missing kernel method. To make sure we can compile the libraries that need the atomic methods, export these:
export pedump_LDFLAGS=`pwd`/linux-atomic.o
export mono_boehm_LDFLAGS=`pwd`/linux-atomic.o
export mono_sgen_LDFLAGS=`pwd`/linux-atomic.o
export monodis_LDFLAGS=`pwd`/linux-atomic.o
export monograph_LDFLAGS=`pwd`/linux-atomic.o

The mono_sgen and mono_boehm LDFLAGS are overwritten in the Makefile, so:
nano mono/mini/Makefile

Look for mono_boehm_LDFLAGS and mono_sgen_LDFLAGS and change the "LDFLAGS=" to "LDFLAGS+=".

 And finally the __clear_cache call is also missing, so edit mono/mini/mini-arm.c, line 1032, and comment out the call, so we use the fallback instead:

#elif __APPLE__
        sys_icache_invalidate (code, size);
//#elif __GNUC_PREREQ(4, 1)
//      __clear_cache (code, code + size);
#elif defined(PLATFORM_ANDROID)
        const int syscall = 0xf0002;
        __asm __volatile (
                "mov     r0, %0\n"
                "mov     r1, %1\n"
                "mov     r7, %2\n"
                "mov     r2, #0x0\n"
                "svc     0x00000000\n"
                :       "r" (code), "r" (code + size), "r" (syscall)
                :       "r0", "r1", "r7", "r2"
        __asm __volatile ("mov r0, %0\n"
                        "mov r1, %1\n"
                        "mov r2, %2\n"
                        "swi 0x9f0002       @ sys_cacheflush"
                        : /* no outputs */
                        : "r" (code), "r" (code + size), "r" (0)
                        : "r0", "r1", "r3" );

This should get you almost through, but there seems to be an install file missing, or perhaps just using the wrong path:
ln -s install-sh docs/install-sh

And now run "make" and wait.... If it fails with something about pthreads, you may need this hack:
mkdir /opt/arm-none-linux-gnueabi/lib_disabled
mv /opt/arm-none-linux-gnueabi/lib/libpthread* /opt/arm-none-linux-gnueabi/lib_disabled
cp /lib/ /opt/arm-none-linux-gnueabi/lib/
ln -s /opt/arm-none-linux-gnueabi/lib/ /opt/arm-none-linux-gnueabi/lib/
ln -s /opt/arm-none-linux-gnueabi/lib/ /opt/arm-none-linux-gnueabi/lib/

Then build again. And that should now build all the way, so you can install: make install If this gives you an error about the EntityFramework.dll no being signed: "Failure adding assembly ./../../class/lib/net_4_5/EntityFramework.dll to the cache: Strong name cannot be verified for delay-signed assembly"

Then you need to manually sign the assembly:
mono/mini/mono mcs/class/lib/build/sn.exe -R mcs/class/lib/net_4_5/EntityFramework.dll mcs/class/mono.snk

Run "make install" again, and finally test:

> /opt/mono-3.2.3/bin/mono --version
Mono JIT compiler version 3.2.3 (tarball Thr Nov 21 10:05:16 CET 2013)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors.
        TLS:           __thread
        SIGSEGV:       normal
        Notifications: epoll
        Architecture:  armel,vfp+fallback
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

Happy building :)

Saturday, March 24, 2012

Mono 2.11 binary build for Synology 2.11

I have put up a build of Mono 2.11 for Synology DS211, so you can install it without compiling everything yourself. Simply download the archive and then run this:

tar -xvf mono-synology-ds211-2.11.tar.bz2
cp -R opt/mono-2.11 /opt/mono-2.11
Or use the one-line version:

tar -C / -xvf mono-synology-ds211-2.11.tar.bz2

This will install everything in /opt/mono-2.11, you can set up symlinks like this:

ln -s /opt/mono-2.11/bin/mono /opt/bin/mono
ln -s /opt/mono-2.11/bin/mcs /opt/bin/mcs
ln -s /opt/mono-2.11/bin/gmcs /opt/bin/gmcs

I have also put up a build of Mono 2.10.9 for Synology DS211, in case Mono 2.11 turns out to be too alpha. You can have both installed at the same time, just change the symlinks to fit.

Friday, March 23, 2012

Mono on Synology NAS DS 211

Updated 2014-01-21: 
There is a repository with pre-built synology packages (including Mono), which might save you some hassle.

There used to be a Mono package for Synology, using the ipkg system. But it was old (Mono 2.4), and it seems to have disappeared. I have a lot of Mono/.Netstuff that I want to run on my NAS box, especially Duplicati for backups.

If you download the source and build the latest Mono, you get strange errors. Hopefully this guide will help you building Mono on your Synology DS. I have tested with DSM 3.1 and DSM 4.0 and both build fine and appear to run as expected.

First of, you need the Synology ipkg system set up. Once this is installed, you can pull some tools to build it. You will need at least make, automake, autoconf, bison, glib, libc-dev, libstdc++, m4, gcc, gawk, textutils, gettext, zlib. You need gawk and textutils to run the configure script. I use wget to download the Mono sources, and nano to edit the makefiles, so install those too.

Type this to get all the packages:
sudo ipkg install wget nano make automake autoconf bison \
glib libc-dev libstdc++ m4 gcc gawk textutils gettext zlib

Then download Mono sources:

wget ""

And extract:

tar -xf mono-2.11.0.tar.bz2

Then configure:

cd mono-2.11
./configure --prefix=/opt/mono-2.11
The --prefix will setup the build to put stuff into /opt/mono-2.11 rather than /usr. If you use just /opt, you will have a hard time uninstalling Mono later should you want to.

Now you should be ready to build it, but there is some weirdness with default includes, so edit the following files:


In all files, look for the line:


Add the -lrt flags so the line becomes:

LDFLAGS = -lrt 

If you already have flags on that line, just add the -lrt option to the end, and keep all the other stuff. This fixes problems with "undefined reference to clock_gettime" and also includes the pthreads library.

Now the pthreads library provided by ipkg is a bit broken, so you need to use the normal pthreads library for the build. Simply do this:
mkdir /opt/arm-none-linux-gnueabi/lib_disabled
mv /opt/arm-none-linux-gnueabi/lib/libpthread* /opt/arm-none-linux-gnueabi/lib_disabled
cp /lib/ /opt/arm-none-linux-gnueabi/lib/
ln -s /opt/arm-none-linux-gnueabi/lib/ /opt/arm-none-linux-gnueabi/lib/
ln -s /opt/arm-none-linux-gnueabi/lib/ /opt/arm-none-linux-gnueabi/lib/

And that is it, now run:


This will take a few hours probably, so sit back and wait. I usually run this in a screen so network issues do not stop the build.

After the build has completed, you can install it into /opt/mono-2.11:

make install

To make life a little easier, add some symlinks:

ln -s /opt/mono-2.11/bin/mono /opt/bin/mono
ln -s /opt/mono-2.11/bin/mcs /opt/bin/mcs
ln -s /opt/mono-2.11/bin/gmcs /opt/bin/gmcs

And finally test it:

mono --version

Mono JIT compiler version 2.11 (tarball Fri Mar 23 15:12:18 CET 2012)
Copyright (C) 2002-2011 Novell, Inc, Xamarin Inc and Contributors.
TLS:           __thread
SIGSEGV:       normal
Notifications: epoll
Architecture:  armel,soft-float
Disabled:      none
Misc:          softdebug
LLVM:          supported, not enabled.
GC:            Included Boehm (with typed GC and Parallel Mark)

I have uploaded a complete build, so you can just use it without doing the long and boring build process.