Saturday, February 04, 2012

Nerd Food: Adventures in F# Land - Part 3

So the hackery continues. Before I go any further I'd like to say that none of the solutions on this series of blog posts are "real" solutions; you shouldn't really be hacking debs and installing them as root - at least not on your main box, at any rate. If you want to do any of this you should really fire off a VM - its really trivial these days what with Qemu and that. Hopefully when we get to the end of this we can submit some real patches to those in charge.

Warnings out of the way, we can now focus on fixing the problems we bumped into last time. Turns out the first one was actually quite straight forward. The error we were getting was:
Missing method .ctor in assembly /usr/lib/fsharp/FSharp.Core.dll, type System.Security.SecurityRulesAttribute
A quick google revealed that this is a symptom suffered by all of those who are silly enough to use a non 4.0 runtime with an application/assembly that requires it. As it happens, the mono guys renamed their compiler with the 4.0 upgrade; gmcs is no longer, long live dmcs. Hey, its a solution as good as any and it avoids confusion I guess. In fact, it appears this compiler-name-changing thing is rather common in mono-land because the F# AddIn guys even put in a configure option to pass in the compiler:
-c Path/name of the C# compiler executable or script
('mono' is NOT automatically added to the front)
Default value: gmcs
So all that was required to fix this problem is to pass in the correct compiler:
$ ./configure.sh -c dmcs
This took as to the next error, the infamous --resident:
error FS0243: Unrecognized option: '--resident'
Googling didn't help with this one, and if you recall, my grepping didn't either. It turns out the problem was with the wrapper scripts the deb offers us:

$ cat /usr/bin/fsharpc
#!/bin/sh
exec mono /usr/lib/fsharp/fsc.exe --resident "$@"

Since we're on a hacking mood, I just su'd to root and updated the contents of this file as follows (notice the runtime parameter being passed in to mono):
$ cat /usr/bin/fsharpc
#!/bin/sh
exec mono --runtime=v4.0 /usr/lib/fsharp/fsc.exe "$@"
With this, we got the F# compiler to actually do some compilation for us. It then moaned about a missing reference to Cairo, which we can easily fix:
diff --git a/Makefile.orig b/Makefile.orig
index a88a8a8..52caf12 100644
--- a/Makefile.orig
+++ b/Makefile.orig
@@ -57,6 +57,8 @@ FILES = \
src/FSharpResolverProvider.fs
REFERENCES = \
+ -r:$(MONOBIN)/Mono.Cairo.dll \
And now we get to the real error: unfortunately the MonoDevelop code has moved on - hey, we've upgraded from 2.4 to 2.10, _something_ had to change, right!

Microsoft (R) F# 2.0 Compiler build 4.0.30319.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

\home\marco\Development\fsharpbinding\src\PowerPack\CodeDomGenerator.fs(248,44): warning FS0044: This construct is deprecated

\home\marco\Development\fsharpbinding\src\Services\Common.fs(11,11): error FS0039: The namespace 'Addins' is not defined

\home\marco\Development\fsharpbinding\src\Services\Common.fs(381,39): error FS0039: The namespace or module 'AddinManager' is not defined

\home\marco\Development\fsharpbinding\src\Services\Common.fs(383,9): error FS0039: The namespace or module 'AddinManager' is not defined

\home\marco\Development\fsharpbinding\src\Services\Common.fs(397,39): error FS0039: The namespace or module 'AddinManager' is not defined

\home\marco\Development\fsharpbinding\src\Services\Common.fs(399,9): error FS0039: The namespace or module 'AddinManager' is not defined
make: *** [all] Error 1
So now we need to get our hands dirty and learn a bit about MonoDevelop's internals. But that's a matter for the next episode.

Update: It seems we're not the first trying to go down this route! Github has a really nice ticket detailing other interpid explorers going down this exact same route!


I'll parse the ticket and see where it will take us!

Nerd Food: Adventures in F# Land - Part 2

