Skip to content

Conversation

@dra27
Copy link
Contributor

@dra27 dra27 commented Dec 8, 2025

This is an attempt to unblock #23.

There are various upstream packages which require patches for OxCaml. If a package has been patched, then switches based on OxCaml must use a patched version. At the moment, this is enforced in two ways:

  1. ocaml-variants.5.2.0+ox conflicts the non-patched versions of all the packages
  2. Packages which use patched versions explicitly refer to a single OxCaml patched version

The main idea behind this repo is that it's a "bleeding edge" repo, but #23 highlights that occasionally we're not in total agreement (between "JS OxCaml" and "Community OxCaml") as to which edge is the bleeding one.......

This PR proposes a different approach - we regard the compiler as the bleeding edge. That means that everything in this repo must be built with the single ocaml-variants.5.2.0+ox package in it. However, it relaxes that constraint for the upstream patched packages.

The first two commits restore the constraints on these packages to their "original" (or at least close to original) versions. For example, alcotest.1.9.0+ox now depends on uutf ≥ 1.0.1 instead of exactly depending on uutf.1.0.3+ox.

The third commit is where the magic happens. Instead of having a massive conflicts clause in ocaml-variants.5.2.0+ox:

conflicts: [
  "base" {< "v0.18~"}
  "alcotest" {!= "1.9.0+ox"}
  "backoff" {!= "0.1.1+ox"}
  ...

we just have a single dependency on a new package oxcaml-patch-guards which is generated by layout.sh and consists of a depends field:

depends: [
  ("oxcaml-alcotest" {post} | "oxcaml-alcotest-patches" {post})
  ("oxcaml-backoff" {post} | "oxcaml-backoff-patches" {post})
  ...
  ("oxcaml-zarith" {post} | "oxcaml-zarith-patches" {post})
]

with one of these disjunctions for each patched upstream package. layout.sh also generates all of these packages, with oxcaml-zarith containing a conflicts clause conflicting all versions of alcotest and also the oxcaml-zarith-patches package:

conflicts: [ "oxcaml-zarith-patches" "alcotest" ]

and then oxcaml-zarith-patches conflicts the oxcaml-zarith package but then depends on the patched version(s) of zarith:

conflicts: "oxcaml-zarith"
depends: "zarith" {build & (
                     = "1.12+ox"
                   | = "1.14+ox"
                   )}

This somewhat convoluted (but fully automated) set-up means that when an OxCaml switch is created, a whole load of dummy oxcaml- packages now get added. However, those packages prevent un-patched versions of dependencies from being installed, for example:

$ opam switch create oxcaml-async-sprints --repos=oxcaml-async-sprints=git+https://github.com/dra27/oxcaml-opam-repository.git#async-sprints,default ocaml-variants.5.2.0+ox

...

$ opam install ecaml
...
  ∗ uutf                               1.0.3+ox                 [required by ecaml]
...

$ opam install tsdl.1.2.0
[ERROR] Package conflict!

It's now possible to reformulate @avsm's #23 as a much simpler PR which:

  1. Just adds the required additional upstream patched packages (see dra27@316652f) - i.e. just ctypes-foreign.0.24.0+ox, ctypes.0.24.0+ox, ocamlbuild.0.16.1+ox, sedlex.3.7+ox, topkg.1.1.1+ox and uutf.1.0.4+ox
  2. Runs the script to update to the oxcaml- packages automatically (see dra27@c8eabb7). Crucially, no other packages require updates.

and this can be seen previewed in dra27#2 and then allows:

$ opam repo add updates-1 git+https://github.com/dra27/oxcaml-opam-repository.git#updates-1

$ opam install tsdl.1.2.0
The following actions will be performed:
=== remove 1 package
  ⊘ oxcaml-ctypes-foreign         guard                  [conflicts with ctypes-foreign]
=== recompile 3 packages
  ↻ jekyll-format                 0.3.4                  [uses yaml]
  ↻ yaml                          3.2.0                  [uses ctypes]
  ↻ yaml-sexp                     3.2.0                  [uses yaml]
=== upgrade 2 packages
  ↗ ctypes                        0.23.0+ox to 0.24.0+ox [required by tsdl]
  ↗ topkg                         1.0.8+ox to 1.1.1+ox   [required by tsdl]
=== install 6 packages
  ∗ conf-libffi                   2.0.0                  [required by ctypes-foreign]
  ∗ conf-pkg-config               4                      [required by conf-sdl2, ctypes-foreign]
  ∗ conf-sdl2                     1                      [required by tsdl]
  ∗ ctypes-foreign                0.24.0+ox              [required by tsdl]
  ∗ oxcaml-ctypes-foreign-patches enabled
  ∗ tsdl                          1.2.0

Proceed with ⊘ 1 removal, ↻ 3 recompilations, ↗ 2 upgrades and ∗ 6 installations? [Y/n]

The only snag is for packages which packages which actually refer to an OCaml version - see ocaml-index and ocaml-lsp-server, for example. Fortunately, this should be quite rare, since most packages which depend on an exact version tend to be structured to use {= version}-style constraints instead.

dra27 added 4 commits December 5, 2025 13:08
oxcaml-foo.guard ensures unpatched upstreams aren't available
oxcaml-foo-patches.enabled depends on patched versions of the upstream
package.
Two-fold reason:
1. Fully automates the generation of the infrastructure (because
   ocaml-variants.5.2.0+ox now always refers just to
   oxcaml-patch-guards)
2. Avoids a DNF explosion in opam
@dra27
Copy link
Contributor Author

dra27 commented Dec 8, 2025

This is draft for two reasons - firstly, I expect that the changes made in the first two commits should be mechanically applied by a generator. Secondly, the process of doing this has revealed a possible problem with the Zarith 1.14 patches added in #14 and I'd like to investigate that further.

@avsm
Copy link
Collaborator

avsm commented Dec 9, 2025

Thanks @dra27! Approach looks sound to me, although I'm a bit worried that I've broken something with my Zarith 1.14 fix!

@dra27
Copy link
Contributor Author

dra27 commented Dec 9, 2025

See avsm/Zarith#1!

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