Skip to content

Commit

Permalink
i#2154 Android64: Simplify build and add GitHub CI workflow (#7248)
Browse files Browse the repository at this point in the history
Adds a job to the GitHub CI that builds DynamoRIO for AArch64 Android.

This patch also simplifies the 64-bit Android CMake file to remove the
need for the user to build `zlib`, instead allowing CMake to find the
`zlib` included in the NDK. Also, the user now only needs to pass the
root folder of the NDK, and a bug relating to the default Android API
level has been fixed.

The Android CMake files have also been renamed to better reflect their
differences - i.e. they are now named `gcc` & `llvm` rather than
`android` and `android-aarch64` (the latter is arch-independent).

Issue: #2154
  • Loading branch information
felixc-arm authored Feb 6, 2025
1 parent 8fb15c2 commit 93bc28e
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 35 deletions.
70 changes: 68 additions & 2 deletions .github/workflows/ci-aarchxx-cross.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ jobs:

- run: git fetch --no-tags --depth=1 origin master

# Fetch and install Android NDK for Andoid cross-compile build.
# Fetch and install Android NDK for Android cross-compile build.
- name: Create Build Environment
run: |
sudo apt-get update
Expand Down Expand Up @@ -241,7 +241,7 @@ jobs:
DYNAMORIO_ANDROID_TOOLCHAIN: /tmp/android-gcc-arm-ndk-10e
CI_TRIGGER: ${{ github.event_name }}
CI_BRANCH: ${{ github.ref }}
run: ./suite/runsuite_wrapper.pl automated_ci
run: ./suite/runsuite_wrapper.pl automated_ci 32_only

- name: Send failure mail to dynamorio-devs
if: failure() && github.ref == 'refs/heads/master'
Expand All @@ -267,6 +267,72 @@ jobs:
to: [email protected]
from: Github Action CI

# Android AArch64 cross-compile with LLVM, no tests:
android-aarch64-cross-compile:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v2
with:
submodules: true

# Cancel any prior runs for a PR (but do not cancel master branch runs).
- uses: n1hility/cancel-previous-runs@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
if: ${{ github.event_name == 'pull_request' }}

- run: git fetch --no-tags --depth=1 origin master

# Fetch the Android NDK for Android cross-compile build.
- name: Create Build Environment
run: |
sudo apt-get update
sudo apt-get -y install doxygen vera++
cd /tmp
wget https://dl.google.com/android/repository/android-ndk-r27c-linux.zip
unzip -q android-ndk-r27c-linux.zip
export ANDROID_NDK_ROOT=/tmp/android-ndk-r27c
- name: Setup cmake
uses: lukka/get-cmake@latest
with:
cmakeVersion: '3.26.4'

- name: Run Suite
working-directory: ${{ github.workspace }}
env:
DYNAMORIO_CROSS_ANDROID_ONLY: yes
DYNAMORIO_ANDROID_NDK: /tmp/android-ndk-r27c
DYNAMORIO_ANDROID_API_LEVEL: 35
CI_TRIGGER: ${{ github.event_name }}
CI_BRANCH: ${{ github.ref }}
run: ./suite/runsuite_wrapper.pl automated_ci 64_only

- name: Send failure mail to dynamorio-devs
if: failure() && github.ref == 'refs/heads/master'
uses: dawidd6/action-send-mail@v2
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{secrets.DYNAMORIO_NOTIFICATION_EMAIL_USERNAME}}
password: ${{secrets.DYNAMORIO_NOTIFICATION_EMAIL_PASSWORD}}
subject: |
[${{github.repository}}] ${{github.workflow}} FAILED
on ${{github.event_name}} at ${{github.ref}}
body: |
Github Actions CI workflow run FAILED!
Workflow: ${{github.workflow}}/android-aarch64-cross-compile
Repository: ${{github.repository}}
Branch ref: ${{github.ref}}
SHA: ${{github.sha}}
Triggering actor: ${{github.actor}}
Triggering event: ${{github.event_name}}
Run Id: ${{github.run_id}}
See more details on github.com/DynamoRIO/dynamorio/actions/runs/${{github.run_id}}
to: [email protected]
from: Github Action CI

