Export build programs as BOO source code

Assume, that we have implemented a build program following the hints of section Typical Use.

This program can be used to create a BOO program source code for producing the targets of the build projects. This program will not use the assembly wx.BuildSystem.dll but implement all calls of the available tools directly.

The resulting program will refer to all those tools that have been available when the build program has been ran. In the following, we will inspect the structure of a build program that has been created on a Windows installation. Microsoft's VC and VS express editions for building C/C++ and C# programs, the GNU MinGW edition for building C/C++ programs and the MONO tools for building C# programs have been available.

Type the following line into the command shell:

> wxSampleBuild.exe /boo=aBooFileName 

This file will create a file aBooFileName.boo containing a BOO program that builds the targets of the original build program in a manner similar to the well-known MAKE systems. This BOO program does nothing more than the original program. The purpose of this export to BOO is to enable users of the system to adopt the build system to their specific needs if unusual or unsupported build environments are used. Thus, the BOO code is designed for manual changes. The code consists of 3 sections.

The declaration section

This sections contains the declaration of BOO variables for options and file names. This is the section that users of the build system will edit to adopt the build system to specific needs.

This section contains several subsections. the first section will import some required namespaces and declare features of some projects. Features define symbols that are used for conditional compilation. The features here define optional parts of the wx.NET system: The styled text control (STC) and the interface to the display:

# BOO script to build the wx.Buildsystem projects from assembly
# wx.Net.Build, Version=0.9.0.0, Culture=neutral, PublicKeyToken=c5f483f7e93d2714.
# This program has been generated automatically by the wx.BuildSystem
# (c) 2010 Harald Meyer auf'm Hofe.
#
# The following lines will declare variables to configure the tools
# that are used to build the system. You may change these declarations
# if you know what you are doing.
import System.Text
import System.IO
import System.Diagnostics
# Features of project wx.NET: The managed part of the wx.NET implementation.
Features_wx_NET=[]
Features_wx_NET.Add("WXNET_DISPLAY") # Display Access: Enables class wx.Display
Features_wx_NET.Add("WXNET_STYLEDTEXTCTRL") # Styled Text Control: Enables namespace wx.StyledText

In the following, the base path will be defined, that will be used to complete all local paths in the build program. Additionally, the build mode (rebuild or reuse of existing build results) and the target directory containing all internal build projects will be declared here.

# This is the root path of the project.
wxNetBase='c:\\sf\\wx.NET\\Bin'
System.IO.Directory.SetCurrentDirectory(wxNetBase)
#
# If true, then any target will be rebuild. If false, many build actions
# will only rebuild targets if prerequisites are newer.
Rebuild=false
#
# This is the directory containing all non-target files that will be created on building the targets.
BuildDir='Build\\Debug'

The following sections will provide definitions of files and options for each avaiable tool. The following listing presents the section defining options for the CSC.EXE C# compiler of Microsoft's .NET framework.

#################################################################
# These are the declarations of tool csc.exe of family MSNET:
# c:\WINDOWS\Microsoft.NET\Framework\v3.5\csc.exe: The C# compiler of the MS .NET framework.
# This variable is the path to the CSC compiler that will be used.
MS_CSC="c:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5\\csc.exe"
# This option defines whether to compile with debug information or not
MS_CSC_OPTIONS='/debug'
# This option turns on optimization
#MS_CSC_OPTIONS+=' /optimize'
# This option defines the warning level
MS_CSC_OPTIONS+=' /warn:3'
MS_CSC_OPTIONS+=' /fullpaths'
#MS_CSC_OPTIONS+=' /warnaserror' # treats warnings as errors
MS_CSC_OPTIONS+=' /define:__MS_CSC__' # identifies the compiler
MS_CSC_OPTIONS+=' /define:TRACE' # enables trace log
#################################################################

The final section defines so-called choice points. Since the build program uses all available build tools, there may be alternative paths to achieve certain targets. The workstation that created this BOO program has been fully equipped with VC Express and GNU MinGW to build C/C++ subsystems, VS Express and MONO to build C# subsystems. Thus, the user of the build system has the choice. The following choice points enable the user to make this choice.

#########################################################
# This section contains choice points- BOO variables that
# control which tools will be used. Assign one of the
# listed values to the choice points in order to select
# a particular tool. If this tool is not available, the
# program will automatically use an alternative.
CppDevelopmentSystem = "MS VC" # "MS VC" "GNU"
CSHARP_COMPILER = "csc.exe" # "csc.exe" "gmcs" "CSharpCodeProvider"

