One of the changes done in the last MonoDevelop release is that now MD depends on GTK# 2.8. In previous versions the dependency was GTK# 2.4. We decided to do this upgrade because 2.4 is now a few years old, and 2.8 is nowadays present in most distributions (at least those used by developers).
One of the problems of depending on GTK# 2.8 is that the applications built by MD will work only in system with GTK# 2.8. That's because it is not possible to install two different versions of GTK# at the same time, so if we require 2.8 to run MD, apps will need to be linked against 2.8. And if an application is built with GTK# 2.8 it won't run on a system with GTK# 2.4 (notice that it will run on a system with GTK# 2.10, because GTK# installs some GAC policy files which redirect old GTK# versions to new versions).
This is an important limitation, so I started looking for a solution.
The first I'm doing is to add support for multiple GTK# versions in Stetic (the GUI designer). The idea is that when you create a project you can select the GTK# version you want to target. The widget palette and the properties window will be filled according to the selected version, so if you select 2.4, widgets or properties introduced in newer versions won't be shown. No big deal to implement.
The real problem to solve is how to allow building applications against GTK# 2.4, even if what is installed is GTK# 2.8. The solution to this problem is simple: even if GTK# 2.4 is not installed, we can have the GTK# 2.4 assemblies copied somewhere, and when building the application link against those assemblies. It doesn't need to be a full 2.4 installation, since we only need the assemblies to compile the application. Once linked to 2.4, the application will happily run on top of the installed GTK# 2.8, thanks to the policy files.
That's what I did. MD now has an extension point which can be used by add-ins to register new assemblies, and those assemblies will be shown in the reference selection dialog. So, I can create an add-in called "GTK# 2.4 compilation support" or something like this, and after installing it the user will be able to select gtk-sharp 2.4 assemblies in the references dialog.
However, this solution doesn't work. Or, it is not so easy to make it work.
When you use "mcs -r:/path/to/my/gtk-sharp.dll myapp.cs" to compile an application, mcs will correctly load gtk-sharp.dll from the specified location, but when trying to load the assemblies on which gtk-sharp depends, e.g. gdk-sharp, it will load them from the GAC, since it will be applying the assembly binding policies which translates 2.4 version requests to 2.8 versions. The result is a compilation failure with some weird casting errors. Explicitly referencing all gtk-sharp dependencies as "-r" references also doesn't work. The assembly loader seems to always apply the binding policies.
I finally found a solution for this problem, although I'm not very happy with it. The idea is to create a private GAC for MD, and install there the GTK# 2.4 assemblies. The compiler would be run using the MONO_GAC_PREFIX env var for pointing to that private GAC, so the compiler will try to load assemblies from this private GAC and will fallback to the main GAC when not found. This solution works, but it needs an additional hack. For some reason Mono is applying the assembly binding policies before looking at the private GAC. I'm not sure if that's a Mono bug or it is supposed to work in this way. To overcome this problem I had to add dummy assembly binding policies to the private GAC which bind 2.4 versions to 2.4.
Nothing of this is yet committed, since I want to do some more tests to make sure I'm not missing a more obvious and easy solutions. So, ideas are welcome :).
Subscribe to:
Post Comments (Atom)
9 comments:
One possible hack can be to specify assembly with non-existent path and then use -lib:path as fall-back to locate correct one.
As a MonoDeveloper user and ISV wannabe I'd say: commit the code and worry about making the solution perfect later.
You see, if you commit your changes now you can alleviate the pain for those who develop commercial applications and want/need to support older versions of the GTK stack while still wanting to be able to use the latest MonoDevelop and take advantage of the great stuff you guys implement version after version, commit after commit.
Thanks for taking care of this!
Mike Kestner had some good thoughts on this. From his email:
If you are looking to allow development against multiple versions, maybe
we could come up with an "sdk" package for 2.8 that would allow
compilation against 2.8 without actually installing anything into the
gac. It would need some additional make magic in gtk-sharp to install
the assemblies into a "pkg" dir instead of creating links there into the
gac with gacutil. The .pc file could be munged for the install-sdk
target to make it parallel-installable. Something like
gtk-sharp-sdk-2.8.pc perhaps.
With the above approach you could compile against 2.8 assemblies, and
run against the policy assemblies that 2.10 would install in the gac,
Wade, that's more or less what I'm trying to do in MD. However, the assembly loading problem I describe in my blog post also would apply to the "sdk" assemblies. When trying to compile with the 2.8 assemblies, MD will load referenced assemblies from the gac.
Lluis,
I'm starting to work with mono under Monodevelop. I have 1 suggestion:
- Stetic can declare the widgets in the Code order to return to the code editor and the widgets are ready to use.
And 1 question:
- How can I build my own widgets to use under Stetic, avoiding to hard code?
Thanks in advance.
Hi, I'm trying to develop a cross platform application on debian unstable which by default has GTK# 2.12.1-1 installed along with all associated libraries of the same version. The trouble for me is that I want it to run on windows where the latest installer is GTK# 2.8.3. Earlier today I installed older versions of GDK from .debs with dpkg -i directly, and built the app and it ran happily on windows. However monodev wouldn't run on the older version and other issues popped up. Does anyone know of a simple way to reference the correct versions directly with an option to MCS if I keep local copies of the older dlls? I tried -r:filename.dll and it seems to work for gtk-sharp and glade-sharp, but NOT for gdk-sharp which I need. The error I get is "error CS0029: Cannot implicitly convert type `Gdk.Pixbuf' to `Gdk.Pixbuf'" followed by "The type `Gdk.Pixbuf' has two conflicting definitions, one comes from `gdk-sharp, Version=2.8.0.0, [snip] and the other from `gdk-sharp, Version=2.12.0.0 [snip]". I've tried a few things to stop it from finding the installed versions, but no luck so far. Any help much appreciated, including being told I'm asking this in the wrong place ;-) Thanks, Fred.
I have a similar issue, I have only one choice for gtk on my target device, the nokia n770 that I am tapping this message with. I have gtk-sharp 2.4.3-2 on the maemo platform, and only have access to 2.8 on my build box / wxp .net 2008 express. Its a work machine so no linux available, also I could not find any gtk 2.4 gtk assembly for windows. Any ideas?
牙醫,植牙,矯正,紋身,刺青,創業,批發,皮膚科,痘痘,中醫,飛梭雷射,毛孔粗大,醫學美容,seo,關鍵字行銷,關鍵字、自然排序,網路行銷,關鍵字、自然排序,關鍵字行銷、seo,關鍵字廣告,部落格行銷,網路行銷,seo,關鍵字行銷,關鍵字廣告,關鍵字,自然排序,部落格行銷,網路行銷,網路爆紅,牛舌餅,婚紗,台中婚紗,腳臭,腳臭,腳臭,腳臭,腳臭,腳臭,腳臭,中古車,二手車,中古車,二手車,高雄婚紗,搬家,搬家公司,服飾批發,團體服,街舞,融資,借貸,借錢,小產,雞精。
I had the same issue, try to disable all addons for binding other versions of gtk, and try if it works with the version nativly shipped with mono(develop). It works for me, and maybe would be a starting poin in your research. Peace.
Post a Comment