Mono: Difference between revisions

From OLPC
Jump to navigation Jump to search
No edit summary
m (Reverted edits by 201.221.52.42 (Talk) to last revision by Mk8)
 
(12 intermediate revisions by 4 users not shown)
Line 9: Line 9:
To write an OLPC Mono activity, you need to prepare a .xo [[Bundle]] including all required libraries. This is necessary because the Mono runtime is not officially supported by the OS images.
To write an OLPC Mono activity, you need to prepare a .xo [[Bundle]] including all required libraries. This is necessary because the Mono runtime is not officially supported by the OS images.


If you use mono, you know that the compiler not traslate the source code to the assembly language, but in IL (Intermediate Language) that need a runtime to be run. Since you don't have the runtime installed on the XO, you need to create a mono bundle so all the runtime is packed in one executable.
If you use Mono, you know that the C# compiler does not traslate the source to machine code, but to an IL (Intermediate Language) that requires a runtime to be executed. Since you don't have the runtime installed on the XO, you need to create a Mono bundle so the runtime is packed with the executable.


To do this you need to have the program already in binary format and use the mkbundle2 utility to create the stand-alone application.
To do this, you need to have the program already in binary format and use the mkbundle2 utility to create the stand-alone application.


mkbundle2 --config /etc/mono/config --deps --static -o MonkeysMemory.exe monkeysmemory.exe Sugar_0.0.1.dll NDesk.DBus.GLib.dll NDesk.DBus.dll
mkbundle2 --config /etc/mono/config --deps --static -o MonkeysMemory.exe monkeysmemory.exe


In this example "monkeysmemory.exe" is the original binary file that use the IL (Intermediate Language), while "MonkeysMemory.exe" is the binary file that can be run without runtime installed.
In this example "monkeysmemory.exe" is the original IL binary file, while "MonkeysMemory.exe" is the binary file that can be run without runtime installed.


Normally the use of --static flag have some licence restriction, but here can be use without limitation.
Normally, --static flag means that LGPL code is linked statically with your application.
A special exception is made for OLPC users where the LGPL restrictions does not apply when you create activities.


In your bundle you need to put some glue shared library that are used by Mono runtime like this:
In your bundle you need to put some glue shared libraries that are used by the Mono runtime like this:


* libgdksharpglue-2.so
* libgdksharpglue-2.so
Line 29: Line 30:
* uiX11Util.so
* uiX11Util.so


All this files (except uiX11Util.so) are taken from mono environment. The latest (uiX11Util.so) is specific for OLPC and allow to setup some X11 parameter need to sugar interface.
All these files (except uiX11Util.so) are taken from mono environment. The last one (uiX11Util.so) is
OLPC specific and allows to setup some X11 atoms needed by the Sugar interface.
This files are placed in the bin directory of the activity.
These files are placed in the bin directory of the activity.


=How to run a Mono activity=
=How to run a Mono activity=
I suppose that you are able to install an activity on the OLPC, but how to create a standard activity bundle?
You can find [http://mk8.codewiz.org/wiki/MonkeysMemory-3.xo a sample activity] written using Mono.
You can find all documentation you need about the contents of a XO Bundle file [[Bundle]] but here give a look inside the activity luncher script.


This example of activity launcher is taken from the e-toys launcher with some little adjustment and is placed in bin directory.
=Interface with the native subsystem=
The name of this script is specify in the ''activity-info'' file:


#!/bin/sh
== Create new application ==
# Author: Torello Querci
# Original Author: Bert Freudenberg
# Purpose: Run binary application. In this case Monkey's Memory
#
# This version of etoys-activity is called only under new Sugar
# (Joyride/Update.1). There is another one in the bundle's root
# directory called under old Sugar which was pre-installed on the
# first mass-produced machines (Trial-3/Ship.1).
echo "$0" "$@"
echo
# arguments are unordered, have to loop
args=""
while [ -n "$2" ] ; do
case "$1" in
-b | --bundle-id) bundle_id="$2" ; args="$args BUNDLE_ID $2" ;;
-a | --activity-id) activity_id="$2" ; args="$args ACTIVITY_ID $2";;
-o | --object-id) object_id="$2" ; args="$args OBJECT_ID $2";;
-u | --uri) uri="$2" ; args="$args URI $2";;
*) echo unknown argument $1 $2 ;;
esac
shift;shift
done
# really need bundle id and activity id
if [ -z "$bundle_id" -o -z "$activity_id" ] ; then
echo ERROR: bundle-id and activity-id arguments required
echo Aborting
exit 1
fi
# some debug output
echo launching $bundle_id instance $activity_id
[ -n "$object_id" ] && echo with journal obj $object_id
[ -n "$uri" ] && echo loading uri $uri
echo
export SUGAR_BUNDLE_PATH=`dirname $0`
export PATH=$SUGAR_BUNDLE_PATH:$PATH
cd $SUGAR_BUNDLE_PATH/..
export LD_LIBRARY_PATH=$SUGAR_BUNDLE_PATH:$LD_LIBRARY_PATH
# Try to setup the SHARED_DIR
export MONO_SHARED_DIR=$TMPDIR
# now run the application
exec MonkeysMemory.exe \
-sugarBundleId $bundle_id \
-sugarActivityId $activity_id \
$args < /dev/null > /dev/null


If you look inside the code script you can find some specific instruction:
== Sugarize existing application ==
* the home directory is changed from the internal bin directory to the parent one. This is not mandatory but is useful for me;
* it is setup the LD_LIBRARY_PATH environment variable. This is needed because the application need to find the specific shared object;
* it is setup the MONO_SHARED_DIR non-system environment variable. This is needed because Mono normally use a special shared internal repository to track the state of mutex across multiple process and this repository is written on /tmp. Since the normal /tmp directory is not writeble from the application in the OLPC security schema, is necessary to change the default path used to store this repository.


Obviously MonkeysMemory.exe is a sample activity name and is not necessary that the application have the .exe suffix because is e normal linux application.
More documentation will be released as soon as possible.


'''Note: the script is changed from previous version because Rainbow isolation subsystem now not create for the process the the stdin and stdout handles. This is not compatibile with some version of mono runtime.'''


= Interfacing with the native subsystem =

== Creating a new application ==

To create a sugarized application with Mono you can use the Sugar.Window class in place of the common Gtk.Window.
This class inherits from Gtk.Window and adds all the code necessary to integrate with Sugar's activity interface.
The constructor of this class expects two parameters that were passed by the startup script. Therefore, your Main function needs to parse its command-line arguments to isolate:
* activityId
* bundleId
The Sugar.Window class adds a new event, '''SetActiveEvent''', generated when Sugar switches between zoom levels.

== Sugarizing an existing application ==

TODO

= Example Activity written in Mono =

You can find [http://mk8.codewiz.org/olpc/MonkeysMemory-13.xo a sample activity] written using Mono. [[MonkeysMemory | Here]] you can find the specific page about this activity.

= Assembly dependency =
To write or migrate your application to OLPC activity you need to use a specific assembly that manager the DBus event and the X property needed to Sugar environment. This assembly use the NDesk.DBus one to manage the DBus message. You can find the NDesk.DBus assembly in your distribution or from the source [http://www.ndesk.org/DBusSharp here].

The source code of sugar assembly can be found [http://mk8.codewiz.org/wiki/sugar-0.1.tgz here].

Latest revision as of 20:54, 6 February 2015

This article is a stub. You can help the OLPC project by expanding it.

Sugar activities are usually written in Python using the Python Activity API. This page documents how it is possible to use Mono to write a Sugar activity. With Mono, you can use any underlying language like C# or Boo.

Overview

XO Bundle and Mono Bundle

To write an OLPC Mono activity, you need to prepare a .xo Bundle including all required libraries. This is necessary because the Mono runtime is not officially supported by the OS images.

If you use Mono, you know that the C# compiler does not traslate the source to machine code, but to an IL (Intermediate Language) that requires a runtime to be executed. Since you don't have the runtime installed on the XO, you need to create a Mono bundle so the runtime is packed with the executable.

To do this, you need to have the program already in binary format and use the mkbundle2 utility to create the stand-alone application.

mkbundle2 --config /etc/mono/config --deps --static -o MonkeysMemory.exe monkeysmemory.exe

In this example "monkeysmemory.exe" is the original IL binary file, while "MonkeysMemory.exe" is the binary file that can be run without runtime installed.

Normally, --static flag means that LGPL code is linked statically with your application. A special exception is made for OLPC users where the LGPL restrictions does not apply when you create activities.

In your bundle you need to put some glue shared libraries that are used by the Mono runtime like this:

  • libgdksharpglue-2.so
  • libgladesharpglue-2.so
  • libglibsharpglue-2.so
  • libgtksharpglue-2.so
  • libMonoPosixHelper.so
  • libpangosharpglue-2.so
  • uiX11Util.so

All these files (except uiX11Util.so) are taken from mono environment. The last one (uiX11Util.so) is OLPC specific and allows to setup some X11 atoms needed by the Sugar interface. These files are placed in the bin directory of the activity.

How to run a Mono activity

I suppose that you are able to install an activity on the OLPC, but how to create a standard activity bundle? You can find all documentation you need about the contents of a XO Bundle file Bundle but here give a look inside the activity luncher script.

This example of activity launcher is taken from the e-toys launcher with some little adjustment and is placed in bin directory. The name of this script is specify in the activity-info file:

#!/bin/sh
# Author: Torello Querci
# Original Author: Bert Freudenberg
# Purpose: Run binary application. In this case Monkey's Memory
#
# This version of etoys-activity is called only under new Sugar
# (Joyride/Update.1). There is another one in the bundle's root
# directory called under old Sugar which was pre-installed on the
# first mass-produced machines (Trial-3/Ship.1).
echo "$0" "$@"
echo

# arguments are unordered, have to loop
args=""
while [ -n "$2" ] ; do
    case "$1" in
        -b | --bundle-id)   bundle_id="$2"   ; args="$args BUNDLE_ID $2" ;;
        -a | --activity-id) activity_id="$2" ; args="$args ACTIVITY_ID $2";;
        -o | --object-id)   object_id="$2"   ; args="$args OBJECT_ID $2";;
        -u | --uri)         uri="$2"         ; args="$args URI $2";;
        *) echo unknown argument $1 $2 ;;
    esac
    shift;shift
done

# really need bundle id and activity id
if [ -z "$bundle_id" -o -z "$activity_id" ] ; then
  echo ERROR: bundle-id and activity-id arguments required
  echo Aborting
  exit 1
fi

# some debug output
echo launching $bundle_id instance $activity_id
[ -n "$object_id"   ] && echo with journal obj $object_id
[ -n "$uri"         ] && echo loading uri $uri
echo

export SUGAR_BUNDLE_PATH=`dirname $0`
export PATH=$SUGAR_BUNDLE_PATH:$PATH

cd $SUGAR_BUNDLE_PATH/..
export LD_LIBRARY_PATH=$SUGAR_BUNDLE_PATH:$LD_LIBRARY_PATH

# Try to setup the SHARED_DIR
export MONO_SHARED_DIR=$TMPDIR

# now run the application
exec MonkeysMemory.exe \
    -sugarBundleId $bundle_id \
    -sugarActivityId $activity_id \
    $args < /dev/null > /dev/null

If you look inside the code script you can find some specific instruction:

  • the home directory is changed from the internal bin directory to the parent one. This is not mandatory but is useful for me;
  • it is setup the LD_LIBRARY_PATH environment variable. This is needed because the application need to find the specific shared object;
  • it is setup the MONO_SHARED_DIR non-system environment variable. This is needed because Mono normally use a special shared internal repository to track the state of mutex across multiple process and this repository is written on /tmp. Since the normal /tmp directory is not writeble from the application in the OLPC security schema, is necessary to change the default path used to store this repository.

Obviously MonkeysMemory.exe is a sample activity name and is not necessary that the application have the .exe suffix because is e normal linux application.


Note: the script is changed from previous version because Rainbow isolation subsystem now not create for the process the the stdin and stdout handles. This is not compatibile with some version of mono runtime.


Interfacing with the native subsystem

Creating a new application

To create a sugarized application with Mono you can use the Sugar.Window class in place of the common Gtk.Window. This class inherits from Gtk.Window and adds all the code necessary to integrate with Sugar's activity interface. The constructor of this class expects two parameters that were passed by the startup script. Therefore, your Main function needs to parse its command-line arguments to isolate:

  • activityId
  • bundleId

The Sugar.Window class adds a new event, SetActiveEvent, generated when Sugar switches between zoom levels.

Sugarizing an existing application

TODO

Example Activity written in Mono

You can find a sample activity written using Mono. Here you can find the specific page about this activity.

Assembly dependency

To write or migrate your application to OLPC activity you need to use a specific assembly that manager the DBus event and the X property needed to Sugar environment. This assembly use the NDesk.DBus one to manage the DBus message. You can find the NDesk.DBus assembly in your distribution or from the source here.

The source code of sugar assembly can be found here.