Skip to content

correct arm64

correct arm64 #70

name: Test-OpenCvSharp
on:
push:
branches: [ main, feature/docker ]
paths: [ '.github/workflows/test-opencvsharp.yml' ]
workflow_dispatch:
jobs:
test:
name: Fast Test
runs-on: ${{ matrix.runs-on }}
defaults:
run:
shell: bash
strategy:
matrix:
include:
- { os: linux, arch: x64, runs-on: ubuntu-22.04 }
- { os: ubuntu.24.04, arch: x64, runs-on: ubuntu-24.04 }
- { os: linux, arch: arm64, runs-on: ubuntu-22.04-arm }
- { os: ubuntu.24.04, arch: arm64, runs-on: ubuntu-24.04-arm }
- { os: win, arch: x64, runs-on: windows-2022 }
- { os: win, arch: x86, runs-on: windows-2022 }
- { os: win11, arch: x64, runs-on: windows-2025 }
- { os: win, arch: arm64, runs-on: windows-11-arm }
- { os: osx, arch: x64, runs-on: macos-13 }
- { os: osx, arch: arm64, runs-on: macos-14 }
- { os: osx.15, arch: arm64, runs-on: macos-15 }
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:7 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:7 }
- { os: rhel.8, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:8 }
- { os: rhel.8, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:8 }
- { os: rhel.9, arch: x64, runs-on: ubuntu-22.04, image: oraclelinux:9 }
- { os: rhel.9, arch: arm64, runs-on: ubuntu-22.04-arm, image: oraclelinux:9 }
- { os: android, arch: arm64, runs-on: ubuntu-24.04 }
- { os: android, arch: x64, runs-on: ubuntu-24.04 }
steps:
- name: Download OpenCvSharp Artifacts
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "Fetching lastest run of opencvsharp.yml on branch ${{ github.ref_name }}"
RUN_ID=$(gh run list -R ${{ github.repository }} --workflow=opencvsharp.yml --branch=${{ github.ref_name }} --status=success --limit=1 --json databaseId | jq -r '.[0].databaseId')
echo "Latest opencvsharp run ID: $RUN_ID"
echo "Downloading artifact 'opencvsharp-${{ matrix.os }}-${{ matrix.arch }}' from run ${RUN_ID}"
gh run download -R ${{ github.repository }} $RUN_ID --name opencvsharp-${{ matrix.os }}-${{ matrix.arch }} --dir opencvsharp
echo "::group::OpenCvSharp Artifacts"
ls -lR opencvsharp
echo "::endgroup::"
- name: Create test.c
run: |
mkdir -p test
cat > test/test.c <<'EOF'
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
/* ==== 简易类型 / 宏定义 ==== */
typedef long long uint64; /* 对应 C# 的 UInt64 */
typedef int ExceptionStatus; /* OpenCvSharpExtern 约定: 0 = OK */
typedef struct { double val[4]; } MyCvScalar;
typedef struct cv_Mat cv_Mat; /* 不需要知道内部实现 */
/* OpenCV 常量(直接抄一份足够用即可) */
#define CV_8UC3 16 /* 8-bit unsigned, 3 channels */
#define IMWRITE_JPEG_QUALITY 1
/* ==== C API 声明 ==== */
/* core */
extern uint64 core_Mat_sizeof(void);
extern ExceptionStatus core_Mat_new3(int rows,int cols,int type, MyCvScalar scalar, cv_Mat **returnValue);
extern ExceptionStatus core_Mat_delete(cv_Mat *self);
/* imgcodecs */
extern ExceptionStatus imgcodecs_imwrite(const char *filename, cv_Mat *img, int *params,int paramsLength,int *returnValue);
extern ExceptionStatus imgcodecs_imread (const char *filename,int flags, cv_Mat **returnValue);
/* ==== 帮助函数:检查返回值 ==== */
static void CHECK_OK(ExceptionStatus st, const char *msg)
{
if(st != 0) { fprintf(stderr,"%s failed: %d\n", msg, st); exit(st); }
}
static void CHECK_BOOL(int ok, const char *msg)
{
if(!ok) { fprintf(stderr,"%s returned false\n", msg); exit(1); }
}
int main(void)
{
printf("sizeof(Mat) reported by native = %llu\n",
(unsigned long long)core_Mat_sizeof());
/* 1. 先创建一张 256x256、彩色渐变图像 ----------------------------- */
cv_Mat *img = NULL;
MyCvScalar black = {0};
CHECK_OK(core_Mat_new3(256, 256, CV_8UC3, black, &img), "core_Mat_new3");
/* 通过指针手动绘制一个 BGR 渐变: B = x, G = y, R = 128 */
unsigned char *data = NULL;
extern ExceptionStatus core_Mat_data(cv_Mat *self, unsigned char **returnValue);
CHECK_OK(core_Mat_data(img, &data), "core_Mat_data");
for(int y = 0; y < 256; ++y)
{
for(int x = 0; x < 256; ++x)
{
unsigned char *pix = data + (y*256 + x)*3;
pix[0] = (unsigned char)x; /* Blue 渐变 */
pix[1] = (unsigned char)y; /* Green 渐变 */
pix[2] = 128; /* Red 固定 */
}
}
/* 2. 保存为 PNG -------------------------------------------------- */
int ok = 0;
CHECK_OK(imgcodecs_imwrite("test.png", img, NULL, 0, &ok), "imwrite PNG");
CHECK_BOOL(ok, "imwrite PNG");
/* 3. 读取刚写出的 PNG ------------------------------------------- */
cv_Mat *img2 = NULL;
CHECK_OK(imgcodecs_imread("test.png", /*flags=*/1, &img2), "imread PNG");
/* 不需要检查 NULL, 因为 C API 出错会抛异常,已在上一步捕获 */
/* 4. 以 JPEG 质量 90 再保存为 JPG -------------------------------- */
int jpegParams[2] = { IMWRITE_JPEG_QUALITY, 90 };
CHECK_OK(imgcodecs_imwrite("test.jpg", img2,
jpegParams, 2, &ok), "imwrite JPG");
CHECK_BOOL(ok, "imwrite JPG");
printf("PNG and JPG written successfully.\n");
/* 5. 释放资源 ---------------------------------------------------- */
core_Mat_delete(img);
core_Mat_delete(img2);
return 0;
}
EOF
cat test/test.c
- name: Setup MSVC(Windows only)
uses: ilammy/msvc-dev-cmd@v1
if: startsWith(matrix.os, 'win')
with:
arch: ${{ matrix.arch }}
- name: Pull Docker Image
if: matrix.image != ''
run: |
docker pull ${{ matrix.image }}
- name: Start Docker Container
if: matrix.image != ''
run: |
docker run -d --name builder -v "$PWD":${{ github.workspace }} -w ${{ github.workspace }} ${{ matrix.image }} tail -f /dev/null
- name: Install Dependencies in Docker Container
if: matrix.image != ''
run: |
if [[ "${{ matrix.os }}" == "centos.7" || "${{ matrix.os }}" =~ "rhel." ]]; then
script=$(
cat <<'EOS'
set -eux
yum install -y gcc
EOS
)
fi
echo "Executing script in Docker container: $script"
docker exec builder bash -c "$script"
- name: Build Test
run: |
script=$(
cat <<'EOS'
set -eux
cd test
if [[ "${{ runner.os }}" == Windows ]]; then
export MSYS2_ARG_CONV_EXCL="*"
cl /nologo /EHsc test.c ../opencvsharp/lib/OpenCvSharpExtern.lib /link /OUT:test.exe
elif [[ "${{ matrix.os }}" =~ ^osx ]]; then
gcc test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,@loader_path -o test.exe
elif [[ "${{ matrix.os }}" == "centos.7" ]]; then
gcc -std=c99 test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,'$ORIGIN' -o test.exe
elif [[ "${{ matrix.os }}" == "android" ]]; then
API=24
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
CLANG=aarch64-linux-android${API}-clang
elif [[ "${{ matrix.arch }}" == "x64" ]]; then
CLANG=x86_64-linux-android${API}-clang
else
echo "Unsupported architecture for Android: ${{ matrix.arch }}"
exit 1
fi
$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/$CLANG test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,'$ORIGIN' -o test.exe
else
gcc test.c -L../opencvsharp/lib -lOpenCvSharpExtern -Wl,-rpath,'$ORIGIN' -o test.exe
fi
ls -lR
EOS
)
if [[ "${{ matrix.image }}" == "" ]]; then
bash -c "$script"
else
docker exec builder bash -c "$script"
fi
- name: Copy opencvsharp/lib to test
run: |
cp -r opencvsharp/lib/* test
- name: Run Test
if: matrix.os != 'android'
run: |
if [[ "${{ matrix.image }}" != "" ]]; then
docker run -d --name runner -v "$PWD":${{ github.workspace }} -w ${{ github.workspace }} ${{ matrix.image }} bash -c "cd test && ./test.exe"
else
cd test && ./test.exe
fi
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: test-${{ matrix.os }}-${{ matrix.arch }}
path: test
android-x64-test:
name: Android x64 Test
runs-on: ubuntu-24.04
needs: test
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: test-android-x64
path: test
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run Test on Android
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 28
arch: x86_64
target: google_apis
script: |
adb push -a test /data/local/tmp/
adb shell 'cd /data/local/tmp/test && ./test.exe'
more-docker-test:
name: More Docker Test
runs-on: ${{ matrix.runs-on }}
defaults:
run:
shell: bash
needs: test
strategy:
matrix:
include:
- { os: centos.7, arch: x64, runs-on: ubuntu-22.04, image: centos:7 }
- { os: centos.7, arch: arm64, runs-on: ubuntu-22.04-arm, image: centos:7 }
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: test-${{ matrix.os }}-${{ matrix.arch }}
path: test
- name: Start Docker Container
run: |
docker run -d --name builder -v "$PWD":${{ github.workspace }} -w ${{ github.workspace }} ${{ matrix.image }} tail -f /dev/null
- name: Run Tests
run: |
docker exec builder bash -c "cd test && ./test.exe"