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

Refactoring: remove visible-binaries #557

Merged
merged 1 commit into from
Jan 14, 2019
Merged

Refactoring: remove visible-binaries #557

merged 1 commit into from
Jan 14, 2019

Conversation

mboes
Copy link
Member

@mboes mboes commented Jan 12, 2019

To precisely control what binaries are available during compilation,
we used to create a single directory called visible-binaries, in
which we put all the binaries (ghc, haddock, etc) and shell
commands (cat, mkdir, etc) that we needed. There was another point to
this: build actions could call any binary and that binary could in
turn exec any other binary, since visible-binaries was in the
PATH.

In this commit, we do away with that. The reason is that there are
downsides to this approach:

  • there is little value in trying to be more hermetic than Bazel is
    when it comes to shell commands;
  • all build actions were reusing the same PATH, so we were actually
    exposing more binaries than strictly necessary (each action needs
    a different subset);
  • the logic to create visible-binaries was pretty complicated, and
    is now all gone, hence the net code reduction;
  • crucially, the visible-binaries is not going to work on Windows,
    because no symlinks on that platform and copying doesn't always work
    (due to limitations of GHC).

With this PR merged in, porting to Windows should now be significantly
easier. The downside is the following breaking change: we have lost
the extra_binaries field in rules. But that field was introduced for
unusual needs that inline-java has, and was a suspicious feature to
begin with.

Probably fixes #244.

Closes #512.

cc @gdeest @nasm @gleber for the stepping stone towards Windows support.

cc @ahermann about the dropped support for extra_binaries.

@mboes mboes requested review from guibou and gdeest January 12, 2019 22:39
@mboes mboes force-pushed the no-visible-binaries branch 3 times, most recently from 6d5393b to 7f16f6e Compare January 13, 2019 15:20
Copy link
Contributor

@gdeest gdeest left a comment

Choose a reason for hiding this comment

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

Good riddance ! The only thing that gets me a bit uneasy is that haddock wrapper script ; if there is no risk of us running into duplicate declared files, I'll approve.

),
]),
outputs = [doctest_log],
mnemonic = "HaskellDoctest",
progress_message = "HaskellDoctest {}".format(ctx.label),
command = """
{doctest} "$@" $(cat {module_list} | tr , ' ') > {output} 2>&1 || rc=$? && cat {output} && exit $rc
""".format(doctest = toolchain.doctest[0].path, output = doctest_log.path, module_list = exposed_modules_file.path),
{env}
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason not to use run_shell's env parameter ?

@@ -89,6 +89,25 @@ def _haskell_doc_aspect_impl(target, ctx):
depset([hs.toolchain.locale_archive]) if hs.toolchain.locale_archive != None else depset()
)

# TODO(mboes): we should be able to instantiate this template only
# once per toolchain instance, rather than here.
haddock_wrapper = ctx.actions.declare_file("haddock_wrapper")
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we run into the risk of multiple targets declaring the same file ? E.g., if we have two libraries in the same package.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a good point. Thanks for catching that. We should make the name target dependent, much like we already do for object files.

arguments = [
prebuilt_deps,
args,
ghc_args,
],
env = hs.env,
use_default_shell_env = True,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because the haddock wrapper script use mktemp and rmdir. Previously, those were "visible binaries". Now, they are taken from the default shell environment (which Bazel will be restricting soon, by flipping --experimental_strict_action_env on by default).

@@ -86,38 +81,33 @@ def _haskell_toolchain_impl(ctx):
ghc_binaries = {}
for tool in ctx.files.tools:
if tool.basename in _GHC_BINARIES:
ghc_binaries[tool.basename] = tool.path
ghc_binaries[tool.basename] = tool
Copy link
Contributor

Choose a reason for hiding this comment

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

So obvious in retrospect, it kinda hurts !

To precisely control what binaries are available during compilation,
we used to create a single directory called `visible-binaries`, in
which we put all the binaries (ghc, haddock, etc) and shell
commands (cat, mkdir, etc) that we needed. There was another point to
this: build actions could call any binary and that binary could in
turn exec any other binary, since `visible-binaries` was in the
`PATH`.

In this commit, we do away with that. The reason is that there are
downsides to this approach:

* there is little value in trying to be more hermetic than Bazel is
  when it comes to shell commands;
* all build actions were reusing the same `PATH`, so we were actually
  exposing more binaries than strictly necessary (each action needs
  a different subset);
* the logic to create `visible-binaries` was pretty complicated, and
  is now all gone, hence the net code reduction;
* crucially, the `visible-binaries` is not going to work on Windows,
  because no symlinks on that platform and copying doesn't always work
  (due to limitations of GHC).

With this PR merged in, porting to Windows should now be significantly
easier. The downside is the following *breaking change*: we have lost
the `extra_binaries` field in rules. But that field was introduced for
unusual needs that inline-java has, and was a suspicious feature to
begin with.

Probably fixes #244.
@mboes mboes force-pushed the no-visible-binaries branch from 7f16f6e to 93e1f6f Compare January 14, 2019 13:17
Copy link
Contributor

@gdeest gdeest left a comment

Choose a reason for hiding this comment

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

LGTM 🎉

@mboes mboes merged commit bad481a into master Jan 14, 2019
@mboes mboes deleted the no-visible-binaries branch January 14, 2019 14:32
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.

Visible binaries and Windows Support Bazel sometimes needs a full clean to locate ar
2 participants