如何将此MSBuild脚本转换为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>

我的主要目标是在最顶层的目标中设置一个具有不同值的属性(CurrentModeAB),并在最深的目标(Compile)中使用它。

最佳答案可能会根据您的实际情况而有所不同。特别是,如果您不打算单独运行流程的不同步骤,则甚至可能不需要单独的目标(在这种情况下,只需使用将模式作为参数并从CompileACompileB调用该函数即可正常工作)。

但是,如果要为所有步骤保留单独的目标,则可以执行以下操作:

#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"

这使用由SetASetB目标设置的可变变量CurrentMode(可以说,功能不是很强大,但它捕获了您正在做的事情)。

目标之间的依赖关系使用==>指定。请注意,SetA必须在CompileA之前发生(B也是如此),IntermediateStage需要在Compile之前发生,这是两种编译的先决条件。

有一个微妙的技巧 - 你不想说IntermediateStep需要SetASetB,因为这样 FAKE 会以非确定性的顺序运行两者。?=>Opreator 允许您指定软依赖项,这些依赖项表示如果要执行IntermediateStepSetA,则SetA必须首先执行 - 所以最后两行不添加依赖项, 但使排序明确。

最新更新