@@ -425,12 +425,60 @@ let copy_lock_dir ~target ~lock_dir ~deps ~files =
425425 ~dirs: (Path.Build.Set. singleton target))
426426;;
427427
428- let setup_copy_rules ~dir :target ~lock_dir =
429- let + deps, files = Source_deps. files (Path. source lock_dir) in
428+ let files dir =
429+ let rec recurse dir =
430+ match Path.Untracked. readdir_unsorted_with_kinds dir with
431+ | Ok entries ->
432+ entries
433+ |> List. fold_left
434+ ~init: (Path.Set. empty, Path.Set. empty)
435+ ~f: (fun (files , empty_directories ) (entry , kind ) ->
436+ let path = Path. relative dir entry in
437+ match (kind : Unix.file_kind ) with
438+ | S_REG ->
439+ let files = Path.Set. add files path in
440+ files, empty_directories
441+ | S_DIR ->
442+ let files', empty_directories' = recurse path in
443+ (match Path.Set. is_empty files', Path.Set. is_empty empty_directories' with
444+ | true , true ->
445+ let empty_directories = Path.Set. add empty_directories path in
446+ files, empty_directories
447+ | _ , _ ->
448+ let files = Path.Set. union files files' in
449+ let empty_directories =
450+ Path.Set. union empty_directories empty_directories'
451+ in
452+ files, empty_directories)
453+ | otherwise ->
454+ Code_error. raise
455+ " unsupported kind of file in folder"
456+ [ " path" , Path. to_dyn path; " kind" , File_kind. to_dyn otherwise ])
457+ | Error (ENOENT, _ , _ ) -> Path.Set. empty, Path.Set. empty
458+ | Error unix_error ->
459+ User_error. raise
460+ [ Pp. textf
461+ " Failed to read lock dir files of %s:"
462+ (Path. to_string_maybe_quoted dir)
463+ ; Pp. text (Unix_error.Detailed. to_string_hum unix_error)
464+ ]
465+ in
466+ let files, empty_directories = recurse dir in
467+ Dep.Set. of_source_files ~files ~empty_directories , files
468+ ;;
469+
470+ let setup_copy_rules ~dir :target ~assume_src_exists ~lock_dir =
471+ let + () = Memo. return () in
472+ let deps, files = files (Path. source lock_dir) in
430473 let directory_targets, rules =
431474 match Path.Set. is_empty files with
432475 | true -> Path.Build.Map. empty, Rules. empty
433476 | false ->
477+ let deps =
478+ match assume_src_exists with
479+ | false -> deps
480+ | true -> Dep.Set. empty
481+ in
434482 let directory_targets = Path.Build.Map. singleton target Loc. none in
435483 let { Action_builder.With_targets. build; targets } =
436484 copy_lock_dir ~target ~lock_dir ~deps ~files
@@ -452,7 +500,7 @@ let setup_lock_rules_with_source (workspace : Workspace.t) ~dir ~lock_dir =
452500 match source with
453501 | `Source_tree lock_dir ->
454502 let dir = Path.Build. append_source dir lock_dir in
455- setup_copy_rules ~dir ~lock_dir
503+ setup_copy_rules ~assume_src_exists: false ~ dir ~lock_dir
456504 | `Generated -> Memo. return (setup_lock_rules ~dir ~lock_dir )
457505;;
458506
@@ -461,7 +509,9 @@ let setup_dev_tool_lock_rules ~dir dev_tool =
461509 let dev_tool_name = Dune_lang.Package_name. to_string package_name in
462510 let dir = Path.Build. relative dir dev_tool_name in
463511 let lock_dir = Lock_dir. dev_tool_source_lock_dir dev_tool in
464- setup_copy_rules ~dir ~lock_dir
512+ (* dev tool lock files are created in _build outside of the build system
513+ so we have to tell the build system not to try to create them *)
514+ setup_copy_rules ~dir ~assume_src_exists: true ~lock_dir
465515;;
466516
467517let setup_rules ~components ~dir =
0 commit comments