Open agarwal opened 8 years ago
Pathname.pwd
is the project path, how does it not work for you? Note that ocamlbuild is designed to only write files in the build directory, not in the source directory, except for explicitly named targets for which links in the source directory are created. You have the expressive power to get out of that model (define a rule "project files" that creates a fixed list of files in _build
and links them in the source directory¹), but this should be done rather carefully.
¹: I think it is better to create in the build dir and then link than to create in pwd
directly, because ocamlbuild will look in the build dir to see if the target has already been built, etc.
Pathname.pwd is the project path, how does it not work for you?
I set ~prod
to Filename.concat Pathname.pwd ".merlin"
, thinking that I'm now specifying an absolute path, so that maybe ocamlbuild would disregard _build
. However, it doesn't recognize the request at all now.
$ ocamlbuild .merlin
Finished, 1 target (0 cached) in 00:00:00.
Solver failed:
Ocamlbuild knows of no rules that apply to a target named .merlin. This can happen if you ask Ocamlbuild to build a target with the wrong extension (e.g. .opt instead of .native) or if the source files live in directories that have not been specified as include directories.
Compilation unsuccessful after building 0 targets (0 cached) in 00:00:00.
Trying your suggestion to define a "project files" rule, I have this:
$ cat myocamlbuild.ml
open Ocamlbuild_plugin
let () = dispatch (function
| After_rules -> (
rule ".merlin"
~prod:".merlin"
(fun env _ -> Echo (["S ./src/**"], ".merlin"))
;
rule "project files"
~stamp:"project_files.stamp"
(fun _ build ->
let project_files = [[".merlin"]] in
List.map Outcome.good (build project_files) |>
List.map (fun result ->
Cmd (S [A "ln"; A "-sf";
P (!Options.build_dir/result);
P Pathname.pwd] )
) |>
fun l -> Seq l
)
)
| _ -> ()
)
The "project files" rule has no prod
, so how do you invoke it? Doing ocamlbuild .merlin
only produces _build/.merlin
, and understandably not the link that "project files" creates.
You have the expressive power to get out of that model
Building in _build is of course good; it should be the default but I shouldn't be disallowed from creating a file elsewhere. Your suggestion to link files is a hack because the link isn't a first class entity of the build DAG.
A better solution would be: relative paths should by default be assumed to be relative to _build, but it should be possible to give repo_root
as an alternative.
I still don't know how to invoke the "project rules" rule, so I thought a workaround is to do ocamlbuild .merlin
. I thought explicit targets to ocamlbuild are symlinked, but no symlink is created in this case. This doesn't work for cma's either so perhaps the automatic linking is only done for executables, which would actually make sense.
I thought I had answered already, sorry. Just request the stamp as target: ocamlbuild project_files.stamp
will run the rule.
(Yes, automatic linking is kind of flaky right now, and I'm not sure exactly how to specify it and whether making it more uniform is a good idea.)
Thanks. I thought I had tried that, but must have done something wrong. This works.
Another thing I noticed is that one cannot create the symlink and git commit it because ocamlbuild deletes the symlink!
I'm writing a rule like this:
which produces the file
_build/.merlin
, but we want.merlin
in the root of our repo. I tried usingPathname.pwd
but that doesn't seem to help. I'm also not usingenv
, but AFAICT that only expands variable names so it isn't relevant.(I realize my issues are questions, but hopefully they suggest documentation improvements so are relevant to this repo.)