The section defining the build programs

The next section implements the wrapper functions that will be called to run the build tools. Users of the build system are not required to know them. However, the following sections shows the function calling the CSC.EXE compiler for all those that like to know how things work.

#########################################################
# The section containing declarations ends here.
# Please refrain from changing the code from this position on.
# The code below will provide definitions of build functions and
# will use this functions afterwards to produce the build targets.
# However, you may want to disable build tools here by replacing
# the body of the corrsponding function with "pass".
def TestForRebuild(targetFile as  string, *sourceFiles as (object)):
        if Rebuild: return true
        if not System.IO.File.Exists(targetFile): return true
        dTarget=System.IO.File.GetLastWriteTime(targetFile)
        inlinedSources=[]
        for sourceFile in sourceFiles:
                if sourceFile == null: continue
                if sourceFile isa System.Array:
                        for containedSource in cast(System.Array, sourceFile):
                                inlinedSources.Add(containedSource)
                else:
                        inlinedSources.Add(sourceFile)
        for inlinedSource in inlinedSources:
                dSource=System.IO.File.GetLastWriteTime(inlinedSource)
                if dTarget < dSource: return true
        return false
#
# These are the definitions of tool csc.exe of family MSNET:
# c:\WINDOWS\Microsoft.NET\Framework\v3.5\csc.exe: The C# compiler of the MS .NET framework.
def RunMsCsc(targettype as string, target as string, w32icon as string, signature as string, mainclass as string, references as (string), sources as (string), features):
        if not TestForRebuild(target, w32icon, signature, references, sources):
                print target,"is up to date"
                return
        print "MS csc.exe creates", target
        args=StreamWriter("${BuildDir}\\plain\\csc.txt")
        args.Write("/out:${target} /target:${targettype}")
        for feature in features:
                if feature=="X32":
                        args.Write(' /platform:x86')
                elif feature=="X64":
                        args.Write(' /platform:x64')
                else:
                        args.Write(' /define:')
                        args.Write(feature)
        for reference in references:
                args.Write(" /reference:\"${reference}\"")
        if signature != null:
                args.Write(" /keyfile:\"${signature}\"")
        if w32icon != null:
                args.Write(" /win32icon:\"${w32icon}\"")
        if mainclass != null:
                args.Write(" /main:${mainclass}")
        args.Write(' ')
        args.Write(MS_CSC_OPTIONS)
        for source in sources:
                args.Write(" \"${source}\"")
        args.Close()
        startinfo=System.Diagnostics.ProcessStartInfo()
        startinfo.FileName=MS_CSC
        startinfo.Arguments="@${BuildDir}\\plain\\csc.txt"
        startinfo.UseShellExecute=false
        p=System.Diagnostics.Process.Start(startinfo)
        p.WaitForExit()
        if p.ExitCode!=0:
                raise System.Exception("Build action failed.")

The section actually building the desired targets

The final section uses the wrapper functions defined in the previous section to actually build the build targets.

This is the code producing the controls.exe programm.

if CSHARP_COMPILER == "gmcs":
        print 'Executing gmcs'
        RunMonoGmcs("winexe", "${wxNetBase}\\controls.exe", ("../Samples/Controls\\Controls.cs", ), ("System.dll", "System.Drawing.dll", "${wxNetBase}\\wx.NET.dll", ), "c:\\sf\\wx.NET\\Src\\wx.NET\\mondrian.ico", "c:\\sf\\wx.NET\\Src\\wx.NET\\keys.snk", null, [])
elif CSHARP_COMPILER == "CSharpCodeProvider":
        print 'Executing CSharpCodeProvider'
        print "Caught exception creating code for action CSharpCodeProvider."
        print "BOO code creation is not supported by action wx.Build.Net.CSharpCodeProvider."
else: # CSHARP_COMPILER == "csc.exe"
        print 'Executing csc.exe'
        RunMsCsc('winexe', "${wxNetBase}\\controls.exe", "c:\\sf\\wx.NET\\Src\\wx.NET\\mondrian.ico", "c:\\sf\\wx.NET\\Src\\wx.NET\\keys.snk", null, ("System.dll", "System.Drawing.dll", "${wxNetBase}\\wx.NET.dll"), ("../Samples/Controls\\Controls.cs",), [])

The wx.NET Build System.   (c) 2009-2010 Harald Meyer auf'm Hofe