@@ -409,12 +409,60 @@ let copy_lock_dir ~target ~lock_dir ~deps ~files =
409409 ~dirs: (Path.Build.Set. singleton target))
410410;;
411411
412- let setup_copy_rules ~dir :target ~lock_dir =
413- let + deps, files = Source_deps. files (Path. source lock_dir) in
412+ let files dir =
413+ let rec recurse dir =
414+ match Path.Untracked. readdir_unsorted_with_kinds dir with
415+ | Ok entries ->
416+ entries
417+ |> List. fold_left
418+ ~init: (Path.Set. empty, Path.Set. empty)
419+ ~f: (fun (files , empty_directories ) (entry , kind ) ->
420+ let path = Path. relative dir entry in
421+ match (kind : Unix.file_kind ) with
422+ | S_REG ->
423+ let files = Path.Set. add files path in
424+ files, empty_directories
425+ | S_DIR ->
426+ let files', empty_directories' = recurse path in
427+ (match Path.Set. is_empty files', Path.Set. is_empty empty_directories' with
428+ | true , true ->
429+ let empty_directories = Path.Set. add empty_directories path in
430+ files, empty_directories
431+ | _ , _ ->
432+ let files = Path.Set. union files files' in
433+ let empty_directories =
434+ Path.Set. union empty_directories empty_directories'
435+ in
436+ files, empty_directories)
437+ | otherwise ->
438+ Code_error. raise
439+ " unsupported kind of file in folder"
440+ [ " path" , Path. to_dyn path; " kind" , File_kind. to_dyn otherwise ])
441+ | Error (ENOENT, _ , _ ) -> Path.Set. empty, Path.Set. empty
442+ | Error unix_error ->
443+ User_error. raise
444+ [ Pp. textf
445+ " Failed to read lock dir files of %s:"
446+ (Path. to_string_maybe_quoted dir)
447+ ; Pp. text (Unix_error.Detailed. to_string_hum unix_error)
448+ ]
449+ in
450+ let files, empty_directories = recurse dir in
451+ Dep.Set. of_source_files ~files ~empty_directories , files
452+ ;;
453+
454+ let setup_copy_rules ~dir :target ~assume_src_exists ~lock_dir =
455+ let + () = Memo. return () in
456+ let deps, files = files (Path. source lock_dir) in
414457 let directory_targets, rules =
415458 match Path.Set. is_empty files with
416459 | true -> Path.Build.Map. empty, Rules. empty
417460 | false ->
461+ let deps =
462+ match assume_src_exists with
463+ | false -> deps
464+ | true -> Dep.Set. empty
465+ in
418466 let directory_targets = Path.Build.Map. singleton target Loc. none in
419467 let { Action_builder.With_targets. build; targets } =
420468 copy_lock_dir ~target ~lock_dir ~deps ~files
@@ -436,7 +484,7 @@ let setup_lock_rules_with_source (workspace : Workspace.t) ~dir ~lock_dir =
436484 match source with
437485 | `Source_tree lock_dir ->
438486 let dir = Path.Build. append_source dir lock_dir in
439- setup_copy_rules ~dir ~lock_dir
487+ setup_copy_rules ~assume_src_exists: false ~ dir ~lock_dir
440488 | `Generated -> Memo. return (setup_lock_rules ~dir ~lock_dir )
441489;;
442490
@@ -445,7 +493,9 @@ let setup_dev_tool_lock_rules ~dir dev_tool =
445493 let dev_tool_name = Dune_lang.Package_name. to_string package_name in
446494 let dir = Path.Build. relative dir dev_tool_name in
447495 let lock_dir = Lock_dir. dev_tool_source_lock_dir dev_tool in
448- setup_copy_rules ~dir ~lock_dir
496+ (* dev tool lock files are created in _build outside of the build system
497+ so we have to tell the build system not to try to create them *)
498+ setup_copy_rules ~dir ~assume_src_exists: true ~lock_dir
449499;;
450500
451501let setup_rules ~components ~dir =
0 commit comments