Try Software Factories on ET Robot Contest!

ETロボコンは、Lego Pathfinderロボットを使って、あらかじめ決められた黒線で描かれたコースを疾走し、走行タイム、課題のクリアを競います。
それら実技に加え、走行を制御するソフトウェアの設計内容も審査の対象になるコンテストです。

ソフトウェアはGNUをLego Mindstorms向けに移植した、brickOSというOS上で開発します。コンパイラも当然GNUのコンパイラです。
通常は、viやemacs、eclipseなどを使って開発するかとは思いますが、日頃使っているVisual Studioを使いたい方もいるでしょう。
加えて、マイクロソフトが提供する、Software Factories実現を支援するDSL DesignerやGAT/GAXといったツール群は、もちろん、Visual Studio 2005で動作します。
他にも、各プロジェクトの事情に合わせて、プロジェクトテンプレートのカスタマイズを行いたい開発者もいるでしょう。

ここでは、プロジェクトテンプレートのカスタマイズ方法の説明を兼ねて、brickOS向けクロスコンパイル環境を作り、今後のSoftware Factoriesの様々なプラクティス導入への準備をしましょう。

事前準備:
Visual Studio 2005がインストールされていない場合、以下のどちらかをインストールしてください。

  • Visual Studio 2005 VC# Express Edition
  • Visual Studio 2005 Professional Edition以上(評価版でも可)

Cygwin、BrickOSもインストールしてください。インストール方法は、ETロボコン事務局から公開されているドキュメントを見るか、インターネット上で調べてみてください。

説明を簡単にするために、サンプルを作成しました。

URL
※注)あくまでもサンプルです。各自の責任において使用してください。
※注)中身は非常に簡単なので、後述する方法で自作も可能ですので、是非トライしてみてください。

このサンプルでは、.NET Frameworkのユーティリティも使うので、.NET Framework SDKもインストールする必要があります。

ZIPファイルをダウンロードし、解凍してください。以下の二つのファイルが入っています。

  • BrickOSConfigSetupDialogInstaller.msi
  • legobrickosapptemplate.vsi

最初のファイルは、Visual Studio上で、プロジェクトを生成する際に、cygwinやbrickOSなどの場所を指定するためのダイアログ表示用クラスをインストールします。
二番目のファイルは、Visual Studioにプロジェクトテンプレートをインストールするためのファイルです。拡張子のvsiをzipに変えて解凍すると中に入っているファイルを見ることができます。
それぞれダブルクリックしてインストールしてください。プロジェクトテンプレートは、各ユーザーの設定が格納されている

%user% \My Document\Visual Studio 2005\Templates\ProjectTemplate

の下に、vsiファイルに入っているzipファイルがコピーされます。名前はLegoBrickOSApp.zipです。
2つのファイルのインストールが終わったら、Visual Studioを起動してください。

Visual Studioのメニューから、ファイル→新規作成→プロジェクト…を選択し、”新しいプロジェクト”ダイアログが表示されます。
テンプレートの項目の”マイテンプレート”のところに、”LegoBrickOSApp"というテンプレートが表示されます。
そのテンプレートを選択し、適切なプロジェクト名を付けて、プロジェクトを生成してください。

すると、以下のダイアログが表示されます。

 setup dialog

cygwinがインストールされているディレクトリと、brickOSがインストールされているディレクトリを入力してください。テキストボックスの右隣のボタンをクリックすると、グラフィカルにフォルダーを選択できます。
一通り設定したらOKボタンをクリックします。
インストールしたファイル群は、サンプルのため、署名等がなされていないため、現状では以下のアラートが表示されます。

図のように、ラジオボタンを選択し、OKボタンをクリックしてください。

そうすると、srcフォルダに4つのファイルが格納されたプロジェクトが出来上がります。
srcフォルダー以下にソースファイル群を作成します。
メニューから、ビルド→プロジェクトのビルドを選択すると、コンパイルが開始され、Lego Mindstormsにダウンロード可能なProject.lxファイルが、binフォルダー直下に作成されます。
それを、brickOSのdllツールでダウンロードしてください。
※現状のバージョンでは、残念ながら、コンパイル時のエラーが表示されません。Visual Studioのコマンドプロンプトから、プロジェクトが存在するディレクトリで以下のコマンドを実行してください。エラーが表示されます。ここは今後の改善ポイントですねぇ。

