@@ -451,12 +451,60 @@ let copy_lock_dir ~target ~lock_dir ~deps ~files =
451451 ~dirs: (Path.Build.Set. singleton target))
452452;;
453453
454- let setup_copy_rules ~dir :target ~lock_dir =
455- let + deps, files = Source_deps. files (Path. source lock_dir) in
454+ let files dir =
455+ let rec recurse dir =
456+ match Path.Untracked. readdir_unsorted_with_kinds dir with
457+ | Ok entries ->
458+ entries
459+ |> List. fold_left
460+ ~init: (Path.Set. empty, Path.Set. empty)
461+ ~f: (fun (files , empty_directories ) (entry , kind ) ->
462+ let path = Path. relative dir entry in
463+ match (kind : Unix.file_kind ) with
464+ | S_REG ->
465+ let files = Path.Set. add files path in
466+ files, empty_directories
467+ | S_DIR ->
468+ let files', empty_directories' = recurse path in
469+ (match Path.Set. is_empty files', Path.Set. is_empty empty_directories' with
470+ | true , true ->
471+ let empty_directories = Path.Set. add empty_directories path in
472+ files, empty_directories
473+ | _ , _ ->
474+ let files = Path.Set. union files files' in
475+ let empty_directories =
476+ Path.Set. union empty_directories empty_directories'
477+ in
478+ files, empty_directories)
479+ | otherwise ->
480+ Code_error. raise
481+ " unsupported kind of file in folder"
482+ [ " path" , Path. to_dyn path; " kind" , File_kind. to_dyn otherwise ])
483+ | Error (ENOENT, _ , _ ) -> Path.Set. empty, Path.Set. empty
484+ | Error unix_error ->
485+ User_error. raise
486+ [ Pp. textf
487+ " Failed to read lock dir files of %s:"
488+ (Path. to_string_maybe_quoted dir)
489+ ; Pp. text (Unix_error.Detailed. to_string_hum unix_error)
490+ ]
491+ in
492+ let files, empty_directories = recurse dir in
493+ Dep.Set. of_source_files ~files ~empty_directories , files
494+ ;;
495+
496+ let setup_copy_rules ~dir :target ~assume_src_exists ~lock_dir =
497+ let + () = Memo. return () in
498+ let deps, files = files (Path. source lock_dir) in
456499 let directory_targets, rules =
457500 match Path.Set. is_empty files with
458501 | true -> Path.Build.Map. empty, Rules. empty
459502 | false ->
503+ let deps =
504+ match assume_src_exists with
505+ | false -> deps
506+ | true -> Dep.Set. empty
507+ in
460508 let directory_targets = Path.Build.Map. singleton target Loc. none in
461509 let { Action_builder.With_targets. build; targets } =
462510 copy_lock_dir ~target ~lock_dir ~deps ~files
@@ -478,7 +526,7 @@ let setup_lock_rules_with_source (workspace : Workspace.t) ~dir ~lock_dir =
478526 match source with
479527 | `Source_tree lock_dir ->
480528 let dir = Path.Build. append_source dir lock_dir in
481- setup_copy_rules ~dir ~lock_dir
529+ setup_copy_rules ~assume_src_exists: false ~ dir ~lock_dir
482530 | `Generated -> Memo. return (setup_lock_rules ~dir ~lock_dir )
483531;;
484532
@@ -487,7 +535,9 @@ let setup_dev_tool_lock_rules ~dir dev_tool =
487535 let dev_tool_name = Dune_lang.Package_name. to_string package_name in
488536 let dir = Path.Build. relative dir dev_tool_name in
489537 let lock_dir = Lock_dir. dev_tool_source_lock_dir dev_tool in
490- setup_copy_rules ~dir ~lock_dir
538+ (* dev tool lock files are created in _build outside of the build system
539+ so we have to tell the build system not to try to create them *)
540+ setup_copy_rules ~dir ~assume_src_exists: true ~lock_dir
491541;;
492542
493543let setup_rules ~components ~dir =
0 commit comments