Skip to content

Ship fstar.lib as source in binary packages, and add fstar.exe --install_lib[_with_deps] to install it#4300

Open
tahina-pro wants to merge 14 commits into
FStarLang:masterfrom
tahina-pro:_taramana_package_lib
Open

Ship fstar.lib as source in binary packages, and add fstar.exe --install_lib[_with_deps] to install it#4300
tahina-pro wants to merge 14 commits into
FStarLang:masterfrom
tahina-pro:_taramana_package_lib

Conversation

@tahina-pro

Copy link
Copy Markdown
Member

Motivation

F* binary packages (e.g. the nightly tarballs) bundle a standalone native
fstar.exe. Until now they also shipped the F* OCaml findlib packages
(fstar.compiler, fstar.pluginlib, and a compiled fstar.lib) that were
produced alongside that binary. Those compiled packages only work for a user
whose OCaml compiler and dependency versions exactly match the ones used to
build the package — which is essentially never true for the recipient of a
binary package. As a result, downstream consumers that need fstar.lib to
compile F*-extracted OCaml code (e.g. EverParse, and any project using
fstar.exe --ocamlopt/--ocamlenv) could not reliably build against a binary
package.

This PR makes binary packages ship fstar.lib as OCaml sources + a dune
project
, and adds a new F* command-line mode, --install_lib
(and --install_lib_with_deps), that builds and installs that fstar.lib
into the user's own opam switch against their own toolchain. The end result is
a single, install-method-independent recipe for building OCaml apps against
F*:

fstar.exe --install_lib_with_deps      # build & install fstar.lib (+ its deps)
fstar.exe --ocamlopt ...               # compile extracted OCaml against it

This recipe is now uniform whether F* was obtained via a source build,
make install, opam install, or a binary package.

What changed

Packaging: binary packages ship fstar.lib as source

  • Binary packages ship no precompiled OCaml packages. .scripts/bin-install.sh
    (run only on the binary-package path) strips compiler/, pluginlib/, META
    and dune-package from the package, and re-ships fstar.lib as OCaml sources
    plus a self-contained dune project (mk/fstar-lib-src/{dune,dune-project,README.md}).
    A regular make install / opam install fstar.opam is unaffected and keeps
    installing the compiled fstar.lib via dune install (the (public_name fstar.lib) stanzas in stage{1,2,3}/dune/libapp/dune are retained).
  • Stripping META from the bundled lib dir also fixes findlib resolution of
    the user-built fstar.lib: --ocamlopt/--ocamlenv prepend <exec>/../lib
    to OCAMLPATH; with no META there, ocamlfind falls through to the user's
    switch (where --install_lib installed a proper fstar.lib) instead of being
    shadowed by the package's own stale META.
  • make package (stage3) fix: stage3 reuses stage2's ulib extraction rather
    than re-extracting, so a new ULIB_ML variable (defaulting to
    $(BROOT)/ulib.ml, overridden to stage2/ulib.ml for package-3) encodes that
    invariant and avoids a cp: cannot stat '.../stage3/ulib.ml' failure.

New command: fstar.exe --install_lib

Builds and installs fstar.lib into the current OCaml/opam environment from the
shipped sources. Behaviour:

  • If fstar.lib already resolves via findlib, it is a clean no-op
    ("already installed; nothing to do").
  • If the findlib package fstar exists but fstar.lib does not, it errors out,
    rather than overwriting that package's META and dropping its other
    sub-packages.
  • Otherwise it drives dune directly (dune build/dune install --root <lib_root>/lib, no shell, no --prefix so it installs into the active
    switch) to build and install fstar.lib.

Implementation notes:

  • Detection uses the findlib library linked into fstar.exe
    (FStarC.Util.findlib_package_existsFindlib.init/package_directory),
    not an ocamlfind subprocess, so it works on native (non-Cygwin) Windows.
    findlib is added to the fstar-guts dune (libraries ...) and to
    fstar.opam's and the nix derivation's dependencies.
  • The install step likewise spawns dune directly (no bash install.sh), again
    for native-Windows support.
  • The detection guard extends OCAMLPATH with the bundled lib dir
    (<exec>/../lib) exactly as --ocamlenv does, so it uniformly detects a
    compiled fstar.lib shipped next to fstar.exe (source build / make install) as well as one in the opam switch (opam install). This is why the
    command is a no-op for non-binary installs.

New command: fstar.exe --install_lib_with_deps

