Boo Compiler Options

There are lots of options for building Boo.

I got fed up having to look up the options so I have them all here.

Usage is: booc [options] file1 …
Options:
 -c:CULTURE           Sets the UI culture to be CULTURE
 -debug[+|-]          Generate debugging information (default: +)
 -define:S1[,Sn]      Defines symbols S1..Sn with optional values (=val) (-d:)
 -delaysign           Delays assembly signing
 -ducky               Turns on duck typing by default
 -checked[+|-]        Turns on or off checked operations (default: +)
 -embedres:FILE[,ID]  Embeds FILE with the optional ID
 -lib:DIRS            Adds the comma-separated DIRS to the assembly search path
 -noconfig            Does not load the standard configuration
 -nostdlib            Does not reference any of the default libraries
 -nologo              Does not display the compiler logo
 -p:PIPELINE          Sets the pipeline to PIPELINE
 -o:FILE              Sets the output file name to FILE
 -keyfile:FILE        The strongname key file used to strongname the assembly
 -keycontainer:NAME   The key pair container used to strongname the assembly
 -reference:ASS       References the specified assembly (-r:ASS)
 -srcdir:DIR          Adds DIR as a directory where sources can be found
 -target:TYPE         Sets the target type (exe, library or winexe)
 -resource:FILE[,ID]  Embeds FILE as a resource
 -pkg:P1[,Pn]         References packages P1..Pn (on supported platforms)
 -utf8                Source file(s) are in utf8 format
 -v, -vv, -vvv        Sets verbosity level from warnings to very detailed
 -wsa                 Enables white-space-agnostic build

Direct compile line:

booc -t:library bender.boo

booc wpfdemo.boo -r:PresentationCore.dll -r:PresentationFramework.dll -r:WindowsBase.dll

Note you can supply multiple boo source files to split the project.

Nant build script:

