Skip to content

Instantly share code, notes, and snippets.

@neetsdkasu
Last active March 1, 2017 22:31
Show Gist options
  • Save neetsdkasu/6730b5f26c3ebe1b12a72ab5ca9e79a6 to your computer and use it in GitHub Desktop.
Save neetsdkasu/6730b5f26c3ebe1b12a72ab5ca9e79a6 to your computer and use it in GitHub Desktop.
MSBuildを使ってF#をコンパイル

MSBuildを使ってF#をコンパイルしてみるテスト

参考にした情報:

検証環境:

  • F# 2.0 Compiler build 4.0.40219.1
  • Windows7 Starter SP1
  • .NET Framework v4.0.30319.42000(?) v4.6.1087.0(?)

分かったこと1:

Microsoft.FSharp.Targets

  • インストールディレクトリの%ProgramFiles%\Microfsoft F#\v4.0\
  • MSBuildディレクトリの%ProgramFiles%\MSBuild\FSharp\1.0\

の2箇所に存在した

MSBuild.exeMicrosoft.Common.targets%WINDIR%\Microsoft.Net\Framework\v4.0.30319\に存在した

MSBuildの予約済みプロパティや共通プロパティや共通項目はMSBuildや.NET Frameworkのバージョンによって異なる   v4.0はBuild Engineバージョンを4.5とか4.6に上げたやつだと多いけど4.0のままだと3.5と大差ない

分かったこと2:

簡単な単一アプリの生成だけならMSBuildプロジェクトの共通項目であるCompileにソースファイル指定するだけでおk。
アプリのファイル名はMSBuildの共通プロパティのAssemblyNameに拡張子除いたファイル名を指定しておけばおk。
ProjectDefaultTargetsの指定はいらない(Buildターゲットになる?)けど
ToolVersionは指定しないとインストールされている一番古いToolVersionでコンパイルされる(?)。
ただし、設定値を反映させるためにはMicrosoft.FSharp.TargetsImportはprojファイルの最後で指定する必要がある。

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <AssemblyName>myapp</AssemblyName>
    </PropertyGroup>
    <ItemGroup>
        <Compile Include="mysourcecode1.fs" />
        <Compile Include="mysourcecode2.fs" />
    </ItemGroup>
    <Import Project="C:\Program Files\MSBuild\FSharp\1.0\Microsoft.FSharp.Targets" />
</Project>

この場合、オブジェクトファイルなどの一時ファイルはobj\Debugディレクトリに、最終生成物はbin\Debugに置かれる。
MSBuildの共通プロパティのConfigurationReleaseを設定するとDebugビルドではなくReleaseビルドになる。
Microsoft.FSharp.TargetsMicrosoft.Common.targetsも読み込むためそれらに定義されている共通ターゲット(Runなど)を呼び出すことができる。

module Fuga
let private func1 =
let value = Baz.Piyo.FooBar.Hoge.hoge 30
in do printfn "Baz.Piyo.FooBar.Hoge.hoge 30 = %d" value
let private func2 =
let value = Baz.Piyo.Hoge.hoge 40
in do printfn "Baz.Piyo.Hoge.hoge 40 = %d" value
let private func3 =
let value = Baz.Hoge.hoge 50
in do printfn "Baz.Hoge.hoge 50 = %d" value
[<EntryPoint>]
let main _ =
do func1
func2
func3
0
<Project DefaultTargets="BuildFuga" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Init Fsharp Build -->
<PropertyGroup>
<FSharpBuildTargetFilePath>C:\Program Files\MSBuild\FSharp\1.0\Microsoft.FSharp.Targets</FSharpBuildTargetFilePath>
</PropertyGroup>
<Import Project="$(FSharpBuildTargetFilePath)" />
<!-- BuildHoge -->
<PropertyGroup>
<OutputHoge>Hoge.dll</OutputHoge>
</PropertyGroup>
<ItemGroup>
<SourceHoge Include="Hoge.fs" />
<CleanupFiles Include="$(OutputHoge)" />
</ItemGroup>
<Target Name="BuildHoge"
Inputs="@(SourceHoge)"
Outputs="$(OutputHoge)"
>
<Fsc OutputAssembly="$(OutputHoge)"
Sources="@(SourceHoge)"
TargetType="library"
/>
</Target>
<!-- BuildFuga -->
<PropertyGroup>
<OutputFuga>Fuga.exe</OutputFuga>
<DependsOnFuga>
BuildHoge
</DependsOnFuga>
</PropertyGroup>
<ItemGroup>
<ReferenceFuga Include="$(OutputHoge)" />
<SourceFuga Include="Fuga.fs" />
<CleanupFiles Include="$(OutputFuga)" />
</ItemGroup>
<Target Name="BuildFuga"
Inputs="@(ReferenceFuga);
@(SourceFuga)"
Outputs="$(OutputFuga)"
DependsOnTargets="$(DependsOnFuga)"
>
<Fsc OutputAssembly="$(OutputFuga)"
References="@(ReferenceFuga)"
Sources="@(SourceFuga)"
/>
</Target>
<!-- Run (Override) -->
<PropertyGroup>
<RunCommand>$(OutputFuga)</RunCommand>
</PropertyGroup>
<Target Name="Run">
<Error Text="$(RunCommand) is not found." Condition="!Exists('$(RunCommand)')" />
<Exec Command="$(RunCommand)" Condition="Exists('$(RunCommand)')" />
</Target>
<!-- Clean (Override) -->
<Target Name="Clean">
<Delete files="@(CleanupFiles)" />
</Target>
</Project>
////////////////////////////////////////////
// Test Dulicate Module
////////////////////////////////////////////
////////////////////////////////////////////
namespace Baz.Piyo.FooBar
module Hoge =
let hoge (x : int) : int = x * 100
////////////////////////////////////////////
namespace Baz.Piyo
module Hoge =
open Baz.Piyo.FooBar.Hoge
let hoge = hoge
////////////////////////////////////////////
namespace Baz
module Hoge =
open Baz.Piyo.FooBar.Hoge
let hoge = hoge
////////////////////////////////////////////
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment