Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReFake: an incremental build logic DSL #497

Closed
wants to merge 1 commit into from
Closed

ReFake: an incremental build logic DSL #497

wants to merge 1 commit into from

Conversation

yawaramin
Copy link
Contributor

My effort at creating an incremental build DSL on top of FAKE. For several reasons, as explained in the commit message, I did this by creating a new type of build 'target' that stores more information about the target and its dependencies. The implementation is as simple as possible; there are no lookups of target names to objects happening in the background. The build script writer directly creates target objects using the helper functions, and arranges them into a dependency network at the same time. They then run the topmost target in the network to lazily build whatever needs to be built.

This also allows a pretty elegant way of setting up multiple build configurations in the same script using what I call 'virtual targets'. A simple example:

#r "/path/to/FakeLib.dll"
open Fake.FscHelper
open Fake.ReFake

// Debug configuration is default.
let debug = ref true
let outputPath = ref "bin/Debug/"
let optimize = ref "--optimize-"

// A virtual target that sets up a release configuration and doesn't have any dependencies.
let releaseConfig = vx "Release Configuration" [] (fun _ _ ->
  debug := false
  outputPath := "../../../build/"
  optimize := "--optimize+"
  0) // Need to return an exit code from build function

// A file target that depends on 'Main.fs'.
let Main_exe = fx' "Main.exe" [fx "Main.fs"] (fun name deps ->
  fxs deps // Gets list of names of input files.
  |> fsc (fun ps -> // 'fsc' automatically returns exit code.
    { ps with Output = !outputPath + name
              Debug = !debug
              OtherParams = [!optimize] }))

// A virtual target that depends on 'Main.exe'.
let debugBuild = vx "Debug Build" [Main_exe] nop
// A virtual target that depends on 'releaseConfig' _and_ 'Main.exe' (list order matters).
let releaseBuild = vx "Release Build" [releaseConfig; Main_exe] nop

reRunAndExit debugBuild
//reRunAndExit releaseBuild

Because the releaseConfig target is a dependency of the releaseBuild target, it will always be run before releaseBuild; and will thus set up the release parameters.

I'm currently trying to convert the FakeLib.fsproj file into a ReFake build script, and am about 80% there. Just ironing out a few referencing issues now.

This is a first effort, so I'd welcome feedback.

Relates to issue #235.

Relies on the new 'fsc' compile function.

For now, a proof-of-concept of incremental build natively within FAKE. I
re-implemented a 'target' record type ('ReTarget') to store a little
more information about each target:

  - The type of target. Can be an output file, a reference file (one
    that's passed in to the F# compiler with the '--reference:' switch),
    or a _virtual_ target (a target that always causes its dependencies
    to be built). I think it's vital to make a distinction so we can
    internally decide whether to build incrementally or not.

  - A list of dependencies of the target, which are themselves also
    targets. I felt this was important to store inside the target type
    itself to make it simpler for the build function ('reRun') to look
    up dependencies and pass them along into the build action function
    (see the tutorial for a concrete example).
@panesofglass
Copy link
Contributor

This is pretty nice! One thing I would mention is that this may be better as a separate library (as mentioned in #235) that builds on FAKE rather than extensions built into FAKE itself. Also, how do you take care of file ordering?

@yawaramin
Copy link
Contributor Author

@panesofglass agh, I forgot this was still open :-) I've since moved more towards writing MSBuild scripts in F#: https://github.com/yawaramin/FsBuild/blob/master/Build.fsx

@yawaramin yawaramin closed this May 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants