Better support for cross-compilation

This commit is contained in:
Jeremie Dimino 2017-02-24 10:28:31 +00:00
parent ae376d30d2
commit 89335dd5e4
2 changed files with 31 additions and 10 deletions

View File

@ -610,6 +610,8 @@ In addition, =(action ...)= fields support the following special variables:
- =@= expands to the list of target, separated by spaces
- =<= expands to the first dependency, or the empty string if there are no dependencies
- =^= expands to the list of dependencies, separated by spaces
- =exe:<path>= expands to =<path>=, except when cross-compiling, in
which case it will expand to =<path>= from the host build context
- =bin:<program>= expands to a path to =program=. If =program= is
provided by a jbuild in the workspace (see [[provide][provide stanzas]]), the
locally built binarry will be used, otherwise it will be searched in
@ -772,8 +774,9 @@ of these two forms:
In both case, each atom in the argument supports [[Variables expansion][variables
expansion]]. Moreover, you don't need to specify dependencies
explicitely for the special =${bin:...}= or =${findlib:...}= forms,
these are recognized automatically by Jbuilder.
explicitely for the special =${exe:...}=, =${bin:...}= or
=${findlib:...}= forms, these are recognized automatically by
Jbuilder.
The DSL is preferable in general as it will make your package more
portable. It is currently quite limited, so the recommendation is to

View File

@ -1087,7 +1087,7 @@ module Gen(P : Params) = struct
+-----------------------------------------------------------------+ *)
let build_exe ~flags ~dir ~requires ~name ~mode ~modules ~dep_graph ~link_flags =
let ext_ext = Mode.exe_ext mode in
let exe_ext = Mode.exe_ext mode in
let mode, link_flags, compiler =
match Mode.compiler mode ctx with
| Some compiler -> (mode, link_flags, compiler)
@ -1176,13 +1176,20 @@ module Gen(P : Params) = struct
end = struct
module U = User_action.Unexpanded
type artefact =
| Direct of Path.t
| Dyn of (unit, Path.t) Build.t
let extract_artifacts ~dir ~dep_kind t =
U.fold t ~init:String_map.empty ~f:(fun acc var ->
let module N = Named_artifacts in
match String.lsplit2 var ~on:':' with
| Some ("bin", s) -> String_map.add acc ~key:var ~data:(N.binary s)
(* CR-someday jdimino: map the exe to the host exe here *)
| Some ("exe", s) ->
String_map.add acc ~key:var ~data:(Direct (Path.relative dir s))
| Some ("bin", s) -> String_map.add acc ~key:var ~data:(Dyn (N.binary s))
| Some ("findlib" , s) ->
String_map.add acc ~key:var ~data:(N.in_findlib ~dir ~dep_kind s)
String_map.add acc ~key:var ~data:(Dyn (N.in_findlib ~dir ~dep_kind s))
| _ -> acc)
let expand t ~artifact_map ~dir ~targets ~deps =
@ -1211,15 +1218,26 @@ module Gen(P : Params) = struct
let s = expand t ~dir ~artifact_map:String_map.empty ~targets ~deps in
Build.return s
else begin
Build.all (List.map (String_map.bindings needed_artifacts) ~f:(fun (name, artifact) ->
artifact
>>>
Build.arr (fun path -> (name, path))))
let directs, dyns =
String_map.bindings needed_artifacts
|> List.partition_map ~f:(function
| (name, Direct x) -> Inl (name, x)
| (name, Dyn x) -> Inr (name, x))
in
Build.fanout
(Build.paths (List.map directs ~f:snd))
(Build.all (List.map dyns ~f:(fun (name, artifact) ->
artifact
>>>
Build.arr (fun path -> (name, path)))))
>>^ snd
>>>
Build.dyn_paths (Build.arr (List.map ~f:snd))
>>>
Build.arr (fun artifacts ->
let artifact_map = String_map.of_alist_exn artifacts in
let artifact_map =
String_map.of_alist_exn (List.rev_append directs artifacts)
in
expand t ~dir ~artifact_map ~targets ~deps)
end