Skip to content

[esy] Out of source compilation #3856

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

Closed
wants to merge 2 commits into from
Closed
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
33 changes: 31 additions & 2 deletions jscomp/bsb/bsb_build_util.ml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ let resolve_bsb_magic_file ~cwd ~desc p : result =
mkp "/a/b/c/d"
]}
*)
let rec mkp dir =
let rec mkp dir =
Bsb_log.info
"@{<info>mkp @} dir: %s @." dir;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you comment these lines temporarily to make sure this diff is small

if not (Sys.file_exists dir) then
let parent_dir = Filename.dirname dir in
if parent_dir = Filename.current_dir_name then
Expand Down Expand Up @@ -178,6 +180,7 @@ let rec walk_all_deps_aux
(top : bool)
(dir : string)
(cb : package_context -> unit) =
let () = Bsb_log.info "@{<info>walk_all_deps_aux dir:@} %s @." dir in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

let bsconfig_json = dir // Literals.bsconfig_json in
match Ext_json_parse.parse_json_from_file bsconfig_json with
| Obj {map; loc} ->
Expand Down Expand Up @@ -229,5 +232,31 @@ let rec walk_all_deps_aux


let walk_all_deps dir cb =
let visited = String_hashtbl.create 0 in
let visited = String_hashtbl.create 0 in
Bsb_log.info "@{<info>walk_all_deps dir:@} %s @." dir;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

walk_all_deps_aux visited [] true dir cb

let build_artifacts_dir = ref None

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a type annotation and a one line comment about what it is

let get_build_artifacts_location cwd =
let () = Bsb_log.info "@{<info>get_build_artifacts_location cwd:@} %s @." cwd in
let () = Bsb_log.info "@{<info>get_build_artifacts_location cur__root:@} %s @." (Sys.getenv "cur__root") in
let bad = match !build_artifacts_dir with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cur_root can be lazily shared

| Some(x) -> x
| None -> "not_set" in
let () = Bsb_log.info "@{<info>build_artifacts_dir:@} %s @." bad in
(* If the project's parent folder is not node_modules, we know it's the top level one. *)
if Sys.getenv "cur__root" = cwd then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think getenv might throw an exception

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is currently "safe" because we are probable in the esy environment. But this is mostly a placeholder for something like a flag.

match !build_artifacts_dir with
| None -> cwd
| Some dir -> dir
else begin
match !build_artifacts_dir with
| None ->
cwd
(* (Filename.dirname (Filename.dirname cwd)) // Bsb_config.lib_lit // Bsb_config.node_modules // project_name *)
| Some dir ->
let project_name = Filename.basename cwd in
let () = Bsb_log.info "@{<info>build_artifacts_location:@} %s @." (dir // Bsb_config.lib_js // project_name) in
dir // Bsb_config.lib_js // project_name
end
4 changes: 4 additions & 0 deletions jscomp/bsb/bsb_build_util.mli
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,7 @@ type package_context = {
}

val walk_all_deps : string -> (package_context -> unit) -> unit

val build_artifacts_dir : (string option) ref

val get_build_artifacts_location : string -> string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add some comments here for easy review

8 changes: 4 additions & 4 deletions jscomp/bsb/bsb_clean.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ let ninja_clean proj_dir =
Bsb_log.warn "@{<warning>ninja clean failed@} : %s @." (Printexc.to_string e)

let clean_bs_garbage proj_dir =
Bsb_log.info "@{<info>Cleaning:@} in %s@." proj_dir ;
let proj_dir = Bsb_build_util.get_build_artifacts_location proj_dir in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you call this function below, inside clean_bs_deps, you might not need to call it here.

let () = Bsb_log.info "@{<info>Cleaning:@} in %s@." proj_dir in
let try_remove x =
let x = proj_dir // x in
if Sys.file_exists x then
Expand All @@ -56,8 +57,7 @@ let clean_bs_garbage proj_dir =
let clean_bs_deps proj_dir =
Bsb_build_util.walk_all_deps proj_dir (fun pkg_cxt ->
(* whether top or not always do the cleaning *)
clean_bs_garbage pkg_cxt.proj_dir
clean_bs_garbage (Bsb_build_util.get_build_artifacts_location proj_dir)
)

let clean_self proj_dir =
clean_bs_garbage proj_dir
let clean_self proj_dir = clean_bs_garbage (Bsb_build_util.get_build_artifacts_location proj_dir)
5 changes: 3 additions & 2 deletions jscomp/bsb/bsb_config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ let rev_lib_bs_prefix p = rev_lib_bs // p

let ocaml_bin_install_prefix p = lib_ocaml // p

let lazy_build_artifacts_dir = "$build_artifacts_dir"
let build_artifacts_dir path = lazy_build_artifacts_dir // path

let lazy_src_root_dir = "$src_root_dir"
let proj_rel path = lazy_src_root_dir // path

Expand All @@ -56,6 +59,4 @@ let proj_rel path = lazy_src_root_dir // path




let cmd_package_specs = ref None

2 changes: 1 addition & 1 deletion jscomp/bsb/bsb_config.mli
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@


val ocaml_bin_install_prefix : string -> string
val build_artifacts_dir : string -> string
val proj_rel : string -> string

val lib_js : string
Expand All @@ -37,4 +38,3 @@ val rev_lib_bs_prefix : string -> string


(** default not install, only when -make-world, its dependencies will be installed *)

2 changes: 1 addition & 1 deletion jscomp/bsb/bsb_config_parse.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let resolve_package cwd package_name =
let x = Bsb_pkg.resolve_bs_package ~cwd package_name in
{
Bsb_config_types.package_name ;
package_install_path = x // Bsb_config.lib_ocaml
package_install_path = (Bsb_build_util.get_build_artifacts_location x) // Bsb_config.lib_ocaml
}

type json_map = Ext_json_types.t String_map.t
Expand Down
12 changes: 7 additions & 5 deletions jscomp/bsb/bsb_ninja_gen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ let output_ninja_and_namespace_map
number_of_dev_groups;
} : Bsb_config_types.t) : unit
=

let cwd_lib_bs = per_proj_dir // Bsb_config.lib_bs in
let build_artifacts_dir = Bsb_build_util.get_build_artifacts_location per_proj_dir in
let cwd_lib_bs = build_artifacts_dir // Bsb_config.lib_bs in
let ppx_flags = Bsb_build_util.ppx_flags ppx_files in
let oc = open_out_bin (cwd_lib_bs // Literals.build_ninja) in
let oc = open_out_bin (cwd_lib_bs // Literals.build_ninja) in
let g_pkg_flg , g_ns_flg =
match namespace with
| None ->
Expand Down Expand Up @@ -168,7 +168,8 @@ let output_ninja_and_namespace_map
bs_dev_dependencies
(fun x -> x.package_install_path));
Bsb_ninja_global_vars.g_ns , g_ns_flg ;
Bsb_build_schemas.bsb_dir_group, "0" (*TODO: avoid name conflict in the future *)
Bsb_build_schemas.bsb_dir_group, "0"; (*TODO: avoid name conflict in the future *)
Bsb_ninja_global_vars.build_artifacts_dir, build_artifacts_dir;
|] oc
in
let bs_groups, bsc_lib_dirs, static_resources =
Expand All @@ -190,6 +191,7 @@ let output_ninja_and_namespace_map
let static_resources =
Ext_list.fold_left bs_file_groups [] (fun (acc_resources : string list) {sources; dir; resources; dir_index}
->
let () = Bsb_log.info "@{<info>bs_file_groups dir:@} %s @." dir in
let dir_index = (dir_index :> int) in
bs_groups.(dir_index) <- Bsb_db_util.merge bs_groups.(dir_index) sources ;
source_dirs.(dir_index) <- dir :: source_dirs.(dir_index);
Expand Down Expand Up @@ -244,7 +246,7 @@ let output_ninja_and_namespace_map

Ext_option.iter namespace (fun ns ->
let namespace_dir =
per_proj_dir // Bsb_config.lib_bs in
build_artifacts_dir // Bsb_config.lib_bs in
Bsb_namespace_map_gen.output
~dir:namespace_dir ns
bs_file_groups;
Expand Down
4 changes: 3 additions & 1 deletion jscomp/bsb/bsb_ninja_global_vars.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ let g_ns = "g_ns"

let warnings = "warnings"

let build_artifacts_dir = "build_artifacts_dir"

let gentypeconfig = "gentypeconfig"

let g_dev_incls = "g_dev_incls"

(* path to stdlib *)
let g_stdlib_incl = "g_std_incl"
let g_stdlib_incl = "g_std_incl"
39 changes: 25 additions & 14 deletions jscomp/bsb/bsb_ninja_regen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,16 @@ let regenerate_ninja
~(toplevel_package_specs : Bsb_package_specs.t option)
~forced ~per_proj_dir
: Bsb_config_types.t option =
let build_artifacts_dir = Bsb_build_util.get_build_artifacts_location per_proj_dir in
let toplevel = toplevel_package_specs = None in
let lib_bs_dir = per_proj_dir // Bsb_config.lib_bs in
let lib_bs_dir = build_artifacts_dir // Bsb_config.lib_bs in
let output_deps = lib_bs_dir // bsdeps in
let () = Bsb_log.info
"@{<info>regenerate_ninja@} per_proj_dir : %s @." per_proj_dir in
let () = Bsb_log.info
"@{<info>regenerate_ninja@} lib_bs_dir : %s @." lib_bs_dir in
let () = Bsb_log.info
"@{<info>regenerate_ninja@} output_deps : %s @." output_deps in
let check_result =
Bsb_ninja_check.check
~per_proj_dir:per_proj_dir
Expand All @@ -53,26 +60,32 @@ let regenerate_ninja
| Other _ ->
if check_result = Bsb_bsc_version_mismatch then begin
Bsb_log.warn "@{<info>Different compiler version@}: clean current repo@.";
Bsb_clean.clean_self per_proj_dir;
end ;
Bsb_clean.clean_self build_artifacts_dir;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually since you're passing the right path here, you don't need to call the get_build_artifacts_location inside of it.

end ;

let config =
Bsb_config_parse.interpret_json
~toplevel_package_specs
~per_proj_dir in

(* create directory, lib/bs, lib/js, lib/es6 etc *)
Bsb_build_util.mkp lib_bs_dir;
Bsb_build_util.mkp build_artifacts_dir;

Bsb_package_specs.list_dirs_by config.package_specs
(fun x ->
let dir = per_proj_dir // x in (*Unix.EEXIST error*)
(fun x ->
let dir = build_artifacts_dir // x in (*Unix.EEXIST error*)
if not (Sys.file_exists dir) then Unix.mkdir dir 0o777);
if toplevel then
Bsb_watcher_gen.generate_sourcedirs_meta
~name:(lib_bs_dir // Literals.sourcedirs_meta)
config.file_groups
if toplevel then
begin
Bsb_log.info "@{<info>toplevel@} %s @." (lib_bs_dir // Literals.sourcedirs_meta);
Bsb_watcher_gen.generate_sourcedirs_meta
~name:(lib_bs_dir // Literals.sourcedirs_meta)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this probably needs to be build_artifacts_dir as well

Copy link
Contributor Author

@ulrikstrid ulrikstrid Oct 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It already is:

  let build_artifacts_dir = Bsb_build_util.get_build_artifacts_location per_proj_dir in
  let lib_bs_dir =  build_artifacts_dir // Bsb_config.lib_bs  in

config.file_groups
end
;
Bsb_merlin_gen.merlin_file_gen ~per_proj_dir
(Bsb_global_paths.vendor_bsppx) config;

(*Bsb_merlin_gen.merlin_file_gen ~per_proj_dir
(Bsb_global_paths.vendor_bsppx) config;*)
Bsb_ninja_gen.output_ninja_and_namespace_map
~per_proj_dir ~toplevel config ;

Expand All @@ -81,5 +94,3 @@ let regenerate_ninja
Bsb_ninja_check.record ~per_proj_dir ~file:output_deps
(Literals.bsconfig_json::config.file_groups.globbed_dirs) ;
Some config


7 changes: 3 additions & 4 deletions jscomp/bsb/bsb_package_specs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ let package_flag ({format; in_source } : spec) dir =
(Ext_string.concat3
(string_of_format format)
Ext_string.single_colon
(if in_source then dir else
prefix_of_format format // dir))
dir)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you still want to support what these lines where doing, insource builds or building inside the prefix-ed sub directory (like es6, commonjs etc...).


let package_flag_of_package_specs (package_specs : t)
(dirname : string ) : string =
Expand Down Expand Up @@ -161,7 +160,7 @@ let get_list_of_output_js
output_file_sans_extension
(if bs_suffix then Literals.suffix_bs_js else Literals.suffix_js)
in
(Bsb_config.proj_rel @@ (if spec.in_source then basename
(Bsb_config.build_artifacts_dir @@ (if spec.in_source then basename
else prefix_of_format spec.format // basename))
:: acc
) package_specs []
Expand All @@ -174,4 +173,4 @@ let list_dirs_by
Spec_set.iter (fun (spec : spec) ->
if not spec.in_source then
f (prefix_of_format spec.format)
) package_specs
) package_specs
1 change: 0 additions & 1 deletion jscomp/bsb/bsb_parse_sources.ml
Original file line number Diff line number Diff line change
Expand Up @@ -501,4 +501,3 @@ let clean_re_js root =
end
| _ -> ()
| exception _ -> ()

10 changes: 6 additions & 4 deletions jscomp/bsb/bsb_world.ml
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,17 @@ let build_bs_deps cwd (deps : Bsb_package_specs.t) (ninja_args : string array) =
in
Bsb_build_util.walk_all_deps cwd (fun {top; proj_dir} ->
if not top then
begin
begin
let () = Bsb_log.info "@{<info>build_bs_deps proj_dir:@} %s @." proj_dir in
let config_opt =
Bsb_ninja_regen.regenerate_ninja
~toplevel_package_specs:(Some deps)
~forced:true
~per_proj_dir:proj_dir in (* set true to force regenrate ninja file so we have [config_opt]*)
let build_artifacts_dir = Bsb_build_util.get_build_artifacts_location proj_dir in
let command =
{Bsb_unix.cmd = vendor_ninja;
cwd = proj_dir // Bsb_config.lib_bs;
cwd = build_artifacts_dir // Bsb_config.lib_bs;
args
} in
let eid =
Expand All @@ -89,7 +91,7 @@ let build_bs_deps cwd (deps : Bsb_package_specs.t) (ninja_args : string array) =
Note that we can check if ninja print "no work to do",
then don't need reinstall more
*)
Ext_option.iter config_opt (install_targets proj_dir);
Ext_option.iter config_opt (install_targets build_artifacts_dir);
end
)

Expand All @@ -105,4 +107,4 @@ let make_world_deps cwd (config : Bsb_config_types.t option) (ninja_args : strin
*)
Bsb_config_parse.package_specs_from_bsconfig ()
| Some config -> config.package_specs in
build_bs_deps cwd deps ninja_args
build_bs_deps cwd deps ninja_args
17 changes: 10 additions & 7 deletions jscomp/main/bsb_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,22 @@ let exec_command_then_exit command =
exit (Sys.command command )

(* Execute the underlying ninja build call, then exit (as opposed to keep watching) *)
let ninja_command_exit ninja_args =
let ninja_command_exit cwd ninja_args =
let ninja_args_len = Array.length ninja_args in
if Ext_sys.is_windows_or_cygwin then
let path_ninja = Filename.quote Bsb_global_paths.vendor_ninja in
exec_command_then_exit
(if ninja_args_len = 0 then
Ext_string.inter3
path_ninja "-C" Bsb_config.lib_bs
path_ninja "-C" (cwd // Bsb_config.lib_bs)
else
let args =
Array.append
[| path_ninja ; "-C"; Bsb_config.lib_bs|]
[| path_ninja ; "-C"; cwd // Bsb_config.lib_bs|]
ninja_args in
Ext_string.concat_array Ext_string.single_space args)
else
let ninja_common_args = [|"ninja.exe"; "-C"; Bsb_config.lib_bs |] in
let ninja_common_args = [|"ninja.exe"; "-C"; cwd // Bsb_config.lib_bs |] in
let args =
if ninja_args_len = 0 then ninja_common_args else
Array.append ninja_common_args ninja_args in
Expand Down Expand Up @@ -160,14 +160,17 @@ let install_target config_opt =

(* see discussion #929, if we catch the exception, we don't have stacktrace... *)
let () =
let getenv_opt env = try Some(Sys.getenv env)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love it if we could make this a command line arg, like -build-artifacts-dir that esy would automatically pass. It would make the flags reusable for other purposes, and usable from the command line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, the current solution is mostly to move quickly, but I can add this flag now as well 👍

with | Not_found -> None in
let () = Bsb_build_util.build_artifacts_dir := getenv_opt "cur__target_dir" in
try begin
match Sys.argv with
| [| _ |] -> (* specialize this path [bsb.exe] which is used in watcher *)
Bsb_ninja_regen.regenerate_ninja
~toplevel_package_specs:None
~forced:false
~per_proj_dir:Bsb_global_paths.cwd |> ignore;
ninja_command_exit [||]
ninja_command_exit (Bsb_build_util.get_build_artifacts_location Bsb_global_paths.cwd) [||]

| argv ->
begin
Expand Down Expand Up @@ -208,7 +211,7 @@ let () =
[bsb -regen ]
*)
end else if make_world then begin
ninja_command_exit [||]
ninja_command_exit (Bsb_build_util.get_build_artifacts_location Bsb_global_paths.cwd) [||]
end else if do_install then begin
install_target config_opt
end)
Expand All @@ -228,7 +231,7 @@ let () =
if !do_install then
install_target config_opt;
if !watch_mode then program_exit ()
else ninja_command_exit ninja_args
else ninja_command_exit (Bsb_build_util.get_build_artifacts_location Bsb_global_paths.cwd) ninja_args
end
end
end
Expand Down