Same as --install_lib, but first installs fstar.lib's OCaml dependencies
(and ocamlfind itself) via opam install --deps-only on a fstar-lib.opam
shipped in the package. opam is driven directly (no shell) for native Windows.
fstar-lib.opam carries build: [ "false" ] so a direct opam install ./fstar-lib.opam fails on purpose — it is a dependency carrier, not an
installable package — while --deps-only (which skips the build step) still
installs the deps. The pre-flight findlib check is hardened to treat a missing
findlib.conf (which makes Findlib.init raise Failure) as "not resolvable",
so it proceeds to install findlib rather than crashing.

Tests / CI

  • make test asserts --install_lib_with_deps is a no-op for a source
    build
    across test-1/2/3 (guards the bundled-lib detection / OCAMLPATH
    extension). It needs no OCaml toolchain since findlib is linked into
    fstar.exe.
  • build-opam.yml: after opam install ., build the sample apps
    (tests/simple_hello, tests/dune_hello, tests/extraction) against the
    switch's fstar.lib.
  • nightly-ci.yml: a new binary-install-lib job that, starting from only
    the binary package, runs --install_lib_with_deps to build+install
    fstar.lib from source into a fresh switch and builds the same sample apps
    against it — exercising the uniform app-build workflow end to end.

Documentation

  • --help text for both options, and mk/fstar-lib-src/README.md, document the
    workflow and the ocamlfind/findlib/dune (and, for --install_lib_with_deps,
    opam) requirements — noting that --install_lib_with_deps installs
    ocamlfind/dune for you, whereas plain --install_lib assumes they are
    already present.

Files touched

 .github/workflows/build-opam.yml      # build sample apps against opam-installed fstar.lib
 .github/workflows/nightly-ci.yml      # binary-install-lib job (build fstar.lib from package)
 .nix/fstar.nix                        # declare findlib build dependency
 .scripts/bin-install.sh               # strip compiled OCaml pkgs; re-ship fstar.lib sources
 .scripts/install-fstar-lib-src.sh     # copy fstar.lib sources + dune project into package
 Makefile                              # ULIB_ML var; pass ulib.ml dir to bin-install.sh
 fstar.opam                            # depend on ocamlfind
 mk/fstar-lib-src/{README.md,dune,dune-project,fstar-lib.opam}  # shipped dune project + deps
 mk/stage.mk, stage3/Makefile          # source-shipping moved to binary-package path only
 src/basic/FStarC.Options.{fst,fsti}   # register --install_lib[_with_deps] + help
 src/basic/FStarC.Util.fsti, src/ml/FStarC_Util.ml  # findlib_package_exists
 src/fstar/FStarC.Main.fst             # dispatch the new terminal modes
 src/fstar/FStarC.OCaml.{fst,fsti}     # install_lib / install_lib_with_deps logic
 stage{1,2,3}/dune/fstar-guts/dune     # link findlib
 stage{1,2,3}/dune/libapp/dune         # keep (public_name fstar.lib) for make/opam install
 stage3/{Makefile,dune/...}            # ULIB_ML override; stage3-reuses-stage2 wiring

Compatibility

  • make install and opam install fstar.opam are unchanged: they still install
    a compiled fstar.lib, and --install_lib[_with_deps] is a no-op there.
  • Only the binary-package path changes shape (sources instead of compiled
    OCaml packages); the new commands rebuild fstar.lib from those sources.
  • The new findlib dependency is statically linked into fstar.exe
    (buildInputs, not propagatedBuildInputs, in nix), needing no runtime
    stublibs.

