I can't get bazel to build an android app when everything is setup in my local environment with `nix-shell`. When I try to build, I get the following error: ```sh $ bazel build //app/java:dnsproxy ERROR: [...]/WORKSPACE:12:23: fetching android_sdk_repository rule //external:androidsdk: Bazel requires Android build tools version 30.0.0 or newer but none are installed. Please install a recent version through the Android SDK manager. ERROR: Analysis of target '//app/java:dnsproxy' failed; build aborted: Bazel requires Android build tools version 30.0.0 or newer but none are installed. Please install a recent version through the Android SDK manager. INFO: Elapsed time: 0.169s INFO: 0 processes. FAILED: Build did NOT complete successfully (0 packages loaded, 0 targets configured) ``` The `sdkmanager` tells me, that the correct versions are installed. ```sh $ sdkmanager --list_installed [=======================================] 100% Fetch remote repository... Installed packages: Path | Version | Description | Location ------- | ------- | ------- | ------- build-tools;33.0.1 | 33.0.1 | Android SDK Build-Tools 33.0.1 | build-tools/33.0.1 cmdline-tools;8.0 | 8.0 | Android SDK Command-line Tools | cmdline-tools/8.0 patcher;v4 | 1 | SDK Patch Applier v4 | patcher/v4 platform-tools | 33.0.3 | Android SDK Platform-Tools | platform-tools platforms;android-31 | 1 | Android SDK Platform 31 | platforms/android-31 ``` The necessary environment variables are set and everything seems fine. ```sh $ echo $ANDROID_HOME /nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/libexec/android-sdk $ which sdkmanager /nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/bin/sdkmanager ``` The paths to everything are there. ```sh $ ls -lah /nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/libexec/android-sdk/build-tools Permissions Size User Date Modified Name lrwxrwxrwx 101 root 1 1月 1970 33.0.1 -> /nix/store/ycc7k5p19ih0ky3pj0zviqk6mkghzgn7-build-tools-33.0.1/libexec/android-sdk/build-tools/33.0.1 $ ls -lah /nix/store/vgcmyvfyqb7kz505r1x1n14lbma2f7ri-androidsdk/libexec/android-sdk/platforms Permissions Size User Date Modified Name lrwxrwxrwx 97 root 1 1月 1970 android-31 -> /nix/store/20bc5fca6vkgyddhjm7l68ams9ccqr6y-platforms-31/libexec/android-sdk/platforms/android-31 ``` I found this Pull Request: https://github.com/bazelbuild/bazel/pull/12626 There was an issue with symlink detection in bazel causing the exact problem I'm having right now, but that has been fixed for some time now. Following are the `.nix`, and bazel files I try to build with. **shell.nix** ```nix with (import { config.allowUnfree = true; config.android_sdk.accept_license = true; }); let jdk = jdk11; android-composition = androidenv.composeAndroidPackages { platformVersions = ["31"]; }; in mkShell rec { name = "android-shell"; buildInputs = [ jdk android-composition.androidsdk bazel ]; JAVA_HOME = jdk.home; ANDROID_SDK_ROOT = "${android-composition.androidsdk}/libexec/android-sdk"; ANDROID_HOME = "${ANDROID_SDK_ROOT}"; } ``` **WORKSPACE** ```starlark # Load the Android build rules load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "build_bazel_rules_android", urls = ["https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"], sha256 = "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", strip_prefix = "rules_android-0.1.1", ) # Configure Android SDK Path load("@build_bazel_rules_android//android:rules.bzl", "android_sdk_repository") android_sdk_repository( name = "androidsdk", ) ``` **app/java/BUILD** ```starlark load("@build_bazel_rules_android//android:rules.bzl", "android_library", "android_binary") android_library( name = "main", srcs = glob(["src/*.java"]), manifest = "AndroidManifest.xml", resource_files = glob(["res/**"]), ) android_binary( name = "dnsproxy", manifest = "AndroidManifest.xml", deps = [":main"], ) ``` **versions** ```sh $ nix --version nix (Nix) 2.15.0 $ nix-channel --list nixpkgs https://nixos.org/channels/nixpkgs-unstable $ bazel --version bazel 6.1.2- (@non-git) $ uname -a Linux archbook 6.2.13-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 26 Apr 2023 20:50:14 +0000 x86_64 GNU/Linux ``` I tried a host of different approaches I found scattered around the internet, like [`buildFHSUserEnv`](https://nixos.wiki/wiki/Android#Building_Android_on_NixOS), but I get the exact same error there. I don't know whether it's still a bazel issue, or a nix package issue or something else entirely and I can't think of anything else that I could check or try to get this to work. PS: Response to [comment](https://stackoverflow.com/questions/76142628/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment#comment134299657_76142628): `strace` returns the same environment variables with the same paths as above. Response to [comment](https://stackoverflow.com/questions/76142628/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment#comment134311204_76142628): I examined the mentioned links and came to the conclusion that I was using an [old guide](https://developer.android.com/codelabs/bazel-android-intro) from https://developer.android.com. Loading the android build rules from https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip doesn't seem to be necessary anymore. [This](https://bazel.build/start/android-app) seems to be a more recent guide from https://bazel.build, so the new file contents are **WORKSPACE** ```starlark android_sdk_repository( name = "androidsdk", ) ``` **app/java/BUILD** ```starlark android_library( name = "main", srcs = glob(["src/*.java"]), manifest = "AndroidManifest.xml", resource_files = glob(["res/**"]), ) android_binary( name = "dnsproxy", manifest = "AndroidManifest.xml", deps = [":main"], ) ``` But I'm still getting the same error, that no build tools are installed. ```sh ERROR: [...]/WORKSPACE:1:23: fetching android_sdk_repository rule //external:androidsdk: Bazel requires Android build tools version 30.0.0 or newer but none are installed. Please install a recent version through the Android SDK manager. ``` I'm still not sure whether this is more a nix or a bazel issue. PPS: I tried copying and symlinking a `30.0.3` build-tools folder to the `/nix/store` path that my `$ANDROID_HOME` reports. Copying the directory there resulted in a new error message, so it seems like it found the build-tools finally. Symlinking it produced the same error about the missing build-tools as before. The new error with `bazel v6` is: ```sh $ bazel build //app/java:dnsproxy Starting local Bazel server and connecting to it... INFO: Analyzed target //app/java:dnsproxy (57 packages loaded, 942 targets configured). INFO: Found 1 target... ERROR: [...]/app/java/BUILD:1:16: Desugaring app/java/libmain.jar for Android failed: Worker process returned an unparseable WorkResponse! Did you try to print something to stdout? Workers arent allowed to do this, as it breaks the protocol between Bazel and the worker process. ---8<---8<--- Start of response ---8<---8<--- # # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory. # An error report file with more information is saved as: # [...]/.cache/bazel/_bazel_dweipert/139e0de675811190a7e9267b6c7ce3c8/execroot/__main__/hs_err_pid128444.log ---8<---8<--- End of response ---8<---8<--- ---8<---8<--- Exception details ---8<---8<--- com.google.protobuf.InvalidProtocolBufferException: While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length. at com.google.protobuf.InvalidProtocolBufferException.truncatedMessage(InvalidProtocolBufferException.java:107) at com.google.protobuf.CodedInputStream$StreamDecoder.readRawBytesSlowPathOneChunk(CodedInputStream.java:2970) at com.google.protobuf.CodedInputStream$StreamDecoder.readBytesSlowPath(CodedInputStream.java:3021) at com.google.protobuf.CodedInputStream$StreamDecoder.readBytes(CodedInputStream.java:2432) at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:514) at com.google.protobuf.GeneratedMessageV3$Builder.parseUnknownField(GeneratedMessageV3.java:863) at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse$Builder.mergeFrom(WorkerProtocol.java:3037) at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse$1.parsePartialFrom(WorkerProtocol.java:3333) at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse$1.parsePartialFrom(WorkerProtocol.java:3325) at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:215) at com.google.protobuf.AbstractParser.parsePartialDelimitedFrom(AbstractParser.java:255) at com.google.protobuf.AbstractParser.parseDelimitedFrom(AbstractParser.java:267) at com.google.protobuf.AbstractParser.parseDelimitedFrom(AbstractParser.java:272) at com.google.protobuf.AbstractParser.parseDelimitedFrom(AbstractParser.java:48) at com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(GeneratedMessageV3.java:382) at com.google.devtools.build.lib.worker.WorkerProtocol$WorkResponse.parseDelimitedFrom(WorkerProtocol.java:2810) at com.google.devtools.build.lib.worker.ProtoWorkerProtocol.getResponse(ProtoWorkerProtocol.java:46) at com.google.devtools.build.lib.worker.SingleplexWorker.getResponse(SingleplexWorker.java:141) at com.google.devtools.build.lib.worker.WorkerSpawnRunner.executeRequest(WorkerSpawnRunner.java:715) at com.google.devtools.build.lib.worker.WorkerSpawnRunner.execInWorkerClassic(WorkerSpawnRunner.java:575) at com.google.devtools.build.lib.worker.WorkerSpawnRunner.execInWorker(WorkerSpawnRunner.java:359) at com.google.devtools.build.lib.worker.WorkerSpawnRunner.exec(WorkerSpawnRunner.java:205) at com.google.devtools.build.lib.exec.SpawnRunner.execAsync(SpawnRunner.java:301) at com.google.devtools.build.lib.exec.AbstractSpawnStrategy.exec(AbstractSpawnStrategy.java:152) at com.google.devtools.build.lib.exec.AbstractSpawnStrategy.exec(AbstractSpawnStrategy.java:112) at com.google.devtools.build.lib.actions.SpawnStrategy.beginExecution(SpawnStrategy.java:47) at com.google.devtools.build.lib.exec.SpawnStrategyResolver.beginExecution(SpawnStrategyResolver.java:64) at com.google.devtools.build.lib.analysis.actions.SpawnAction.beginExecution(SpawnAction.java:352) at com.google.devtools.build.lib.actions.Action.execute(Action.java:133) at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor$5.execute(SkyframeActionExecutor.java:957) at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor$ActionRunner.continueAction(SkyframeActionExecutor.java:1124) at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor$ActionRunner.run(SkyframeActionExecutor.java:1082) at com.google.devtools.build.lib.skyframe.ActionExecutionState.runStateMachine(ActionExecutionState.java:160) at com.google.devtools.build.lib.skyframe.ActionExecutionState.getResultOrDependOnFuture(ActionExecutionState.java:93) at com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.executeAction(SkyframeActionExecutor.java:516) at com.google.devtools.build.lib.skyframe.ActionExecutionFunction.checkCacheAndExecuteIfNeeded(ActionExecutionFunction.java:827) at com.google.devtools.build.lib.skyframe.ActionExecutionFunction.computeInternal(ActionExecutionFunction.java:323) at com.google.devtools.build.lib.skyframe.ActionExecutionFunction.compute(ActionExecutionFunction.java:161) at com.google.devtools.build.skyframe.AbstractParallelEvaluator$Evaluate.run(AbstractParallelEvaluator.java:571) at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:382) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) ---8<---8<--- End of exception details ---8<---8<--- ---8<---8<--- Start of log, file at [...]/.cache/bazel/_bazel_dweipert/139e0de675811190a7e9267b6c7ce3c8/bazel-workers/worker-1-Desugar.log ---8<---8<--- OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000600000000, 8589934592, 0) failed; error='Not enough space' (errno=12) ---8<---8<--- End of log ---8<---8<--- Target //app/java:dnsproxy failed to build Use --verbose_failures to see the command lines of failed build steps. INFO: Elapsed time: 12.429s, Critical Path: 2.73s INFO: 17 processes: 12 internal, 5 linux-sandbox. FAILED: Build did NOT complete successfully ``` I tried older bazel versions in-between when trying to figure out what works and what not, so I tried that here as well. With `bazel v5` I get a different error: ```sh $ bazel build //app/java:dnsproxy Starting local Bazel server and connecting to it... INFO: Analyzed target //app/java:dnsproxy (57 packages loaded, 1164 targets configured). INFO: Found 1 target... ERROR: [...]/app/java/BUILD:8:15: Building deploy jar app/java/dnsproxy_deploy.jar failed: (Exit 1): singlejar_cc_bin failed: error executing command bazel-out/k8-opt-exec-2B5CBBC6/bin/external/remote_java_tools/singlejar_cc_bin @bazel-out/k8-fastbuild/bin/app/java/dnsproxy_deploy.jar-0.params Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging singlejar_cc_bin: external/remote_java_tools/java_tools/src/tools/singlejar/singlejar_main.cc:27: Desugar checking not currently supported in Bazel. Target //app/java:dnsproxy failed to build Use --verbose_failures to see the command lines of failed build steps. INFO: Elapsed time: 17.899s, Critical Path: 7.33s INFO: 40 processes: 13 internal, 26 linux-sandbox, 1 worker. FAILED: Build did NOT complete successfully ``` With `bazel v4` I actually get a working environment and I could run `bazel build` without errors. With `bazel v4` I get a similar error to before, it's just now complaining about the platforms not being installed. Here it's the same with the build-tools. The platforms are there, but they are symlinks. So I tried copying instead of symlinking a directory there and that then actually ran without errors. **bazel v4 with error** ```sh $ bazel build //app/java:dnsproxy ERROR: Error fetching repository: [...]/WORKSPACE:1:23: android_sdk_repository requires that at least one Android SDK Platform is installed in the Android SDK. Please install an Android SDK Platform through the Android SDK manager. ERROR: Analysis of target '//app/java:dnsproxy' failed; build aborted: android_sdk_repository requires that at least one Android SDK Platform is installed in the Android SDK. Please install an Android SDK Platform through the Android SDK manager. INFO: Elapsed time: 0.183s INFO: 0 processes. FAILED: Build did NOT complete successfully (0 packages loaded, 0 targets configured) ``` **bazel v4 without error** ```sh $ bazel build //app/java:dnsproxy Starting local Bazel server and connecting to it... INFO: Analyzed target //app/java:dnsproxy (35 packages loaded, 631 targets configured). INFO: Found 1 target... Target //app/java:dnsproxy up-to-date: bazel-bin/app/java/dnsproxy_deploy.jar bazel-bin/app/java/dnsproxy_unsigned.apk bazel-bin/app/java/dnsproxy.apk INFO: Elapsed time: 9.581s, Critical Path: 1.51s INFO: 16 processes: 13 internal, 3 linux-sandbox. INFO: Build completed successfully, 16 total actions ``` I tried to investigate the version differences and noticed for the pull request I mentioned above (https://github.com/bazelbuild/bazel/pull/12626), that it only concerns the `platforms` and not the `build-tools`. Under tag `6.1.2` I found this line: https://github.com/bazelbuild/bazel/blob/6.1.2/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java#LL376C68-L376C68 Here the `Dirent.Type.SYMLINK` check is missing, so it makes sense that I got that error. The OOM issue with `v6` I found here: https://github.com/bazelbuild/bazel/issues/17665 So it looks like I have to bring that up in the [bazel issues](https://github.com/bazelbuild/bazel/issues).