Allow to set the library path at configure time (#575)
This allow to drop the dependency on ocamlfind
This commit is contained in:
parent
2acbc72f76
commit
dfdb6c09f4
|
@ -10,3 +10,4 @@ bootstrap.cmi
|
|||
bootstrap.cmo
|
||||
bootstrap.exe
|
||||
Makefile.dev
|
||||
src/setup.ml
|
|
@ -7,6 +7,9 @@ next
|
|||
compiler is not installed but still has a META file (#574, fixes
|
||||
#563)
|
||||
|
||||
- Do not depend on ocamlfind. Instead, hard-code the library path when
|
||||
installing from opam (#575)
|
||||
|
||||
- Reduce interleaving in the scheduler in an attempt to make Jbuilder
|
||||
keep file descriptors open for less long (#586)
|
||||
|
||||
|
|
3
Makefile
3
Makefile
|
@ -41,6 +41,9 @@ clean:
|
|||
$(BIN) clean
|
||||
rm -f ./boot.exe $(wildcard ./bootstrap.cmi ./bootstrap.cmo ./bootstrap.exe)
|
||||
|
||||
distclean: clean
|
||||
rm -f src/setup.ml
|
||||
|
||||
doc:
|
||||
cd doc && sphinx-build . _build
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
exec ocaml configure.ml "$@"
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env ocaml
|
||||
|
||||
open StdLabels
|
||||
open Printf
|
||||
|
||||
let list f l = sprintf "[%s]" (String.concat ~sep:"; " (List.map l ~f))
|
||||
let string s = sprintf "%S" s
|
||||
let option f = function
|
||||
| None -> "None"
|
||||
| Some x -> sprintf "Some %s" (f x)
|
||||
|
||||
let () =
|
||||
let bad fmt = ksprintf (fun s -> raise (Arg.Bad s)) fmt in
|
||||
let library_path = ref None in
|
||||
let library_destdir = ref None in
|
||||
let set_libdir s =
|
||||
let dir =
|
||||
if Filename.is_relative s then
|
||||
Filename.concat (Sys.getcwd ()) s
|
||||
else
|
||||
s
|
||||
in
|
||||
library_path := Some [dir];
|
||||
library_destdir := Some dir
|
||||
in
|
||||
let args =
|
||||
[ "--libdir", Arg.String set_libdir,
|
||||
"DIR where installed libraries are for the default build context"
|
||||
]
|
||||
in
|
||||
let anon s =
|
||||
bad "Don't know what to do with %s" s
|
||||
in
|
||||
Arg.parse (Arg.align args)
|
||||
anon "Usage: ocaml configure.ml [OPTRIONS]]\nOptions are:";
|
||||
let oc = open_out "src/setup.ml" in
|
||||
let pr fmt = fprintf oc (fmt ^^ "\n") in
|
||||
pr "let library_path = %s" (option (list string) !library_path);
|
||||
pr "let library_destdir = %s" (option string !library_destdir);
|
||||
close_out oc
|
|
@ -6,17 +6,9 @@ bug-reports: "https://github.com/ocaml/dune/issues"
|
|||
dev-repo: "https://github.com/ocaml/dune.git"
|
||||
license: "Apache-2.0"
|
||||
build: [
|
||||
["ocaml" "configure.ml" "--libdir" lib]
|
||||
["ocaml" "bootstrap.ml"]
|
||||
["./boot.exe" "--subst"] {pinned}
|
||||
["./boot.exe" "-j" jobs]
|
||||
]
|
||||
depends: [
|
||||
# ocamlfind is not mandatory to build packages using
|
||||
# jbuilder. However if it is present jbuilder will use it. Making
|
||||
# it a hard-dependency avoids problems when there is a previous
|
||||
# ocamlfind in the PATH. We make it a "build" depepdency even though
|
||||
# it is only a runtime dependency so that reinstalling ocamlfind
|
||||
# doesn't resintall jbuilder
|
||||
"ocamlfind" {build}
|
||||
]
|
||||
available: [ ocaml-version >= "4.02.3" ]
|
||||
|
|
|
@ -136,7 +136,8 @@ let opam_config_var ~env ~cache var =
|
|||
match Bin.opam with
|
||||
| None -> Fiber.return None
|
||||
| Some fn ->
|
||||
Process.run_capture (Accept All) (Path.to_string fn) ~env ["config"; "var"; var]
|
||||
Process.run_capture (Accept All) (Path.to_string fn) ~env
|
||||
["config"; "var"; var]
|
||||
>>| function
|
||||
| Ok s ->
|
||||
let s = String.trim s in
|
||||
|
@ -180,7 +181,7 @@ let extend_env ~vars ~env =
|
|||
|> Array.of_list
|
||||
|
||||
let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin
|
||||
~use_findlib ~targets () =
|
||||
~targets () =
|
||||
let env = extend_env ~env:base_env ~vars:env_extra in
|
||||
let opam_var_cache = Hashtbl.create 128 in
|
||||
(match kind with
|
||||
|
@ -251,7 +252,10 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin
|
|||
|
||||
let build_dir = Path.of_string (sprintf "_build/%s" name) in
|
||||
let findlib_path () =
|
||||
if use_findlib then
|
||||
match kind, findlib_toolchain, Setup.library_path with
|
||||
| Default, None, Some l ->
|
||||
Fiber.return (List.map l ~f:Path.absolute)
|
||||
| _ ->
|
||||
(* If ocamlfind is present, it has precedence over everything else. *)
|
||||
match which "ocamlfind" with
|
||||
| Some fn ->
|
||||
|
@ -270,11 +274,9 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin
|
|||
>>| function
|
||||
| Some s -> [Path.absolute s]
|
||||
| None ->
|
||||
(* If neither opam neither ocamlfind are present, assume that libraries are
|
||||
[dir ^ "/../lib"] *)
|
||||
(* If neither opam neither ocamlfind are present, assume
|
||||
that libraries are [dir ^ "/../lib"] *)
|
||||
[Path.relative (Path.parent dir) "lib"]
|
||||
else
|
||||
Fiber.return []
|
||||
in
|
||||
Fiber.fork_and_join
|
||||
findlib_path
|
||||
|
@ -282,9 +284,10 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin
|
|||
>>= fun (findlib_path, ocamlc_config) ->
|
||||
let version = Ocamlc_config.version ocamlc_config in
|
||||
let env, env_extra =
|
||||
(* See comment in ansi_color.ml for setup_env_for_colors. For OCaml < 4.05,
|
||||
OCAML_COLOR is not supported so we use OCAMLPARAM. OCaml 4.02 doesn't support
|
||||
'color' in OCAMLPARAM, so we just don't force colors with 4.02. *)
|
||||
(* See comment in ansi_color.ml for setup_env_for_colors. For
|
||||
OCaml < 4.05, OCAML_COLOR is not supported so we use
|
||||
OCAMLPARAM. OCaml 4.02 doesn't support 'color' in OCAMLPARAM,
|
||||
so we just don't force colors with 4.02. *)
|
||||
if !Clflags.capture_outputs
|
||||
&& Lazy.force Colors.stderr_supports_colors
|
||||
&& version >= (4, 03, 0)
|
||||
|
@ -397,7 +400,7 @@ let initial_env = lazy (
|
|||
Lazy.force Colors.setup_env_for_colors;
|
||||
Unix.environment ())
|
||||
|
||||
let default ?(merlin=true) ?(use_findlib=true) ~targets () =
|
||||
let default ?(merlin=true) ~targets () =
|
||||
let env = Lazy.force initial_env in
|
||||
let path =
|
||||
match get_env env "PATH" with
|
||||
|
@ -405,7 +408,7 @@ let default ?(merlin=true) ?(use_findlib=true) ~targets () =
|
|||
| None -> []
|
||||
in
|
||||
create ~kind:Default ~path ~base_env:env ~env_extra:Env_var_map.empty
|
||||
~name:"default" ~merlin ~use_findlib ~targets ()
|
||||
~name:"default" ~merlin ~targets ()
|
||||
|
||||
let create_for_opam ?root ~targets ~switch ~name ?(merlin=false) () =
|
||||
match Bin.opam with
|
||||
|
@ -445,11 +448,11 @@ let create_for_opam ?root ~targets ~switch ~name ?(merlin=false) () =
|
|||
in
|
||||
let env = Lazy.force initial_env in
|
||||
create ~kind:(Opam { root; switch }) ~targets
|
||||
~path ~base_env:env ~env_extra:vars ~name ~merlin ~use_findlib:true ()
|
||||
~path ~base_env:env ~env_extra:vars ~name ~merlin ()
|
||||
|
||||
let create ?use_findlib ?merlin def =
|
||||
let create ?merlin def =
|
||||
match (def : Workspace.Context.t) with
|
||||
| Default targets -> default ~targets ?merlin ?use_findlib ()
|
||||
| Default targets -> default ~targets ?merlin ()
|
||||
| Opam { name; switch; root; targets; _ } ->
|
||||
create_for_opam ?root ~switch ~name ?merlin ~targets ()
|
||||
|
||||
|
@ -461,15 +464,19 @@ let install_prefix t =
|
|||
| None -> Path.parent t.ocaml_bin
|
||||
|
||||
let install_ocaml_libdir t =
|
||||
(* If ocamlfind is present, it has precedence over everything else. *)
|
||||
match which t "ocamlfind" with
|
||||
| Some fn ->
|
||||
(Process.run_capture_line ~env:t.env Strict
|
||||
(Path.to_string fn) ["printconf"; "destdir"]
|
||||
>>| fun s ->
|
||||
Some (Path.absolute s))
|
||||
| None ->
|
||||
Fiber.return None
|
||||
match t.kind, t.findlib_toolchain, Setup.library_destdir with
|
||||
| Default, None, Some d ->
|
||||
Fiber.return (Some (Path.absolute d))
|
||||
| _ ->
|
||||
(* If ocamlfind is present, it has precedence over everything else. *)
|
||||
match which t "ocamlfind" with
|
||||
| Some fn ->
|
||||
(Process.run_capture_line ~env:t.env Strict
|
||||
(Path.to_string fn) ["printconf"; "destdir"]
|
||||
>>| fun s ->
|
||||
Some (Path.absolute s))
|
||||
| None ->
|
||||
Fiber.return None
|
||||
|
||||
(* CR-someday jdimino: maybe we should just do this for [t.env] directly? *)
|
||||
let env_for_exec t =
|
||||
|
|
|
@ -129,12 +129,8 @@ val sexp_of_t : t -> Sexp.t
|
|||
(** Compare the context names *)
|
||||
val compare : t -> t -> Ordering.t
|
||||
|
||||
(** If [use_findlib] is [false], don't try to guess the library search path with opam or
|
||||
ocamlfind. This is only for building jbuilder itself, so that its build is completely
|
||||
independent of the user setup. *)
|
||||
val create
|
||||
: ?use_findlib:bool
|
||||
-> ?merlin:bool
|
||||
: ?merlin:bool
|
||||
-> Workspace.Context.t
|
||||
-> t list Fiber.t
|
||||
|
||||
|
|
|
@ -13,3 +13,8 @@
|
|||
(synopsis "Internal Jbuilder library, do not use!")))
|
||||
|
||||
(ocamllex (meta_lexer glob_lexer))
|
||||
|
||||
(rule
|
||||
((targets (setup.ml))
|
||||
(mode fallback)
|
||||
(action (copy# setup.defaults.ml setup.ml))))
|
||||
|
|
|
@ -21,7 +21,6 @@ let package_install_file { packages; _ } pkg =
|
|||
let setup ?(log=Log.no_log)
|
||||
?filter_out_optional_stanzas_with_missing_deps
|
||||
?workspace ?(workspace_file="jbuild-workspace")
|
||||
?(use_findlib=true)
|
||||
?only_packages
|
||||
?extra_ignored_subtrees
|
||||
?x
|
||||
|
@ -56,11 +55,12 @@ let setup ?(log=Log.no_log)
|
|||
|
||||
Fiber.parallel_map workspace.contexts ~f:(fun ctx_def ->
|
||||
let name = Workspace.Context.name ctx_def in
|
||||
Context.create ctx_def ~merlin:(workspace.merlin_context = Some name) ~use_findlib)
|
||||
Context.create ctx_def ~merlin:(workspace.merlin_context = Some name))
|
||||
>>= fun contexts ->
|
||||
let contexts = List.concat contexts in
|
||||
List.iter contexts ~f:(fun (ctx : Context.t) ->
|
||||
Log.infof log "@[<1>Jbuilder context:@,%a@]@." Sexp.pp (Context.sexp_of_t ctx));
|
||||
Log.infof log "@[<1>Jbuilder context:@,%a@]@." Sexp.pp
|
||||
(Context.sexp_of_t ctx));
|
||||
let rule_done = ref 0 in
|
||||
let rule_total = ref 0 in
|
||||
let gen_status_line () =
|
||||
|
@ -168,7 +168,6 @@ let bootstrap () =
|
|||
Scheduler.go ~log ~config
|
||||
(setup ~log ~workspace:{ merlin_context = Some "default"
|
||||
; contexts = [Default [Native]] }
|
||||
~use_findlib:false
|
||||
~extra_ignored_subtrees:ignored_during_bootstrap
|
||||
()
|
||||
>>= fun { build_system = bs; _ } ->
|
||||
|
@ -183,7 +182,7 @@ let bootstrap () =
|
|||
Report_error.report exn;
|
||||
exit 1
|
||||
|
||||
let setup = setup ~use_findlib:true ~extra_ignored_subtrees:Path.Set.empty
|
||||
let setup = setup ~extra_ignored_subtrees:Path.Set.empty
|
||||
|
||||
let find_context_exn t ~name =
|
||||
match List.find t.contexts ~f:(fun c -> c.name = name) with
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
let library_path = Some []
|
||||
let library_destdir = None
|
|
@ -0,0 +1,2 @@
|
|||
let library_path = None
|
||||
let library_destdir = None
|
|
@ -0,0 +1,12 @@
|
|||
(** Setup of Jbuilder *)
|
||||
|
||||
(** These parameters are set by [ocaml configure.ml] or copied from
|
||||
[setup.defaults.ml]. During bootstrap, values from [setup.boot.ml]
|
||||
are used *)
|
||||
|
||||
(** Where to find installed libraries for the default context. If
|
||||
[None], auto-detect it using standard tools such as [ocamlfind]. *)
|
||||
val library_path : string list option
|
||||
|
||||
(** Where to install libraries for the default context. *)
|
||||
val library_destdir : string option
|
Loading…
Reference in New Issue