%ProjectDir% > msbuild

中身の説明:
legobrickosapptemplate.vsi
このファイルの拡張子を、zipに変更して、中身を覗いてください。このファイルはVisual Studio 2005にプロジェクトテンプレートをインストールすためのインストーラです。このファイルには、

  • legobrickosapptemplate.vscontent
  • LegoBrickOSApp.zip

という二つのファイルが入っています。二番目のファイルはプロジェクトテンプレート本体で、最初のファイルは、プロジェクトテンプレートをインストールする際の指示が記述されています。このファイルをメモ帳やXML Editorで開き、中身を確認してみてください。それらしき内容が記述されているのがわかるでしょう。
二番目のファイルは、ユーザー設定のプロジェクトテンプレート格納場所にコピーされたZIPファイルの元ファイルです。

%user%\My Documents\Visual Studio\Templates\ProjectTemplate\LegoBrickOSApp.zip

を開いてください。
中には、

  • MyTemplate.vstemplate
  • LegoBrickOSApp.csproj
  • __TemplateIcon.ico

の3つのファイルが入っています。ほかにsrcという名のフォルダーがあり、そこに4つのC言語ファイルが格納されています。このsrc以下のファイルをもとに、プロジェクト生成時に、最初に用意されているフォルダとファイルが作成されます。
MyTemplate.vstemplateは、このプロジェクトテンプレートの記述ファイルです。LegoBrickOSApp.csprojは、プロジェクト生成時に作成されるプロジェクトファイルのひな形になります。残りの__TemplateIcon.icoは、プロジェクトをGUI上に表示する場合のアイコンイメージです。このファイルを変えれば、望みのアイコンに変えることができます。

では、MyTemplate.vstemplateの中身をのぞいてみましょう。このファイルの中身はXMLファイルなので、メモ帳などで開いてください。
(・・中略:作成中・・)
このファイルの最後の方に、

<WizardExtension>    <Assembly>BrickOSConfigSetupDialog, Version=1.0.0.0, Culture=Neutral, PublickeyToken=193099d8a21855ce</Assembly>    <FullClassName>BrickOSConfigSetupDialog.ProjSetupWizardImpl</FullClassName></WizardExtension>

という記述があります。これが、プロジェクト生成時に必要なパラメータを入力するために表示するダイアログの設定です。
自分独自のダイアログを表示したい場合には、この記述を変更してください。

次に、LegoBrickOSApp.csprojを覗いてみましょう。このファイルの中身もまたXMLファイルなので、メモ帳などで開いてください。
Visual StudioにはBasic版やC#、C/C++版といった各種言語向けのIDEが用意されています。プロジェクト定義の方法がVisual C/C++ではあまり自由度がないというのも、プロジェクトテンプレートの作成でVisual C#を基本にしている理由の一つです。
このファイルの中で、コンパイルやリンクに関するビルドのルールが定義されています。CやC++で開発するときには、UNIXの時代からしぶとく生き残っているmakeを使う事が一般的だと思いますが、ここでは、「どんどん新しいことにチャレンジしよう!!」という意気込みで、MSBuildを使ってビルドルールを定義しています。
MSBuildは、Javaのビルドツールとして使われているantのようなツールです。ビルドルールの書き方の詳細については、https://msdn2.microsoft.com/ja-jp/library/ms171468(VS.80).aspx を参照してください。

ビルドルールを読むための説明を簡単にしておきます。このファイルは途中からTargetタグが順番に並んでいます。ビルドルールはTarget要素によって記述された基本実行単位の集合として記述されます。一番最後のTarget要素は下の様な記述になっています。

<Target Name="Build"  DependsOnTargets="DS"  Inputs="$(OBJDIR)\$(TARGETLX).ds1;$(OBJDIR)\$(TARGETLX).ds2"  Outputs="$(BINDIR)\$TARGETLX).lx"> <Exec    Command="$(BRICKOS_ROOT)util\makelx.exe $(OBJDIR)\$(TARGETLX).ds1 $(OBJDIR)\$(TARGETLX).ds2 $(BINDIR)\$(TARGETLX).lx"></Exec></Target>

