Docker for ARM64 (Raspberry Pi 4) 上的 Android SDK 用于构建 APK

fre*_*zen 5 android jenkins docker arm64 react-native

我正在尝试创建一个ARM64 Docker 映像,它能够构建我的 React Native 应用程序的 apk 文件。

背景:

为了练习目的,我使用 5 个 Raspberry Pi 4 板构建了一个 Kubernetes 集群。一切工作正常,Jenkins 正在其上运行,并且后端部分(Java 微服务、Maven)可以在其上构建、部署和运行。

现在我正在尝试为Android 应用程序部分创建一个管道,我在React Native、Gradle中构建了该管道。我只是在学习一切如何组合在一起,并且一直致力于在 Jenkins 上构建 apk文件。本地构建它(在 Linux 上)工作正常,但我无法为aarch64 架构创建 Docker 容器,并安装必要的 Android SDK 内容以使用 Jenkins 构建它。这是我现在所拥有的(告诉我,如果我需要提供更多信息!):

Dockerfile:

FROM openjdk:8-alpine3.9

ENV ANDROID_SDK_ROOT /opt/android-sdk-linux

RUN apk add --no-cache curl wget bash unzip \
    && apk add --no-cache --update nodejs npm \
    && npm install -g react-native-cli

RUN cd /opt \
    && wget -q https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip -O android-commandline-tools.zip \
    && mkdir -p ${ANDROID_SDK_ROOT}/cmdline-tools \
    && unzip -q android-commandline-tools.zip -d ${ANDROID_SDK_ROOT}/cmdline-tools \
    && rm android-commandline-tools.zip

ENV PATH ${PATH}:${ANDROID_SDK_ROOT}/platform-tools:${ANDROID_SDK_ROOT}/cmdline-tools/tools/bin

RUN yes | sdkmanager --licenses

RUN touch /root/.android/repositories.cfg

# This part fails!
# RUN yes | sdkmanager "emulator" "platform-tools"

RUN yes | sdkmanager --update --channel=3
RUN yes | sdkmanager \
    "platforms;android-29" \
    "build-tools;29.0.3" \
    "build-tools;29.0.2" \
    "build-tools;29.0.1" \
    "build-tools;29.0.0"
Run Code Online (Sandbox Code Playgroud)

詹金斯文件:

pipeline {
    agent {
        kubernetes {
            defaultContainer 'app-build'
            yamlFile 'kubernetes-pod.yaml'
        }
    }
    stages {
        stage ('print env vars') {
            steps {
                sh 'printenv'
                sh 'echo "JAVA-VERSION: "'
                sh 'java -version'
                sh 'echo "NODE-VERSION:"'
                sh 'node --version'
                sh 'echo "NPM version:" '
                sh 'npm --version'
                sh 'echo "REACT-NATIVE-VERSION:"'
                sh 'react-native --version'
            }
        }
       stage ('Gradle Build') {
           steps {
               sh ('react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res')
               dir ('android') {
                   // this step fails (error message below)
                   gradlew('assembleRelease', '--scan')
               }
           }
       }

       /* ... more steps ... */
    }
}

def gradlew(String... args) {
    sh "./gradlew ${args.join(' ')} -s"
}
Run Code Online (Sandbox Code Playgroud)

我在 Jenkins 上收到的错误消息如下:

Starting a Gradle Daemon (subsequent builds will be faster)

> Configure project :react-native-reanimated
Warning: Dependant package with key emulator not found!

FAILURE: Build failed with an exception.

* Where:
Build file '/home/jenkins/agent/workspace/nches_CHEF-8-frontend-deployment/node_modules/react-native-reanimated/android/build.gradle' line: 89

* What went wrong:
A problem occurred configuring project ':react-native-reanimated'.
> Failed to install the following SDK components:
      build-tools;29.0.2 Android SDK Build-Tools 29.0.2
  Install the missing components using the SDK manager in Android Studio.
Run Code Online (Sandbox Code Playgroud)

kubernetes-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  labels:
    label: jenkins-agent
    job: build-services
  namespace: build-services
spec:
  containers:
    - name: jnlp
      image: franzbuholzer/jenkins-jnlp-arm64:4.6
      tty: true
    - name: maven
      image: maven:3.6.3-jdk-11
      tty: true
      command: ["cat"]
      volumeMounts:
        - name: repository
          mountPath: /root/.m2/repository
    - name: docker
      image: docker:19.03.13
      command: ["cat"]
      tty: true
      volumeMounts:
        - name: docker-sock
          mountPath: /var/run/docker.sock
  volumes:
    - name: repository
      persistentVolumeClaim:
        claimName: repository
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
Run Code Online (Sandbox Code Playgroud)

如果有人能帮助我解决这个问题,我会非常高兴,这样我就可以解决下一个障碍,我想这将是将生成的 apk 复制到另一个 Docker 镜像中并将其部署在集群上以使其可下载......

hol*_*scn 3

虽然这个问题已经一个月没有活跃了,但我应该记录一下我的努力以供以后使用。由于sdkmanager使用类似进度条的输出,一些消息被覆盖,导致关键问题很难找到:有一个关键依赖emulator安装失败。我认为是因为没有匹配的qemu版本。但实际上我们在编译时并不需要模拟器。所以我的简单解决方案是:

  1. 在基于 x86 的 Linux 上安装 Android 命令行工具
  2. 安装平台工具、构建工具
  3. 将模拟器目录压缩到 $ANDROID_SDK_ROOT 中
  4. 在树莓派上安装Android命令行工具
  5. 安装创建基本目录结构的平台工具
  6. 将模拟器从 tarball 中提取到 $ANDROID_SDK_ROOT 中
  7. 祝你好运

似乎有些工具无法在32位系统下运行,因此无法使用他们最喜欢的32位Raspberry Pi操作系统。请改用 Ubuntu 64 位。

不幸的是,经过又一个小时的研究,除了可以安装构建工具之外,该解决方案无法工作。您不能仅仅因为从官方存储库下载的所有工具链都是为 x86 构建的,就在 AArch64(或 arm64)上编译 Android 应用程序。如果想要在 AArch64 CPU(例如 Raspberry PI)上构建 Android 应用程序,他们需要在该架构上构建整个工具链。