<?xml version=”1.0″ ?>
<project name=”wpfdemo” default=”build”>
<property name=”boo.dir” value=”C:/boo/bin” />
    <target name=”build” depends=”wpfdemo” />
    <target name=”wpfdemo”>
        <loadtasks assembly=”${boo.dir}/Boo.NAnt.Tasks.dll” />
                 <booc output=”wpfdemo.exe” target=”winexe”>
            <references>
                <include name=”C:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0/*.dll” />
            </references>
            <sources>
                <include name=”wpfdemo.boo” />
            </sources>
        </booc>
    </target>
</project>

You can also use msbuild:

<Project DefaultTargets=”Build” xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″&gt;
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <RootNamespace>Bake.Example</RootNamespace>
    <AssemblyName>Bake.Example</AssemblyName>
    <Configuration Condition=” ‘$(Configuration)’ == ” “>Debug</Configuration>
    <Platform Condition=” ‘$(Platform)’ == ” “>AnyCPU</Platform>
    <ProjectGuid>{707667FA-CDCB-4756-9EF0-96DB18A53DCD}</ProjectGuid>
    <NoStdLib>False</NoStdLib>
    <Ducky>False</Ducky>
  </PropertyGroup>
  <PropertyGroup Condition=” ‘$(Configuration)’ == ‘Debug’ “>
    <BaseIntermediateOutputPath>obj</BaseIntermediateOutputPath>
    <IntermediateOutputPath>objDebug</IntermediateOutputPath>
    <OutputPath>….bin</OutputPath>
    <Optimize>False</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>Full</DebugType>
  </PropertyGroup>
  <PropertyGroup Condition=” ‘$(Configuration)’ == ‘Release’ “>
    <BaseIntermediateOutputPath>obj</BaseIntermediateOutputPath>
    <IntermediateOutputPath>objRelease</IntermediateOutputPath>
    <OutputPath>….bin</OutputPath>
    <Optimize>True</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <DebugSymbols>false</DebugSymbols>
    <DebugType>None</DebugType>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include=”Program.boo” />
  </ItemGroup>
  <ItemGroup>
    <Content Include=”example.boobs” />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include=”..bake.engineBake.Engine.booproj”>
      <Project>{B86E7336-0498-486D-A199-FC19ED9740AF}</Project>
      <Name>Bake.Engine</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project=”$(BooBinPath)Boo.Microsoft.Build.targets” />
</Project>

Bake:

import Bake.IO.Extensions

Task(“default”, [“test”])

Task(“compile”, [“codeGen”]) do:
    print “> do compile stuff”

Task(“dataLoad”, [“codeGen”]) do:
    print “> do dataLoad stuff”

Task(“codeGen”) do:
    print “> do codeGen stuff”

Task(“test”, [“compile”, “dataLoad”]) do:
    print “> do test stuff”
    print Configuration.test

Boo build system

Here is a build system that is pure Boo.

It was called BooBS and may be transitioning to Bake.

This reminds me of a build tool that I built once in Python.
It would do the packaging and deployment details but left the compilation to want (the delphi port of nant).
There are big advantages of having the build tool in a scripting language.  This makes fixes much easier and quicker – which you really need if you are trying to get an emergency build out.

Having an automated build tool seriously improves the quality of a build – it reduces the bar on releases so you don’t need a hideous checklist.  I found the need for it when I forgot to release half of the dll’s for a project once.

These days I would recommend creating an automated installer as part of the build.  This seriously reduces the mistakes that the instalation engineer makes.

Boo and WPF

Here is an example of Boo and WPF.
I am not claiming that it is origonal since it was cribbed from someone elses site.
However this version is not broken and does have a build script.

The following is wpdemo.boo:

namespace Boo.WinFx
import System
import System.Windows
import System.Windows.Controls
import System.Windows.Navigation

[STAThread]
def Main():
    # create a window host
    win = NavigationWindow()   
    # create a textblock
    para = TextBlock(Text:”Hello World!!!”, FontSize:36)
    para.VerticalAlignment = VerticalAlignment.Center
    para.HorizontalAlignment =HorizontalAlignment.Center   
    # create a button
    button = Button(Content:”Click Me”, Height:30, Width:100)
    # display the textblock when the button is clicked
    button.Click += { win.Navigate(para) }
    # display the button first
    win.Navigate(button)
    # create an application host
    app = Application()
    # show the window
    win.Show()
    # fire the application
    app.Run()

The following is default.build:

<?xml version=”1.0″ ?>

<project name=”wpfdemo” default=”build”>
<property name=”boo.dir” value=”C:/boo/bin” />
    <target name=”build” depends=”wpfdemo” />
    <target name=”wpfdemo”>
        <loadtasks assembly=”${boo.dir}/Boo.NAnt.Tasks.dll” />
                 <booc output=”wpfdemo.exe” target=”winexe”>
            <references>
                <include name=”C:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0/*.dll” />
            </references>
            <sources>
                <include name=”wpfdemo.boo” />
            </sources>
        </booc>
    </target>
</project>

Boo and WF

This is based upon an example that has been floating around the blogs.
I have removed the Python accent from it (hint you don’t need to use self in a Boo class):

The following is wf.boo

import System.Workflow.Activities
import System.Workflow.Runtime
import System
class MyWorkflow(SequentialWorkflowActivity):
_codeActivity as CodeActivity
def constructor():
super()
_codeActivity = CodeActivity()
_codeActivity.ExecuteCode += SayHello
_codeActivity.Name = “Hello”
Activities.Add(_codeActivity)
def SayHello(sender, args):
print “Hello”

def Started(sender as object, args as EventArgs):
print “Startedn”
def Completed(sender as object, args as EventArgs):
print “Completed”

tf = MyWorkflow()
rt = WorkflowRuntime()
rt.WorkflowStarted += Started
rt.WorkflowCompleted += Completed
type = tf.GetType()
instance = rt.CreateWorkflow(type)
instance.Start()
Console.ReadKey()

The following is default.build:

<?xml version=”1.0″ ?>

<project name=”wpfdemo” default=”build”>
<property name=”boo.dir” value=”C:/boo/bin” />
<target name=”build” depends=”wpfdemo” />
    <target name=”wpfdemo”>
        <loadtasks assembly=”${boo.dir}/Boo.NAnt.Tasks.dll” />
            <booc output=”wf.exe” target=”exe”>
                <sources>
                    <include name=”wf.boo” />
                </sources>
            </booc>
    </target>
</project>

Why I like Boo

Boo is a very simple programming language.

I am not sure that I would use it in a production application for fear of the maintenance problems (where do you get Boo programmers from?).

Things that I particularly like are:

Booish – being able to interactively play with practacally any .NET class without the need for a heavyweight IDE to be open.

The fact that you can post the source code to a blog like this without messing up the formatting!

I am planning a series of topics on Boo and the .NET 3 Pillars:

  • WF – windows workflow
  • WPF – windows presentation foundation
  • WCF – windows communication framework

At first I will be using Boo plus Nant but may need to stray into MSBuild.

Domain Specific Languages and XML

There has been a lot of thinking about the use of Domain Specific Languages to solve a particular problem.
This is even a major feature of Visual Studio 2005 and above.

Typically these are things like Ruby on Rails which is essentially a DSL for creating dynamic websites quickly.

However there is a much simpler solution.
State your problem in XML and use xslt to generate the solution.
If done carefully you can eliminate a lot of easy to write, but easy to get wrong code.

This is really what Kathleen Dollard has been talking about in her Code Generation in .net book.

Here is an example that almost all applications have to deal with:

How much work is it to add another maintenance screen to the system?
or even
How much work is it to add one field to one maintenance screen?

If you get the principle working for one screen you can add another by adding a few lines to an xml document and regenerating the script.

Boo Generic Support

The following blog listed generic support details for boo: link

states that generic type definitions in Boo are handled thus:

 MyType of MyGenericParam

or for multiple generic parameters

MyType[of X,Y,Z]

I find Boo to be a great exerimentation language, ideal for turning a class into a commandline tool.

wmi in boo

# The following is a very simple example of using wmi from boo
import System
import System.Collections
import System.Data
import Boo.Lang
import System.Management
import System.Windows.Forms

class WmiApp:
    _tb as TextBox
    _dgv as DataGridView
    [STAThread]
    def Run():
        f = Form(Text: “Hello, boo!”)
        _tb = TextBox(Text: “SELECT * FROM Win32_Service”, Dock: DockStyle.Top)
        _dgv = DataGridView(Dock: DockStyle.Fill)
        b = Button(Text: “Click Me!”, Dock: DockStyle.Top)
        b.Click += ButtonClick
        f.Controls.Add(_dgv)
        f.Controls.Add(b)
        f.Controls.Add(_tb)

        Application.Run(f)
    def ButtonClick(args, sender):
        WMIQuery(_tb.Text)
    def WMIQuery(query as string):
        qry = SelectQuery(query)
        ds = DataSet()
        table = ds.Tables.Add(“WMI”)
        mos = ManagementObjectSearcher(qry)
        loaded = false
        moc as ManagementObjectCollection
        moc = mos.Get()
        for prop as PropertyData in (array(moc)[0] as ManagementObject).Properties:
            table.Columns.Add(prop.Name)
        moa = array(moc)
        mo as ManagementObject
        for i in range(0, moc.Count):
            mo = moa[i]
            row = table.NewRow()
            for prop as PropertyData in mo.Properties:
                row[prop.Name] = prop.Value
            table.Rows.Add(row)

        _dgv.DataSource = table

WmiApp().Run()