Sunday, 27 January 2013

Umbraco 4.11.3 on mono update

Umbraco 4.11.3 now compiles

Umbraco 4.11.3 now compiles in the Monodevelop IDE under mono 3.x. Thanks to the work of the Umbraco HQ team, the changes required were actually quite small: a few casing changes, increasing .NET to 4.5 so that we can use native mono MVC 3, and a few small idiosyncrasies.

Details here:

Saturday, 5 January 2013

Umbraco 4.11.x mono port kicks off

I have had a start on the Umbraco 4.11.x port to mono

4.11.x introduces MVC type views, and can be seen as a stepping stone to Umbraco 6

With the addition of MVC, my quick impression at this point is that mono & monodevelop are not yet quite ready to handle the port "out of the box." Yet, I think we will be able to make a port, but I think it will initially be a bumpy ride.

A number of porting avenues are available

  1. Use Visual Studio & mono windows and mono tools

  2. Use native (e.g. Linux) mono & tools but with the Umbraco supplied MVC and related dlls

  3. Develop on a fully native platform, and use the open sourced stack that is now also used by mono

1. is probably the easiest way to get started. Especially, if the code is placed on a Linux VM, and shared into the windows host - this will also provide "casing" checks, and can be easily tested in two environments. On the downside, it requires a Windows and VS license (especially if you wanted to use Resharper etc.)

2. is a middle of the road approach. It might side-step the following issue: in mono, MVC 3 is only available for .NET 4.5 and above. But a downside is that, if there are any exceptions originating in the MS dll's we will not be able to debug through these.

3. is the hardest option. It will require immediate changes to all solution projects so that they are incremented to .NET 4.5. At present, there is an annoying bug in the monodevelop IDE and projects referencing MVC3 need to be re-referenced every time the solution is re-loaded.

For people looking to get their hands dirty, I would recommend option 1. Personally, however, I have been using option 3 - mainly because I am interested in developing a platform independent development environment - i.e. one that does not require ownership of a windows / VS license.

Some gottchas for option 3

  • If you are compiling mono (and you will be...), at present you need to use automake version < 1.13 so that you still have support for "Cygnus style trees."

  • You will need to set up a parallel mono development environment

  • Compiling monodevelop is not easy at all. Here's what I have been doing:

    cd monodevelop
    find -name '*.csproj' -print -exec sed -i.bak 's/False<\/SpecificVersion>/True<\/SpecificVersion>/g' {} \;
    #find -name '*.csproj' -print -exec sed -i.bak 's/Net_2_0/Net_4_0/g' {} \;
    ./configure --prefix=/opt/mono
    sudo make install
    #switch to mono 3 environment
    (batch file to set environment variables)
    sudo make install

    #this also seems to work
    #find -name '*.csproj' -print -exec sed -i.bak 's/False<\/SpecificVersion>//g' {} \;

  • With this approach, the Microsoft, "xdt:" config file transforms do not work, and I am looking for an alternative.

  • the manual build targets need to be re-written to account for mono's limited implementation of msbuild.

Snapshots are available here, but unless tagged they are not considered to be working: umbraco-mono on git, umbraco-mono on codeplex

Mono parallel environment set-up example

$ cat mono_dev-env
export LD_LIBRARY_PATH=$MONO_PREFIX/lib:usr/lib
export C_INCLUDE_PATH=$MONO_PREFIX/include:/usr/include
export ACLOCAL_PATH=$MONO_PREFIX/share/aclocal:/usr/share/aclocal
export PKG_CONFIG_PATH=$MONO_PREFIX/lib/pkgconfig:/usr/lib/pkgconfig
PS1="[mono] \w @ "

script for resetting to regular mono development environment

$ pwd
$ cat

#unset parallel mono environment
export DYLD_LIBRARY_FALLBACK_PATH=`echo ${DYLD_LIBRARY_FALLBACK_PATH} | awk -v RS=: -v ORS=: '/opt/ {next} {print}' | sed 's/:*$//'`
export LD_LIBRARY_PATH=`echo ${LD_LIBRARY_PATH} | awk -v RS=: -v ORS=: '/opt/ {next} {print}' | sed 's/:*$//'`
export C_INCLUDE_PATH=`echo ${C_INCLUDE_PATH} | awk -v RS=: -v ORS=: '/opt/ {next} {print}' | sed 's/:*$//'`
export ACLOCAL_PATH=`echo ${ACLOCAL_PATH} | awk -v RS=: -v ORS=: '/opt/ {next} {print}' | sed 's/:*$//'`
export PKG_CONFIG_PATH=`echo ${PKG_CONFIG_PATH} | awk -v RS=: -v ORS=: '/opt/ {next} {print}' | sed 's/:*$//'`
export PATH=`echo ${PATH} | awk -v RS=: -v ORS=: '/opt/ {next} {print}' | sed 's/:*$//'`