tahina-pro and others added 14 commits June 2, 2026 13:16
A regular build/install (e.g. `opam install fstar.opam`, which runs
`make install`) installs a *compiled* fstar.lib via `dune install`, built
against the user's own OCaml toolchain. Binary packages, however, should
not ship a precompiled fstar.lib, to avoid OCaml ABI mismatches with the
user's compiler/findlib; instead they ship fstar.lib as OCaml sources plus
a dune project the user builds themselves.

 - stage{1,2,3}/dune/libapp/dune: keep (public_name fstar.lib) so that a
   plain `dune install` / `make install` (and hence `opam install
   fstar.opam`) installs a usable compiled fstar.lib.
 - .scripts/bin-install.sh (run only for binary packages): when given the
   extracted ulib.ml directory, strip the compiled fstar.lib (and its
   "lib" sub-package from META) and replace it with sources + dune project.
 - Makefile (__do-archive): pass the stage's ulib.ml dir to bin-install.sh.
 - mk/stage.mk, stage3/Makefile: drop the source-shipping from the shared
   install rule (it now only happens in the binary-package path).
 - mk/fstar-lib-src/{dune,dune-project,README.md}: self-contained dune
   project (with public_name fstar.lib) for the user to build & install.
 - mk/fstar-lib-src/install.sh: mediated installer that builds fstar.lib
   and installs it WITHOUT clobbering the rest of the F* findlib metadata.
   fstar.lib is the `lib` sub-package of the findlib package `fstar` (which
   also provides `compiler`/`pluginlib`), and dune writes <libdir>/fstar/META
   with no merge/skip option, so a bare `dune install` would overwrite that
   META down to just `lib`, dropping `compiler`/`pluginlib` and breaking
   `fstar.exe --ocamlopt_plugin`. install.sh runs the install and then merges
   the freshly generated `lib` stanza back into the pre-existing META.
 - .scripts/install-fstar-lib-src.sh: copy the fstar.lib sources, the dune
   project, and install.sh into <prefix>/lib/fstar/lib. Keeps app/ints/dune,
   which generates the fixed-width integer modules at build time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a new command-line mode that builds and installs the F* application
library (fstar.lib) into the current OCaml/opam environment, intended for
binary packages that ship fstar.lib as sources rather than precompiled.

Behavior:
 - If `ocamlfind query fstar.lib` already succeeds, do nothing (exit 0).
 - Else if `ocamlfind query fstar` succeeds, error out (exit 1): the
   findlib package `fstar` already exists (e.g. providing fstar.compiler
   and fstar.pluginlib), and installing fstar.lib there would overwrite
   its META and drop the other sub-packages.
 - Else, run the installer shipped alongside the sources at
   <lib_root>/lib/install.sh, which builds fstar.lib with dune and
   installs it (merging the `lib` stanza into any existing META).

The findlib queries are run in the ambient environment (no OCAMLPATH
override), so they reflect the user's current opam switch rather than the
library bundled with this fstar.exe.

 - FStarC.OCaml.{fsti,fst}: new `install_lib` (returns an exit code) plus
   an `ocamlfind_query` helper, using Util.system_run.
 - FStarC.Main.fst: dispatch `--install_lib` in go_normal, beside the
   other do-something-and-exit modes (--locate_*).
 - FStarC.Options.{fst,fsti}: register the `install_lib` boolean option
   and its --help text.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The findlib package presence checks for `--install_lib` previously shelled
out to `ocamlfind query <pkg>` via Sys.command, which needs a shell and is
unavailable on native (non-Cygwin) Windows builds of fstar.exe.

Use the findlib library directly instead: a new
FStarC.Util.findlib_package_exists wraps `Findlib.init` +
`Findlib.package_directory`, returning whether the package resolves in the
current (ambient) OCaml environment, with no subprocess. As before the
queries run before any OCAMLPATH override, so they reflect the user's opam
switch rather than the library bundled with fstar.exe.

 - src/ml/FStarC_Util.ml, src/basic/FStarC.Util.fsti: add
   findlib_package_exists.
 - src/fstar/FStarC.OCaml.fst: ocamlfind_query now calls it.
 - stage{1,2,3}/dune/fstar-guts/dune: link the `findlib` library into
   fstar.compiler.
 - fstar.opam: depend on `ocamlfind`.
 - FStarC.Options.fst: update the --help text (no longer mentions invoking
   ocamlfind for the check).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The install step of --install_lib previously shelled out to the shipped
`install.sh`, which requires bash and so does not work with the native
(non-Cygwin) Windows build of fstar.exe.

Build and install fstar.lib by spawning `dune` directly (no shell), via
Util.create_process / Util.waitpid:

  dune build   --root <lib_root>/lib
  dune install --root <lib_root>/lib

- `--root` avoids needing to chdir into the source directory.
- No `--prefix` is passed, so dune installs into the active opam switch
  (its default destination), matching what install.sh did via `opam var`.
- We no longer merge META: --install_lib already refuses when an `fstar`
  findlib package is present, so at install time dune writes a fresh
  fstar/META with just the `lib` sub-package, clobbering nothing.

The buildable-package check now looks for `dune-project` (rather than the
old install.sh). install.sh is still shipped for the standalone
`./install.sh` flow documented in mk/fstar-lib-src/README.md, which keeps
the META-merge behavior for users installing into a switch that already has
the `fstar` package.

Also updates the --help text accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Now that `fstar.exe --install_lib` drives dune directly (commit 431c320),
nothing in the tree invokes the shipped `install.sh`: it was only copied into
binary packages for a manual `./install.sh` end-user flow.

Drop the script and its references:
 - .scripts/install-fstar-lib-src.sh: stop copying install.sh into the
   packaged fstar.lib sources directory.
 - mk/fstar-lib-src/README.md: document `fstar.exe --install_lib` (or a plain
   `dune build && dune install`) instead of `./install.sh`, and reframe the
   META section as a caveat about installing into a switch that already has the
   `fstar` findlib package (which --install_lib guards against).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`--install_lib` builds and installs fstar.lib but assumes its OCaml
dependencies are already present in the current opam switch. This adds a
companion option, `--install_lib_with_deps`, that first installs those
dependencies and then performs the same build/install.

It works by shipping `fstar-lib.opam` in the binary package (in the parent
of the dune project dir, so `dune build` does not pick it up as a project
package). `--install_lib_with_deps` runs the same fstar.lib/fstar findlib
checks as `--install_lib`, then `opam install --deps-only` on that file, then
the dune build/install. opam is driven directly (no shell), so this works on
native Windows too.

`fstar-lib.opam` has `build: [ "false" ]` so that a direct
`opam install ./fstar-lib.opam` fails on purpose: the file only carries
fstar.lib's dependencies and is not meant to be installed as a package.
`--deps-only` does not run the build step, so it still installs the deps.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A binary package's fstar.exe is a standalone native binary, but the
findlib packages produced alongside it (fstar.compiler, fstar.pluginlib
and a compiled fstar.lib, advertised by META/dune-package) only work for a
user whose OCaml compiler and dependency package versions exactly match
those used to build the package. That is impossible for a recipient of a
binary package, so .scripts/bin-install.sh now removes compiler/,
pluginlib/, META and dune-package from the binary package. fstar.lib is
still re-shipped as OCaml sources + a dune project, so the user builds it
themselves against their own toolchain via `fstar.exe --install_lib`.

This only affects the binary-package path (bin-install.sh, invoked from
the Makefile __do-archive target with a ulib.ml source dir). `make install`
and `opam install fstar.opam` go through mk/stage.mk's install rule, which
does not call this script, and keep shipping the compiled OCaml packages.

Removing META also fixes findlib resolution of the user-built fstar.lib:
--ocamlopt/--ocamlenv prepend <exec>/../lib to OCAMLPATH, and with no META
there ocamlfind falls through to the user's switch (where --install_lib
installed fstar.lib with a proper META) instead of being shadowed by the
package's own META.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… installs)

`fstar.exe --install_lib[_with_deps]` now extends OCAMLPATH with the bundled
library dir (<exec>/../lib), exactly as --ocamlenv does, before its "is
fstar.lib already available?" detection guard. Findlib.init re-reads OCAMLPATH
on each query, so the guard now sees a compiled fstar.lib shipped alongside
this fstar.exe (source build, `make install`) in addition to the current opam
switch (`opam install`).

