F* Package Manager (FPM) is a package manager for F*, on top of the Nix package manager.
Given a list of F* modules and of (git-based) F* dependencies, FPM automatically provides:
- ready-to-use development environment (with a fully configured F* binary in path);
- automatic OCaml compilation (if needed);
- automatic JavaScript compilation (if needed).
Run nix run github:W95Psp/fpm#create
to interactively setup FPM on a local folder.
The example hello-ocaml-world consists in one module, that just prints an "Hello World"
after OCaml extraction and compilation. The example is really small and has no external F* dependency.
The Main.fst
module is very simple:
module Main
let main () =
FStar.IO.print_string "Hello world!"
The file flake.nix
contains the library and program declaration:
{
inputs = {
fpm.url = github:W95Psp/fpm; # fetches FPM
# here, we would declare F* libraries, for this example there's nothing
};
outputs = { nixpkgs, fpm, ... }@libs:
fpm rec {
# we declare a library, basically an empty shell in this case
lib = {
name = "hello-world";
dependencies = []; # no dependencies
modules = [ ./Main.fst ]; # just one module
plugin-entrypoints = [ ]; # no F* plugin
};
# and one ocaml program
ocaml-programs = [{
name = "hello-world";
dependencies = [lib];
entrypoint = ./Main.fst;
}];
};
}
Running nix run
(or nix run .#hello-world
) produces Hello World!
in the console! It automatically:
- fetches an F* binary;
- pulls and sets up every F* depenedncies (here, none);
- compile declared plugins entrypoints (here, none, again) into native ones;
- extracts the module
Main.fst
intoMain.ml
; - compile
Main.ml
with the correct OCaml libraries; - runs the resulting program.
nix build
(or nix build .#hello-world
)
nix develop
will drop you in a shell with an fstar.exe
binary available, configured so that all dependencies and native F* plugins are loaded automatically (again, in this example there's no dependency nor any native plugins).
TODO
A set with the following attributes:
name: string
;modules: list path
: a list of files (F* modules, OCaml modules, C header, C implementation, JS file);plugin-entrypoints?: list path
: subset ofmodule
, F* or OCaml modules (default[]
);dependencies: list library
: a list of dependencies;fstar-options?: fstar-options
: F* options (default{}
).
A set with the following attributes:
name: string
;modules: list path
: a list of files (F* modules, OCaml modules, C header, C implementation, JS file);dependencies: list library
: a list of dependencies;entrypoint: path
: the entrypoint module (has to be a subset ofmodules
);driver?: path
: OCaml driver (default driver simply calls the functionmain
from moduleentrypoint
);assets?: path
: path of a directory containing non-F* assets (default: empty directory);lflags?: string
: list oflflags
for ocaml (default""
);ocaml-packages?: list {name: string; package: derivations}
: list of (supplementary tofstarlib
) OCaml packages with their (opam) name (default[]
);target?: "native"|"byte"
: build either an ocaml bytecode or a native binary (default"native"
);fstar-options?: fstar-options
: F* options (default{}
).
A set:
patches?: list path
: list of patches to apply on F*'s own sources (default[]
);source?: source object
(defaulnull
);unsafe_tactic_exec?: bool
(defaultsfalse
).
Type: library -> next:'a -> 'a
Validate the sturcture of a library, and continue with next
.
Type: lib:library -> derivation
Builds a derivation for library lib
, with the following structure:
./modules
: flat listings of all the direct or indirect (via dependencies) modules oflib
;./plugins
: onecmxs
file for every module listed inplugin-entrypoints
.
Type: lib:library -> derivation