# AArch64 drdecode and drmemtrace on x86:
a64-on-x86:
runs-on: ubuntu-20.04
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
# --toolchain=arm-linux-androideabi-4.9 --platform=android-21 \
# --install-dir=/TOOLCHAIN/INSTALL/PATH
# - cross-compiling config with ANDROID_TOOLCHAIN
# $cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-android.cmake \
# $cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-android-gcc.cmake \
# -DANDROID_TOOLCHAIN=/TOOLCHAIN/INSTALL/PATH ../dynamorio

# Target system
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,12 @@
# DAMAGE.

# For cross compiling for 64-bit arm Android using the Android LLVM toolchain:
# - Download toolchain, and install the standalone toolchain:
# - Download the toolchain:
# https://developer.android.com/ndk/downloads/revision_history
# $ /PATH/TO/ANDROID_NDK/toolchains/llvm/prebuilt/<build>/bin
# - Build ZLIB with the Android toolchain (included in third_party/zlib):
# $ AR=/TOOLCHAIN/INSTALL/PATH/llvm-ar \
# CC=/TOOLCHAIN/INSTALL/PATH/aarch64-linux-android<chosen-version>-clang \
# CFLAGS="-fPIC -O" ./configure --static && make install prefix=$HOME/zlib
# - Cross-compiling config with ANDROID_TOOLCHAIN:
# $ cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-android-aarch64.cmake \
# -DANDROID_TOOLCHAIN=/TOOLCHAIN/INSTALL/PATH -DTOOLCHAIN_VERSION=<chosen-version> \
# -DZLIB_LIBRARY=$HOME/zlib/lib/libz.a -DZLIB_INCLUDE_DIR=$HOME/zlib/include \
# - Cross-compiling config with ANDROID_NDK:
# $ cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-android-llvm.cmake \
# -DANDROID_NDK=/PATH/TO/android-ndk-<version> \
# -DANDROID_API_LEVEL=<chosen-api-level> \
# ../dynamorio

# Target system.
Expand All @@ -55,43 +50,40 @@ if (TARGET_ABI MATCHES "^aarch64")
endif ()

# Specify the cross compiler.
if (NOT DEFINED ANDROID_TOOLCHAIN)
if (NOT DEFINED ANDROID_NDK)
set(toolchain_bin_path "")
else ()
set(toolchain_bin_path "${ANDROID_TOOLCHAIN}/")
set(toolchain_bin_path
"${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/")
set(toolchain_sysroot_path
"${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot")
endif ()

if (NOT DEFINED TOOLCHAIN_VERSION)
set(toolchain_version "30")
if (NOT DEFINED ANDROID_API_LEVEL)
set(api_level "30")
else ()
set(toolchain_version "${TOOLCHAIN_VERSION}")
set(api_level "${ANDROID_API_LEVEL}")
endif ()

