GCC - How to statically link a static mono package

I have a .NET application that I want to connect to an ARM7 based embedded system. The target is a locked system running Busybox and I have no write access to the / lib directory (which is btw empty). However, I do have write access to a separate mount point with enough space for my application.

My idea is to compile a static application on a device with the same architecture and copy the binary to the target device. I am using Beaglebone black to compile.

How can I compile a .NET application into a 100% statically linked binary copy?

I am aware of the licensing restrictions for Mono (I have a commercial license).

To keep it simple, my application looks like this.

/// hello.cs

using System;
internal class Program
{
    private static void Main()
    {
        Console.WriteLine("hello");
    }
}

      

Step 1: Compile the cs code

$ mcs hello.cs

      

Step 2: Bundle compiled binary with Mono and output to c code

$  mkbundle -c -o hello.c -oo bundles.o --deps hello.exe --static

OS is: Linux
Note that statically linking the LGPL Mono runtime has more licensing restrictions than    
dynamically linking.
See http://www.mono-project.com/Licensing for details on licensing.
Sources: 1 Auto-dependencies: True
   embedding: /root/csharp/hello.exe
   embedding: /usr/local/lib/mono/4.5/mscorlib.dll
Compiling:
as -o bundles.o temp.s

      

Step 3: Compile the resulting c code

cc -o hello -Wall `pkg-config --cflags mono-2` hello.c bundles.o  `pkg-   
config --libs-only-L mono-2` -Wl,-Bstatic -lmono-2.0 ./Lib2/libm.a ./Lib2/librt.a ./Lib2/libdl.a 
./Lib2/libpthread.a ./Lib2/libgcc.a ./Lib2/libc.a -Wl,-Bdynamic ./Lib2/ld-linux-armhf.so.3

***** Warning message receieved (example):

/media/mono-3.10.0/mono/io-layer/sockets.c:992: warning: Using 'gethostbyname' in statically   
linked applications requires at runtime the shared libraries from the glibc version used for 
linking

      

Step 4: check dependencies

$ ldd hello
    /lib/ld-linux-armhf.so.3 (0xb6f92000)
    libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6f5e000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e7f000)

      

At this point, the application is running on my development system, but not on the target system. I am guessing due to missing libraries as the error message I receive is not supported by the File. How do I link the remaining libraries statically?

As an experiment, I tried a similar approach with my own C application

/// hello.c
#include <stdio.h>
int main()
{
   printf("hello\n");
   return 0;
}

      

Step 1: Compile with Dynamic Links

$ cc hello.c -o hello

      

Step 2: check dependencies

$ ldd hello
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e26000)
    /lib/ld-linux-armhf.so.3 (0xb6f14000)

      

As expected, this application does not work on the target system.

Step 3. Compilation with static links

$ cc hello.c -o hello -static

      

Step 4: check dependencies

$ ldd hello
   not a dynamic executable

      

This application works on my target system.

I am new to Linux systems in general and have been trying for hours to find a solution. I'm a little worried that I'm not even sure if this is solvable :). Any help would be much appreciated!

Note. If it is not possible to link all the libraries statically (for whatever reason), a solution where they are placed in the same folder as the main application will be completely acceptable. In a scenario like this, how would I re-link the libraries to. /?

+3


source to share





All Articles