TargetのNameがBuildになっていますね。これは、Visual Studio 2005のメニューからビルド→プロジェクトのビルドを選択した時に、このターゲットが実行されることを意味しています。実行される内容は、Exec要素で記述されています。Exec要素のCommand属性で記述されたコマンドが実行されます。ここではbrickOSがインストールされているディレクトリのutil/makelx.exeコマンドの実行が記述されています。
Targetの属性でDependsOnTargetsが記述されています。これはTargetの依存関係を定義するもので、ここでは、DSという名前のTargetに依存することが示されています。DependsOnTargets属性をもつTargetを実行するには、依存しているTargetが実行されている必要があります。つまり、ここでは、「Buildターゲットを実行する前にDSターゲットを実行して成功していなさいよ」ということを意味しています。依存関係を順にたどって、逆から読むと、どういう順番でコマンドが実行されていくのか、理解できるでしょう。
他に、$(XXX)という記述がありますが、これは、コマンド実行時に、値が確定する変数です。具体的にどんな値が入るかは、ファイルの上の方に記載されているPropertyGroupタグの中で、記述されています。PropertyGroupの記述内容を以下に示します。

<PropertyGroup> <TOOL_DIR>$cygwininstalldir$\usr\local\bin\</TOOL_DIR> <TOOL_PREFIX>h8300-hitachi-hms-</TOOL_PREFIX> <BRICKOS_ROOT>$brickosinstalldir$\</BRICKOS_ROOT> <CFLAGS>-D_W32 -O2 -fno-builtin -fomit-frame-pointer -Wall -I$(BRICKOS_ROOT)include -I$(BRICKOS_ROOT)include/lnp -I. -I$(BRICKOS_ROOT)boot $(USR_DFLAGS)</CFLAGS> <LIBS>-lc -lmint -lfloat -lc++</LIBS> <KERNEL>$(BRICKOS_ROOT)boot\brickOS.lds</KERNEL> <DLDFLAGS>-T $(KERNEL) -relax -L$(BRICKOS_ROOT)lib</DLDFLAGS> <ODFLAGS>--disassemble-all --no-show-raw-insn -m h8300</ODFLAGS> <USR_DFLAGS></USR_DFLAGS> <ADDR_BASE1>0xb000</ADDR_BASE1> <ADDR_BASE2>0xb210</ADDR_BASE2> <TARGETLX>$(MSBuildProjectName)</TARGETLX> <SRCDIR>src</SRCDIR> <OBJDIR>obj</OBJDIR> <BINDIR>bin</BINDIR></PropertyGroup>

PropertyGroup要素直下の各要素が、各プロパティ名の定義になり、各要素のテキスト要素がそれぞれのプロパティの値になります。
ここで$XXX$という記述(赤字の部分)に注目してください。ここは、このプロジェクトテンプレートを基にプロジェクトを生成する際に置き換わる文字列です。
既に、プロジェクトを生成している場合は、プロジェクトを作成したディレクトリのcsprojファイルをメモ帳などで開いてみてください。この部分の文字列が、プロジェクト生成時にダイアログで入力した文字列に置き換わっているのがわかるでしょう。これはcsprojファイルだけでなく、他のファイルでもこの機能を使うことが可能です。
ダイアログとこの仕組みを使って、プロジェクト生成時にパラメータを任意に入力して初期ファイルの内容を変更することができます。

さて、次に、プロジェクトテンプレートの作成方法を説明します。作成方法を以下に示します。

  1. Visual Studio 2005でプロジェクトを作成
  2. プロジェクト生成時にあらかじめ必要なテキストファイルを作成
  3. メニューから、ファイル→テンプレートのエクスポート・・・を選択しテンプレートをエクスポート
  4. %user%\My Documents\Visual Studio 2005\My Exported Templatesに、ZIPファイル形式でエクスポートされるので、適当な場所にコピー
  5. ZIPファイル内のxxprojファイルとvstemplateファイルを必要に応じてカスタマイズし、保存

