如何指定假目标输入和输出?

时间:2016-08-24 21:12:07

标签: f#-fake

在我熟悉的构建系统(make和msbuild)中,有一种方法可以指定目标的输入和输出。如果输入文件上的时间戳早于输出上的时间戳,则跳过任务。我在FAKE中找不到相似的东西。

例如,如果我想将此Makefile翻译为Fake

a.exe: a.fs
   fsharpc a.fs -o a.exe

它可能看起来像:

Target "a.exe" (fun _ -> ["a.fs"] |> FscHelper.compile [...])

但是,当我运行build命令时,总是执行编译器并生成一个新的a.exe,无论a.fs上的修改时间如何。是否有一种简单的方法可以获得与makefile相同的行为?

2 个答案:

答案 0 :(得分:2)

您可以使用=?>并提供一个在任务运行时返回true或false的函数。

let fileModified f1 f2 =
     FileInfo(f1).LastWriteTime > FileInfo(f2).LastWriteTime

然后是目标依赖项

     =?> ("a.exe", fileModified "a.fs" "a.exe")

答案 1 :(得分:0)

一个更完整的代码示例,以充实Lazydevs回答:

#r "packages/FAKE/tools/FakeLib.dll"
open Fake
open System.IO

Target "build" (fun _ ->
  trace "built"
)

let needsUpdate f1 f2 =
  let lastWrite files =
    files
    |> Seq.map (fun f -> FileInfo(f).LastWriteTime)
    |> Seq.max
  let t1 = lastWrite f1
  let t2 = lastWrite f2
  t1 > t2

let BuildTarget name infiles outfiles fn =
  Target name (fn infiles)
  name =?> ("build", needsUpdate infiles outfiles)

BuildTarget "compile" ["Test2.fs"; "Test1.fs"] ["Test2.dll"] (fun files _ ->
  files
  |> FscHelper.compile [
    FscHelper.Target FscHelper.TargetType.Library
  ]
  |> function 0 -> () | c -> failwithf "compile error"
)

RunTargetOrDefault "build"