如何将此 MSBuild 脚本转换为 F#/FAKE?
How to translate this MSBuild script to F#/FAKE?
将以下 MSBuild 脚本翻译成 F#/FAKE 是什么?
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CurrentMode>None</CurrentMode>
</PropertyGroup>
<Target Name="Compile_A">
<Message Text="Hello from Compile_A" />
<CallTarget Targets="SetToA"/>
<CallTarget Targets="IntermediateStage"/>
</Target>
<Target Name="Compile_B">
<Message Text="Hello from Compile_B" />
<CallTarget Targets="SetToB"/>
<CallTarget Targets="IntermediateStage"/>
</Target>
<Target Name="IntermediateStage">
<Message Text="Hello from IntermediateStage" />
<CallTarget Targets="Compile"/>
</Target>
<Target Name="Compile">
<Message Text="Hello from Compile. I'm using $(CurrentMode)" />
</Target>
<!-- The following Targets are only necessary due to a MSBuild bug (CallTarget and CreateProperty cannot be combined) -->
<Target Name="SetToA">
<CreateProperty Value="A">
<Output TaskParameter="Value" PropertyName="CurrentMode" />
</CreateProperty>
</Target>
<Target Name="SetToB">
<CreateProperty Value="B">
<Output TaskParameter="Value" PropertyName="CurrentMode" />
</CreateProperty>
</Target>
</Project>
我的主要目标是在最上面的目标中设置一个 属性 具有不同的值(CurrentMode
是 A
或 B
)并在最深处消耗它目标 (Compile
).
最佳答案可能会因您的实际情况而异。特别是,如果您不打算单独 运行 它们,您甚至可能不需要为流程的不同步骤单独设置目标(在这种情况下,只需使用一个将模式作为参数的函数并调用它来自 CompileA
和 CompileB
可以正常工作)。
但是,如果您想为所有步骤保留单独的目标,您可以这样做:
#load ".fake/build.fsx/intellisense.fsx"
open Fake.Core
open Fake.Core.TargetOperators
let mutable CurrentMode = "None"
Target.create "SetA" (fun _ ->
CurrentMode <- "A"
)
Target.create "SetB" (fun _ ->
CurrentMode <- "B"
)
Target.create "IntermediateStage" (fun _ ->
printfn "In the intermediate stage"
)
Target.create "Compile" (fun _ ->
printfn "Compiling using mode %s" CurrentMode
)
Target.create "CompileA" ignore
Target.create "CompileB" ignore
"SetA" ==> "CompileA"
"SetB" ==> "CompileB"
"IntermediateStage" ==> "Compile" ==> "CompileA"
"IntermediateStage" ==> "Compile" ==> "CompileB"
"SetA" ?=> "IntermediateStage"
"SetB" ?=> "IntermediateStage"
Target.runOrDefault "CompileA"
这使用由 SetA
或 SetB
目标设置的可变变量 CurrentMode
(可以说,不是很实用,但它捕获了你正在做的事情)。
目标之间的依赖关系使用==>
指定。请注意,SetA
必须在 CompileA
之前发生(B 也类似)并且 IntermediateStage
需要在 Compile
之前发生,这是两种编译的先决条件。
有一个巧妙的技巧 - 你不想说 IntermediateStep
需要 SetA
和 SetB
,因为 FAKE 会 运行 都在非确定性顺序。 ?=>
opreator 允许您指定 soft dependencies 表示如果 IntermediateStep
和 SetA
都被执行,那么 SetA
有首先 - 所以最后两行不是添加依赖项,而是明确排序。
将以下 MSBuild 脚本翻译成 F#/FAKE 是什么?
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CurrentMode>None</CurrentMode>
</PropertyGroup>
<Target Name="Compile_A">
<Message Text="Hello from Compile_A" />
<CallTarget Targets="SetToA"/>
<CallTarget Targets="IntermediateStage"/>
</Target>
<Target Name="Compile_B">
<Message Text="Hello from Compile_B" />
<CallTarget Targets="SetToB"/>
<CallTarget Targets="IntermediateStage"/>
</Target>
<Target Name="IntermediateStage">
<Message Text="Hello from IntermediateStage" />
<CallTarget Targets="Compile"/>
</Target>
<Target Name="Compile">
<Message Text="Hello from Compile. I'm using $(CurrentMode)" />
</Target>
<!-- The following Targets are only necessary due to a MSBuild bug (CallTarget and CreateProperty cannot be combined) -->
<Target Name="SetToA">
<CreateProperty Value="A">
<Output TaskParameter="Value" PropertyName="CurrentMode" />
</CreateProperty>
</Target>
<Target Name="SetToB">
<CreateProperty Value="B">
<Output TaskParameter="Value" PropertyName="CurrentMode" />
</CreateProperty>
</Target>
</Project>
我的主要目标是在最上面的目标中设置一个 属性 具有不同的值(CurrentMode
是 A
或 B
)并在最深处消耗它目标 (Compile
).
最佳答案可能会因您的实际情况而异。特别是,如果您不打算单独 运行 它们,您甚至可能不需要为流程的不同步骤单独设置目标(在这种情况下,只需使用一个将模式作为参数的函数并调用它来自 CompileA
和 CompileB
可以正常工作)。
但是,如果您想为所有步骤保留单独的目标,您可以这样做:
#load ".fake/build.fsx/intellisense.fsx"
open Fake.Core
open Fake.Core.TargetOperators
let mutable CurrentMode = "None"
Target.create "SetA" (fun _ ->
CurrentMode <- "A"
)
Target.create "SetB" (fun _ ->
CurrentMode <- "B"
)
Target.create "IntermediateStage" (fun _ ->
printfn "In the intermediate stage"
)
Target.create "Compile" (fun _ ->
printfn "Compiling using mode %s" CurrentMode
)
Target.create "CompileA" ignore
Target.create "CompileB" ignore
"SetA" ==> "CompileA"
"SetB" ==> "CompileB"
"IntermediateStage" ==> "Compile" ==> "CompileA"
"IntermediateStage" ==> "Compile" ==> "CompileB"
"SetA" ?=> "IntermediateStage"
"SetB" ?=> "IntermediateStage"
Target.runOrDefault "CompileA"
这使用由 SetA
或 SetB
目标设置的可变变量 CurrentMode
(可以说,不是很实用,但它捕获了你正在做的事情)。
目标之间的依赖关系使用==>
指定。请注意,SetA
必须在 CompileA
之前发生(B 也类似)并且 IntermediateStage
需要在 Compile
之前发生,这是两种编译的先决条件。
有一个巧妙的技巧 - 你不想说 IntermediateStep
需要 SetA
和 SetB
,因为 FAKE 会 运行 都在非确定性顺序。 ?=>
opreator 允许您指定 soft dependencies 表示如果 IntermediateStep
和 SetA
都被执行,那么 SetA
有首先 - 所以最后两行不是添加依赖项,而是明确排序。