From 6a657f93343e921841ab4b22531843b00b296664 Mon Sep 17 00:00:00 2001
From: Etienne Marais <dev@maiste.fr>
Date: Thu, 16 Jan 2025 17:14:17 +0100
Subject: [PATCH 1/2] fix: allow ocaml.5.3.0 to be built with package
 management

Signed-off-by: Etienne Marais <dev@maiste.fr>
---
 src/dune_rules/pkg_rules.ml     | 21 +++++++++++++++------
 src/dune_rules/pkg_toolchain.ml | 21 ++++++++++++++++-----
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/src/dune_rules/pkg_rules.ml b/src/dune_rules/pkg_rules.ml
index 02c5060f289..d5bcd1ec2f0 100644
--- a/src/dune_rules/pkg_rules.ml
+++ b/src/dune_rules/pkg_rules.ml
@@ -1931,14 +1931,23 @@ let ocaml_toolchain context =
   | `System_provided -> None
   | `Inside_lock_dir pkg ->
     let toolchain =
-      let cookie = (Pkg_installed.of_paths pkg.paths).cookie in
       let open Action_builder.O in
-      let* cookie = cookie in
-      (* TODO we should use the closure of [pkg] *)
-      let binaries =
-        Section.Map.find cookie.files Bin |> Option.value ~default:[] |> Path.Set.of_list
+      let transitive_deps = pkg :: Pkg.deps_closure pkg in
+      let* env, binaries =
+        Action_builder.List.fold_left
+          ~init:(Global.env (), Path.Set.empty)
+          ~f:(fun (env, binaries) pkg ->
+            let env = Env.extend_env env (Pkg.exported_env pkg) in
+            let+ cookie = (Pkg_installed.of_paths pkg.paths).cookie in
+            let binaries =
+              Section.Map.find cookie.files Bin
+              |> Option.value ~default:[]
+              |> Path.Set.of_list
+              |> Path.Set.union binaries
+            in
+            env, binaries)
+          transitive_deps
       in
-      let env = Env.extend_env (Global.env ()) (Pkg.exported_env pkg) in
       let path = Env_path.path (Global.env ()) in
       Action_builder.of_memo @@ Ocaml_toolchain.of_binaries ~path context env binaries
     in
diff --git a/src/dune_rules/pkg_toolchain.ml b/src/dune_rules/pkg_toolchain.ml
index af4d954901a..0236c778008 100644
--- a/src/dune_rules/pkg_toolchain.ml
+++ b/src/dune_rules/pkg_toolchain.ml
@@ -49,6 +49,8 @@ let is_compiler_and_toolchains_enabled name =
       (* TODO don't hardcode these names here *)
       [ Package_name.of_string "ocaml-base-compiler"
       ; Package_name.of_string "ocaml-variants"
+      ; Package_name.of_string
+          "ocaml-compiler" (* HACK: This is required for ocaml.5.3.0 *)
       ]
     in
     List.mem compiler_package_names name ~equal:Package_name.equal
@@ -164,11 +166,20 @@ let modify_install_action ~prefix ~suffix action =
 (* Create an empty config.cache file so other packages see that the
    compiler package is installed. *)
 let touch_config_cache =
-  Dune_lang.Action.Run
-    [ Slang.text "touch"
-    ; Slang.concat
-        [ Slang.pform (Pform.Var (Pform.Var.Pkg Pform.Var.Pkg.Build))
-        ; Slang.text "/config.cache"
+  Dune_lang.Action.Progn
+    [ Dune_lang.Action.Run
+        [ Slang.text "touch"
+        ; Slang.concat
+            [ Slang.pform (Pform.Var (Pform.Var.Pkg Pform.Var.Pkg.Build))
+            ; Slang.text "/config.cache"
+            ]
+        ]
+    ; Dune_lang.Action.Run
+        [ Slang.text "touch"
+        ; Slang.concat
+            [ Slang.pform (Pform.Var (Pform.Var.Pkg Pform.Var.Pkg.Build))
+            ; Slang.text "/config.status"
+            ]
         ]
     ]
 ;;

From c0f90836ffa830c9c4156d9bec9164a71ac6f6fd Mon Sep 17 00:00:00 2001
From: Etienne Marais <dev@maiste.fr>
Date: Fri, 17 Jan 2025 08:52:58 +0100
Subject: [PATCH 2/2] fix: apply reviews

Signed-off-by: Etienne Marais <dev@maiste.fr>
---
 src/dune_rules/pkg_toolchain.ml | 38 +++++++++++++++------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/src/dune_rules/pkg_toolchain.ml b/src/dune_rules/pkg_toolchain.ml
index 0236c778008..e413e5d47c4 100644
--- a/src/dune_rules/pkg_toolchain.ml
+++ b/src/dune_rules/pkg_toolchain.ml
@@ -49,8 +49,10 @@ let is_compiler_and_toolchains_enabled name =
       (* TODO don't hardcode these names here *)
       [ Package_name.of_string "ocaml-base-compiler"
       ; Package_name.of_string "ocaml-variants"
-      ; Package_name.of_string
-          "ocaml-compiler" (* HACK: This is required for ocaml.5.3.0 *)
+      ; Package_name.of_string "ocaml-compiler"
+        (* The [ocaml-compiler] package is required to include all the
+           packages that might install a compiler, starting from ocaml.5.3.0.
+        *)
       ]
     in
     List.mem compiler_package_names name ~equal:Package_name.equal
@@ -163,34 +165,28 @@ let modify_install_action ~prefix ~suffix action =
   else modify_install_action action ~installation_prefix:prefix ~suffix
 ;;
 
-(* Create an empty config.cache file so other packages see that the
-   compiler package is installed. *)
-let touch_config_cache =
-  Dune_lang.Action.Progn
-    [ Dune_lang.Action.Run
-        [ Slang.text "touch"
-        ; Slang.concat
-            [ Slang.pform (Pform.Var (Pform.Var.Pkg Pform.Var.Pkg.Build))
-            ; Slang.text "/config.cache"
-            ]
-        ]
-    ; Dune_lang.Action.Run
-        [ Slang.text "touch"
-        ; Slang.concat
-            [ Slang.pform (Pform.Var (Pform.Var.Pkg Pform.Var.Pkg.Build))
-            ; Slang.text "/config.status"
-            ]
-        ]
+let touch file =
+  Dune_lang.Action.Run
+    [ Slang.text "touch"
+    ; Slang.concat
+        [ Slang.pform (Pform.Var (Pform.Var.Pkg Pform.Var.Pkg.Build)); Slang.text file ]
     ]
 ;;
 
+(* Create an empty config.cache and config.status files so other packages see
+   that the compiler package is installed.
+   TODO: extract this from the .install *)
+let touch_compiler_install =
+  Dune_lang.Action.Progn [ touch "/config.cache"; touch "/config.status" ]
+;;
+
 let modify_build_action ~prefix action =
   let+ installed = Fs_memo.dir_exists prefix in
   if installed
   then
     (* If the toolchain is already installed, just create config.cache file.
        TODO(steve): Move this check to action execution time *)
-    touch_config_cache
+    touch_compiler_install
   else action
 ;;