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

Conversation

ulrikstrid
Copy link
Contributor

@ulrikstrid ulrikstrid commented Sep 30, 2019

This is heavily based on #2514 from @bsansouci and the goal is to build everything in a directory that is okay to build into for esy.

This will probably only be a "proof of concept" and I'm going to need help from someone that know more about the internals.

relevant issues: #2418 and #3276

@bobzhang
Copy link
Member

bobzhang commented Oct 1, 2019

@ulrikstrid hi, can you write down what directory layout you are trying to achieve

@ulrikstrid
Copy link
Contributor Author

I don't really care where the files are put, I guess passing a flag about where to put the files would be the best since it would then work outside of esy.

My current thought is that I should just put everything under ./lib/... but if you have something else in mind that's probably better! @bobzhang

@ulrikstrid
Copy link
Contributor Author

Now it actually puts the .js files somewhere so it's getting closer. There seems to be some issues with the paths in the generated output and the output is suspiciously empty, but this might be intended because they are 0-cost bindings?

var Ref = { };

var Context = { };

var Fragment = { };

var Suspense = { };

export {
  Ref ,
  Context ,
  Fragment ,
  Suspense ,
  
}
/* No side effect */

@ulrikstrid
Copy link
Contributor Author

ulrikstrid commented Oct 2, 2019

There are 2 bigger issues left in this PR

  1. Somewhere in bucklescript there seems to be a assumption that the folder name where the source lives is the package name which is not true with esy, this gives us paths like this:
    _esy/default/store/b/reason_sample_project-d306440c/lib/js/reason_react__0.7.0__8e25ac00/src/React.js

  2. There is a assumption that dependencies can be resolved from node_modules so we get javacsript like this:

import * as ReactDOMRe from "reason-react/src/ReactDOMRe.js";

But it should be something like this:

import * as ReactDOMRe from "../lib/js/reason-react/src/ReactDOMRe.js";

When those are solved I need to cleanup the PR from all the extra logging and see how I can remove hard coded assumptions on esys environment.

Copy link
Contributor

@bsansouci bsansouci left a comment

Choose a reason for hiding this comment

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

There are a couple of things that I'd change in there, overall I think it looks pretty good.
The module that's in charge of finding deps seems to already support an env variable: https://github.com/BuckleScript/bucklescript/blob/7cea069a7507f8db510e8e506a7e4c211df1e444/jscomp/bsb/bsb_pkg.ml#L90 (for looking up deps in alternative places).

For the import statements maybe @bobzhang can give better recommendation, but maybe doing some work inside here: https://github.com/BuckleScript/bucklescript/blob/master/jscomp/core/js_packages_info.ml

| 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.

@@ -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.

@@ -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.

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

@@ -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...).

@@ -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 👍

Copy link
Member

@bobzhang bobzhang left a comment

Choose a reason for hiding this comment

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

Can you write down the typical layout under esy and the expected path in JS import statements

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

@@ -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

@@ -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


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

@ulrikstrid ulrikstrid mentioned this pull request Nov 6, 2019
8 tasks
@bobzhang
Copy link
Member

it seems this PR did not gain traction

@bobzhang bobzhang closed this Oct 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants