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 list of target, separated by spaces
- =<= expands to the first dependency, or the empty string if there are no dependencies - =<= expands to the first dependency, or the empty string if there are no dependencies
- =^= expands to the list of dependencies, separated by spaces - =^= 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 - =bin:<program>= expands to a path to =program=. If =program= is
provided by a jbuild in the workspace (see [[provide][provide stanzas]]), the provided by a jbuild in the workspace (see [[provide][provide stanzas]]), the
locally built binarry will be used, otherwise it will be searched in 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 In both case, each atom in the argument supports [[Variables expansion][variables
expansion]]. Moreover, you don't need to specify dependencies expansion]]. Moreover, you don't need to specify dependencies
explicitely for the special =${bin:...}= or =${findlib:...}= forms, explicitely for the special =${exe:...}=, =${bin:...}= or
these are recognized automatically by Jbuilder. =${findlib:...}= forms, these are recognized automatically by
Jbuilder.
The DSL is preferable in general as it will make your package more The DSL is preferable in general as it will make your package more
portable. It is currently quite limited, so the recommendation is to 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 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 = let mode, link_flags, compiler =
match Mode.compiler mode ctx with match Mode.compiler mode ctx with
| Some compiler -> (mode, link_flags, compiler) | Some compiler -> (mode, link_flags, compiler)
@ -1176,13 +1176,20 @@ module Gen(P : Params) = struct
end = struct end = struct
module U = User_action.Unexpanded 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 = let extract_artifacts ~dir ~dep_kind t =
U.fold t ~init:String_map.empty ~f:(fun acc var -> U.fold t ~init:String_map.empty ~f:(fun acc var ->
let module N = Named_artifacts in let module N = Named_artifacts in
match String.lsplit2 var ~on:':' with 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) -> | 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) | _ -> acc)
let expand t ~artifact_map ~dir ~targets ~deps = 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 let s = expand t ~dir ~artifact_map:String_map.empty ~targets ~deps in
Build.return s Build.return s
else begin else begin
Build.all (List.map (String_map.bindings needed_artifacts) ~f:(fun (name, artifact) -> let directs, dyns =
artifact String_map.bindings needed_artifacts
>>> |> List.partition_map ~f:(function
Build.arr (fun path -> (name, path)))) | (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.dyn_paths (Build.arr (List.map ~f:snd))
>>> >>>
Build.arr (fun artifacts -> 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) expand t ~dir ~artifact_map ~targets ~deps)
end end