diff --git a/conformance/android/build.gradle.kts b/conformance/android/build.gradle.kts new file mode 100644 index 00000000..019c29d2 --- /dev/null +++ b/conformance/android/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + id("com.android.application") +} + +repositories { + mavenCentral() + mavenLocal() + google() +} + +android { + namespace = "pbandk.conformance" + compileSdk = 36 + + defaultConfig { + minSdk = 21 + } +} + +dependencies { + implementation(project(":conformance:conformance-jvm")) +} + diff --git a/conformance/android/run.sh b/conformance/android/run.sh new file mode 100755 index 00000000..67e28469 --- /dev/null +++ b/conformance/android/run.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +exec adb shell "CLASSPATH=/data/local/tmp/conformance.apk app_process . pbandk.conformance.MainKt" \ No newline at end of file diff --git a/conformance/android/src/main/AndroidManifest.xml b/conformance/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..099dea46 --- /dev/null +++ b/conformance/android/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/conformance/lib/build.gradle.kts b/conformance/lib/build.gradle.kts index e8373deb..3505ff46 100644 --- a/conformance/lib/build.gradle.kts +++ b/conformance/lib/build.gradle.kts @@ -29,6 +29,10 @@ kotlin { } else { macosX64() } + + androidNativeArm32() + androidNativeArm64() + // Uncomment to enable Windows // mingwX64("windows") diff --git a/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSink.kt b/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSink.kt index 914cffd3..de8a9be9 100644 --- a/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSink.kt +++ b/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSink.kt @@ -5,9 +5,12 @@ package pbandk.conformance.io +import kotlinx.cinterop.ByteVar import kotlinx.cinterop.CPointer import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.UnsafeNumber import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert import kotlinx.cinterop.usePinned import kotlinx.io.Buffer import kotlinx.io.IOException @@ -37,7 +40,7 @@ internal class StdIoSink(private val file: CPointer) : RawSink { val allContent = source.readByteArray(byteCount.toInt()) // Copy bytes from that segment into the file. val bytesWritten = allContent.usePinned { pinned -> - fwrite(pinned.addressOf(0), 1u, byteCount.toULong(), file).toLong() + variantFwrite(pinned.addressOf(0), byteCount.toUInt(), file).toLong() } if (bytesWritten < byteCount) { throw IOException(errno.toString()) @@ -57,4 +60,11 @@ internal class StdIoSink(private val file: CPointer) : RawSink { throw IOException(errno.toString()) } } + + @OptIn(UnsafeNumber::class) + private fun variantFwrite( + source: CPointer, + byteCount: UInt, + file: CPointer + ): UInt = fwrite(source, 1u, byteCount.convert(), file).convert() } \ No newline at end of file diff --git a/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSource.kt b/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSource.kt index cc341e1b..5e53aacb 100644 --- a/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSource.kt +++ b/conformance/lib/src/nativeMain/kotlin/pbandk/conformance/io/StdIoSource.kt @@ -5,9 +5,12 @@ package pbandk.conformance.io +import kotlinx.cinterop.ByteVar import kotlinx.cinterop.CPointer import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.UnsafeNumber import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert import kotlinx.cinterop.usePinned import kotlinx.io.Buffer import kotlinx.io.IOException @@ -34,7 +37,7 @@ internal class StdIoSource(private val file: CPointer) : RawSource { // Copy bytes from the file to the segment. val fd = fileno(file) val bytesRead = temporaryBuffer.usePinned { pinned -> - read(fd, pinned.addressOf(0), byteCount.toULong()) + variantRead(pinned.addressOf(0), byteCount.toUInt(), fd).toLong() } sink.write(temporaryBuffer, startIndex = 0, endIndex = bytesRead.toInt()) @@ -52,4 +55,11 @@ internal class StdIoSource(private val file: CPointer) : RawSource { closed = true fclose(file) } + + @OptIn(UnsafeNumber::class) + internal fun variantRead( + target: CPointer, + byteCount: UInt, + fd: Int + ): UInt = read(fd, target, byteCount.convert()).convert() } \ No newline at end of file diff --git a/conformance/native/build.gradle.kts b/conformance/native/build.gradle.kts index 213cec3a..9776df64 100644 --- a/conformance/native/build.gradle.kts +++ b/conformance/native/build.gradle.kts @@ -13,6 +13,9 @@ kotlin { macosX64() } + androidNativeArm32() + androidNativeArm64() + targets.withType { binaries { executable("conformance") diff --git a/conformance/native/run_android.sh b/conformance/native/run_android.sh new file mode 100755 index 00000000..5a5b4559 --- /dev/null +++ b/conformance/native/run_android.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +exec adb shell "/data/local/tmp/conformance.kexe" \ No newline at end of file diff --git a/conformance/test-conformance.sh b/conformance/test-conformance.sh index 354aba5f..0b78a669 100755 --- a/conformance/test-conformance.sh +++ b/conformance/test-conformance.sh @@ -31,3 +31,25 @@ if [ "$1" = "macos" ]; then exit 1 fi fi +if [ "$1" = "androidNative" ]; then + DEVICE_EXECUTABLE="/data/local/tmp/conformance.kexe" + abi_list=$(adb shell getprop ro.product.cpu.abilist) + if [[ "$abi_list" == *"arm64-v8a"* ]]; then + adb push $DIR/native/build/bin/androidNativeArm64/conformanceReleaseExecutable/conformance.kexe $DEVICE_EXECUTABLE + adb shell chmod 777 $DEVICE_EXECUTABLE + $CONF_TEST_PATH --enforce_recommended --failure_list $DIR/native/failing_tests.txt $DIR/native/run_android.sh + adb shell rm $DEVICE_EXECUTABLE + fi + if [[ "$abi_list" == *"armeabi"* ]]; then + adb push $DIR/native/build/bin/androidNativeArm32/conformanceReleaseExecutable/conformance.kexe $DEVICE_EXECUTABLE + adb shell chmod 777 $DEVICE_EXECUTABLE + $CONF_TEST_PATH --enforce_recommended --failure_list $DIR/native/failing_tests.txt $DIR/native/run_android.sh + adb shell rm $DEVICE_EXECUTABLE + fi +fi +if [ "$1" = "androidJvm" ]; then + DEVICE_APK="/data/local/tmp/conformance.apk" + adb push $DIR/android/build/outputs/apk/release/conformance-android-release-unsigned.apk $DEVICE_APK + $CONF_TEST_PATH --enforce_recommended --failure_list $DIR/jvm/failing_tests.txt $DIR/android/run.sh + adb shell rm $DEVICE_APK +fi diff --git a/settings.gradle.kts b/settings.gradle.kts index 8f4542f5..787b2098 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -32,5 +32,7 @@ include(":conformance:lib") project(":conformance:lib").name = "conformance-lib" include(":conformance:jvm") project(":conformance:jvm").name = "conformance-jvm" +include(":conformance:android") +project(":conformance:android").name = "conformance-android" include(":conformance:native") project(":conformance:native").name = "conformance-native"