ocamlbuild icon indicating copy to clipboard operation
ocamlbuild copied to clipboard

Include dirs and ocaml dependencies

Open Drup opened this issue 9 years ago • 7 comments

I would like to reproduce the behavior of the include tag, in particular with relation to auto-discovering dependencies with ocamldep, but without getting the -I command line, how should I do that ? Ideally, I would like the exact same behavior, but inserting another command line argument instead.

I feel like the answer is in Pathname.define_context, but I'm not sure how to use that in a tag.

Drup avatar Sep 29 '16 10:09 Drup

If you want to do exactly the same as -I, you can add a new command-line option Options.add that would manipulate the Options.include_dirs reference. Note that this has to be done in the After_options hook or before, as the "state of the world" as OCamlbuild sees it (the slurp) may be affected by include directories -- and is computed before hygiene, and before rules are defined.

Pathname.define_context is used to define the dirs in scope for producing targets living in a specific directory, which influences the Pathname.include_dirs_of function -- and if no context have been defined, Options.include_dirs is used. Unfortunately, I don't know enough about this feature to be confident on what was the intended use-case. (It seems inadequate if you want to change included directories globally.)

gasche avatar Sep 30 '16 20:09 gasche

I do not want a new ocamlbuild command line flag. When I said -I, I meant ocaml's command line flag, so setting include_dirs is not going to work.

Drup avatar Sep 30 '16 20:09 Drup

I don't understand what you want. Could you clarify?

gasche avatar Sep 30 '16 22:09 gasche

I would like to create a tag that behaves like include, let's call it include_foo. When you specify dir: include_foo, dir would be considered by the whole ocamldep mechanisms but ocamlc would not get -I dir, it would get -foo dir instead (or whatever I choose).

After examination of the implementation, I'm quite convinced that this is actually not possible without patching ocamlbuild, include is baked too much into the various details of ocamlbuild's rules.

Drup avatar Sep 30 '16 22:09 Drup

Well include does not affect ocamldep directly (there is nothing related to the include paths in the ocamldep calls), but rather which modules are known to exist when compiling other modules.

If you want to avoid having -I <foo> options passed to the compiler for included directories, you can replace the OCamlbuild rules that call the compiler to change the way they build their command. This is doable purely as a plugin, but of course that may be more work than just patching the source directly as you have to copy/reproduce/reuse the glue between the rule and the actual compiler command.

(Of course in general if do not pass the included directories to ocamlc as -I flags you may have compilation failures as the compiler is locate to find the compiler units it expects. I don't know what you want to do.)

gasche avatar Oct 01 '16 14:10 gasche

Well include does not affect ocamldep directly

Not directly, but the resolution from module names (given by ocamldep) to files uses the directory returned by Pathname.include_dirs_of, which uses the directory added by include. My issues is precisely that this list of directories is also used to decide which -I flag to add to the ocaml command line.

Drup avatar Oct 01 '16 15:10 Drup

So, to summarize:

  • The set of dirs included with -I when compiling foo is derived from Pathname.include_dirs_of foo. This is done in Ocaml_utils.ocaml_include_flags.
  • The list of files that are potential dependencies of a file is given by Ocaml_compiler.prepare_link, which is computed by getting the module names given by ocamldep and searching those in each directories given by Pathname.include_dirs_of foo

So if a directory is used to compute build dependencies, it will necessary be added to the compiler call with -I.

The only way to add things to what is returned by Pathname.include_dirs_of foo are

  • the include tags
  • Pathname.define_context, which seems to work on a file-by-file basis.

I'm not sure how to modify ocamlbuild to do what I want.

Drup avatar Dec 08 '16 19:12 Drup