Unverified Commit 1b3f124b authored by Ivan Matkov's avatar Ivan Matkov Committed by GitHub

Build Docker images locally when `Dockerfile`s change (#1161)

Fixes [SKIKO-1103](https://youtrack.jetbrains.com/issue/SKIKO-1103)
Properly handle Dockerfile changes in CI

### 1. Handle Dockerfile Changes in CI
When a PR modifies both the `Dockerfile` and C++ source, CI must build
the library against the **new** container logic before merging to catch
compatibility issues.
Workflows now detect `Dockerfile` changes and automatically build images
locally before running tests. When no `Dockerfile` changes are detected,
published images from `ghcr.io` are used.

### 2. Avoid GLIBC Mismatches: Run GitHub Actions Outside Containers
Running GitHub Actions native steps (like `actions/checkout`) inside
custom containers causes GLIBC version mismatches since GitHub's
Node.js-based actions require newer GLIBC than Amazon Linux 2 provides.
This change introduced new composite action `docker-skiko-run` that runs
GitHub actions outside the container on `ubuntu-24.04` runner, and only
executes build/test commands inside the Docker container via `docker
run`.

### 3. Environment Alignment: Use `linux-compat` for GitHub Actions
Builds
GitHub Actions used Ubuntu 20.04 images with GLIBC 2.31, while TeamCity
publishing used Amazon Linux 2 with GLIBC 2.26. This mismatch could mask
GLIBC compatibility issues during PR validation.
Most GitHub Actions workflows now use `linux-compat` (Amazon Linux 2).
- Web builds are out of the scope here because emsdk requires newer
GLIBC.
- Cross-compilation is out of the scope because there is no simply way
to get arm shared libraries to x64 image on AL2

Note: TeamCity publishing should be updated to use `linux-compat` too

### 4. Introduce Orchestrator Workflows
New orchestrator workflows compose existing test/build/docs workflows:
- **`pull-request.yml`** - Runs on every PR: detects Docker changes,
builds images if needed (dry-run), runs tests + publish dry run + docs
validation
- **`post-merge.yml`** - Runs on push to master/release: detects Docker
changes, publishes images if changed, runs tests + publish dry run +
docs publication

So, we should have fewer "Run CI" temporary PRs now

### 5. Documentation as Pre-Merge Check
Documentation builds now run inside the same `linux-compat` Docker
environment used for library builds, and are validated as part of PR
checks (previously only ran post-merge).


### 6. Docker Tags Use Branch Names
Published Docker images are tagged with the branch name (e.g., `master`,
`release/0.9.46`), so the release branches might publish its own version
of the image. This way changes in `master` shouldn't prevent making a
patch for a previous version if it's required
parent 5ffb421a
name: 'Docker Publish' name: 'Docker Skiko Publish'
description: 'Build and optionally publish a Docker image to a registry' description: 'Build and optionally publish a Docker image to ghcr.io for skiko'
inputs: inputs:
registry:
description: 'Docker registry (e.g., ghcr.io)'
required: true
namespace:
description: 'Image namespace (e.g., owner/repo)'
required: true
image_name: image_name:
description: 'Image name (e.g., linux-amd64)' description: 'Image name (e.g., linux-compat)'
required: true
context:
description: 'Build context path (e.g., ./skiko/docker/linux-amd64)'
required: true required: true
platforms: platforms:
description: 'Target platforms (e.g., linux/amd64 or linux/amd64,linux/arm64)' description: 'Target platforms (e.g., linux/amd64 or linux/amd64,linux/arm64). If not specified, uses runner architecture.'
required: true required: false
tag: tag:
description: 'Image tag (e.g., ubuntu-2004)' description: 'Image tag (e.g., latest)'
required: true required: true
load:
description: 'Whether to load the image into the local Docker daemon'
required: false
default: 'false'
should_publish: should_publish:
description: 'Whether to push the image to the registry' description: 'Whether to push the image to the registry'
required: true required: true
github_token: github_token:
description: 'GitHub token for authentication' description: 'GitHub token for authentication (required only if should_publish is true)'
required: true required: false
runs: runs:
using: 'composite' using: 'composite'
steps: steps:
- name: 'Set Variables'
id: vars
shell: bash
run: |
echo "image_namespace=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT
# Normalize tag: replace invalid docker tag characters
TAG="${{ inputs.tag }}"
TAG="${TAG//\//-}"
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- name: 'Set up Docker Buildx' - name: 'Set up Docker Buildx'
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
...@@ -37,7 +43,7 @@ runs: ...@@ -37,7 +43,7 @@ runs:
if: inputs.should_publish == 'true' if: inputs.should_publish == 'true'
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ inputs.registry }} registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ inputs.github_token }} password: ${{ inputs.github_token }}
...@@ -45,16 +51,17 @@ runs: ...@@ -45,16 +51,17 @@ runs:
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: ${{ inputs.registry }}/${{ inputs.namespace }}/${{ inputs.image_name }} images: ghcr.io/${{ steps.vars.outputs.image_namespace }}/${{ inputs.image_name }}
tags: | tags: |
type=raw,value=${{ inputs.tag }} type=raw,value=${{ steps.vars.outputs.tag }}
- name: 'Build and push' - name: 'Build and push'
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: ${{ inputs.context }} context: ./skiko/docker/${{ inputs.image_name }}
platforms: ${{ inputs.platforms }} platforms: ${{ inputs.platforms }}
push: ${{ inputs.should_publish == 'true' }} push: ${{ inputs.should_publish == 'true' }}
load: ${{ inputs.load == 'true' }}
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha cache-from: type=gha
......
name: 'Docker Skiko Run'
description: 'Build Docker image locally if needed and run commands inside it'
inputs:
image_name:
description: 'Image name (e.g., linux-compat)'
required: true
command:
description: 'Command to run inside the container'
required: true
working_directory:
description: 'Working directory relative to project root (e.g., samples/SkiaAndroidSample)'
required: false
default: '.'
virtual-display:
description: 'Enable virtual display for UI testing (enables e2e UI interaction tests with real windows)'
required: false
default: 'false'
runs:
using: 'composite'
steps:
- name: 'Detect Docker changes'
id: filter
uses: dorny/paths-filter@v3
with:
base: ${{ github.event.pull_request.base.sha || github.event.before || 'master' }}
filters: |
docker_changed:
- '.github/actions/docker-skiko-publish/**'
- '.github/workflows/docker-publish.yml'
- 'skiko/docker/${{ inputs.image_name }}/**'
- name: 'Set Variables'
id: vars
shell: bash
run: |
IMAGE_NAMESPACE="${GITHUB_REPOSITORY,,}"
echo "image_namespace=${IMAGE_NAMESPACE}" >> $GITHUB_OUTPUT
# Determine which tag to use
# github.base_ref is set for PRs regardless of event type (pull_request or workflow_call)
if [[ -n "${{ github.base_ref }}" && "${{ steps.filter.outputs.docker_changed }}" != "true" ]]; then
# For PRs without docker changes, use the base (target) branch name as the docker tag.
# Most of the time it points to an already built-image.
TAG="${{ github.base_ref }}"
else
# For PRs with docker changes or non-PRs, use the current branch name as the docker tag
TAG="${GITHUB_REF_NAME}"
fi
TAG="${TAG//\//-}"
# Try to pull image from GHCR
# This checks both if the image exists in the registry and loads it into the local daemon
if docker pull "ghcr.io/${IMAGE_NAMESPACE}/${{ inputs.image_name }}:${TAG}" >/dev/null 2>&1; then
IMAGE_EXISTS="true"
else
IMAGE_EXISTS="false"
fi
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "image_exists=${IMAGE_EXISTS}" >> $GITHUB_OUTPUT
- name: 'Build Docker image locally (if needed)'
if: steps.filter.outputs.docker_changed == 'true' || steps.vars.outputs.image_exists == 'false'
uses: ./.github/actions/docker-skiko-publish
with:
image_name: ${{ inputs.image_name }}
tag: ${{ steps.vars.outputs.tag }}
load: true
should_publish: false
- name: 'Prepare command'
id: cmd
shell: bash
run: |
CMD="${{ inputs.command }}"
if [[ "${{ inputs.virtual-display }}" == "true" ]]; then
CMD="Xvfb :1 -screen 0 1920x1080x24 -extension RANDR +extension GLX & export DISPLAY=:1.0 && ${CMD}"
fi
{
echo "command<<EOF"
echo "${CMD}"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: 'Run command in container'
shell: bash
run: |
docker run --rm \
-v "${{ github.workspace }}":/workspace \
-v "${HOME}/.gradle":/gradle-cache \
-e GRADLE_USER_HOME=/gradle-cache \
-w /workspace/${{ inputs.working_directory }} \
"ghcr.io/${{ steps.vars.outputs.image_namespace }}/${{ inputs.image_name }}:${{ steps.vars.outputs.tag }}" \
bash -c '${{ steps.cmd.outputs.command }}'
name: 'Setup Prerequisites' name: 'Setup Prerequisites'
description: 'Shared steps to prepare build environment'
runs: runs:
using: "composite" using: "composite"
steps: steps:
- name: Free up space on GitHub runner
if: runner.os == 'Linux'
shell: bash
run: |
df -h
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
df -h
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v4
with: with:
......
name: Docker Build and Publish name: Docker Build and Publish
on: on:
workflow_dispatch: workflow_dispatch: # Allow manual triggering with an option to publish
inputs: inputs:
publish: publish:
description: 'Publish to registry (if false, only dry-run build)' description: 'Publish to registry (if false, only dry-run build)'
required: false required: false
type: boolean type: boolean
default: true default: true
push: workflow_call: # Allow being called by other workflows
branches: inputs:
- master publish:
paths: description: 'Publish to registry (if false, only dry-run build)'
- 'skiko/docker/**' required: true
- '.github/workflows/docker-publish.yml' type: boolean
pull_request:
paths:
- 'skiko/docker/**'
- '.github/workflows/docker-publish.yml'
env:
REGISTRY: ghcr.io
jobs: jobs:
# Determine if we should publish (only on push to master or manual trigger with publish=true) changes:
config: name: 'Detect Docker Changes'
name: 'Configuration'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
outputs: outputs:
should_publish: ${{ steps.vars.outputs.should_publish }} linux_amd64: ${{ steps.filter.outputs.linux_amd64 }}
image_namespace: ${{ steps.vars.outputs.image_namespace }} linux_compat: ${{ steps.filter.outputs.linux_compat }}
steps: linux_emscripten_amd64: ${{ steps.filter.outputs.linux_emscripten_amd64 }}
- id: vars windows: ${{ steps.filter.outputs.windows }}
name: 'Set Variables' docker_workflow: ${{ steps.filter.outputs.docker_workflow }}
run: |
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/master" ]]; then
echo "should_publish=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.publish }}" == "true" ]]; then
echo "should_publish=true" >> $GITHUB_OUTPUT
else
echo "should_publish=false" >> $GITHUB_OUTPUT
fi
echo "image_namespace=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
linux-amd64:
name: 'Docker Linux (x64)'
runs-on: ubuntu-24.04
needs: config
permissions:
contents: read
packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/docker-publish - uses: dorny/paths-filter@v3
name: 'Build and Publish Docker Image' id: filter
with: with:
registry: ${{ env.REGISTRY }} base: ${{ github.event.pull_request.base.sha || github.event.before || 'master' }}
namespace: ${{ needs.config.outputs.image_namespace }} filters: |
image_name: linux-amd64 docker_workflow:
context: ./skiko/docker/linux-amd64 - '.github/actions/docker-skiko-publish/**'
platforms: linux/amd64 - '.github/workflows/docker-publish.yml'
tag: ubuntu-2004 linux_amd64:
should_publish: ${{ needs.config.outputs.should_publish }} - 'skiko/docker/linux-amd64/**'
github_token: ${{ secrets.GITHUB_TOKEN }} linux_compat:
- 'skiko/docker/linux-compat/**'
linux_emscripten_amd64:
- 'skiko/docker/linux-emscripten-amd64/**'
windows:
- 'skiko/docker/windows/**'
linux-arm64: linux-amd64:
name: 'Docker Linux (arm64)' name: 'Docker Linux (x64)'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
needs: config needs: changes
if: |
needs.changes.outputs.linux_amd64 == 'true' ||
needs.changes.outputs.docker_workflow == 'true'
permissions: permissions:
contents: read contents: read
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/docker-publish - uses: ./.github/actions/docker-skiko-publish
name: 'Build and Publish Docker Image' name: 'Build and Publish Docker Image'
id: docker-publish
with: with:
registry: ${{ env.REGISTRY }} image_name: linux-amd64
namespace: ${{ needs.config.outputs.image_namespace }} tag: ${{ github.ref_name }}
image_name: linux-arm64 should_publish: ${{ inputs.publish }}
context: ./skiko/docker/linux-arm64
platforms: linux/arm64
tag: ubuntu-2004
should_publish: ${{ needs.config.outputs.should_publish }}
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
linux-android-amd64: linux-compat:
name: 'Docker Linux with Android SDK (x64)' name: 'Docker Linux (Compatibility)'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
needs: config needs: changes
if: |
needs.changes.outputs.linux_compat == 'true' ||
needs.changes.outputs.docker_workflow == 'true'
permissions: permissions:
contents: read contents: read
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/docker-publish - uses: ./.github/actions/docker-skiko-publish
name: 'Build and Publish Docker Image' name: 'Build and Publish Docker Image'
id: docker-publish
with: with:
registry: ${{ env.REGISTRY }} image_name: linux-compat
namespace: ${{ needs.config.outputs.image_namespace }} platforms: linux/amd64,linux/arm64
image_name: linux-android-amd64 tag: ${{ github.ref_name }}
context: ./skiko/docker/linux-android-amd64 should_publish: ${{ inputs.publish }}
platforms: linux/amd64
tag: ubuntu-2004
should_publish: ${{ needs.config.outputs.should_publish }}
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
linux-emscripten-amd64: linux-emscripten-amd64:
name: 'Docker Linux with Emscripten (x64)' name: 'Docker Linux with Emscripten (x64)'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
needs: config needs: changes
if: |
needs.changes.outputs.linux_emscripten_amd64 == 'true' ||
needs.changes.outputs.docker_workflow == 'true'
permissions: permissions:
contents: read contents: read
packages: write packages: write
steps:
- uses: actions/checkout@v4
name: 'Check out code'
- uses: ./.github/actions/docker-publish
name: 'Build and Publish Docker Image'
with:
registry: ${{ env.REGISTRY }}
namespace: ${{ needs.config.outputs.image_namespace }}
image_name: linux-emscripten-amd64
context: ./skiko/docker/linux-emscripten-amd64
platforms: linux/amd64
tag: ubuntu-2004
should_publish: ${{ needs.config.outputs.should_publish }}
github_token: ${{ secrets.GITHUB_TOKEN }}
linux-compat:
name: 'Docker Linux (Compatibility)'
runs-on: ubuntu-24.04
needs: config
permissions:
contents: read
packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/docker-publish - uses: ./.github/actions/docker-skiko-publish
name: 'Build and Publish Docker Image' name: 'Build and Publish Docker Image'
id: docker-publish
with: with:
registry: ${{ env.REGISTRY }} image_name: linux-emscripten-amd64
namespace: ${{ needs.config.outputs.image_namespace }} tag: ${{ github.ref_name }}
image_name: linux-compat should_publish: ${{ inputs.publish }}
context: ./skiko/docker/linux-compat
platforms: linux/amd64,linux/arm64
tag: amazonlinux2-latest
should_publish: ${{ needs.config.outputs.should_publish }}
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
windows: windows:
name: 'Docker Windows' name: 'Docker Windows'
runs-on: windows-2022 runs-on: windows-2022
needs: config needs: changes
if: |
needs.changes.outputs.windows == 'true' ||
needs.changes.outputs.docker_workflow == 'true'
permissions: permissions:
contents: read contents: read
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- name: 'Log in to GitHub Container Registry' - name: 'Set Variables'
if: needs.config.outputs.should_publish == 'true'
shell: pwsh shell: pwsh
run: | run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin "IMAGE_REPOSITORY=$($env:GITHUB_REPOSITORY.ToLower())" >> $env:GITHUB_ENV
$tag = "${{ github.ref_name }}".Replace('/', '-')
"TAG=$tag" >> $env:GITHUB_ENV
- name: 'Log in to GitHub Container Registry'
if: inputs.publish == true
shell: pwsh
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: 'Build Image' - name: 'Build Image'
shell: pwsh shell: pwsh
working-directory: ./skiko/docker/windows working-directory: ./skiko/docker/windows
run: | run: |
docker build -t ${{ env.REGISTRY }}/${{ needs.config.outputs.image_namespace }}/windows-amd64:ltsc2022 -m 2G . docker build -t "ghcr.io/$($env:IMAGE_REPOSITORY)/windows-amd64:$($env:TAG)" -m 2G .
- name: 'Push Image' - name: 'Push Image'
if: needs.config.outputs.should_publish == 'true' if: inputs.publish == true
shell: pwsh shell: pwsh
run: | run: |
docker push ${{ env.REGISTRY }}/${{ needs.config.outputs.image_namespace }}/windows-amd64:ltsc2022 docker push "ghcr.io/$($env:IMAGE_REPOSITORY)/windows-amd64:$($env:TAG)"
# Build Skiko documentation name: Skiko Documentation
name: Doc
on: on:
push: workflow_call: # Allow being called by other workflows
branches: [ master ] inputs:
# Temporary, for testing. Remove! publish:
#pull_request: description: 'Publish documentation (if false, only dry-run build)'
# branches: [ master ] required: true
type: boolean
workflow_dispatch: secrets:
ACCESS_TOKEN:
description: 'GitHub token for deploying to gh-pages (required when publish is true)'
required: false
jobs: jobs:
dokka: dokka:
runs-on: ubuntu-22.04 name: 'Build and Publish Documentation'
runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: actions/setup-java@v3 - uses: ./.github/actions/setup-prerequisites
name: 'Set up JDK 21' name: 'Setup Prerequisites'
with:
distribution: 'adopt'
java-version: '21'
cache: 'gradle'
- shell: bash
name: 'Set up Linux build environment'
run: |
sudo apt-get update -y
sudo apt-get install libglu1-mesa-dev libxrandr-dev libdbus-1-dev multistrap -y
sudo apt-get install gcc-9 g++-9 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9
sudo update-alternatives --config gcc
sudo apt-get install gcc-9-aarch64-linux-gnu g++-9-aarch64-linux-gnu -y
sudo update-alternatives --install /usr/bin/aarch64-linux-gnu-gcc aarch64-linux-gnu-gcc /usr/bin/aarch64-linux-gnu-gcc-9 60 --slave /usr/bin/aarch64-linux-gnu-g++ aarch64-linux-gnu-g++ /usr/bin/aarch64-linux-gnu-g++-9
sudo update-alternatives --config aarch64-linux-gnu-gcc
sudo Xvfb :0 -screen 0 1280x720x24 &
- name: 'Build Dokka documentation' - uses: ./.github/actions/docker-skiko-run
run: bash -c 'JAVA_OPTS="-Xmx4g" ./gradlew --no-daemon -Pskiko.native.enabled=true -Pskiko.wasm.enabled=true -Pskiko.android.enabled=true :skiko:dokkaHtml' name: 'Build Dokka Documentation'
with:
image_name: linux-compat
command: |
./gradlew --no-daemon --stacktrace \
-Pskiko.native.enabled=true \
-Pskiko.wasm.enabled=true \
-Pskiko.android.enabled=true \
:skiko:dokkaHtml
- name: 'Publish documentation' - name: 'Publish Documentation'
if: ${{ inputs.publish }}
uses: JamesIves/github-pages-deploy-action@releases/v3 uses: JamesIves/github-pages-deploy-action@releases/v3
with: with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
......
name: Post-Merge CI
on:
workflow_dispatch: # Allow manual triggering
push: # Trigger on pushes to master and release branches
branches:
- master
- 'release/*'
concurrency:
group: post-merge-${{ github.ref }}
cancel-in-progress: false
jobs:
docker-publish:
name: 'Docker Publish'
uses: ./.github/workflows/docker-publish.yml
with:
publish: true
permissions:
contents: read
packages: write
tests:
name: 'Tests'
needs: docker-publish
uses: ./.github/workflows/tests.yml
skiko-publish:
name: 'Skiko Publish (Dry Run)'
needs: docker-publish
uses: ./.github/workflows/publish-dry-run.yml
docs-publish:
name: 'Documentation Publish'
needs: docker-publish
uses: ./.github/workflows/docs.yml
with:
publish: true
secrets: inherit
name: Skiko Publish Dry Run name: Skiko Publish Dry Run
on: on:
workflow_dispatch: workflow_call: # Allow being called by other workflows
pull_request:
push:
branches:
- master
jobs: jobs:
Android: Android:
name: 'Android Publish Dry Run'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container:
image: ghcr.io/jetbrains/skiko/linux-android-amd64:ubuntu-2004
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/setup-prerequisites - uses: ./.github/actions/setup-prerequisites
name: 'Setup Prerequisites' name: 'Setup Prerequisites'
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Publish Maven Local' name: 'Publish Maven Local'
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-compat
-Pskiko.android.enabled=true \ command: |
:skiko:publishToMavenLocal ./gradlew --no-daemon --stacktrace \
-Pskiko.android.enabled=true \
:skiko:publishToMavenLocal
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Check Android Sample' name: 'Check Android Sample'
working-directory: samples/SkiaAndroidSample with:
run: | image_name: linux-compat
./gradlew --no-daemon --stacktrace \ working_directory: samples/SkiaAndroidSample
packageRelease command: |
./gradlew --no-daemon --stacktrace \
packageRelease
Web: Web:
name: 'Web Publish Dry Run'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container:
image: ghcr.io/jetbrains/skiko/linux-emscripten-amd64:ubuntu-2004
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/setup-prerequisites - uses: ./.github/actions/setup-prerequisites
name: 'Setup Prerequisites' name: 'Setup Prerequisites'
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Publish Maven Local' name: 'Publish Maven Local'
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-emscripten-amd64
-Pskiko.wasm.enabled=true \ command: |
:skiko:publishToMavenLocal ./gradlew --no-daemon --stacktrace \
-Pskiko.wasm.enabled=true \
:skiko:publishToMavenLocal
Linux: Linux:
name: 'Linux Publish Dry Run'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container:
image: ghcr.io/jetbrains/skiko/linux-amd64:ubuntu-2004
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/setup-prerequisites - uses: ./.github/actions/setup-prerequisites
name: 'Setup Prerequisites' name: 'Setup Prerequisites'
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Publish Maven Local' name: 'Publish Maven Local'
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-compat
-Pskiko.native.enabled=true \ command: |
:skiko:publishToMavenLocal ./gradlew --no-daemon --stacktrace \
-Pskiko.native.enabled=true \
:skiko:publishToMavenLocal
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Check AWT Sample' name: 'Check AWT Sample'
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-compat
:SkiaAwtSample:installDist command: |
./gradlew --no-daemon --stacktrace \
:SkiaAwtSample:installDist
macOS: macOS:
name: 'macOS Publish Dry Run'
runs-on: macos-15 runs-on: macos-15
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: actions/setup-java@v4 - uses: actions/setup-java@v4
...@@ -103,9 +108,10 @@ jobs: ...@@ -103,9 +108,10 @@ jobs:
:SkiaAwtSample:installDist :SkiaAwtSample:installDist
Windows: Windows:
name: 'Windows Publish Dry Run'
runs-on: windows-2022 runs-on: windows-2022
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: microsoft/setup-msbuild@v1 - uses: microsoft/setup-msbuild@v1
......
name: Pull Request CI
on:
workflow_dispatch: # Allow manual triggering
pull_request: # Trigger on all pull requests
jobs:
docker-publish:
name: 'Docker Publish (Dry Run)'
uses: ./.github/workflows/docker-publish.yml
with:
publish: false
permissions:
contents: read
packages: write # Is not used in case of dry run, but required to avoid "The workflow is not valid" error
tests:
name: 'Tests'
uses: ./.github/workflows/tests.yml
skiko-publish:
name: 'Skiko Publish (Dry Run)'
uses: ./.github/workflows/publish-dry-run.yml
docs-publish:
name: 'Documentation Publish (Dry Run)'
uses: ./.github/workflows/docs.yml
with:
publish: false
secrets: inherit
name: Skiko Tests name: Skiko Tests
on: on:
workflow_dispatch: workflow_call: # Allow being called by other workflows
pull_request:
push:
branches:
- master
jobs: jobs:
macos: macos:
...@@ -14,7 +11,7 @@ jobs: ...@@ -14,7 +11,7 @@ jobs:
# TODO: Update once resolved # TODO: Update once resolved
runs-on: macos-14 runs-on: macos-14
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: actions/setup-java@v4 - uses: actions/setup-java@v4
...@@ -52,6 +49,7 @@ jobs: ...@@ -52,6 +49,7 @@ jobs:
path: | path: |
./skiko/build/reports/tests ./skiko/build/reports/tests
./skiko/src/jvmTest/screenshots/*_actual.png ./skiko/src/jvmTest/screenshots/*_actual.png
./skiko/hs_err_pid*.log
retention-days: 5 retention-days: 5
- uses: test-summary/action@v2 - uses: test-summary/action@v2
...@@ -64,7 +62,7 @@ jobs: ...@@ -64,7 +62,7 @@ jobs:
name: 'iOS' name: 'iOS'
runs-on: macos-15 runs-on: macos-15
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: actions/setup-java@v4 - uses: actions/setup-java@v4
...@@ -122,7 +120,7 @@ jobs: ...@@ -122,7 +120,7 @@ jobs:
name: 'tvOS' name: 'tvOS'
runs-on: macos-15 runs-on: macos-15
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: actions/setup-java@v4 - uses: actions/setup-java@v4
...@@ -161,39 +159,37 @@ jobs: ...@@ -161,39 +159,37 @@ jobs:
linux-amd64: linux-amd64:
name: 'Linux (x64)' name: 'Linux (x64)'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container:
image: ghcr.io/jetbrains/skiko/linux-amd64:ubuntu-2004
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/setup-prerequisites - uses: ./.github/actions/setup-prerequisites
name: 'Setup Prerequisites' name: 'Setup Prerequisites'
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Start X Server'
run: |
Xvfb :1 -screen 0 1920x1080x24 -extension RANDR +extension GLX &
echo "DISPLAY=:1.0" >> $GITHUB_ENV
- shell: bash
name: 'Run Linux (x64) Tests' name: 'Run Linux (x64) Tests'
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-compat
-Pskiko.native.enabled=true \ virtual-display: true
-Dskiko.test.onci=true \ command: |
-Dskiko.test.performance.enabled=false \ ./gradlew --no-daemon --stacktrace \
:skiko:linuxX64Test -Pskiko.native.enabled=true \
-Dskiko.test.onci=true \
-Dskiko.test.performance.enabled=false \
:skiko:linuxX64Test
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Run AWT Tests' name: 'Run AWT Tests'
timeout-minutes: 25 timeout-minutes: 25
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-compat
-Pskiko.native.enabled=true \ virtual-display: true
-Dskiko.test.onci=true \ command: |
-Dskiko.test.performance.enabled=false \ ./gradlew --no-daemon --stacktrace \
:skiko:awtTest -Pskiko.native.enabled=true \
-Dskiko.test.onci=true \
-Dskiko.test.performance.enabled=false \
:skiko:awtTest
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
name: 'Upload Test Results' name: 'Upload Test Results'
...@@ -203,6 +199,7 @@ jobs: ...@@ -203,6 +199,7 @@ jobs:
path: | path: |
./skiko/build/reports/tests ./skiko/build/reports/tests
./skiko/src/jvmTest/screenshots/*_actual.png ./skiko/src/jvmTest/screenshots/*_actual.png
./skiko/hs_err_pid*.log
- uses: test-summary/action@v2 - uses: test-summary/action@v2
name: 'Test Summary' name: 'Test Summary'
...@@ -213,22 +210,22 @@ jobs: ...@@ -213,22 +210,22 @@ jobs:
linux-cross-compile: linux-cross-compile:
name: 'Cross-compile Linux (arm) on x64' name: 'Cross-compile Linux (arm) on x64'
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container:
image: ghcr.io/jetbrains/skiko/linux-amd64:ubuntu-2004
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/setup-prerequisites - uses: ./.github/actions/setup-prerequisites
name: 'Setup Prerequisites' name: 'Setup Prerequisites'
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Compile Linux (arm64) Tests' name: 'Compile Linux (arm64) Tests'
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-amd64
-Pskiko.arch=x64 \ command: |
-Pskiko.native.linux.enabled=true \ ./gradlew --no-daemon --stacktrace \
:skiko:linkDebugTestLinuxArm64 -Pskiko.arch=x64 \
-Pskiko.native.linux.enabled=true \
:skiko:linkDebugTestLinuxArm64
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
name: 'Upload linuxArm64 test binary as artifact' name: 'Upload linuxArm64 test binary as artifact'
...@@ -242,43 +239,41 @@ jobs: ...@@ -242,43 +239,41 @@ jobs:
name: 'Linux (arm64)' name: 'Linux (arm64)'
needs: linux-cross-compile needs: linux-cross-compile
runs-on: ubuntu-24.04-arm runs-on: ubuntu-24.04-arm
container:
image: ghcr.io/jetbrains/skiko/linux-arm64:ubuntu-2004
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: ./.github/actions/setup-prerequisites - uses: ./.github/actions/setup-prerequisites
name: 'Setup Prerequisites' name: 'Setup Prerequisites'
- shell: bash
name: 'Start X Server'
run: |
Xvfb :1 -screen 0 1920x1080x24 -extension RANDR +extension GLX &
echo "DISPLAY=:1.0" >> $GITHUB_ENV
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
name: 'Download precompiled linuxArm64 test binary' name: 'Download precompiled linuxArm64 test binary'
with: with:
name: test-binary-linuxArm64 name: test-binary-linuxArm64
path: ./skiko/build/bin/linuxArm64 path: ./skiko/build/bin/linuxArm64
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Run Linux (arm64) Tests' name: 'Run Linux (arm64) Tests'
working-directory: skiko with:
run: | image_name: linux-compat
chmod +x ./build/bin/linuxArm64/debugTest/test.kexe working_directory: skiko
./build/bin/linuxArm64/debugTest/test.kexe virtual-display: true
command: |
chmod +x ./build/bin/linuxArm64/debugTest/test.kexe
./build/bin/linuxArm64/debugTest/test.kexe
- shell: bash - uses: ./.github/actions/docker-skiko-run
name: 'Run AWT Tests' name: 'Run AWT Tests'
timeout-minutes: 25 timeout-minutes: 25
run: | with:
./gradlew --no-daemon --stacktrace \ image_name: linux-compat
-Pskiko.native.enabled=true \ virtual-display: true
-Dskiko.test.onci=true \ command: |
-Dskiko.test.performance.enabled=false \ ./gradlew --no-daemon --stacktrace \
:skiko:awtTest -Pskiko.native.enabled=true \
-Dskiko.test.onci=true \
-Dskiko.test.performance.enabled=false \
:skiko:awtTest
- name: Upload Test Results - name: Upload Test Results
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
...@@ -288,6 +283,7 @@ jobs: ...@@ -288,6 +283,7 @@ jobs:
path: | path: |
./skiko/build/reports/tests ./skiko/build/reports/tests
./skiko/src/jvmTest/screenshots/*_actual.png ./skiko/src/jvmTest/screenshots/*_actual.png
./skiko/hs_err_pid*.log
retention-days: 5 retention-days: 5
- name: Test Summary - name: Test Summary
...@@ -300,7 +296,7 @@ jobs: ...@@ -300,7 +296,7 @@ jobs:
name: 'Windows' name: 'Windows'
runs-on: windows-2022 runs-on: windows-2022
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: microsoft/setup-msbuild@v1 - uses: microsoft/setup-msbuild@v1
...@@ -334,6 +330,7 @@ jobs: ...@@ -334,6 +330,7 @@ jobs:
path: | path: |
./skiko/build/reports/tests ./skiko/build/reports/tests
./skiko/src/jvmTest/screenshots/*_actual.png ./skiko/src/jvmTest/screenshots/*_actual.png
./skiko/hs_err_pid*.log
retention-days: 5 retention-days: 5
- uses: test-summary/action@v2 - uses: test-summary/action@v2
...@@ -344,24 +341,29 @@ jobs: ...@@ -344,24 +341,29 @@ jobs:
web-wasm: web-wasm:
name: 'Web' name: 'Web'
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: 'Check out code' name: 'Check out code'
- uses: actions/setup-java@v3 # Setup environment directly instead of using docker image
# because of instability of running tests inside docker
- uses: actions/setup-java@v4
name: 'Setup JDK 21' name: 'Setup JDK 21'
with: with:
java-version: '21' java-version: '21'
distribution: 'adopt' distribution: 'corretto'
cache: 'gradle'
- uses: ./.github/actions/setup-prerequisites
name: 'Setup Prerequisites'
- uses: browser-actions/setup-chrome@v1 - uses: browser-actions/setup-chrome@v1
name: 'Setup Google Chrome' name: 'Setup Google Chrome'
with: with:
chrome-version: stable chrome-version: stable
- name: 'Install emscripten' - name: 'Install Emscripten'
shell: bash shell: bash
working-directory: skiko working-directory: skiko
run: | run: |
......
...@@ -254,6 +254,7 @@ fun SkikoProjectContext.configureNativeTarget(os: OS, arch: Arch, target: Kotlin ...@@ -254,6 +254,7 @@ fun SkikoProjectContext.configureNativeTarget(os: OS, arch: Arch, target: Kotlin
} }
OS.Linux -> { OS.Linux -> {
val options = mutableListOf( val options = mutableListOf(
"-L/usr/lib64",
"-L/usr/lib/${if (arch == Arch.Arm64) "aarch64" else "x86_64"}-linux-gnu", "-L/usr/lib/${if (arch == Arch.Arm64) "aarch64" else "x86_64"}-linux-gnu",
"-lfontconfig", "-lfontconfig",
"-lGL", "-lGL",
......
...@@ -45,12 +45,11 @@ RUN cd /tmp && mkdir -p $ARM_TOOLCHAIN_PATH && \ ...@@ -45,12 +45,11 @@ RUN cd /tmp && mkdir -p $ARM_TOOLCHAIN_PATH && \
ln -s $ARM_TOOLCHAIN_PATH/bin/aarch64-none-linux-gnu-ar /usr/local/bin/aarch64-linux-gnu-ar ln -s $ARM_TOOLCHAIN_PATH/bin/aarch64-none-linux-gnu-ar /usr/local/bin/aarch64-linux-gnu-ar
# Copy development headers to ARM64 sysroot # Copy development headers to ARM64 sysroot
ENV ARM_SYSROOT_HEADERS="fontconfig freetype2 GL X11 KHR"
RUN mkdir -p $ARM_TOOLCHAIN_SYSROOT/usr/include && \ RUN mkdir -p $ARM_TOOLCHAIN_SYSROOT/usr/include && \
cp -r /usr/include/fontconfig $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \ for dir in $ARM_SYSROOT_HEADERS; do \
cp -r /usr/include/freetype2 $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \ cp -r /usr/include/$dir $ARM_TOOLCHAIN_SYSROOT/usr/include/ || exit 1; \
cp -r /usr/include/GL $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \ done
cp -r /usr/include/X11 $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \
cp -r /usr/include/KHR $ARM_TOOLCHAIN_SYSROOT/usr/include/
# Use UTF-8 by default # Use UTF-8 by default
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
......
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update -y && \
apt install binutils build-essential software-properties-common -y && \
apt install zip unzip git python curl wget -y && \
apt install fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev libdbus-1-dev -y && \
apt install openjdk-21-jdk -y && \
rm -rf /var/lib/apt/lists/*
# Install Android SDK
ENV ANDROID_SDK_ROOT=/android/sdk
ARG CMD_TOOLS_VERSION=13114758
ARG CMD_TOOLS_ROOT=$ANDROID_SDK_ROOT/cmdline-tools/$CMD_TOOLS_VERSION
ARG SDK_MANAGER=$CMD_TOOLS_ROOT/bin/sdkmanager
RUN mkdir -p $CMD_TOOLS_ROOT && \
export CMD_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-${CMD_TOOLS_VERSION}_latest.zip" && \
wget $CMD_TOOLS_URL -O cmd-tools.zip && \
unzip cmd-tools.zip && \
rm cmd-tools.zip && \
mv cmdline-tools/* $CMD_TOOLS_ROOT/
ARG ANDROID_PLATFORM=android-33
RUN yes | $SDK_MANAGER --licenses && \
$SDK_MANAGER "platforms;$ANDROID_PLATFORM" && \
cd $ANDROID_SDK_ROOT/platforms/$ANDROID_PLATFORM && \
ls -1 | grep -v android.jar | xargs rm -rf
ARG NDK_VERSION=29.0.14206865
RUN $SDK_MANAGER "ndk;$NDK_VERSION" && \
cd $ANDROID_SDK_ROOT/ndk/$NDK_VERSION && \
ls -1 | grep -v toolchains | xargs rm -rf
# Use UTF-8 by default
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
FROM arm64v8/ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update -y && \
apt install binutils build-essential software-properties-common -y && \
apt install zip unzip git python curl wget xvfb -y && \
apt install fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev libdbus-1-dev -y && \
apt install openjdk-21-jdk -y && \
rm -rf /var/lib/apt/lists/*
# Install chromium tools
ENV DEPOT_TOOLS=/usr/depot_tools
ENV PATH=$DEPOT_TOOLS:$PATH
RUN git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git' $DEPOT_TOOLS
# Use UTF-8 by default
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
# Multi-architecture Dockerfile for building Skiko on Linux, compatiable with GLIBC 2.26 # Multi-architecture Dockerfile for building Skiko on Linux, compatible with GLIBC 2.26
# Supports both amd64 (x64) and arm64 architectures # Supports both amd64 (x64) and arm64 architectures
FROM amazonlinux:2 FROM amazonlinux:2
ARG TARGETARCH ARG TARGETARCH
# Install basic & development tools # Install basic & development tools
RUN yum install -y tar xz git wget curl zip gzip && \ RUN yum install -y tar xz git wget curl zip unzip gzip && \
yum install -y gcc10 gcc10-c++ gcc10-binutils make && \ yum install -y gcc10 gcc10-c++ gcc10-binutils make && \
ln -sf /usr/bin/gcc10-gcc /usr/bin/gcc && \ ln -sf /usr/bin/gcc10-gcc /usr/bin/gcc && \
ln -sf /usr/bin/gcc10-g++ /usr/bin/g++ && \ ln -sf /usr/bin/gcc10-g++ /usr/bin/g++ && \
ln -sf /usr/bin/gcc10-ar /usr/bin/ar && \ ln -sf /usr/bin/gcc10-ar /usr/bin/ar && \
yum clean all yum clean all
# Install libraries # Install Xvfb (and GLX module) for headless UI testing
RUN yum install -y fontconfig fontconfig-devel mesa-libGLU-devel libXrandr-devel dbus-devel && \ RUN yum install -y xorg-x11-server-Xvfb xorg-x11-server-Xorg && \
yum clean all
# Install libraries for native builds
RUN yum install -y \
fontconfig fontconfig-devel \
freetype freetype-devel \
mesa-libGL mesa-libGL-devel \
mesa-libEGL mesa-libEGL-devel \
mesa-libGLU mesa-libGLU-devel \
mesa-libgbm mesa-libgbm-devel \
mesa-dri-drivers \
libdrm libdrm-devel \
libX11 libX11-devel \
libXrandr libXrandr-devel \
libXext libXext-devel \
libXrender libXrender-devel \
libXfixes libXfixes-devel \
libXdamage libXdamage-devel \
libXtst libXtst-devel \
libglvnd libglvnd-devel \
libglvnd-glx libglvnd-egl \
dbus-devel dbus-libs && \
yum clean all yum clean all
# Install Java (architecture-specific) # Install Java (architecture-specific)
...@@ -34,12 +56,38 @@ RUN if [ "$TARGETARCH" = "arm64" ]; then \ ...@@ -34,12 +56,38 @@ RUN if [ "$TARGETARCH" = "arm64" ]; then \
find $JAVA_BASE -type d -maxdepth 1 -name "$JAVA_PATTERN" -exec mv {} $JAVA_HOME \; && \ find $JAVA_BASE -type d -maxdepth 1 -name "$JAVA_PATTERN" -exec mv {} $JAVA_HOME \; && \
rm $JAVA_ARCHIVE rm $JAVA_ARCHIVE
# Install Android SDK
ENV ANDROID_SDK_ROOT=/android/sdk
ENV CMD_TOOLS_VERSION=13114758
ENV CMD_TOOLS_ROOT=$ANDROID_SDK_ROOT/cmdline-tools/$CMD_TOOLS_VERSION
ENV SDK_MANAGER=$CMD_TOOLS_ROOT/bin/sdkmanager
RUN mkdir -p $CMD_TOOLS_ROOT && \
export CMD_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-${CMD_TOOLS_VERSION}_latest.zip" && \
wget $CMD_TOOLS_URL -O /tmp/cmd-tools.zip && \
unzip /tmp/cmd-tools.zip -d /tmp/cmd-tools && \
rm /tmp/cmd-tools.zip && \
mv /tmp/cmd-tools/cmdline-tools/* $CMD_TOOLS_ROOT/ && \
rm -rf /tmp/cmd-tools
ENV ANDROID_PLATFORM=android-33
RUN yes | $SDK_MANAGER --licenses && \
$SDK_MANAGER "platforms;$ANDROID_PLATFORM" && \
cd $ANDROID_SDK_ROOT/platforms/$ANDROID_PLATFORM && \
ls -1 | grep -v android.jar | xargs rm -rf
ENV NDK_VERSION=29.0.14206865
RUN $SDK_MANAGER "ndk;$NDK_VERSION" && \
cd $ANDROID_SDK_ROOT/ndk/$NDK_VERSION && \
ls -1 | grep -v toolchains | xargs rm -rf
# Install chromium tools # Install chromium tools
ENV DEPOT_TOOLS=/usr/depot_tools ENV DEPOT_TOOLS=/usr/depot_tools
ENV PATH=$DEPOT_TOOLS:$PATH ENV PATH=$DEPOT_TOOLS:$PATH
RUN git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git' $DEPOT_TOOLS RUN git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git' $DEPOT_TOOLS
# Install cross-compilation toolchain for ARM64 # Install cross-compilation toolchain for ARM64
# This cross-compilation setup is required because Kotlin/Native doesn't support
# Linux ARM64 as a HOST platform (only as a target). When cross-compiling from x64 to ARM64,
# Kotlin/Native's linker needs ARM64 versions of system libraries.
# See: https://youtrack.jetbrains.com/issue/KT-36871
ENV ARM_TOOLCHAIN_VERSION=10.3-2021.07 ENV ARM_TOOLCHAIN_VERSION=10.3-2021.07
ENV ARM_TOOLCHAIN_NAME=gcc-arm-${ARM_TOOLCHAIN_VERSION}-x86_64-aarch64-none-linux-gnu ENV ARM_TOOLCHAIN_NAME=gcc-arm-${ARM_TOOLCHAIN_VERSION}-x86_64-aarch64-none-linux-gnu
ENV ARM_TOOLCHAIN_PATH=/opt/arm-gnu-toolchain ENV ARM_TOOLCHAIN_PATH=/opt/arm-gnu-toolchain
...@@ -55,13 +103,12 @@ RUN if [ "$TARGETARCH" = "amd64" ]; then \ ...@@ -55,13 +103,12 @@ RUN if [ "$TARGETARCH" = "amd64" ]; then \
fi fi
# Copy development headers to ARM64 sysroot # Copy development headers to ARM64 sysroot
ENV ARM_SYSROOT_HEADERS="fontconfig freetype2 GL X11 KHR"
RUN if [ "$TARGETARCH" = "amd64" ]; then \ RUN if [ "$TARGETARCH" = "amd64" ]; then \
mkdir -p $ARM_TOOLCHAIN_SYSROOT/usr/include && \ mkdir -p $ARM_TOOLCHAIN_SYSROOT/usr/include && \
cp -r /usr/include/fontconfig $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \ for dir in $ARM_SYSROOT_HEADERS; do \
cp -r /usr/include/freetype2 $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \ cp -r /usr/include/$dir $ARM_TOOLCHAIN_SYSROOT/usr/include/ || exit 1; \
cp -r /usr/include/GL $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \ done; \
cp -r /usr/include/X11 $ARM_TOOLCHAIN_SYSROOT/usr/include/ && \
cp -r /usr/include/KHR $ARM_TOOLCHAIN_SYSROOT/usr/include/; \
fi fi
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment