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

Allow to set the library path at configure time #575

Merged
4 commits merged into from Mar 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ bootstrap.cmi
bootstrap.cmo
bootstrap.exe
Makefile.dev
src/setup.ml
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
exec ocaml configure.ml "$@"
40 changes: 40 additions & 0 deletions configure.ml
Original file line number Diff line number Diff line change
@@ -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
10 changes: 1 addition & 9 deletions jbuilder.opam
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]
55 changes: 31 additions & 24 deletions src/context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 ->
Expand All @@ -270,21 +274,20 @@ 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
(fun () -> Ocamlc_config.read ~ocamlc ~env)
>>= 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)
Expand Down Expand Up @@ -397,15 +400,15 @@ 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
| Some s -> Bin.parse_path s
| 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
Expand Down Expand Up @@ -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 ()

Expand All @@ -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 =
Expand Down
6 changes: 1 addition & 5 deletions src/context.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions src/jbuild
Original file line number Diff line number Diff line change
Expand Up @@ -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))))
9 changes: 4 additions & 5 deletions src/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 () =
Expand Down Expand Up @@ -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; _ } ->
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/setup.boot.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let library_path = Some []
let library_destdir = None
2 changes: 2 additions & 0 deletions src/setup.defaults.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let library_path = None
let library_destdir = None
12 changes: 12 additions & 0 deletions src/setup.mli
Original file line number Diff line number Diff line change
@@ -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