This makes the command behave uniformly across all install methods:
  - source build / `make install`: the bundled compiled fstar.lib + META is
    detected, so the command is a clean no-op ("already installed; nothing to
    do"). Previously it errored, because the guard only queried the ambient
    switch and then looked for a fstar.lib-src dune project that these flavors
    do not ship.
  - `opam install`: fstar.lib is in the switch (ambient) -> no-op, as before.
  - binary package: the bundled dir ships no findlib metadata (we strip it),
    so the extension is a no-op and we build+install fstar.lib into the switch
    from the shipped sources, as before.

The recipe "run `fstar --install_lib_with_deps`, then build the app with
`fstar --ocamlopt`/`--ocamlenv`" is now uniform regardless of how F* was
installed. install_lib runs as a terminal command (Main.fst exits right
after), so mutating the process environment here is harmless.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`make test` (via the shared _test rule) now runs a small _test_install_lib
check that asserts `fstar.exe --install_lib_with_deps` is a no-op: a
source-built (or `make install`ed) F* ships a compiled fstar.lib next to
fstar.exe, which the command must detect (returning 0 and "already
installed; nothing to do") rather than rebuilding fstar.lib or invoking
opam. This guards against regressions in that detection (e.g. in the
OCAMLPATH extension that lets the guard see the bundled library).

The check uses the per-stage FSTAR_EXE already plumbed through _test, so it
covers test-1/test-2/test-3. It needs no OCaml toolchain (findlib is linked
into fstar.exe), so it is unconditional. The binary-package path, where
fstar.lib is shipped as sources and the command actually builds+installs
it, is exercised separately (not here).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… package

Exercise the F* application-build workflow (tests/simple_hello,
tests/dune_hello, tests/extraction) across install methods:

- build-opam.yml (the `opam` job): after `opam install .`, build the three
  sample apps against the fstar.lib installed in the switch. Pass an
  absolute FSTAR_EXE, since tests/extraction includes mk/test.mk which
  resolves FSTAR_EXE to an absolute path (so a bare `fstar.exe` would be
  mis-resolved relative to the test directory).

- nightly-ci.yml: new `binary-install-lib` job that, starting from only the
  binary package (which ships no precompiled OCaml packages), runs
  `fstar.exe --install_lib_with_deps` to build+install fstar.lib from
  source into a fresh opam switch, then builds the same three sample apps
  against it. This covers the uniform, install-method-independent app-build
  workflow end to end.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`make package` (= package-3, BROOT=stage3) failed at the binary-package
archive step with:

  cp: cannot stat '.../stage3/ulib.ml': No such file or directory

Commit 83defea made __do-archive pass `$(BROOT)/ulib.ml` to
bin-install.sh as the directory of F*-extracted ulib OCaml sources to
re-ship as fstar.lib in the binary package. That works for package-1 and
package-2 (stage1/ulib.ml, stage2/ulib.ml are produced by the build), but
stage3 never re-extracts ulib to OCaml -- it reuses stage2's extraction
(cf. the committed stage3/dune/libapp/ulib.ml -> ../../../stage2/ulib.ml
symlink) -- so stage3/ulib.ml does not exist.

Introduce a ULIB_ML variable (default `$(BROOT)/ulib.ml`, unchanged
behavior for package-1/2) and have package-3 override it to
`stage2/ulib.ml`, encoding the stage3-reuses-stage2 invariant where it
belongs. Verified end to end:

  make -j16 package package-src FSTAR_TAG= FSTAR_PACKAGE_Z3=false ADMIT=1

now completes successfully; the resulting fstar.tar.gz ships all 96
ulib.ml sources under lib/fstar/lib/ and no precompiled OCaml packages.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
F* now links the findlib OCaml library: FStarC_Util.findlib_package_exists
calls Findlib.init/Findlib.package_directory directly (instead of spawning
ocamlfind), and stage{1,2,3}/dune/fstar-guts/dune list `findlib` in their
(libraries ...) stanza. This was introduced together in the commit that
switched --install_lib's package detection to the findlib library.

The nix derivation did not reflect this new dependency. Add `findlib` to
.nix/fstar.nix's buildInputs (and the function arguments; callPackage fills
it from ocamlPackages.findlib), following the nixpkgs convention for
packages that link the findlib library (cf. utop). It goes in buildInputs
rather than propagatedBuildInputs because findlib is statically linked into
fstar.exe and needs no runtime stublibs -- Findlib.init reads OCAMLPATH /
findlib.conf from the user's environment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The --help text and the fstar.lib README mentioned dune (and opam for
--install_lib_with_deps) but never stated that ocamlfind/findlib must be
installed, even though it genuinely is: F* uses the findlib library to
detect whether fstar.lib is already installed, 'dune install' records the
fstar/META that 'ocamlfind query fstar.lib' resolves, and OCaml code
extracted by F* is compiled by invoking ocamlfind.

Add the ocamlfind/findlib requirement to both --install_lib and
--install_lib_with_deps help strings and to the README prerequisites.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tection

--install_lib_with_deps installs fstar.lib's OCaml dependencies via
`opam install --deps-only` on fstar-lib.opam. Add ocamlfind to that
file's depends so findlib itself is installed when missing -- but only
for --install_lib_with_deps; plain --install_lib never runs opam and
still assumes ocamlfind/dune are already present.

For this to work, the pre-flight "is fstar.lib already installed?" check
must not crash when findlib is absent. Findlib.init raises Failure when
no findlib.conf can be located (verified empirically), so move it inside
the try and also catch Failure, returning false ("not resolvable") so
the caller proceeds to install findlib via opam.

