2016-08-24 22 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"