Eric
Eric

Reputation: 610

How do you specify Fake Target inputs and output?

In the build systems that I'm familiar with (make and msbuild) there's a way to specify the inputs and outputs for a target. If the time stamps on the input files are earlier than those on the outputs the task is skipped. I can't find something similar in FAKE.

For example if I wanted to translate this Makefile to Fake

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

it might look like:

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

However, when I run the build command it will always execute the compiler and produce a new a.exe regardless the modification time on a.fs. Is there a simple way to get the same behavior as the makefile?

Upvotes: 1

Views: 114

Answers (2)

Eric
Eric

Reputation: 610

A more complete code example to flesh out Lazydevs answer:

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

Upvotes: 0

Lazydev
Lazydev

Reputation: 459

You could use =?>and provide a function that returns true or false if the task should run.

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

and then in target dependencies

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

Upvotes: 2

Related Questions