Skip to content
OlegZeePublic
forked from FakeBuild/Xake

About

Another MAKE utility implementation on F#, fully declarative with no-brain parallelism, inspired by Shake

Resources

Stars

5 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Xake is a build utility that uses the full power of the F# programming language. Xake is inspired by shake build tool.

Build and Test

Sample script

The simple script looks like:

#r "nuget: Xake"

open Xake
open Xake.Dotnet

do xakeScript {
    "main" <== ["helloworld.exe"]

    "helloworld.exe" ..> csc {
        targetfwk "net-4.6.2"
        src !!"helloworld.cs"
        grefs ["System.dll"]
    }
}

This script compiles helloworld assembly from helloworld.cs file, on any OS. Rules are written straight in the body of xakeScript — no rules [ ... ] wrapper needed.

The single Xake package contains both the engine (Xake, Xake.Tasks) and the tasks for the full .NET Framework (Xake.Dotnet) — one reference is enough.

Getting started

Make sure dotnet SDK 8.0 or newer is installed. Save any of the scripts below as build.fsx and run it with dotnet fsi build.fsx — Xake comes from NuGet, there is nothing else to install.

1. Hello world

The smallest useful script: one phony rule, printing a message. main is the default target, so no arguments are needed.

#r "nuget: Xake"

open Xake

do xakeScript {
    "main" => trace Message "Hello world!"
}

2. A rule that produces a file

..> declares a file target. The recipe writes the target file, and main demands it — targets are built on demand, and only the ones that are actually needed.

#r "nuget: Xake"

open Xake
open Xake.Tasks

do xakeScript {
    "main" => need ["out/hello.txt"]

    "out/hello.txt" ..> writeText "Hello world!"

    "clean" => rm { dir "out" }
}
dotnet fsi build.fsx            # builds "main"
dotnet fsi build.fsx -- -- clean

3. A recipe with dependencies

A recipe { ... } is a sequence of steps. Anything it reads through Xake — readText here — is recorded as a dependency, so the target is rebuilt when, and only when, one of its inputs changes.

#r "nuget: Xake"

open Xake
open Xake.Tasks

do xakeScript {
    "main" => need ["out/hello.txt"]

    "out/hello.txt" ..> recipe {
        // records name.txt as a dependency of this target
        let! name = readText "name.txt"

        do! trace Info "greeting %s" (name.Trim())
        do! writeText $"Hello, {name.Trim()}!"
    }

    "clean" => rm { dir "out" }
}

Create name.txt next to the script and run it twice: the second run reports Skipped main (up to date). Change name.txt and it rebuilds.

More samples

git clone https://github.com/OlegZee/Xake
cd xake
dotnet fsi build.fsx -- -- build      # features.fsx and fullframework.fsx use the local build
cd samples
dotnet fsi gettingstarted.fsx
dotnet fsi features.fsx
dotnet fsi fullframework.fsx

Further reading

Build the project

Once you cloned the repository you are ready to compile and test the binaries:

dotnet fsi build.fsx -- -- build test

... or use build.cmd (build.sh) in the root folder. build.fsx (msbuild via dotnet build) is the build of record: packages and releases come from it.

The declarative build (build.fsc.fsx)

The same three libraries, compiled by fsc from committed data instead of msbuild: a project description per project (src/<dir>/xake.project.json), a lock per project and configuration (locks/<name>/Release.json) and their fingerprints (xake.fingerprints). The script runs on the published Xake and Xake.Hermetic.Dotnet packages, so a fresh clone needs no bootstrap:

dotnet fsi build.fsc.fsx -- -- build              # out/Release/<fwk>/*.dll from the committed locks
dotnet fsi build.fsc.fsx -- -- build check        # and fail on a stale description or lock
Command What it does
import msbuild evaluates each .fsproj and writes its xake.project.json (only on change)
update-locks writes locks/<name>/Release.json from the descriptions, referenced projects first; packages via msbuild restore, kept versions unless -d LOCK_REFRESH=<ids|*>
build compiles from the committed locks only, no msbuild; warns when a description or lock is stale against its inputs
check fails where build only warns (stale or hand-edited descriptions and locks)

After changing a project file: import, update-locks, commit the changed descriptions, locks and xake.fingerprints. The locks name the SDK's compiler by the SDK version (no hash), so they hold for that SDK version (10.0.401) on any OS (CI runs this build on Linux with that SDK). See docs/hermetic/lock.md.

Releases are published to nuget.org by CI from a v* tag — see docs/devprocess.md for the packaging and release procedure.

Building .NET Framework targets

The csc, fsc, msbuild and resgen tasks build full-framework binaries on any OS with nothing installed beyond the .NET SDK: the compilers come from the SDK and the reference assemblies from the Microsoft.NETFramework.ReferenceAssemblies.* packages, restored on first use. Mono is still supported as a fallback and can be requested explicitly with a mono- prefixed framework name.

See docs/dotnet-build.md for the discovery rules, the supported runtimes, and how to switch between them.

Documentation

See documentation for more details.

References

About

Another MAKE utility implementation on F#, fully declarative with no-brain parallelism, inspired by Shake

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages