1. Today I spent some time learning about Maven. I got some comments about my library repository idea, and several of them suggested taking a look at Maven.

    Maven is basically a pluggable development environment (not to mistake it for an IDE). It defines a project model, a project development life cycle, and a model for extending both the project model and the process using plug-ins. Maven is able to automatically download all required dependencies of a project, including compilers, libraries or whatever is necessary to build a project.

    Would it be good to have this kind of environment for Mono? I think so, and I have several reasons:
    • It greatly simplifies the work of developers. The development tools we are using for Mono were not really designed for modern managed platforms. For example, resolving the needed library and tool dependencies should be much more simple, just for the "simple" fact that Mono binaries are portable.
    • It allows offering development tools which are more consistent and integrated. For example, if I install "Boo" (the language), it might provide the Boo compiler (for compiling Boo projects), the Boo runtime (so projects build with Boo can distribute it), a Boo CodeDom provider (so code generators like wsdl or stetic can generate Boo classes), a graphical Boo compiler options editor (so I can change the options of a Boo project in an IDE) and MonoDoc documentation. All that are extensions to the development environment, and all the tools can use them.
    • It improves reusability by making it easy to share libraries and tools.
    I've been thinking about this idea for quite a long time now, and some of the work I've done in the past years has been in this direction. When working on MonoDevelop, I always had in mind that we were building a development platform, not just and IDE. That's why one of the first things I did in the project was doing a complete reorganization of the assemblies, which had as a result a well defined Project Object Model (implemented in MonoDevelop.Projects). I spent half of the time making the project model independent from the GUI, and the other half improving the add-in engine to better support complex add-in relations.

    However, the MonoDevelop add-in engine, even if improved, had important limitations. It wasn't really suitable for a large add-in ecosystem. I took into account those limitations when I designed Mono.Addins, and this new add-in engine is more scalable and ready to be used in a more global and generic add-in space.

    Does it mean that we are ready to create a "Maven" for Mono? To some extent, yes. The infrastructure I'm going to implement to support the library management system may be the foundation over which to build it (well, in fact Mono.Addins already provides most of the needed infrastructure). Once we have the basic infrastructure in place, we can make it organically grow by adding more extension points. At some point maybe we'll extract the Project Model from MonoDevelop, make it more generic, and move it to the development foundation. But that's long term, maybe a goal for MD 2.0.
    8

    View comments

  2. So, this week is a Hack Week at Novell, and we are free to choose what we want to hack on. I had several ideas in mind for this week, but I finally decided to work on something that might be completed in one week, and that will be really useful for the Mono community: a repository for sharing Mono libraries.

    Well, the idea is not building the repository itself, but all the needed infrastructure to make it easy to share libraries, that is, something like Ruby Gems. So, I'm going to create a set of tools which will allow searching for libraries, downloading and installing, and referencing them from projects. I'm also going to define a way of publishing libraries, and I'll eventually create a real repository in some server where we can start adding some libraries.

    Scope of the Project

    So, first of all let's state the scope of this project:
    • This is going to be a library packaging and distribution system designed for development only. That is, I'm not trying to compete with existing packaging systems. You'll be able to more or less automatically download libraries from the repository, but when building a package for distribution, the package will have to either include the library binary, or have a dependency on a package that provides it.
    • Only fully managed libraries will be supported for now. In the future we may add support for libraries which need some C glue code by compiling them after downloading.
    • It will allow parallel installation of different versions of the same library.
    • It will support dependencies between libraries. So, when a library is requested, all libraries on which it depends will be downloaded/installed. Of course it will only work for libraries in the repository.
    Architecture

    My plan is to use Mono.Addins to implement this infrastructure. It may sound a bit strange to use add-ins for building a library management system, but if you think a bit about it you'll see that it makes perfect sense:
    • A library can be seen as an extension to the system. There will be an extension point where new libraries will be registered. An 'add-in' will be able to register one or several libraries.
    • Mono.Addins already provides a system for publishing, downloading and installing add-ins, including support for dependency check. We can share the same file formats and package management tools.
    • Such add-ins might include not only libraries, but also Monodoc documentation, support tools or other extensions. For example, we could publish a library which implements a Chart widget, and we might include a chart designer to be integrated in Stetic.
    Different ways of sharing a library

    There will be three different types of library packages:
    • Binary package: it will include the library compiled in an assembly. Projects will directly reference this library. At deploy time, the library will be copied together with the application using it.
    • Binary package with GAC install. Same as previous, but the library will be installed in the GAC. To run the project it won't be necessary to copy the library to the project directory (since it will be loaded from the GAC). At deploy time, the developer will be able to choose between packaging the library together with the application, or not packaging it and generating a package dependency instead (of course this last option only makes sense if a package providing the library is available).
    • Source package: I'm still unsure about this type of package. My idea is that it may be useful to be able to share some classes which are very common, but for which it is not worth to create a .DLL because they are too small. So projects would just include the source files in the project. However, it may also make sense to include the source files in binary packages, even if it's only for debugging purposes. Also, given the multi-language nature of .NET, source-only packages would too limited, since they would be useful only for projects using the same language.
    Integration in MonoDevelop

    My idea is to provide something like the add-in manager, but specialized to installing library packages. After installing a library package, all assemblies it provides would be shown in the references dialog. After adding an assembly reference to a project, if the assembly belongs to a package installed in the GAC, the user will be able to set or reset the 'local copy' flag.

    I'm still not sure if it would make sense to add an "Include Library as Source" command, which would include the source files of the library to the project.

    Integration in Visual Studio

    Why not? it would dramatically increase the number of potential libraries and users. Any volunteer?

    Command Line Tools

    There will be a command line tool for managing library packages, and for querying information about libraries. This should be some kind of replacement of pkg-config for Mono. It will be able to check if a library package is installed, and which assemblies does it provide.

    Configuration scripts might be able to use this tool to automatically download packages not installed in the system.

    Library Repository

    I don't plan to implement any server-side logic or service for publishing or browsing libraries. An on-line library repository will be a set of package files in a directory and an index file. We can easily generate a set of static html files for the repository and for each package, so that people can browse it and Google can index it.

    Looking for a Name!

    "Ruby Gems" sounds really cool. Any idea about how all this infrastructure could be named in Mono?

    Other more general comments and suggestions are also welcome :)
    36

    View comments

  3. 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 :).
    8

    View comments

  4. MonoDevelop 0.14 has been released today. Those suffering triskaidekaphobia will be specially happy about it.

    This release has quite a lot of new features and improvements, which are detailed in the release notes. It's worth trying the new packaging system (which simplifies the creation of packages for projects), the improved support for C# smart indent, or the new code refactory commands.

    This is also the first release which is based on the new Mono.Addins framework, and I hope I can now find more time to work on my add-in authoring add-in to take full advantage of it.

    So, what's next? There are several features we plan to work on for the next two releases: configurable key bindings, improved ASP.NET support, improved makefile integration, C/C++ projects support, debugger integration (the last two from Google SoC projects), and others. A lot of work to do, but I hope we can finish all this in the following three months and then do a code freeze for the long time due 1.0 release.
    2

    View comments

Blog Archive
About Me
About Me
My complete name is Lluis Sanchez Gual, and I work as a developer for Novell. I'm part of the Mono team, and I'm leading the MonoDevelop project, a very exciting open source IDE for GNOME.
Loading