Update the --install_lib_with_deps help text and the fstar.lib README to
reflect that it now installs ocamlfind/dune for you, while --install_lib
still requires them preinstalled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tahina-pro

Copy link
Copy Markdown
Member Author

New nightly-ci tasks succeed (ocaml client tests with opam install and the binary package) : https://github.com/tahina-pro/FStar/actions/runs/26916542314

@gebner

gebner commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

I am a bit torn on the --install_lib option. We typically don't (require F* packages to) modify the opam switch, so you can use the same switch for many F* builds.

Can we point dune to the fstar.lib ML source directory? (That is, 3dgen's dune file would build fstar.lib from source.)

@tahina-pro

tahina-pro commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

I have an EverParse PR into its fstar2 branch, project-everest/everparse#292, to build EverParse with a F* binary package. There, the fstarpkg.Dockerfile tests that feature, and it succeeds on my side with the binary package obtained from https://github.com/tahina-pro/FStar/actions/runs/26922219139

@tahina-pro

Copy link
Copy Markdown
Member Author

Can we point dune to the fstar.lib ML source directory? (That is, 3dgen's dune file would build fstar.lib from source.)

Alas, I am not sure this solution works for cascading F* applications: if an user develops a F* application meant to be an ocaml package, and if another user develops an F* application that uses that ocaml package, fstar.lib will be compiled and linked twice, which may be a problem.

Another problematic scenario: what if an OCaml program depends on two libraries that both depend on fstar.lib.

@tahina-pro

Copy link
Copy Markdown
Member Author

Gabriel:

I am a bit torn on the --install_lib option. We typically don't (require F* packages to) modify the opam switch, so you can use the same switch for many F* builds.

I acknowledge I am not sure about use cases for --install_lib.

However, for --install_lib_with_deps, which also installs dependencies in the user's switch, the main purpose of this option is to make the build of F* applications uniform, regardless of how the user installs F*:

  • if they install F* with opam install fstar.opam, this step installs fstar.lib and its dependencies, and --install_lib_with_deps is a noop;
  • if they build F* from sources, they will have installed the fstar.lib dependencies beforehand because F* also depends on them, and then the F* source build builds fstar.opam, so --install_lib_with_deps is a noop
  • if they use a binary package, --install_lib_with_deps installs fstar.lib and its dependencies.

Notably, the process with --install_lib_with_deps is uniform in its treatment of dependencies of fstar.lib : especially, if a user uses F* with a binary package, they do not need to look into any detail about such dependencies.

In light of the problematic scenarios in my previous comment, a possible alternative to your proposal would be to make --install_lib build fstar.lib but not install it into the switch. This would ensure --install_lib does not change the user's switch, as you are proposing. But then, should --install_lib_with_deps behave in a hybrid way, by also building fstar.lib without installing it, while still installing its dependencies into the user's switch?

@gebner

gebner commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

My proposal.

  1. --ocamlenv is only used for plugins, and only works with local F* installations.

  2. Applications that intend to be buildable with binary releases use a new --install_lib dest_dir option and manually set up OCAMLPATH to include that directory.

@tahina-pro

Copy link
Copy Markdown
Member Author

Thanks Gabriel for your proposal!

  1. --ocamlenv is only used for plugins, and only works with local F* installations.

By local F* installations, I presume you mean both F* built from source and F* installed with opam install fstar.opam, as opposed to F* binary packages. I consider opam to be a clean way to build F* plugins, since opam guarantees that the fstar.exe executable and the fstar.compilerlib and fstar.pluginlib libraries are always in sync. I hope we can keep this setup for F* plugins with your proposal. Is my understanding correct?

  1. Applications that intend to be buildable with binary releases use a new --install_lib dest_dir option and manually set up OCAMLPATH to include that directory.

Here, you are proposing that applications must explicitly choose the place where to install fstar.lib, because we should not automatically install it into either the F* binary package (which you deem read-only) or the current user's opam switch (which you want to keep clean, except maybe for the fstar.lib dependencies), and that F* should not care about where fstar.lib is installed. Is my understanding correct?

Other than that, I presume the check on fstar.lib and fstar not already installed will stay. This is necessary to maintain uniformity in the opam install fstar.opam case. If so, then I buy your proposal, and it will be easy for me to adapt EverParse accordingly.

@mtzguido , @nikswamy, what do you think?

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.

2 participants