SET(CMAKE_C_COMPILER ${toolchain_bin_path}${TARGET_ABI}${TOOLCHAIN_VERSION}-clang
SET(CMAKE_C_COMPILER ${toolchain_bin_path}${TARGET_ABI}${api_level}-clang
CACHE FILEPATH "cmake_c_compiler")
SET(CMAKE_CXX_COMPILER ${toolchain_bin_path}${TARGET_ABI}${TOOLCHAIN_VERSION}-clang++
SET(CMAKE_CXX_COMPILER ${toolchain_bin_path}${TARGET_ABI}${api_level}-clang++
CACHE FILEPATH "cmake_cxx_compiler")
SET(CMAKE_LINKER ${toolchain_bin_path}ld.lld
CACHE FILEPATH "cmake_linker")
SET(CMAKE_ASM_COMPILER ${toolchain_bin_path}${TARGET_ABI}${TOOLCHAIN_VERSION}-clang
SET(CMAKE_ASM_COMPILER ${toolchain_bin_path}${TARGET_ABI}${api_level}-clang
CACHE FILEPATH "cmake_asm_compiler")
SET(CMAKE_OBJCOPY ${toolchain_bin_path}llvm-objcopy
CACHE FILEPATH "cmake_objcopy")
SET(CMAKE_STRIP ${toolchain_bin_path}llvm-strip
CACHE FILEPATH "cmake_strip")
SET(CMAKE_CPP ${toolchain_bin_path}${TARGET_ABI}${TOOLCHAIN_VERSION}-clang
SET(CMAKE_CPP ${toolchain_bin_path}${TARGET_ABI}${api_level}-clang
CACHE FILEPATH "cmake_cpp")

# Specify sysroot.
if (NOT DEFINED ANDROID_SYSROOT)
# Assuming default android standalone toolchain directory layout.
find_path(compiler_path ${CMAKE_C_COMPILER})
set(ANDROID_SYSROOT "${compiler_path}/../sysroot")
endif ()

SET(CMAKE_FIND_ROOT_PATH ${ANDROID_SYSROOT})
SET(CMAKE_FIND_ROOT_PATH ${toolchain_sysroot_path})
# Search for programs in the build host directories.
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories.
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_LIBRARY_ARCHITECTURE ${TARGET_ABI})
36 changes: 31 additions & 5 deletions suite/runsuite.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -533,28 +533,54 @@ if (UNIX AND ARCH_IS_X86)
set(android_extra_rel "${android_extra_dbg}
ANDROID_TOOLCHAIN:PATH=$ENV{DYNAMORIO_ANDROID_TOOLCHAIN}")
endif()
if (DEFINED ENV{DYNAMORIO_ANDROID_NDK})
set(android_extra_dbg "${android_extra_dbg}
ANDROID_NDK:PATH=$ENV{DYNAMORIO_ANDROID_NDK}")
set(android_extra_rel "${android_extra_dbg}
ANDROID_NDK:PATH=$ENV{DYNAMORIO_ANDROID_NDK}")
endif()
if (DEFINED ENV{DYNAMORIO_ANDROID_API_LEVEL})
set(android_extra_dbg "${android_extra_dbg}
ANDROID_API_LEVEL:STRING=$ENV{DYNAMORIO_ANDROID_API_LEVEL}")
set(android_extra_rel "${android_extra_dbg}
ANDROID_API_LEVEL:STRING=$ENV{DYNAMORIO_ANDROID_API_LEVEL}")
endif()

# For CI cross_android_only builds, we want to fail on config failures.
# For user suite runs, we want to just skip if there's no cross setup.
if (NOT cross_android_only)
set(optional_cross_compile ON)
endif ()

testbuild_ex("android-debug-internal-32" OFF "
testbuild_ex("arm-android-debug-internal" OFF "
DEBUG:BOOL=ON
INTERNAL:BOOL=ON
CMAKE_TOOLCHAIN_FILE:PATH=${CTEST_SOURCE_DIRECTORY}/make/toolchain-android.cmake
CMAKE_TOOLCHAIN_FILE:PATH=${CTEST_SOURCE_DIRECTORY}/make/toolchain-android-gcc.cmake
${build_tests}
${android_extra_dbg}
" OFF ${arg_package} "")
testbuild_ex("android-release-external-32" OFF "
testbuild_ex("arm-android-release-external" OFF "
DEBUG:BOOL=OFF
INTERNAL:BOOL=OFF
CMAKE_TOOLCHAIN_FILE:PATH=${CTEST_SOURCE_DIRECTORY}/make/toolchain-android.cmake
CMAKE_TOOLCHAIN_FILE:PATH=${CTEST_SOURCE_DIRECTORY}/make/toolchain-android-gcc.cmake
${android_extra_rel}
" OFF ${arg_package} "")

testbuild_ex("aarch64-android-debug-internal" ON "
DEBUG:BOOL=ON
INTERNAL:BOOL=ON
CMAKE_TOOLCHAIN_FILE:PATH=${CTEST_SOURCE_DIRECTORY}/make/toolchain-android-llvm.cmake
${build_tests}
${android_extra_dbg}
" OFF ${arg_package} "")
testbuild_ex("aarch64-android-release-external" ON "
DEBUG:BOOL=OFF
INTERNAL:BOOL=OFF
CMAKE_TOOLCHAIN_FILE:PATH=${CTEST_SOURCE_DIRECTORY}/make/toolchain-android-llvm.cmake
${android_extra_rel}
" OFF ${arg_package} "")
set(run_tests ${prev_run_tests})

set(run_tests ${prev_run_tests})
set(optional_cross_compile ${prev_optional_cross_compile})
set(ARCH_IS_X86 ON)
endif (UNIX AND ARCH_IS_X86)
Expand Down

0 comments on commit 93bc28e

Please sign in to comment.