From e148f75ee453a4155a48501b162f70768d812a68 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Fri, 24 Feb 2017 12:54:51 +0000 Subject: [PATCH] add an install alias --- bin/main.ml | 10 ++++++++-- doc/manual.org | 11 ++++++++++- src/gen_rules.ml | 26 +++++++++++++++++++------- src/path.ml | 2 +- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/bin/main.ml b/bin/main.ml index 0feda68f..a7565d7b 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -135,6 +135,11 @@ type target = | File of Path.t | Alias of Path.t * Alias.t +let aliases_in_source_tree = + String_set.of_list + [ "install" + ] + let resolve_targets (setup : Main.setup) user_targets = match user_targets with | [] -> [] @@ -147,14 +152,15 @@ let resolve_targets (setup : Main.setup) user_targets = if Path.is_root path then die "@ on the command line must be followed by a valid alias name" else + let name = Path.basename path in let path = - if Path.is_in_build_dir path then + if Path.is_in_build_dir path || + String_set.mem name aliases_in_source_tree then path else Path.append setup.context.build_dir path in let dir = Path.parent path in - let name = Path.basename path in Alias (path, Alias.make ~dir name) else File ( diff --git a/doc/manual.org b/doc/manual.org index ec2797a2..e7ea0e53 100644 --- a/doc/manual.org +++ b/doc/manual.org @@ -130,7 +130,16 @@ Jbuilder doesn't read =.opam= files, however when a =.opam= is present, Jbuilder will knows that the package named == exists. It will know how to construct a =.install= file in the same directory, to handle installation -via [[https://opam.ocaml.org/][opam]]. +via [[https://opam.ocaml.org/][opam]]. In addition, Jbuilder will also know how to build +=.install= at the root of the workspace, for +convenience. Jbuilder also defines the =install= alias, which depends +on all the buildable =.install= at the root of the +workspace. So for instance to build everything that is installable in +a workspace, run: + +#+begin_src +$ jbuilder build @install +#+end_src Declaring a package this way will allow you to add elements such as libraries, executables, documentations, ... to your package by diff --git a/src/gen_rules.ml b/src/gen_rules.ml index 406fcb69..edb79a82 100644 --- a/src/gen_rules.ml +++ b/src/gen_rules.ml @@ -1658,13 +1658,25 @@ module Gen(P : Params) = struct install_file package_path package) let () = - if Path.basename ctx.build_dir = "default" then - String_map.iter P.packages ~f:(fun ~key:pkg ~data:path -> - let install_file = Path.relative path (pkg ^ ".install") in - add_rule - (Build.copy - ~src:(Path.append ctx.build_dir install_file) - ~dst:install_file)) + let install_alias = Alias.make ~dir:ctx.build_dir "install" in + let global_install_alias = Alias.make ~dir:Path.root "install" in + let is_default = Path.basename ctx.build_dir = "default" in + String_map.iter P.packages ~f:(fun ~key:pkg ~data:path -> + let install_fn = pkg ^ ".install" in + let in_source_dir = Path.relative path install_fn in + let orig = Path.append ctx.build_dir in_source_dir in + let at_root_of_build_context = Path.relative ctx.build_dir install_fn in + if not (Path.is_root path) then + add_rule (Build.copy ~src:orig ~dst:at_root_of_build_context); + Alias.add_deps install_alias [at_root_of_build_context]; + + if is_default then begin + add_rule (Build.copy ~src:orig ~dst:in_source_dir); + let at_root = Path.relative Path.root install_fn in + if not (Path.is_root path) then + add_rule (Build.copy ~src:orig ~dst:at_root); + Alias.add_deps global_install_alias [at_root] + end) end let gen ~context ~file_tree ~tree ~stanzas ~packages diff --git a/src/path.ml b/src/path.ml index 65c5c457..ee68f800 100644 --- a/src/path.ml +++ b/src/path.ml @@ -80,7 +80,7 @@ module Local = struct | t -> let len = String.length t in match String.rindex_from t (len - 1) '/' with - | exception Not_found -> "" + | exception Not_found -> t | i -> String.sub t ~pos:(i + 1) ~len:(len - i - 1) let relative initial_t path =