From fc560859b0bb09c15e50edc48650bf5d50de3c97 Mon Sep 17 00:00:00 2001 From: Emilio Jesus Gallego Arias Date: Wed, 16 Jun 2021 19:30:51 +0200 Subject: [PATCH] [install] Allow users to specify docdir and etcdir Fixes #4723 This is an important fix for those using Dune to build, for example, Debian packages, as docdir is there `prefix/share/doc/package`, similarly for `etc`. Thus, I request for approval to ship this in 2.9. I have written the patch very conservatively, as to allow easy backporting, but once we release 2.9 it would be convenient to refactor this code so overridable directories are placed into a record. Signed-off-by: Emilio Jesus Gallego Arias --- CHANGES.md | 5 ++++ bin/install_uninstall.ml | 28 +++++++++++++++++-- configure.ml | 19 ++++++++++--- doc/usage.rst | 5 ++++ src/dune_engine/install.ml | 11 ++++++-- src/dune_engine/install.mli | 2 ++ src/dune_rules/artifact_substitution.ml | 5 ++-- src/dune_rules/artifact_substitution.mli | 2 ++ src/dune_rules/setup.defaults.ml | 4 +++ src/dune_rules/setup.mli | 6 ++++ .../test-cases/install-docdir.t/run.t | 14 ++++++++++ .../test-cases/install-etcdir.t/run.t | 14 ++++++++++ 12 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 test/blackbox-tests/test-cases/install-docdir.t/run.t create mode 100644 test/blackbox-tests/test-cases/install-etcdir.t/run.t diff --git a/CHANGES.md b/CHANGES.md index ddbb0b2b039..1f642bd7926 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -172,6 +172,11 @@ Unreleased - Fix generation of merlin configuration when using `(include_subdirs unqualified)` on Windows (#4745, @nojb) +- Allow users to specify install target directories for `doc` and + `etc` sections. We add new options `--docdir` and `--etcdir` to both + Dune's configure and `dune install` command. (#4744, fixes #4723, + @ejgallego, thanks to @JasonGross for reporting this issue) + 2.8.5 (28/03/2021) ------------------ diff --git a/bin/install_uninstall.ml b/bin/install_uninstall.ml index ae066df64db..1fe87871b18 100644 --- a/bin/install_uninstall.ml +++ b/bin/install_uninstall.ml @@ -384,6 +384,17 @@ let install_uninstall ~what = "When passed, manually override the directory to install man pages" in Arg.(value & opt (some string) None & info [ "mandir" ] ~docv:"PATH" ~doc) + and+ docdir = + let doc = + "When passed, manually override the directory to install documentation" + in + Arg.(value & opt (some string) None & info [ "docdir" ] ~docv:"PATH" ~doc) + and+ etcdir = + let doc = + "When passed, manually override the directory to install configuration \ + files" + in + Arg.(value & opt (some string) None & info [ "etcdir" ] ~docv:"PATH" ~doc) and+ dry_run = Arg.( value & flag @@ -507,6 +518,18 @@ let install_uninstall ~what = | Some _ -> mandir | None -> Dune_rules.Setup.mandir) in + let docdir = + Option.map ~f:Path.of_string + (match docdir with + | Some _ -> docdir + | None -> Dune_rules.Setup.docdir) + in + let etcdir = + Option.map ~f:Path.of_string + (match etcdir with + | Some _ -> etcdir + | None -> Dune_rules.Setup.etcdir) + in Fiber.sequential_iter install_files_by_context ~f:(fun (context, entries_per_package) -> let* prefix, libdir = @@ -516,13 +539,14 @@ let install_uninstall ~what = let conf = Dune_rules.Artifact_substitution.conf_for_install ~relocatable ~default_ocamlpath:context.default_ocamlpath - ~stdlib_dir:context.stdlib_dir ~prefix ~libdir ~mandir + ~stdlib_dir:context.stdlib_dir ~prefix ~libdir ~mandir ~docdir + ~etcdir in Fiber.sequential_iter entries_per_package ~f:(fun (package, entries) -> let paths = Install.Section.Paths.make ~package ~destdir:prefix ?libdir - ?mandir () + ?mandir ?docdir ?etcdir () in Fiber.sequential_iter entries ~f:(fun entry -> let special_file = Special_file.of_entry entry in diff --git a/configure.ml b/configure.ml index c4b13aff176..45676923830 100644 --- a/configure.ml +++ b/configure.ml @@ -16,6 +16,8 @@ let () = let library_path = ref None in let library_destdir = ref None in let mandir = ref None in + let docdir = ref None in + let etcdir = ref None in let cwd = lazy (Sys.getcwd ()) in let dir_of_string s = if Filename.is_relative s then @@ -28,17 +30,24 @@ let () = library_path := Some [ dir ]; library_destdir := Some dir in - let set_mandir s = + let set_dir v s = let dir = dir_of_string s in - mandir := Some dir + v := Some dir in let args = [ ( "--libdir" , Arg.String set_libdir , "DIR where installed libraries are for the default build context" ) ; ( "--mandir" - , Arg.String set_mandir - , "DIR where man pages are installed are for the default build context" ) + , Arg.String (set_dir mandir) + , "DIR where man pages are installed for the default build context" ) + ; ( "--docdir" + , Arg.String (set_dir docdir) + , "DIR where documentation is installed for the default build context" ) + ; ( "--etcdir" + , Arg.String (set_dir etcdir) + , "DIR where configuration files are installed for the default build \ + context" ) ] in let anon s = bad "Don't know what to do with %s" s in @@ -49,4 +58,6 @@ let () = pr "let library_path = %s" (option (list string) !library_path); pr "let library_destdir = %s" (option string !library_destdir); pr "let mandir = %s" (option string !mandir); + pr "let docdir = %s" (option string !docdir); + pr "let etcdir = %s" (option string !etcdir); close_out oc diff --git a/doc/usage.rst b/doc/usage.rst index 517f8203be7..291308b3aa1 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -537,6 +537,11 @@ no difference. Note that ``--prefix`` and ``--libdir`` are only supported if a single build context is in use. +Note that ``dune install`` (and Dune's ``configure``) support +additional parameters to override install directories in addition to +``--prefix``, in particular, ``--mandir``, ``--docdir``, and +``--etcdir`` are supported + Relocation Mode --------------- diff --git a/src/dune_engine/install.ml b/src/dune_engine/install.ml index dd037e17d07..90df3d9779d 100644 --- a/src/dune_engine/install.ml +++ b/src/dune_engine/install.ml @@ -143,14 +143,19 @@ module Section = struct ; man : Path.t } + (* FIXME: we should handle all directories uniformly, instead of + special-casing etcdir, mandir, and docdir as of today [which was done for + convenience of backporting] *) let make ~package ~destdir ?(libdir = Path.relative destdir "lib") - ?(mandir = Path.relative destdir "man") () = + ?(mandir = Path.relative destdir "man") + ?(docdir = Path.relative destdir "doc") + ?(etcdir = Path.relative destdir "etc") () = let package = Package.Name.to_string package in let lib_root = libdir in let libexec_root = libdir in let share_root = Path.relative destdir "share" in - let etc_root = Path.relative destdir "etc" in - let doc_root = Path.relative destdir "doc" in + let etc_root = etcdir in + let doc_root = docdir in { lib_root ; libexec_root ; share_root diff --git a/src/dune_engine/install.mli b/src/dune_engine/install.mli index 15344d1c91b..80311e38e1f 100644 --- a/src/dune_engine/install.mli +++ b/src/dune_engine/install.mli @@ -55,6 +55,8 @@ module Section : sig -> destdir:Path.t -> ?libdir:Path.t -> ?mandir:Path.t + -> ?docdir:Path.t + -> ?etcdir:Path.t -> unit -> t diff --git a/src/dune_rules/artifact_substitution.ml b/src/dune_rules/artifact_substitution.ml index e24755d32d1..dbee3634943 100644 --- a/src/dune_rules/artifact_substitution.ml +++ b/src/dune_rules/artifact_substitution.ml @@ -77,7 +77,7 @@ let conf_of_context (context : Context.t option) = } let conf_for_install ~relocatable ~default_ocamlpath ~stdlib_dir ~prefix ~libdir - ~mandir = + ~mandir ~docdir ~etcdir = let get_vcs = Source_tree.nearest_vcs in let hardcoded_ocaml_path = if relocatable then @@ -87,7 +87,8 @@ let conf_for_install ~relocatable ~default_ocamlpath ~stdlib_dir ~prefix ~libdir in let get_location section package = let paths = - Install.Section.Paths.make ~package ~destdir:prefix ?libdir ?mandir () + Install.Section.Paths.make ~package ~destdir:prefix ?libdir ?mandir + ?docdir ?etcdir () in Install.Section.Paths.get paths section in diff --git a/src/dune_rules/artifact_substitution.mli b/src/dune_rules/artifact_substitution.mli index ae6ef0f7e02..4b94a27c801 100644 --- a/src/dune_rules/artifact_substitution.mli +++ b/src/dune_rules/artifact_substitution.mli @@ -37,6 +37,8 @@ val conf_for_install : -> prefix:Path.t -> libdir:Path.t option -> mandir:Path.t option + -> docdir:Path.t option + -> etcdir:Path.t option -> conf val conf_dummy : conf diff --git a/src/dune_rules/setup.defaults.ml b/src/dune_rules/setup.defaults.ml index 2e803586423..43e4042f52a 100644 --- a/src/dune_rules/setup.defaults.ml +++ b/src/dune_rules/setup.defaults.ml @@ -5,3 +5,7 @@ let library_path = None let library_destdir = None let mandir = None + +let docdir = None + +let etcdir = None diff --git a/src/dune_rules/setup.mli b/src/dune_rules/setup.mli index aac558e7923..41b0e4af0b1 100644 --- a/src/dune_rules/setup.mli +++ b/src/dune_rules/setup.mli @@ -13,3 +13,9 @@ val library_destdir : string option (** Where to install manpages for the default context. *) val mandir : string option + +(** Where to install docs for the default context. *) +val docdir : string option + +(** Where to install configuration files for the default context. *) +val etcdir : string option diff --git a/test/blackbox-tests/test-cases/install-docdir.t/run.t b/test/blackbox-tests/test-cases/install-docdir.t/run.t new file mode 100644 index 00000000000..38390da8463 --- /dev/null +++ b/test/blackbox-tests/test-cases/install-docdir.t/run.t @@ -0,0 +1,14 @@ + $ echo "(lang dune 2.0)" > dune-project + $ touch foo.opam docfile + $ cat >dune < (install + > (section doc) + > (files docfile)) + > EOF + $ dune build @install + $ mkdir install docdir + $ dune install --dry-run --prefix ./install --docdir ./docdir 2>&1 | grep docdir + Removing (if it exists) docdir/foo/docfile + Installing docdir/foo/docfile + Creating directory docdir/foo + Copying _build/install/default/doc/foo/docfile to docdir/foo/docfile (executable: false) diff --git a/test/blackbox-tests/test-cases/install-etcdir.t/run.t b/test/blackbox-tests/test-cases/install-etcdir.t/run.t new file mode 100644 index 00000000000..b41ba800233 --- /dev/null +++ b/test/blackbox-tests/test-cases/install-etcdir.t/run.t @@ -0,0 +1,14 @@ + $ echo "(lang dune 2.0)" > dune-project + $ touch foo.opam configfile + $ cat >dune < (install + > (section etc) + > (files configfile)) + > EOF + $ dune build @install + $ mkdir install etcdir + $ dune install --dry-run --prefix ./install --etcdir ./etcdir 2>&1 | grep etcdir + Removing (if it exists) etcdir/foo/configfile + Installing etcdir/foo/configfile + Creating directory etcdir/foo + Copying _build/install/default/etc/foo/configfile to etcdir/foo/configfile (executable: false)