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
bazel: add darwin support #40990
bazel: add darwin support #40990
Conversation
customBash = writeScriptBin "bash" '' | ||
#!${stdenv.shell} | ||
PATH="$PATH:${lib.makeBinPath [ coreutils ]}" exec ${bash}/bin/bash "$@" | ||
customBash = writeCBin "bash" '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be a native binary instead of a script because otherwise sandbox-exec
will replace the interpreter with /bin/sh
instead of using stdenv.shell
. This might be a security feature, I could repro the behaviour even when using /bin/bash
as the interpreter, in fact it will use /bin/sh
as the interpreter even when the first two bytes aren't #!
, as long as they're not any of the Mach-O byte signatures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does sandbox-exec come into play here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a simple repro:
mybash
:
#!/bin/bash
exec /bin/bash "$@"
u.sh
:
#!/Users/uri/github/NixOS/nixpkgs/mybash
echo $BASH_VERSION
$ which bash; bash --version
/Users/uri/homebrew/bin/bash
GNU bash, version 4.4.19(1)-release (x86_64-apple-darwin17.4.0)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ which sh; sh --version
/bin/sh
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
Copyright (C) 2007 Free Software Foundation, Inc.
# executing u.sh directly uses mybash as expected
$ ./u.sh
4.4.19(1)-release
# executing u.sh through sandbox-exec uses /bin/sh
$ sandbox-exec -p "(version 1) (allow default)" $PWD/u.sh
3.2.57(1)-release
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #40990 (comment) .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, scripts are not allowed as a shebang. I wonder if we should generalise this a bit and expose it.
while [ -n "${next}" ]; do | ||
previous="${next}" | ||
- next=$(readlink "${previous}") | ||
+ next=$(readlink "${previous}" | sed -e 's/\n//g') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nix's readlink
when running on macOS will output an additional newline. This does not happen with macOS' own readlink
, or on Linux and NixOS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very weird. We are using coreutils' readlink for both Linux & macOS so I'm not sure why it is different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that sounds very weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to isolate the issue as I did before, but when I looked into it more I realised this is just a different symptom of the same issue as sandbox-exec
: it's not that it's calling readlink
differently, it's a different version of bash: see the comment about sandbox-exec
above, and repro for env:
$ env ./u.sh
3.2.57(1)-release
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #40990 (comment) .
''; | ||
|
||
postPatch = '' | ||
postPatch = stdenv.lib.optionalString stdenv.hostPlatform.isDarwin '' | ||
export NIX_LDFLAGS="$NIX_LDFLAGS -F${CoreFoundation}/Library/Frameworks -F${CoreServices}/Library/Frameworks -F${Foundation}/Library/Frameworks" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we wouldn't need to specify these explicitly, as https://github.com/NixOS/nixpkgs/blob/bbcaf78350d87c4657b1a2451132535467a454eb/pkgs/build-support/bintools-wrapper/setup-hook.sh should add these automatically, like it does -L
flags, and like how https://github.com/NixOS/nixpkgs/blob/bbcaf78350d87c4657b1a2451132535467a454eb/pkgs/build-support/cc-wrapper/setup-hook.sh adds -F
flags, but when I tried to fix that I found out a bunch of packages are finicky on macOS so I gave up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odd, CoreFoundation should be the only special case here (since it's already in the stdenv). I would expect something like this to work.
{
preConfigure = ''
export NIX_LDFLAGS="-F${CoreFoundation}/Library/Frameworks $NIX_LDFLAGS"
'';
}
Nitpick: the configure phase is more appropriate for changing environment variables, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried it:
ERROR: /private/tmp/nix-build-bazel-0.12.0.drv-0/third_party/protobuf/3.4.0/BUILD:399:1: Linking of rule '//third_party/protobuf/3.4.0:js_embed' failed (Exit 1): cc_wrapper.sh failed: error executing command
(cd /tmp/bazel_FhkpSXM4/out/execroot/io_bazel && \
exec env - \
APPLE_SDK_PLATFORM='' \
APPLE_SDK_VERSION_OVERRIDE='' \
PATH=/nix/store/allybvvm28bybqrjpkdqvqi7d4r5x38q-zip-3.0/bin:/nix/store/10f4qxb00wk9j6cicd9h1qzwqgnc36ji-python-2.7.14/bin:/nix/store/dparbm2kq903rx6kp1m9zy1l2dcsxcmx-unzip-6.0/bin:/nix/store/gkzi1rn6qlqnalynjifmzgfzwh0x5aa2-which-2.21/bin:/nix/store/468wzkb2swaj4zdc1p6biiw1157jn673-bash/bin:/nix/store/8b0gj3bmcy5bh1zcnhn0146199b3m5kb-clang-wrapper-5.0.1/bin:/nix/store/p85m242dg1zd85ln3cg0agx0q1n0n6h0-clang-5.0.1/bin:/nix/store/5lkrw9dnsgy62qm1ampvww1c5n1pdm4b-coreutils-8.29/bin:/nix/store/jxmp27m26646f67faji9v94d5471ma8y-cctools-binutils-darwin-wrapper/bin:/nix/store/kdff2gim6417493yha769kh00n63lnrw-cctools-binutils-darwin/bin:/nix/store/5lkrw9dnsgy62qm1ampvww1c5n1pdm4b-coreutils-8.29/bin:/nix/store/bc5fk65ijws2938z3nlvkay7i83qjvp7-zulu1.8.0_121-8.20.0.5/bin:/nix/store/5lkrw9dnsgy62qm1ampvww1c5n1pdm4b-coreutils-8.29/bin:/nix/store/lzrwadp3l7np2734jxzqmxsgnjqfy4m7-findutils-4.6.0/bin:/nix/store/jrcykkx415grrjvrrhvs8hgl6pvj6x5b-diffutils-3.6/bin:/nix/store/llk6iyb3ppvyaflbkg5rbv960wlsxpkc-gnused-4.4/bin:/nix/store/c3sa761qjcaa5rg0s8h8qxj0mghkidv5-gnugrep-3.1/bin:/nix/store/gpp9x3ninvcw6m2n5m075q8nckzmcv09-gawk-4.2.1/bin:/nix/store/m88jhn3qgiz48zdllhpvgkz1ricmh89m-gnutar-1.30/bin:/nix/store/61bqs4awrycwdiaz7yb3bxvbyja1ghxr-gzip-1.9/bin:/nix/store/7vldi2061ga9phyhkr3sin8fk2kpc6sl-bzip2-1.0.6.0.1-bin/bin:/nix/store/y2nxw92is8125gdng3bsv23isray1g9m-gnumake-4.2.1/bin:/nix/store/r8bx3qf1bpncb14i9gzma4vr089pc3pv-bash-4.4-p19/bin:/nix/store/l1d4iaik29pkg7pdng7iw8ch75h71n36-patch-2.7.6/bin:/nix/store/03x40jq9ik0j4br0k2jmn288hz25589l-xz-5.2.3-bin/bin:/nix/store/5lkrw9dnsgy62qm1ampvww1c5n1pdm4b-coreutils-8.29/bin \
XCODE_VERSION_OVERRIDE=9.3.1 \
external/local_config_cc/cc_wrapper.sh -fobjc-link-runtime -Wl,-S -o bazel-out/host/bin/third_party/protobuf/3.4.0/js_embed bazel-out/host/bin/third_party/protobuf/3.4.0/_objs/js_embed/third_party/protobuf/3.4.0/src/google/protobuf/compiler/js/embed.o -headerpad_max_install_names -lc++ -no-canonical-prefixes -Wl,-L/nix/store/10f4qxb00wk9j6cicd9h1qzwqgnc36ji-python-2.7.14/lib -Wl,-L/nix/store/zl3vsrqfwx4xvxagdrdqav73yl53cxps-libc++-5.0.1/lib -Wl,-L/nix/store/anpyw2fy2f4qfz3d5yy0x9yxfxnx7sxy-objc4-osx-10.11.6/lib -Wl,-L/nix/store/zl3vsrqfwx4xvxagdrdqav73yl53cxps-libc++-5.0.1/lib -Wl,-L/nix/store/bc5fk65ijws2938z3nlvkay7i83qjvp7-zulu1.8.0_121-8.20.0.5/lib -Wl,-L/nix/store/10f4qxb00wk9j6cicd9h1qzwqgnc36ji-python-2.7.14/lib -Wl,-L/nix/store/zl3vsrqfwx4xvxagdrdqav73yl53cxps-libc++-5.0.1/lib -Wl,-L/nix/store/anpyw2fy2f4qfz3d5yy0x9yxfxnx7sxy-objc4-osx-10.11.6/lib -Wl,-L/nix/store/zl3vsrqfwx4xvxagdrdqav73yl53cxps-libc++-5.0.1/lib -Wl,-L/nix/store/bc5fk65ijws2938z3nlvkay7i83qjvp7-zulu1.8.0_121-8.20.0.5/lib)
ld: framework not found Foundation
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Do you mean in normal operation cc_wrapper
would take care of that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to specify it in the postPatch
so I can use the updated flags to patch the build commands.
sed -i -e "348 a --copt=\"$(echo $NIX_CFLAGS_COMPILE | sed -e 's/ /" --copt=\"/g')\" \\\\" scripts/bootstrap/compile.sh | ||
sed -i -e "348 a --host_copt=\"$(echo $NIX_CFLAGS_COMPILE | sed -e 's/ /" --host_copt=\"/g')\" \\\\" scripts/bootstrap/compile.sh | ||
sed -i -e "348 a --linkopt=\"-Wl,$(echo $NIX_LDFLAGS | sed -e 's/ /" --linkopt=\"-Wl,/g')\" \\\\" scripts/bootstrap/compile.sh | ||
sed -i -e "348 a --host_linkopt=\"-Wl,$(echo $NIX_LDFLAGS | sed -e 's/ /" --host_linkopt=\"-Wl,/g')\" \\\\" scripts/bootstrap/compile.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bazel will clear the environment when invoking cc
and ld
, both in the bootstrap build and in the proper build, so the Nix wrappers won't pick up the correct flags. I'm not sure why this didn't cause the build to fail on Linux and NixOS, but on macOS it means it won't be able to find the correct libraries and headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to open an issue with Bazel on this. Does this just affect builds of bazel itself or also projects building with bazel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's intended to work like that: https://bazel.build/designs/2016/06/21/environment.html
Note that --action_env
doesn't work with cc targets, which is why we have to pass them in using the other 4 variants: bazelbuild/bazel#4304.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It affects Bazel's bootstrap build, the build of Bazel built with the bootstrap Bazel, and anything built with the final Bazel.
# Always assume all markers valid (don't redownload dependencies). | ||
# Also, don't clean up environment variables. | ||
, enableNixHacks ? false | ||
# Apple dependencies | ||
, libcxx, CoreFoundation, CoreServices, Foundation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want the current version of CoreFoundation
even though we have 10.10 CoreFoundation
already because Bazel uses CFURL
APIs that only exist in the newer versions:
https://github.com/bazelbuild/bazel/blob/8d782751aa34a1fbb8c3ad38047bb7de2baf1bdb/src/main/cpp/blaze_util_darwin.cc#L106
https://developer.apple.com/documentation/corefoundation/1542764-cfurlcopyresourcepropertyforkey
Tested by building Bazel on macOS 10.13, Ubuntu 18 and NixOS 18. Also built a java codebase with it on macOS. Couldn't test with |
Whoa! |
while [ -n "${next}" ]; do | ||
previous="${next}" | ||
- next=$(readlink "${previous}") | ||
+ next=$(readlink "${previous}" | sed -e 's/\n//g') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that sounds very weird.
customBash = writeScriptBin "bash" '' | ||
#!${stdenv.shell} | ||
PATH="$PATH:${lib.makeBinPath [ coreutils ]}" exec ${bash}/bin/bash "$@" | ||
customBash = writeCBin "bash" '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does sandbox-exec come into play here?
''; | ||
|
||
postPatch = '' | ||
postPatch = stdenv.lib.optionalString stdenv.hostPlatform.isDarwin '' | ||
export NIX_LDFLAGS="$NIX_LDFLAGS -F${CoreFoundation}/Library/Frameworks -F${CoreServices}/Library/Frameworks -F${Foundation}/Library/Frameworks" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odd, CoreFoundation should be the only special case here (since it's already in the stdenv). I would expect something like this to work.
{
preConfigure = ''
export NIX_LDFLAGS="-F${CoreFoundation}/Library/Frameworks $NIX_LDFLAGS"
'';
}
Nitpick: the configure phase is more appropriate for changing environment variables, etc.
pkgs/top-level/all-packages.nix
Outdated
@@ -7637,7 +7637,10 @@ with pkgs; | |||
bam = callPackage ../development/tools/build-managers/bam {}; | |||
|
|||
bazel_0_4 = callPackage ../development/tools/build-managers/bazel/0.4.nix { }; | |||
bazel = callPackage ../development/tools/build-managers/bazel { }; | |||
bazel = callPackage ../development/tools/build-managers/bazel { | |||
stdenv = if stdenv.isDarwin then clangStdenv else stdenv; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stdenv
and clangStdenv
are equivalent on darwin.
Sorry was away for the weekend, I looked into this more and found this: https://stackoverflow.com/questions/9988125/shebang-pointing-to-script-also-having-shebang-is-effectively-ignored
|
An alternative to having Note that the current find and replace also replaces instances of |
cc @matthewbauer @LnL7 addressed review |
@matthewbauer @LnL7 ping |
'' | ||
n=$out/bin/${name} | ||
mkdir -p "$(dirname "$n")" | ||
echo -n '${code}' > code.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's probably better to use passAsFile
for this.
Used |
@matthewbauer @LnL7 ping |
1 similar comment
@matthewbauer @LnL7 ping |
Merged in 274bb96 with a few minor changes. The .bazelrc stuff is left out for now. Let's see if it's needed when building a few of our bazel packaages. |
I think you misunderstood the point of the bazelrc additions, put up #41911 to add them, will explain them in detail there. |
Motivation for this change
Things done
build-use-sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)