bazel: fix the compilation of .proto on Darwin (#63879)

On Darwin, the last argument to GCC is coming up as an empty string.
This is breaking the build of proto_library targets. However, I was not
able to reproduce with the example cpp project[0].

This commit patches the cc_wrapper of Bazel that gets installed on
Darwin to remove the last argument if it's an empty string. This is
not a probem on Linux.

[0]: https://github.com/bazelbuild/examples/tree/master/cpp-tutorial/stage3

authored by Wael Nasreddine and committed by GitHub c49b7f64 95165e03

+251 -5
+49
pkgs/development/tools/build-managers/bazel/cpp-test.nix
···
··· 1 + { 2 + bazel 3 + , bazelTest 4 + , bazel-examples 5 + , gccStdenv 6 + , lib 7 + , runLocal 8 + , runtimeShell 9 + , writeScript 10 + , writeText 11 + }: 12 + 13 + let 14 + 15 + toolsBazel = writeScript "bazel" '' 16 + #! ${runtimeShell} 17 + 18 + export CXX='${gccStdenv.cc}/bin/g++' 19 + export LD='${gccStdenv.cc}/bin/ld' 20 + export CC='${gccStdenv.cc}/bin/gcc' 21 + 22 + # XXX: hack for macosX, this flags disable bazel usage of xcode 23 + # See: https://github.com/bazelbuild/bazel/issues/4231 24 + export BAZEL_USE_CPP_ONLY_TOOLCHAIN=1 25 + 26 + exec "$BAZEL_REAL" "$@" 27 + ''; 28 + 29 + workspaceDir = runLocal "our_workspace" {} ('' 30 + cp -r ${bazel-examples}/cpp-tutorial/stage3 $out 31 + find $out -type d -exec chmod 755 {} \; 32 + '' 33 + + (lib.optionalString gccStdenv.isDarwin '' 34 + mkdir $out/tools 35 + cp ${toolsBazel} $out/tools/bazel 36 + '')); 37 + 38 + testBazel = bazelTest { 39 + name = "bazel-test-cpp"; 40 + inherit workspaceDir; 41 + bazelPkg = bazel; 42 + bazelScript = '' 43 + ${bazel}/bin/bazel \ 44 + build --verbose_failures \ 45 + //... 46 + ''; 47 + }; 48 + 49 + in testBazel
+21 -4
pkgs/development/tools/build-managers/bazel/default.nix
··· 1 - { stdenv, callPackage, lib, fetchurl, runCommand, runCommandCC, makeWrapper 2 # this package (through the fixpoint glass) 3 , bazel 4 , lr, xe, zip, unzip, bash, writeCBin, coreutils ··· 133 sourceRoot = "."; 134 135 patches = [ 136 ./python-stub-path-fix.patch 137 ] ++ lib.optional enableNixHacks ./nix-hacks.patch; 138 ··· 198 ''); 199 200 bazelWithNixHacks = bazel.override { enableNixHacks = true; }; 201 in { 202 - pythonBinPathWithoutNixHacks = callPackage ./python-bin-path-test.nix{ inherit runLocal bazelTest; }; 203 - bashToolsWithoutNixHacks = callPackage ./bash-tools-test.nix { inherit runLocal bazelTest; }; 204 205 - pythonBinPathWithNixHacks = callPackage ./python-bin-path-test.nix{ inherit runLocal bazelTest; bazel = bazelWithNixHacks; }; 206 bashToolsWithNixHacks = callPackage ./bash-tools-test.nix { inherit runLocal bazelTest; bazel = bazelWithNixHacks; }; 207 }; 208 209 # update the list of workspace dependencies
··· 1 + { stdenv, callPackage, lib, fetchurl, fetchFromGitHub, runCommand, runCommandCC, makeWrapper 2 # this package (through the fixpoint glass) 3 , bazel 4 , lr, xe, zip, unzip, bash, writeCBin, coreutils ··· 133 sourceRoot = "."; 134 135 patches = [ 136 + # On Darwin, the last argument to gcc is coming up as an empty string. i.e: '' 137 + # This is breaking the build of any C target. This patch removes the last 138 + # argument if it's found to be an empty string. 139 + ./trim-last-argument-to-gcc-if-empty.patch 140 + 141 ./python-stub-path-fix.patch 142 ] ++ lib.optional enableNixHacks ./nix-hacks.patch; 143 ··· 203 ''); 204 205 bazelWithNixHacks = bazel.override { enableNixHacks = true; }; 206 + 207 + bazel-examples = fetchFromGitHub { 208 + owner = "bazelbuild"; 209 + repo = "examples"; 210 + rev = "5d8c8961a2516ebf875787df35e98cadd08d43dc"; 211 + sha256 = "03c1bwlq5bs3hg96v4g4pg2vqwhqq6w538h66rcpw02f83yy7fs8"; 212 + }; 213 + 214 in { 215 + bashTools = callPackage ./bash-tools-test.nix { inherit runLocal bazelTest; }; 216 + cpp = callPackage ./cpp-test.nix { inherit runLocal bazelTest bazel-examples; }; 217 + protobuf = callPackage ./protobuf-test.nix { inherit runLocal bazelTest; }; 218 + pythonBinPath = callPackage ./python-bin-path-test.nix{ inherit runLocal bazelTest; }; 219 220 bashToolsWithNixHacks = callPackage ./bash-tools-test.nix { inherit runLocal bazelTest; bazel = bazelWithNixHacks; }; 221 + cppWithNixHacks = callPackage ./cpp-test.nix { inherit runLocal bazelTest bazel-examples; bazel = bazelWithNixHacks; }; 222 + protobufWithNixHacks = callPackage ./protobuf-test.nix { inherit runLocal bazelTest; bazel = bazelWithNixHacks; }; 223 + pythonBinPathWithNixHacks = callPackage ./python-bin-path-test.nix{ inherit runLocal bazelTest; bazel = bazelWithNixHacks; }; 224 }; 225 226 # update the list of workspace dependencies
+144
pkgs/development/tools/build-managers/bazel/protobuf-test.nix
···
··· 1 + { 2 + bazel 3 + , bazelTest 4 + , fetchFromGitHub 5 + , fetchurl 6 + , gccStdenv 7 + , lib 8 + , runLocal 9 + , runtimeShell 10 + , writeScript 11 + , writeText 12 + }: 13 + 14 + let 15 + com_google_protobuf = fetchFromGitHub { 16 + owner = "protocolbuffers"; 17 + repo = "protobuf"; 18 + rev = "v3.7.0"; 19 + sha256 = "0nlxif4cajqllsj2vdh7zp14ag48fb8lsa64zmq8625q9m2lcmdh"; 20 + }; 21 + 22 + bazel_skylib = fetchFromGitHub { 23 + owner = "bazelbuild"; 24 + repo = "bazel-skylib"; 25 + rev = "f83cb8dd6f5658bc574ccd873e25197055265d1c"; 26 + sha256 = "091fb0ky0956wgv8gghy9ay3yfx6497mb72qvibf0y9dllmxyn9l"; 27 + }; 28 + 29 + net_zlib = fetchurl rec { 30 + url = "https://zlib.net/zlib-1.2.11.tar.gz"; 31 + sha256 = "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1"; 32 + 33 + passthru.sha256 = sha256; 34 + }; 35 + 36 + WORKSPACE = writeText "WORKSPACE" '' 37 + workspace(name = "our_workspace") 38 + 39 + load("//:proto-support.bzl", "protobuf_deps") 40 + protobuf_deps() 41 + ''; 42 + 43 + protoSupport = writeText "proto-support.bzl" '' 44 + """Load dependencies needed to compile the protobuf library as a 3rd-party consumer.""" 45 + 46 + load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 47 + 48 + def protobuf_deps(): 49 + """Loads common dependencies needed to compile the protobuf library.""" 50 + 51 + if "zlib" not in native.existing_rules(): 52 + # proto_library, cc_proto_library, and java_proto_library rules implicitly 53 + # depend on @com_google_protobuf for protoc and proto runtimes. 54 + # This statement defines the @com_google_protobuf repo. 55 + native.local_repository( 56 + name = "com_google_protobuf", 57 + path = "${com_google_protobuf}", 58 + ) 59 + native.local_repository( 60 + name = "bazel_skylib", 61 + path = "${bazel_skylib}", 62 + ) 63 + 64 + native.bind( 65 + name = "zlib", 66 + actual = "@net_zlib//:zlib", 67 + ) 68 + http_archive( 69 + name = "net_zlib", 70 + build_file = "@com_google_protobuf//:third_party/zlib.BUILD", 71 + sha256 = "${net_zlib.sha256}", 72 + strip_prefix = "zlib-1.2.11", 73 + urls = ["file://${net_zlib}"], 74 + ) 75 + ''; 76 + 77 + personProto = writeText "person.proto" '' 78 + syntax = "proto3"; 79 + 80 + message Person { 81 + string name = 1; 82 + int32 id = 2; 83 + string email = 3; 84 + } 85 + ''; 86 + 87 + personBUILD = writeText "BUILD" '' 88 + proto_library( 89 + name = "person_proto", 90 + srcs = ["person.proto"], 91 + visibility = ["//visibility:public"], 92 + ) 93 + 94 + java_proto_library( 95 + name = "person_java_proto", 96 + deps = [":person_proto"], 97 + ) 98 + 99 + cc_proto_library( 100 + name = "person_cc_proto", 101 + deps = [":person_proto"], 102 + ) 103 + ''; 104 + 105 + toolsBazel = writeScript "bazel" '' 106 + #! ${runtimeShell} 107 + 108 + export CXX='${gccStdenv.cc}/bin/g++' 109 + export LD='${gccStdenv.cc}/bin/ld' 110 + export CC='${gccStdenv.cc}/bin/gcc' 111 + 112 + # XXX: hack for macosX, this flags disable bazel usage of xcode 113 + # See: https://github.com/bazelbuild/bazel/issues/4231 114 + export BAZEL_USE_CPP_ONLY_TOOLCHAIN=1 115 + 116 + exec "$BAZEL_REAL" "$@" 117 + ''; 118 + 119 + workspaceDir = runLocal "our_workspace" {} ('' 120 + mkdir $out 121 + cp ${WORKSPACE} $out/WORKSPACE 122 + touch $out/BUILD.bazel 123 + cp ${protoSupport} $out/proto-support.bzl 124 + mkdir $out/person 125 + cp ${personProto} $out/person/person.proto 126 + cp ${personBUILD} $out/person/BUILD.bazel 127 + '' 128 + + (lib.optionalString gccStdenv.isDarwin '' 129 + mkdir $out/tools 130 + cp ${toolsBazel} $out/tools/bazel 131 + '')); 132 + 133 + testBazel = bazelTest { 134 + name = "bazel-test-protocol-buffers"; 135 + inherit workspaceDir; 136 + bazelPkg = bazel; 137 + bazelScript = '' 138 + ${bazel}/bin/bazel \ 139 + build --verbose_failures \ 140 + //person:person_proto 141 + ''; 142 + }; 143 + 144 + in testBazel
-1
pkgs/development/tools/build-managers/bazel/python-bin-path-test.nix
··· 45 bazelScript = '' 46 ${bazel}/bin/bazel \ 47 run \ 48 - --host_javabase='@local_jdk//:jdk' \ 49 //python:bin 50 ''; 51 };
··· 45 bazelScript = '' 46 ${bazel}/bin/bazel \ 47 run \ 48 //python:bin 49 ''; 50 };
+37
pkgs/development/tools/build-managers/bazel/trim-last-argument-to-gcc-if-empty.patch
···
··· 1 + From 177b4720d6fbaa7fdd17e5e11b2c79ac8f246786 Mon Sep 17 00:00:00 2001 2 + From: "Wael M. Nasreddine" <wael.nasreddine@gmail.com> 3 + Date: Thu, 27 Jun 2019 21:08:51 -0700 4 + Subject: [PATCH] Trim last argument to gcc if empty, on Darwin 5 + 6 + On Darwin, the last argument to GCC is coming up as an empty string. 7 + This is breaking the build of proto_library targets. However, I was not 8 + able to reproduce with the example cpp project[0]. 9 + 10 + This commit removes the last argument if it's an empty string. This is 11 + not a problem on Linux. 12 + 13 + [0]: https://github.com/bazelbuild/examples/tree/master/cpp-tutorial/stage3 14 + --- 15 + tools/cpp/osx_cc_wrapper.sh.tpl | 6 +++++- 16 + 1 file changed, 5 insertions(+), 1 deletion(-) 17 + 18 + diff --git a/tools/cpp/osx_cc_wrapper.sh.tpl b/tools/cpp/osx_cc_wrapper.sh.tpl 19 + index 4c85cd9b6b..6c611e3d25 100644 20 + --- a/tools/cpp/osx_cc_wrapper.sh.tpl 21 + +++ b/tools/cpp/osx_cc_wrapper.sh.tpl 22 + @@ -53,7 +53,11 @@ done 23 + %{env} 24 + 25 + # Call the C++ compiler 26 + -%{cc} "$@" 27 + +if [[ ${*: -1} = "" ]]; then 28 + + %{cc} "${@:0:$#}" 29 + +else 30 + + %{cc} "$@" 31 + +fi 32 + 33 + function get_library_path() { 34 + for libdir in ${LIB_DIRS}; do 35 + -- 36 + 2.19.2 37 +