diff options
Diffstat (limited to 'stackoverflow-posts')
-rw-r--r-- | stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md b/stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md new file mode 100644 index 0000000..aca7af4 --- /dev/null +++ b/stackoverflow-posts/building-an-android-app-with-bazel-setup-in-a-nix-shell-environment.md @@ -0,0 +1,320 @@ +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 <nixpkgs> { + 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). |