2016-08-24 42 views
1

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

例如,如果我想这个Makefile转化为假

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

它可能看起来像:

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

然而,当我运行此命令,它会总是执行编译并生成一个新的a.exe,无论a.fs.上的修改时间如何。有没有一种简单的方法来获得与makefile相同的行为?

回答

2

您可以使用=?>并提供一个函数,如果任务应该运行,则返回true或false。

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

,然后在目标的依赖

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

这个作品真的很好。我也可以使用它来轻松定义一个接受输入和输出文件列表的BuildTarget,所以没有冗余。如果其他人发现它有用,我会添加一个完整的示例。 – Eric

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"