ここまでで、プロジェクトテンプレートファイルが出来上がります。サンプルで公開しているプロジェクトテンプレートに仕立て上げるには、LegoBrickOSAppという名前でC#用のプロジェクトを作成してsrcフォルダーを作成し4つのCソースファイルをsrcフォルダーに格納してプロジェクトテンプレートをエクスポートします。
そしてvstemplateファイルの中のTemplateContent要素の中身を以下のように変更し、

<TemplateContent> <Project TargetFileName="LegoBrickOSApp.csproj" File="LegoBrickOSApp.csproj" ReplaceParameters="true">  <Folder Name="Properties" TargetFolderName="Properties" />  <Folder Name="src" TargetFolderName="src">   <ProjectItem ReplaceParameters="true" TargetFileName="lmarch.c">lmarch.c</ProjectItem>   <ProjectItem ReplaceParameters="true" TargetFileName="lmarch.h">lmarch.h</ProjectItem>   <ProjectItem ReplaceParameters="true" TargetFileName="lmarchctrl.c">lmarchctrl.c</ProjectItem>   <ProjectItem ReplaceParameters="true" TargetFileName="main.c">main.c</ProjectItem>  </Folder> </Project></TemplateContent>

TemplateContent要素の次に前述のWizard指定の記述を入れます。このとき、Wizardも自作する場合は、自作したWizardに合わせてAssembly要素やFullClassNameを変える必要があります。
また、TemplateContent要素のReplaceParameters属性は、プロジェクト生成時にファイル内のパラメータを置き換える必要がある場合にはTrueに設定しておきましょう。それから、TargetFileName属性の値を変える場合は、その値と同じ名前になるようにprojファイルの名前を変えましょう。
次にLegoBrickOSApp.csprojをサンプルに入っているcsprojとおなじ内容になるように変更します。

さて、次に、VSIファイルの作成方法を説明します。作成方法は以下のとおりです。

  1. 適当な名前でXMLファイルを作成
  2. 内容を作成し、保存
  3. 拡張子をvscontentに変更
  4. ZIPファイルを一つ作成
  5. 作成したZIPファイルにプロジェクトテンプレートのZIPファイルとvscontentファイルを格納
  6. 作成したZIPファイルの拡張子をvsiに変更

手順2で作成するファイルの内容は、

<?xml version="1.0" encoding="utf-8"?><VSContent xmlns="https://schemas.microsoft.com/developer/vscontent/2005">  <Content>    <FileName>LegoBrickOSApp.zip</FileName>    <DisplayName>Lego brickOS Cross Development Project Template</DisplayName>    <Description></Description>    <FileContentType>VSTemplate</FileContentType>    <ContentVersion>1.0</ContentVersion>    <Attributes>      <Attribute name="ProjectType" value="Visual C#"/>      <Attribute name="ProjectSubType" value="Lego"/>      <Attribute name="TemplateType" value="Project"/>    </Attributes>  </Content></VSContent></Target>

こんな感じです。Content要素の中のFileName要素にインストールしたいプロジェクトテンプレートZIPファイル名を、表示したい名前や説明をそれぞれDisplayName要素とDescription要素に記述します。その他Attributes要素以下のAttribute要素のnameとvalueを必要に応じて変更します。vscontentファイルの詳細については、https://msdn2.microsoft.com/ja-jp/library/ms246580(vs.80).aspx を参照してください。

では次に、プロジェクト生成時に表示するダイアログの作成方法を説明します。まずは、C#のクラスライブラリプロジェクトを1つ作成し、https://msdn2.microsoft.com/ja-jp/library/ms185301(VS.80).aspx を参照してカスタムウィザードクラスライブラリを作成してください。公開しているサンプルでは、$cygwininstalldir$と$brickosinstalldir$の二つの値を供給する必要があります。
MSDNに記載のやりかたを参考にして作成したフォームにこの二つのパラメータを入力するためのUIを追加します。
その後、MSDNの中でIWizardImplementationとして紹介されているクラスに相当して作成したクラスのRunStartedメソッド内に、引数replacementDictionaryに、フォームから取得した値をそれぞれ、$cygwininstalldir$と$brickosinstalldir$で格納するコードを追加します。
これでダイアログ用クラスライブラリは完成です。
署名の設定をし、ビルドすれば必要なDLLファイルができます。

(・・Under Construction・・・)