From 84ae20721db27706006a951cd8f69e475e18a4bb Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Fri, 7 Sep 2018 16:14:48 +0200 Subject: [PATCH 1/3] Pass C include paths to runCCdep In case the C sources rely on other files (usually headers) in other directories, then "c-libpaths" is used when building the target. OTOH, this will not help during the C dependency discovery, since the compiler is invoked without those, and thus it will fail. Hence, use the include paths for a target when running its C dependency discovery. --- obuild/dependencies.ml | 4 ++-- obuild/prepare.ml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/obuild/dependencies.ml b/obuild/dependencies.ml index c46317e..15049b8 100644 --- a/obuild/dependencies.ml +++ b/obuild/dependencies.ml @@ -71,8 +71,8 @@ let joinLines s = in bytes_to_string (replace 0) -let runCCdep srcDir files : (filename * filepath list) list = - let args = [Prog.getCC (); "-MM"] @ List.map (fun fn -> fp_to_string (srcDir fn)) files in +let runCCdep srcDir clibpaths files : (filename * filepath list) list = + let args = [Prog.getCC (); "-MM"] @ (Utils.to_include_path_options clibpaths) @ List.map (fun fn -> fp_to_string (srcDir fn)) files in match Process.run args with | Process.Failure err -> raise (BuildCDepAnalyzeFailed err) | Process.Success (out,_,_) -> diff --git a/obuild/prepare.ml b/obuild/prepare.ml index 5549476..98d265e 100644 --- a/obuild/prepare.ml +++ b/obuild/prepare.ml @@ -500,7 +500,7 @@ let prepare_target_ bstate buildDir target toplevelModules = (* just append each C sources as single node in the stepsDag *) if cbits.target_csources <> [] then ( - let objDeps = runCCdep cbits.target_cdir cbits.target_csources in + let objDeps = runCCdep cbits.target_cdir cbits.target_clibpaths cbits.target_csources in List.iter (fun cSource -> let (fps : filepath list) = From 7663c5dc6628792d4818db37dcdfc3ce0a46534b Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Fri, 7 Sep 2018 16:22:35 +0200 Subject: [PATCH 2/3] Add missing newlines at the end of verbose calls --- obuild/build.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/obuild/build.ml b/obuild/build.ml index 9ac9c9e..b07a104 100644 --- a/obuild/build.ml +++ b/obuild/build.ml @@ -306,7 +306,7 @@ let wait_for_files cdep_files = List.for_all (fun f -> let test = Filesystem.exists f in if not test then - verbose Debug "warning: (temporarily?) missing file %s" (fp_to_string f); + verbose Debug "warning: (temporarily?) missing file %s\n" (fp_to_string f); test ) cdep_files @@ -451,11 +451,11 @@ let sanity_check build_dir target = let allOK = List.for_all (fun f -> let test = Filesystem.exists (build_dir f) in if not test then - verbose Debug "warning: missing file %s" (fp_to_string (build_dir f)); + verbose Debug "warning: missing file %s\n" (fp_to_string (build_dir f)); test ) files in if not allOK - then verbose Report "warning: some target file appears to be missing"; + then verbose Report "warning: some target file appears to be missing\n"; () let check task_index task task_context dag = From 9ed84d53c6aa8d8dc57d6490a9b325b08d0f3f92 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Fri, 7 Sep 2018 16:28:45 +0200 Subject: [PATCH 3/3] Hopefully fix C dependencies for OCaml linking Nodes for C sources are added to the DAGs of each target using them, without creating any edge between these nodes and the targets. The result is that an OCaml linking task does not wait for all the C builds to finish, resulting in missing files halting the linking. Hence, set the proper edge between the CompileC node and the LinkTarget one, hopefully fixing the dependency. This also means the hack of waiting for the .o files is not needed anymore. --- obuild/build.ml | 12 ------------ obuild/prepare.ml | 8 ++++++-- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/obuild/build.ml b/obuild/build.ml index b07a104..66e742c 100644 --- a/obuild/build.ml +++ b/obuild/build.ml @@ -302,21 +302,9 @@ let compile_module task_index task is_intf h bstate task_context dag = (if reason <> "" then " ( " ^ reason ^ " )" else ""); Scheduler.AddTask (task, all_fun_lists) -let wait_for_files cdep_files = - List.for_all (fun f -> - let test = Filesystem.exists f in - if not test then - verbose Debug "warning: (temporarily?) missing file %s\n" (fp_to_string f); - test - ) cdep_files - let link_c cstate clib_name = let lib_name = cstate.compilation_builddir_c fn clib_name in let cdep_files = List.map (fun x -> cstate.compilation_builddir_c o_from_cfile x) cstate.compilation_csources in - (* Not sure why it is necessary ... gcc seems to return before the files are ready. *) - while not (wait_for_files cdep_files) do - ignore (Unix.select [] [] [] 0.02) (* sleep 1/50 second *) - done; if gconf.ocamlmklib then [[(fun () -> runCLinking LinkingShared cdep_files lib_name)]] else ( diff --git a/obuild/prepare.ml b/obuild/prepare.ml index 98d265e..07d5394 100644 --- a/obuild/prepare.ml +++ b/obuild/prepare.ml @@ -498,7 +498,9 @@ let prepare_target_ bstate buildDir target toplevelModules = List.iter (Hashtbl.remove h) freeModules; done; - (* just append each C sources as single node in the stepsDag *) + (* Append each C sources as single node in the stepsDag, making them dependencies + * of the final linking target. + *) if cbits.target_csources <> [] then ( let objDeps = runCCdep cbits.target_cdir cbits.target_clibpaths cbits.target_csources in @@ -520,7 +522,9 @@ let prepare_target_ bstate buildDir target toplevelModules = Dag.addChildrenEdges oNode hFiles filesDag; (* add C source compilation task into the step DAG *) - Dag.addNode (CompileC cSource) stepsDag + let ccNode = CompileC cSource in + Dag.addNode ccNode stepsDag; + Dag.addEdge (LinkTarget target) ccNode stepsDag; ) cbits.target_csources; );