更新:ほとんどの場合、より簡単な方法があることを示しています。:-)
最初のステップは、条件付きコンパイルを使用して Silverlight 固有のコードを分離することです。(「デフォルト」のターゲットはWPFであると想定しています。)
次に、各プラットフォームのコードをコンパイルし、適切な定義とアセンブリ参照を設定するビルド スクリプトが必要です。
オープンソースのCaliburn プロジェクトを見てみましょう。このすべてを行います。
Caliburn の ExtensionMethods クラスの例を次に示します。
public static T GetResource<T>(this FrameworkElement element, object key)
{
DependencyObject currentElement = element;
while (currentElement != null)
{
var frameworkElement = currentElement as FrameworkElement;
if (frameworkElement != null && frameworkElement.Resources.Contains(key))
return (T)frameworkElement.Resources[key];
#if !SILVERLIGHT
currentElement = (LogicalTreeHelper.GetParent(currentElement) ??
VisualTreeHelper.GetParent(currentElement));
#else
currentElement = VisualTreeHelper.GetParent(currentElement);
#endif
}
if (Application.Current.Resources.Contains(key))
return (T)Application.Current.Resources[key];
return default(T);
}
Caliburn を VS で開いてコンパイルすると、標準フレームワークに準拠します。参照は、Silverlight ではなく、.NET 3.5 および WPF 用です。前処理ディレクティブが「!SILVERLIGHT」であるのはそのためでもあります。
ビルド スクリプト (Caliburn は NAnt を使用) には、各プラットフォームの定義を設定するターゲットがあります。たとえば、Caliburn の Silverlight ターゲットは次のとおりです。
<target name="config-platform-silverlight20">
<property name="nant.settings.currentframework" value="silverlight-2.0"/>
<property name="build.platform" value="silverlight-2.0"/>
<property name="build.defines" value="${global.build.defines},SILVERLIGHT,SILVERLIGHT_20,NO_WEB,NO_REMOTING,NO_CONVERT,NO_PARTIAL_TRUST,NO_EXCEPTION_SERIALIZATION,NO_SKIP_VISIBILITY,NO_DEBUG_SYMBOLS"/>
<property name="current.path.bin" value="${path.bin}/silverlight-2.0/${build.config}"/>
<property name="current.path.test" value="${path.bin}/silverlight-2.0/tests" />
<property name="current.path.lib" value="${path.lib}/Silverlight" />
</target>
次に、実際の Silverlight ビルドを呼び出すターゲットを次に示します。
<target name="platform-silverlight20" depends="config">
<if test="${framework::exists('silverlight-2.0')}">
<echo message="Building Caliburn ${build.version} for Silverlight v2.0."/>
<call target="config-platform-silverlight20"/>
<copy todir="${current.path.bin}">
<fileset basedir="${current.path.lib}">
<include name="*.dll"/>
<include name="*.xml"/>
</fileset>
</copy>
<call target="core"/>
<call target="messaging"/>
<call target="actions"/>
<call target="commands"/>
<call target="package-platform"/>
</if>
<if test="${not(framework::exists('silverlight-2.0'))}">
<echo message="Silverlight v2.0 is not available. Skipping platform."/>
</if>
</target>
最後に、Caliburn.Core.dll の生成を担当する「コア」ターゲットの例を次に示します。
<target name="core" depends="config, ensure-platform-selected">
<mkdir dir="${current.path.bin}"/>
<csc keyfile="${path.src}/Caliburn.snk" noconfig="true" warnaserror="false" target="library" debug="${build.debug}" optimize="${build.optimize}" define="${build.defines}"
output="${current.path.bin}/Caliburn.Core.dll"
doc="${current.path.bin}/Caliburn.Core.xml">
<sources basedir="${path.src}">
<include name="${build.asminfo}"/>
<include name="Caliburn.Core/**/*.cs"/>
</sources>
<references basedir="${current.path.bin}">
<include name="mscorlib.dll"/>
<include name="System.dll"/>
<include name="System.Core.dll"/>
<!--WPF-->
<include name="PresentationCore.dll"/>
<include name="PresentationFramework.dll"/>
<include name="WindowsBase.dll"/>
<!--Silverlight-->
<include name="System.Windows.dll" />
</references>
<nowarn>
<warning number="1584"/>
</nowarn>
</csc>
</target>
必要なアセンブリを参照する方法に注意してください。
おそらく NAnt.exe.config を編集して (NAnt を使用している場合)、Silverlight フレームワークの正しいバージョンに一致させる必要があります。Silverlight RTW の場合、フレームワークのバージョンは 2.0.31005.0 になります。