SharpDevelop Community

Get your problems solved!
Welcome to SharpDevelop Community Sign in | Join | Help
in Search

Matt Ward

October 2005 - Posts

  • Creating a Gtk# App with SharpDevelop 2.0 Using Glade

    The starting point is the Glade xml file.

    Glade xml file

    This was created using the Glade UI Builder that ships with the Mono installer. The xml file specifies the UI components and signals (events) for these components. In our case the main components we have are a mainWindow and a messageLabel. There is also a delete_event signal defined for the main window named MainWindowDeleteEvent.

    <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
    <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

    <glade-interface>

    <widget class="GtkWindow" id="mainWindow">
      <property name="visible">True</property>
      <property name="title" translatable="yes">Hello, Gtk# World</property>
      <property name="type">GTK_WINDOW_TOPLEVEL</property>
      <property name="window_position">GTK_WIN_POS_NONE</property>
      <property name="modal">False</property>
      <property name="default_width">300</property>
      <property name="default_height">300</property>
      <property name="resizable">True</property>
      <property name="destroy_with_parent">False</property>
      <property name="decorated">True</property>
      <property name="skip_taskbar_hint">False</property>
      <property name="skip_pager_hint">False</property>
      <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
      <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
      <signal name="delete_event" handler="MainWindowDeleteEvent" last_modification_time="Thu, 20 Oct 2005 13:24:07 GMT"/>

      <child>
        <widget class="GtkLabel" id="messageLabel">
          <property name="visible">True</property>
          <property name="label" translatable="yes">Message here...</property>
          <property name="use_underline">False</property>
          <property name="use_markup">False</property>
          <property name="justify">GTK_JUSTIFY_LEFT</property>
          <property name="wrap">False</property>
          <property name="selectable">False</property>
          <property name="xalign">0.5</property>
          <property name="yalign">0.5</property>
          <property name="xpad">0</property>
          <property name="ypad">0</property>
        </widget>
      </child>
    </widget>

    </glade-interface>

    Now we need to create a SharpDevelop project to add this Glade xml file to.

    Create a new empty project

    1. Select File | New | Solution to open the "New Project" dialog.
    2. Select the C# category and the "Empty Project" template. Enter in project name "HelloGtkWorld" and choose a location. Click the "Create" button to create your empty project.

    Remove all unwanted assembly references

    1. Select View | Projects to open up the project browser.
    2. Expand the tree so the assembly references are displayed. There should be two, System and System.Xml. Select one at a time, right click and select "Remove". Repeat until all references have been removed.

    Add a Glade xml file to the project

    1. Select the project tree node, right click and select Add | New Item... to open the "New File" dialog.
    2. Select the Misc category and the "Empty XML file" template. Type in the name "glade.xml" and click the "Create" button.
    3. Modify the glade.xml file so it contains the xml shown above.
    4. Embed this xml file as a resource. Select the file in the Project Browser. Select the menu View | Properties. Change the "Build action" to "EmbeddedResource".

    Create a new C# class that will be the main entry point for the application

    1. Open the project browser again. Select the project tree node, right click and select Add | New Item... to open the "New File" dialog.
    2. Select the C# category and the Class template. Type in the filename GladeApp.cs and click the "Create" button to add the new C# class file to the project.
    3. This file should be opened when created. Modify the code so the file contains:

    using Glade;
    using Gtk;
    using System;

    public class GladeApp
    {    
        [Widget]
        Label messageLabel;
           
        public static void Main (string[] args)
        {
            new GladeApp (args);
        }

        public GladeApp (string[] args
        {
            Application.Init();
            Glade.XML gxml new Glade.XML(null"HelloGtkWorld.glade.xml""mainWindow"null);
            gxml.Autoconnect(this);
            messageLabel.Text "Hello, Gtk# World.";
            Application.Run();
        }
        
        void MainWindowDeleteEvent(object oDeleteEventArgs args)
        {
            Application.Quit();
            args.RetVal true;
        }
    }

    Let us have a look at this code before we attempt to make sure it compiles. The main part of interest is in the GladeApp class's constructor. First Gtk is initialised:

            Application.Init();

    This must be called before any Gtk libraries are used.

    Then a Glade.XML object is created that will use our "glade.xml" file which has been embedded as a resource. Note that the resource name is the name of the file with the project's namespace prefixed "HelloGtkWorld.gui.xml".

            Glade.XML gxml new Glade.XML(null"HelloGtkWorld.glade.xml""mainWindow"null);

    The Autoconnect call connects the signals defined in the Glade xml file to matching handlers in the GladeApp class. It will also initialise any fields that correspond to UI components defined in the Glade xml file.

            gxml.Autoconnect(this);

    The next line sets the text of the label that will be displayed in the main window.

            messageLabel.Text "Hello, Gtk# World.";

    The messageLabel object

        [Widget]
        Label messageLabel;

    will auto-magically be initialised for us by the Glade.Xml object.

    Finally the application is run via:

            Application.Run();

    When the user closes the main window the MainWindowDeleteEvent method is called.

        void MainWindowDeleteEvent(object oDeleteEventArgs args)
        {
            Application.Quit();
            args.RetVal true;
        }

    This method makes sure the application quits. If the Application.Quit method is not called then even though the main window has been closed the app will still be running in the background.

    Add references to the Glade and Gtk assemblies.

    1. Open the Project Browser. Select the "References" node, right click and select "Add References".
    2. In the "Add Reference" dialog select the ".NET Assembly Browser" tab and click the "Browse..." button.
    3. Browse to the Mono folder containing the assemblies for Glade and Gtk#. The folder should be something like "C:\Program Files\Mono\lib\mono\gtk-sharp". Select the glade-sharp and gtk-sharp dlls and click the "Open" button. In the "Add Reference" dialog click the "OK" button.

    Compiling the code

    1. Select the menu item Project | Project Options. In the "Application" tab, change the "Output type" to be "Windows Application".
    2. In the "Compiling" tab, change the "Target framework" to "Mono 1.1".
    3. In the "Debug" tab, change the "Start Action" to "Start external program". Set the external program field by browsing and selecting Mono.exe, which lives in "C:\Program Files\Mono\bin". In the "Start Options" group set the "Command line arguments to be "${TargetPath}" and the "Working directory" to "${TargetDir}".
    4. Select the menu Build | Rebuild Solution. The code should build successfully. There will be two warnings, one about MainWindowDeleteEvent method never being called and another about the messageLabel variable never being assigned to, both of which can be safely ignored.

    It is optional whether you use the Mono as the Target framework, the Gtk# and Glade libraries should work under the .NET framework. You will have to add references to the Glib and Atk libraries to be able to compile using Csc.

    Running the app

    1. Select the menu Debug | Run without debugger.


    As with the target framework, it is optional whether you run the application under Mono since the Gtk# and Glade libraries should work under the .NET framework.

    Other Useful Resources

    Introduction to Mono - Your first Mono app - Covers creating a Mono console app.

    A google search application using Gtk# - Uses Visual Studio to create a Gtk# Mono app that uses Google's web service.

    A Gtk# beginners guide. - Covers Gtk# and Glade.

    GUI development with Glade - A tutorial covering the Glade User Interface Builder.

    Mono Documentation - Covers all the Mono libraries including Gtk# and Glade.

    [Update: 10 Jan, 2006]

    SharpDevelop2 now ships with Gtk# and Glade# templates.  Support for Mono's GAC has also been added.  Read more here.

    Posted Oct 20 2005, 04:40 PM by MattWard with 1 comment(s)
    Filed under:
  • Detecting Where Mono is Installed

    Whilst looking at the NAnt config file (Nant.exe.config), I noticed that NAnt does a much better job at detecting where the Mono compilers, Mcs and Gmcs, are located. NAnt reads the registry, whilst SharpDevelop assumes that they exist somewhere in a folder, typically "C:\Program Files\Mono\bin", that has been added to the Path environment variable. If you add the "C:\Program Files\Mono\bin" folder to the Path then everything should work. In this bin folder there are several .bat files that can be used to run the various Mono compilers, and these are what SharpDevelop uses. The Mono executables live in "C:\Program Files\Mono\lib\mono\1.0" and "C:\Program Files\Mono\lib\mono\2.0", depending on the framework being targeted, and the .bat files run these executables under Mono.

    Mono's Registry Settings

    When you install Mono under Windows the installer adds a registry key under HKEY_LOCAL_MACHINE\SOFTWARE\Novell\Mono, and the values entered here can be used to detect where Mono is.

    [HKEY_LOCAL_MACHINE\SOFTWARE\Novell\Mono]
    DefaultCLR=1.1.9.2

    [HKEY_LOCAL_MACHINE\SOFTWARE\Novell\Mono\1.1.9.2]
    FrameworkAssemblyDirectory=C:\Program Files\Mono\lib
    MonoConfigDir=C:\Program Files\Mono\etc
    SdkInstallRoot=C:\Program Files\Mono


    SharpDevelop will now use the registry to locate the Mono bin folder, and if this fails then it falls back on its original method of assuming that the compiler lives in a folder added to the Path.

    This small improvement has been added to SharpDevelop 2.0 in revision 593.
    Posted Oct 17 2005, 10:19 PM by MattWard with 1 comment(s)
    Filed under:
  • NAnt Integration

    Support for NAnt has been added to SharpDevelop 2.0. in revision 573.

    Changes from SharpDevelop 1.1

    There are a few things missing from the NAnt addin compared to the previous version that shipped with SharpDevelop 1.1.

    The "Create Build File" menu option has been removed.  SharpDevelop now uses MSBuild project files instead of SharpDevelop projects (.prjx) and there is currently no conversion code written.  The original code took the project file and ran an XSL transform on it to produce the NAnt build file.  This feature will be added at a later date.

    NAnt no longer ships with SharpDevelop.  This means that NAnt needs to be installed separately.  By default SharpDevelop assumes that the NAnt executable is accessible by the Path environment variable.  If this not the case the NAnt executable to use can be set via Tools | Options | Tools | NAnt | Command.  If you install one of the NAnt nightly builds  you will be able to target .NET Framework 2.0 Beta 2.

    By default SharpDevelop supports NAnt 0.85 RC3, previously the 0.84 schema was the default.

    Issues

    The first time SharpDevelop is run the NAnt pad may not display any contents.  To fix this you
    will need to restart SharpDevelop.  There seems to be an issue with the default layout information.

    Creating a new NAnt build file

    To add a new build file to your project:
    1. Open the project browser, View | Projects.
    2. Right click the project and select Add | Add New Item...
    3. In the "New File" dialog, select the Misc category.
    4. Choose the "NAnt Build File" template, specify a file name and click the "Create" button.



    Xml auto-completion, based on the NAnt 0.85 RC3 schema, will occur whilst you are editing the NAnt build.



    Project Menu



    Run Default Target Runs the default target of the build file for the project.  The build file must be part
    of the project (i.e. it exists in the project view).
    Run Clean Target Runs the "clean" target of the build file for the project.
    There is currently no clever add-in logic here, in order for this menu option to work there needs to be a target called "clean".
    Stop NAnt Stops a currently running build.  A warning message is displayed.  This option kills the NAnt process.


    Project Browser

    NAnt ".build" and ".include" files are displayed in the project browser with their own icon.



    NAnt Pad

    To open the NAnt pad, select View | Tools | NAnt.



    The NAnt Pad displays all the build files in the solution.  It gives a high level overview of the build file, showing all the build targets.

    Double clicking a target node will open up the build file and move the cursor to the corresponding <target> element.

    The NAnt pad's toolbar buttons, from left to right:

    Run If the build file node is selected, runs the default target.
    If a target node is selected, runs that target.
    Refresh Refreshes the tree.  Reads the build file again and updates the display.
    Stop Stops the currently running build.

    The NAnt pad has a text box at the bottom where the user can specify extra command line options.  In the screenshot below the user has entered "-targetframework:net-1.1", this will be added to the NAnt command line.

    NAnt Pad Context Menu

    Right clicking the build file node shows the context menu:



    The Open menu option will open the build file into the SharpDevelop text editor.

    The other menu options have been described in the "Project Menu" section.

    Right clicking on a target node shows the context menu:



    Run Target Runs the target selected.  This passes the target's name to NAnt on the command line.
    Open Opens the build file into the SharpDevelop's text editor.
    Goto Definition Opens up the build file and moves the mouse cursor to the corresponding <target> element.

    Output Window

    All NAnt output is shown in a NAnt output window.



    The first two lines are outputted by the NAnt add-in showing the NAnt command line used.  The rest is the output from NAnt.

    Errors Window

    Errors and warnings from the NAnt build are displayed in the Errors window.



      NAnt Configuration

    Open the NAnt options panel via Tools | Options | Tools | NAnt 



    Panel Option Description
    Command The location of the NAnt executable to use.
    Arguments Standard arguments that will be passed to NAnt (e.g. -targetframework:net-1.1).
    Quiet Maps to NAnt's -quiet command line option.
    Show Logo Shows/hides the NAnt logo in the output window.
    Verbose Maps to NAnt's -verbose command line option.
    Debug Maps to NAnt's -debug command line option.
    Posted Oct 15 2005, 07:36 PM by MattWard with no comments
    Filed under:
  • Targeting Different Frameworks with SharpDevelop

    Daniel recently added support for .NET 1.1 and .NET 1.0 to SharpDevelop 2.0.  Let us take a low level look at how SharpDevelop 2.0 targets other frameworks.  Targeting another framework involves a custom .targets file and custom MSBuild tasks. 

    SharpDevelop Custom MSBuild Tasks and Targets

    Component Description
    ICSharpCode.Build.Tasks.dll Assembly containing custom MSBuild tasks.
    SharpDevelop.Build.Common.targets Specifies targets common to all SharpDevelop targets.
    SharpDevelop.Build.CSharp.targets Specifies targets for C# projects that target a framework other than the default.
    SharpDevelop.Build.Mono.Mcs.targets Defines the Mcs task.
    SharpDevelop.Build.Mono.Gmcs.targets Defines the Gmcs task.
    SharpDevelop.Build.MSIL.targets Specifies targets for ILAsm projects.

    What happens when another framework is targeted?

    When the project has been configured to target a framework other than the default, the project is modified to use a customised .targets file and has a property added that specifies the framework being targeted.  Below is a project file for a console application that targets Mono 1.1.

    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <RootNamespace>HelloMonoWorld</RootNamespace>
        <AssemblyName>HelloMonoWorld</AssemblyName>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProjectGuid>{0534CD74-E5FA-4349-866E-4E0C6428E840}</ProjectGuid>
        <TargetFrameworkVersion>Mono v1.1</TargetFrameworkVersion>
        <NoStdLib>False</NoStdLib>
        <WarningLevel>4</WarningLevel>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
        <OutputPath>bin\Debug\</OutputPath>
        <Optimize>False</Optimize>
        <DefineConstants>DEBUG;TRACE</DefineConstants>
        <DebugSymbols>true</DebugSymbols>
        <DebugType>Full</DebugType>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
        <OutputPath>bin\Release\</OutputPath>
        <Optimize>True</Optimize>
        <DefineConstants>TRACE</DefineConstants>
        <DebugSymbols>False</DebugSymbols>
        <DebugType>None</DebugType>
      </PropertyGroup>
      <ItemGroup>
        <Compile Include="Main.cs" />
        <Compile Include="AssemblyInfo.cs" />
      </ItemGroup>
      <Import Project="$(SharpDevelopBinPath)\SharpDevelop.Build.CSharp.targets" />
    </Project>

    The .csproj file has a <TargetFrameworkVersion> element and includes a custom .targets file "SharpDevelop.Build.CSharp.targets" instead of the usual "Microsoft.CSharp.Targets".

    The "SharpDevelop.Build.CSharp.targets" file looks at the TargetFrameworkVersion information and targets the appropriate runtime.  If we are targeting Mono, the file imports one of the Mono specific target files.

    <Import Condition=" '$(TargetFrameworkVersion)' == 'Mono v1.1' " 
            Project="$(SharpDevelopBinPath)\SharpDevelop.Build.Mono.Mcs.targets"/>
    <Import Condition=" '$(TargetFrameworkVersion)' == 'Mono v2.0' "
            Project="$(SharpDevelopBinPath)\SharpDevelop.Build.Mono.Gmcs.targets"/>

    These Mono specific files reference the custom MSBuild tasks in the ICSharpCode.Build.Tasks assembly.

    If one of the Microsoft .NET frameworks is targeted, various properties, such as CscToolPath, are changed so the correct compiler is used, but no custom tasks are involved.
    Posted Oct 15 2005, 03:55 PM by MattWard with 2 comment(s)
    Filed under:
  • Custom MSBuild Tasks for Mono

    SharpDevelop ships with two custom MSBuild tasks for Mono, one for Mcs and the other for Gmcs, both of which live in the ICSharpCode.Build.Tasks assembly.  With the recent Mono release, 1.1.9, the command line options and compiler error message formats are the same for Mcs and Gmcs, earlier versions differed.  This means that the Mcs and Gmcs classes do not do much apart from determine the name of the compiler to use.  The MonoCompilerTask class does the hard work of compiling the code and reporting error messages back.

    Simple C# Console Project

    HelloMonoWorld.csproj:

    <Project DefaultTargets="Build" 
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <AssemblyName>HelloMonoWorld</AssemblyName>
        <WarningLevel>4</WarningLevel>
      </PropertyGroup>
      <PropertyGroup>
        <OutputPath>bin</OutputPath>
      </PropertyGroup>
      <ItemGroup>
        <Compile Include="Main.cs" />
        <Compile Include="AssemblyInfo.cs" />
      </ItemGroup>
      <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
    </Project>

    Main.cs:

    using System;

    namespace HelloMonoWorld
    {
        class MainClass
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
            }
        }
    }

    Running MSBuild, passing the .csproj as a command line argument, will build the console app using Microsoft's Csc and targets the .NET Framework 2.0.

    Using the Mcs Task Directly

    Let us modify the project file so it calls the Mcs task directly.  I am assuming that the ICSharpCode.Build.Tasks.dll exists in the same folder as the project file.

    <Project DefaultTargets="Build" 
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <AssemblyName>HelloMonoWorld</AssemblyName>
        <WarningLevel>4</WarningLevel>
      </PropertyGroup>
      <PropertyGroup>
        <OutputPath>bin</OutputPath>
      </PropertyGroup>
      <ItemGroup>
        <Compile Include="Main.cs" />
        <Compile Include="AssemblyInfo.cs" />
      </ItemGroup>
      
      <UsingTask TaskName="ICSharpCode.Build.Tasks.Mcs"
                 AssemblyFile="ICSharpCode.Build.Tasks.dll"/>

      <Target Name="Build">
        <Mcs
          OutputAssembly="$(OutputPath)\$(AssemblyName).exe"
          References="@(ReferencePath)"
          Sources="@(Compile)"
          TargetType="$(OutputType)"/>
      </Target>
    </Project>

    The project file above is a bit limited, it does not have standard targets such as "Rebuild" and "Clean".  We could write everything ourselves, but instead why not use the standard .targets that Microsoft provides and just override the bare minimum?

    Mono.Mcs.targets

    So what is the bare minimum .targets file we need in order to get MSBuild to use our custom Mono tasks?

    First let us look at the modified project file:

    <Project DefaultTargets="Build" 
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <AssemblyName>HelloMonoWorld</AssemblyName>
        <WarningLevel>4</WarningLevel>
      </PropertyGroup>
      <PropertyGroup>
        <OutputPath>bin</OutputPath>
      </PropertyGroup>
      <ItemGroup>
        <Compile Include="Main.cs" />
        <Compile Include="AssemblyInfo.cs" />
      </ItemGroup>
      <Import Project="Mono.Mcs.targets" />
    </Project>

    The Mono.Mcs.targets file, which is based on the Microsoft.CSharp.targets file, overrides the CoreCompile target:

    <Project DefaultTargets="Build"
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

        <UsingTask TaskName="ICSharpCode.Build.Tasks.Mcs"
                   AssemblyFile="ICSharpCode.Build.Tasks.dll"/>
        
       <PropertyGroup>
            <MSBuildAllProjects>$(MSBuildAllProjects);Mono.Mcs.targets</MSBuildAllProjects>
            <DefaultLanguageSourceExtension>.cs</DefaultLanguageSourceExtension>
            <Language>C#</Language>
        </PropertyGroup>
        
        <Target Name="CreateManifestResourceNames"/>

        <PropertyGroup>
            <DebugSymbols Condition=" '$(DebugType)' == 'none' ">false</DebugSymbols>
            <DebugType    Condition=" '$(DebugType)' == 'none' "></DebugType>    
        </PropertyGroup>

        <ItemGroup>
            <DocFileItem Include="$(DocumentationFile)" Condition="'$(DocumentationFile)'!=''">
                <InProject>false</InProject>
            </DocFileItem>
        </ItemGroup>

        <PropertyGroup>
            <CoreCompileDependsOn>_ComputeNonExistentFileProperty</CoreCompileDependsOn>
        </PropertyGroup>
        
        <Target
            Name="CoreCompile"
            Inputs="$(MSBuildAllProjects);
                    @(Compile);
                    @(ManifestResourceWithNoCulture);
                    $(ApplicationIcon);
                    $(AssemblyOriginatorKeyFile);
                    @(ManifestNonResxWithNoCultureOnDisk);
                    @(ReferencePath);
                    @(CompiledLicenseFile)"
            Outputs="@(DocFileItem);
                     @(IntermediateAssembly);
                     $(NonExistentFile)"
            DependsOnTargets="$(CoreCompileDependsOn)"
        >
           
            <Mcs
                  AdditionalLibPaths="$(AdditionalLibPaths)"
                  AddModules="@(AddModules)"
                  AllowUnsafeBlocks="$(AllowUnsafeBlocks)"
                  CheckForOverflowUnderflow="$(CheckForOverflowUnderflow)"
                  CodePage="$(CodePage)"
                  DebugType="$(DebugType)"
                  DefineConstants="$(DefineConstants)"
                  DelaySign="$(DelaySign)"
                  DisabledWarnings="$(NoWarn)"
                  DocumentationFile="@(DocFileItem)"
                  EmitDebugInformation="$(DebugSymbols)"
                  KeyContainer="$(KeyContainerName)"
                  KeyFile="$(KeyOriginatorFile)"
                  LangVersion="$(LangVersion)"
                  MainEntryPoint="$(StartupObject)"
                  NoConfig="true"
                  NoLogo="$(NoLogo)"
                  NoStandardLib="$(NoStdLib)"
                  Optimize="$(Optimize)"
                  OutputAssembly="@(IntermediateAssembly)"
                  References="@(ReferencePath)"
                  Resources="@(ManifestResourceWithNoCulture);@(ManifestNonResxWithNoCultureOnDisk);@(CompiledLicenseFile)"
                  ResponseFiles="$(CompilerResponseFile)"
                  Sources="@(Compile)"
                  TargetType="$(OutputType)"
                  ToolPath="$(McsToolPath)"
                  TreatWarningsAsErrors="$(TreatWarningsAsErrors)"
                  WarningLevel="$(WarningLevel)"
                  Win32Icon="$(ApplicationIcon)"
                  Win32Resource="$(Win32Resource)" />
        </Target>
        
        <Import Project="$(MSBuildBinPath)\Microsoft.Common.targets" />
    </Project>

    The differences between this is and the standard Microsoft.CSharp.targets file is that a few properties have been removed (NoWarn and UseHostCompilerIfAvailable) and the CreateManifestResourceNames target has essentially been removed, the target is defined, but it does nothing.  This targets file is good enough to compile our console application, as long as we do not add any embedded resources to it.

    SharpDevelop

    How does this compare with the .targets files that ship with SharpDevelop?  Since SharpDevelop can target more than just Mono, it supports the older .NET frameworks too, things are a little more complicated.  This will be covered in another post.
    Posted Oct 15 2005, 03:15 PM by MattWard with 4 comment(s)
    Filed under: ,
  • SharpDevelop 2.0 and Mono

    As of revision 568, available from the repository, SharpDevelop 2.0 supports C# projects targeting Mono 1.1.9.2.

    Prerequisites

    • Mono 1.1.9.2 is installed.
    • The Mono bin folder has been added to the "Path" environment variable (Control Panel | System | Advanced | Environment Variables).

    Targeting Mono

    To target Mono, open the project's "Compiling" options (Project | Project Options | Compiling) and select either "Mono 1.1" or "Mono 2.0" from the "Target Framework" drop down list.

    With "Mono 1.1" selected the Mcs compiler will be used.  With "Mono 2.0" selected the Gmcs compiler will be used.

    Running your Application

    After you have compiled your code using Mcs or Gmcs you can then run your application under Microsoft's .NET Framework or under Mono's Framework. If you want to run it under Microsoft's .NET Framework then you can use either of the menu options "Debug | Run" or "Debug | Run without debugger" as you would with a normal application created using SharpDevelop. You will need to make sure all the Mono specific assembly references (e.g. glib-sharp) have "Local Copy" set to "true", otherwise the Microsoft .NET Framework will be unable to find them. If you want to run your application under Mono's Framework instead follow the instructions in the next section.

    Running under Mono

    To configure your application to run under Mono's Framework, open the project's "Debug" options (Project | Project Options | Debug), switch the "Start Action" to "Start external program" and enter the path to the Mono executable, and finally set the "Command line arguments" to "${TargetPath}". If the path to your application's executable contains spaces put double quotes around the ${TargetPath} string.

    To run your application under Mono, select the menu option Debug | Run without debugger.  You cannot use the SharpDevelop debugger to debug or run your Mono application.

    Common Problems

    Mcs/Gmcs exiting with code -1

    If you are seeing errors such as:

    "Mcs.exe" exited with code -1
    Failed to execute compiler: -1: "C:\Program Files\Mono\bin\Mcs.bat"

    This is usually because Mono cannot convert the command line into Unicode.  To fix this create a environment variable called MONO_EXTERNAL_ENCODINGS and set it to be "default_locale" without the quotes.

    From the Mono man page:

    MONO_EXTERNAL_ENCODINGS

    If set, contains a colon-separated list of text encodings to try when turning externally-generated text (e.g. command-line arguments or filenames) into Unicode. The encoding names come from the list provided by iconv, and the special case "default_locale" which refers to the current locale's default encoding.

    When reading externally-generated text strings UTF-8 is tried first, and then this list is tried in order with the first successful conversion ending the  search. When writing external text (e.g. new filenames or arguments to new processes) the first item in this list is used, or UTF-8 if the environment variable is not set.


    [UPDATE 6th March, 2006]

    Added MONO_EXTERNAL_ENCODINGS fix for the Mcs/Gmcs compiler failing with error code -1.  Thanks to Luis Segura for finding this solution.

    [UPDATE 10th April, 2006]

    Added some information about running under Microsoft's .NET Framework versus running under Mono. Added a note about putting double quotes around ${TargetPath} if the path to the executable being run under Mono contains spaces.
    Posted Oct 12 2005, 11:16 PM by MattWard with 3 comment(s)
    Filed under:
Powered by Community Server (Commercial Edition), by Telligent Systems
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.