let link_gen cmX_ext cma_ext a_ext extensions linker tagger cmX out env build =
let cmX = env cmX and out = env out in
let tags = tagger (tags_of_pathname out) in
let dyndeps = Rule.build_deps_of_tags build (tags++"link_with") in
let cmi = Pathname.update_extensions "cmi" cmX in
prepare_link cmX cmi extensions build;
let libs = prepare_libs cma_ext a_ext out build in
let hidden_packages = List.map (fun x -> x-.-cmX_ext) !hidden_packages in
let deps =
caml_transitive_closure
~caml_obj_ext:cmX_ext ~caml_lib_ext:cma_ext
~used_libraries:libs ~hidden_packages (cmX :: dyndeps) in
let deps = (List.filter (fun l -> not (List.mem l deps)) libs) @ deps in
let stdlib = "stdlib/stdlib"-.-cma_ext in
let is_not_stdlib x = x <> stdlib in
let deps = List.filter is_not_stdlib deps in
if deps = [] then failwith "Link list cannot be empty";
let () = dprintf 6 "link: %a -o %a" print_string_list deps Pathname.print out in
linker (tags++"dont_link_with") deps out