And so the adventures in F# continue. After some digging, I found out that the "sources" for F# are actually available on mercurial in CodePlex, as part of fsxplat. To obtain them, just clone as one would with git:
$ hg clone https://hg01.codeplex.com/fsxplat fsxplat
I say "sources" because there wasn't a lot of source code; its mainly the skeleton of a debian package, that uses a shell script to go away and download the F# binaries. The work is all done inside of make_package.sh and the binaries are available from Microsoft's download website; I even found an updated version here but decided against using it, in case the changes caused further problems.

To my great joy, perusing the zip file revealed a 4.0 build of the F# compiler. I made some surgical modifications to make package, as follows:
$ hg diff
diff -r 4d371abd932f make_package.sh
--- a/make_package.sh Sun Jan 01 22:39:08 2012 +0100
+++ b/make_package.sh Sat Feb 04 17:30:29 2012 +0000
@@ -7,13 +7,20 @@
mv FSharp-2.0.0.0/* fsharp
rmdir FSharp-2.0.0.0
rm fsharp.zip
+rm -rf fsharp/bin
+mv fsharp/v4.0/bin fsharp/bin
+mv fsharp/bin/Fsc.exe fsharp/bin/fsc.exe
+mv fsharp/bin/Fsi.exe fsharp/bin/fsi.exe
cd fsharp
# get Mono key and re-sign the F# dll
# this trick will be removed once the following bug is closed:
# https://bugzilla.novell.com/show_bug.cgi?id=615445
-wget http://anonsvn.mono-project.com/source/trunk/mcs/class/mono.snk
+wget https://github.com/mono/mono/blob/master/mcs/class/mono.snk?raw=true -O mono.snk
sn -q -R bin/FSharp.Core.dll mono.snk
+sn -q -R bin/FSharp.Compiler.Interactive.Settings.dll mono.snk
+sn -q -R bin/FSharp.Compiler.Server.Shared.dll mono.snk
+sn -q -R bin/FSharp.Compiler.dll mono.snk
rm mono.snk
# make the package
Nothing particularly exciting: we delete the existing bin directory and replace it with the one provided in 4.0; we also update the path to mono's SNK file, as the svn server appears to be down; finally, we sign a few more DLLs while we're at it. With these changes one can create a new debian package:
$ ./make_package.sh
We leave the script to perform its magic and eventually one ends up with a lovely deb: fsharp_2.0-1_all.deb. If, like me, you're more comfortable with the command line, you can easily install the package from there:
$ su
# gdebi fsharp_2.0-1_all.deb
Amazingly, it all installs without any problems! So now that we have a 4.0 build of F# we can return to the F# bindings. Unfortunately, we're not quite there yet:
$ make
mkdir -p bin
gmcs -debug+ -out:bin/FSharpBinding.Gui.dll -target:library -r:/usr/lib/mono/4.0/Mono.Posix.dll -r:/usr/lib/mono/4.0/mscorlib.dll -r:System.dll -r:System.Xml.dll -r:/usr/lib/monodevelop/bin/MonoDevelop.Core.dll -r:/usr/lib/monodevelop/bin/MonoDevelop.Ide.dll -r:/usr/lib/monodevelop/bin/Mono.TextEditor.dll -r:/usr/lib/fsharp/FSharp.Core.dll -r:/usr/lib/fsharp/FSharp.Compiler.dll -r:/usr/lib/fsharp/FSharp.Compiler.Interactive.Settings.dll -r:/usr/lib/fsharp/FSharp.Compiler.Server.Shared.dll -r:/usr/lib/cli/atk-sharp-2.0/atk-sharp.dll -r:/usr/lib/cli/pango-sharp-2.0/pango-sharp.dll -r:/usr/lib/cli/gtk-sharp-2.0/gtk-sharp.dll -r:/usr/lib/cli/gdk-sharp-2.0/gdk-sharp.dll -r:/usr/lib/cli/glib-sharp-2.0/glib-sharp.dll src/Gui/FSharpBuildOrderWidget.cs src/Gui/FSharpSettingsWidget.cs src/Gui/FSharpCompilerOptionsWidget.cs src/Gui/gtk-gui/FSharp.MonoDevelop.Gui.FSharpBuildOrderWidget.cs src/Gui/gtk-gui/FSharp.MonoDevelop.Gui.FSharpSettingsWidget.cs src/Gui/gtk-gui/FSharp.MonoDevelop.Gui.FSharpCompilerOptionsWidget.cs src/Gui/gtk-gui/generated.cs
Missing method .ctor in assembly /usr/lib/fsharp/FSharp.Core.dll, type System.Security.SecurityRulesAttribute
Can't find custom attr constructor image: /usr/lib/fsharp/FSharp.Core.dll mtoken: 0x0a000006
fsharpc --noframework --debug --optimize- --target:library -r:bin/FSharpBinding.Gui.dll --out:bin/FSharpBinding.dll -r:/usr/lib/mono/4.0/Mono.Posix.dll -r:/usr/lib/mono/4.0/mscorlib.dll -r:System.dll -r:System.Xml.dll -r:/usr/lib/monodevelop/bin/MonoDevelop.Core.dll -r:/usr/lib/monodevelop/bin/MonoDevelop.Ide.dll -r:/usr/lib/monodevelop/bin/Mono.TextEditor.dll -r:/usr/lib/fsharp/FSharp.Core.dll -r:/usr/lib/fsharp/FSharp.Compiler.dll -r:/usr/lib/fsharp/FSharp.Compiler.Interactive.Settings.dll -r:/usr/lib/fsharp/FSharp.Compiler.Server.Shared.dll -r:/usr/lib/cli/atk-sharp-2.0/atk-sharp.dll -r:/usr/lib/cli/pango-sharp-2.0/pango-sharp.dll -r:/usr/lib/cli/gtk-sharp-2.0/gtk-sharp.dll -r:/usr/lib/cli/gdk-sharp-2.0/gdk-sharp.dll -r:/usr/lib/cli/glib-sharp-2.0/glib-sharp.dll --resource:src/Resources/FSharpBinding.addin.xml --resource:src/Resources/EmptyFSharpSource.xft.xml --resource:src/Resources/EmptyFSharpScript.xft.xml --resource:src/Resources/FSharpConsoleProject.xpt.xml --resource:src/Resources/fsharp-icon-32.png --resource:src/Resources/fsharp-script-32.png --resource:src/Resources/fsharp-file-icon.png --resource:src/Resources/fsharp-project-icon.png --resource:src/Resources/fsharp-script-icon.png --resource:src/Resources/FSharpSyntaxMode.xml src/PowerPack/CodeDomVisitor.fs src/PowerPack/CodeDomGenerator.fs src/PowerPack/CodeProvider.fs src/PowerPack/LazyList.fsi src/PowerPack/LazyList.fs src/Services/Mailbox.fs src/Services/Parameters.fs src/Services/FSharpCompiler.fs src/Services/CompilerLocationUtils.fs src/Services/Common.fs src/Services/Parser.fs src/Services/LanguageService.fs src/Services/CompilerService.fs src/Services/InteractiveSession.fs src/FSharpInteractivePad.fs src/FSharpOptionsPanels.fs src/FSharpSyntaxMode.fs src/FSharpResourceIdBuilder.fs src/FSharpLanguageBinding.fs src/FSharpParser.fs src/FSharpTextEditorCompletion.fs src/FSharpResolverProvider.fs
Microsoft (R) F# 2.0 Compiler build 4.0.30319.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

error FS0243: Unrecognized option: '--resident'
make: *** [all] Error 1
So now we got two problems. The first one seems to be a dependency issue with F#'s core. The second one is even more worrying as it appears we are trying to use an invalid compiler option. Greping for resident on the AddIn sources didn't reveal who's attempting to use --resident, however.

Stay tuned for the next episode...



Nerd Food: Adventures in F# Land - Part 1

So me and the lads went to yet another event organised by SkillsMatters on F#. As usual the gurus were there, including Phil Trelford and Tomas Petricek, two very nice guys and fairly easy to approach. This time round they organised a kata around the pacman game, all in F#. Unfortunately, none of us was overly prepared and whilst I had my netbook on me, I didn't set it up with F# and associated tools. This was obviously a mistake as the kata was all about coding (duh!). So we spent a large amount of it trying to get F# going on Linux under pressure - not an experience that I'd recommend.

Now that the dust has settled, I thought I'd have a proper go. The key thing that triggered my attention was a massive update to my debian testing box this morning: nice and shiny mono 2.12 and MonoDevelop 2.10! These little babies target the 4.0 profile - none of that old stuff any more. Excellent news. So I got the dist-upgrade out of the way - fairly painlessly I might add, it just went straight through - fired off MonoDevelop and got myself to work (actually, in truth, the first thing I did was to setup F# mode in emacs, but I digress).

I started off by following Tomas instructions but noticed that things had moved on a bit since his video. For one, there are debs of F# in CodePlex these days: http://fsxplat.codeplex.com/releases/view/55463. I grabbed myself the deb - thinking it wouldn't really work on my 64-bit build, really - but it installed without any problems and even registered all the assemblies in the Gac. Nice one. Second step was to get the MonoDevelop AddIn working. Now this is were things didn't go so well. I dutifully went to Tools | AddIn Manager, Gallery, Clicked on the combo and selected Manage Repositories; I added their repo:


Which was immediately recognised and told me I had a language binding available for F#; but, alas, just as we neared the end of the adventure, it all went wrong. The AddIn was developed for MonoDevelop 2.4 and I'm now running 2.10. Joys of bleeding edge. But fear not! I found the source of the AddIn on GitHub, cloned it and started to get it to build with MonoDevelop 2.10!

git clone https://github.com/fsharp/fsharpbinding.git
I did a couple of tentative fixes:
$ git diff
diff --git a/Makefile.orig b/Makefile.orig
index a88a8a8..0234959 100644
--- a/Makefile.orig
+++ b/Makefile.orig
@@ -57,6 +57,7 @@ FILES = \
src/FSharpResolverProvider.fs
REFERENCES = \
+ -r:$(MONOBIN)/Mono.Posix.dll \
-r:$(MONOBIN)/mscorlib.dll \
-r:System.dll -r:System.Xml.dll \
-r:$(MDBIN)/MonoDevelop.Core.dll \
diff --git a/configure.sh b/configure.sh
index 06f06f5..94f33aa 100755
--- a/configure.sh
+++ b/configure.sh
@@ -83,12 +83,12 @@ searchpaths "MonoDevelop" bin/MonoDevelop.Core.dll PATHS[@]
MDDIR=$RESULT
echo "Successfully found MonoDevelop root directory." $MDDIR
-PATHS=( /usr/lib/fsharp /usr/local/lib/fsharp /opt/mono/lib/mono/2.0 )
+PATHS=( /usr/lib/fsharp /usr/local/lib/fsharp /opt/mono/lib/mono/4.0 )
searchpaths "F#" FSharp.Core.dll PATHS[@]
FSDIR=$RESULT
echo "Successfully found F# root directory." $FSDIR
-PATHS=( /usr/lib/mono/2.0 /Library/Frameworks/Mono.framework/Versions/2.8/lib/mono/2.0 /opt/mono/lib/mono/2.0 )
+PATHS=( /usr/lib/mono/4.0 /Library/Frameworks/Mono.framework/Versions/2.8/lib/mono/2.0 /opt/mono/lib/mono/4.0 )
searchpaths "Mono" mscorlib.dll PATHS[@]
MONODIR=$RESULT
echo "Successfully found Mono root directory." $MONODIR
But finally succumbed to the following error:
./Configure.sh
make
error FS0219: The referenced or default base CLI library 'mscorlib' is binary-incompatible with the referenced F# core library '/usr/lib/fsharp/FSharp.Core.dll'. Consider recompiling the library or making an explicit reference to a version of this library that matches the CLI version you are using.

error FS0218: Unable to read assembly '/usr/lib/fsharp/FSharp.Core.dll'
make: *** [all] Error 1
So it seems I need to get a 4.0 build of FSharp.Core. We'll continue on the next installment!