Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to create files outside of _build #21

Open
agarwal opened this issue Dec 8, 2015 · 7 comments
Open

how to create files outside of _build #21

agarwal opened this issue Dec 8, 2015 · 7 comments

Comments

@agarwal
Copy link
Contributor

agarwal commented Dec 8, 2015

I'm writing a rule like this:

rule ".merlin"
  ~prod:".merlin"
  (fun env _ -> Echo (["S ./src/**"], ".merlin"))

which produces the file _build/.merlin, but we want .merlin in the root of our repo. I tried using Pathname.pwd but that doesn't seem to help. I'm also not using env, 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.)

@gasche
Copy link
Owner

gasche commented Dec 9, 2015

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.

@agarwal
Copy link
Contributor Author

agarwal commented Dec 9, 2015

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.

@agarwal
Copy link
Contributor Author

agarwal commented Dec 9, 2015

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.

@agarwal
Copy link
Contributor Author

agarwal commented Dec 9, 2015

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.

@agarwal
Copy link
Contributor Author

agarwal commented Dec 10, 2015

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.

@gasche
Copy link
Owner

gasche commented Dec 10, 2015

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.)

@agarwal
Copy link
Contributor Author

agarwal commented Dec 11, 2015

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants