OpenCV v4系をARM64向けにVisual Studioでビルドして、知識0だがビルド成功して動作はした、という手順を紹介します

# 概要

ほとんど知識の無い人間が急にOpenCV v4系をARM64向けにビルドする必要に迫られ、VisualStudioで試行錯誤して上手く行った手順を紹介します。

そういう位置づけなので、どのやり方が推奨であるとか、ケースごとに妥当なオプション指定だとか、そういった情報は有りません。私の用途ではビルドしたDLLを使ったら欲しい機能がちゃんと動きましたが、全ての機能が動くかどうかも分かりません。とにかく上手く行った手順を一つ紹介する、という内容です。

# 最初に結論まとめ

1. VisualStudio 2022の構成で、ARM64ビルドに必要な物を入れる
1. OpenCVのソースコードのフォルダにサブフォルダを作り、そのサブフォルダをカレントにしてコンソールを開く
1. cmakeを次のオプションで実行して、ビルド用のソースコード構成を生成する
    1. `cmake -B . -S .. -G "Visual Studio 17 2022" -A ARM64 -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DBUILD_opencv_world=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_PROCESSOR=ARM64 -DCMAKE_SYSTEM_VERSION=10.0.22621.0 -DCPU_BASELINE=NEON -DENABLE_FP16=OFF -DCMAKE_CXX_FLAGS="/D_ARM64_DISTINCT_NEON_TYPES"`
1. cmakeで次のコマンドを順に実行し、ビルドする
    1. `cmake --build . --config Release`
    1. `cmake --build . --target INSTALL --config Release`
1. Installフォルダの中に、dllとlibファイルのできあがり！


# 説明

まず最初に、本件では次のWebサイトの手順をベースにさせてもらって、そこからビルドするために必要なオプションを試行錯誤するという形で解決しました。とても参考になりました、ありがとうございます。

https://learn.arm.com/learning-paths/laptops-and-desktops/win-opencv/2-1-build-msvc/

概要に書いた通り、上手く行った手順を一つ紹介します。この記事を読んでいる人の用途に合うかどうかはともかく、この手順通りに進めればビルドは成功するはずです。

## OpenCV v4系のソースコードを入手

ソースコードは単純にGitHubから入手します。今回は都合上Ver.4.10.0が欲しかったため、このタグを使いました。

https://github.com/opencv/opencv/releases/tag/4.10.0

## Visual StudioでARMビルドに必要な物をインストール

VisualStudioの構成として、インストールされていなければ次のものをインストールします。VisualStudioインストーラの操作はこの記事では省略します。

1. MSVC v143- VS 2022 C++ ARM64/ARM64EC ビルドツール(最新)
1. MSVC v143 - VS 2022 C++ ARM64/ARM64EC Spectre 軽減ライブラリ(最新)

.vsconfigなら次のものです。

1. Microsoft.VisualStudio.Component.VC.Tools.ARM64
1. Microsoft.VisualStudio.Component.VC.Tools.ARM64EC
1. Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre
1. Microsoft.VisualStudio.Component.VC.Runtimes.ARM64EC.Spectre

## cmakeでビルド用ソースコード構成を生成

cmakeにオプションを指定して、VisualStudioビルド用のソースコードを作成してもらいます。ここで指定するオプションがこの話の要です。

指定して成功したのは、次のオプションです。

`cmake -B . -S .. -G "Visual Studio 17 2022" -A ARM64 -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DBUILD_opencv_world=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_PROCESSOR=ARM64 -DCMAKE_SYSTEM_VERSION=10.0.22621.0 -DCPU_BASELINE=NEON -DENABLE_FP16=OFF -DCMAKE_CXX_FLAGS="/D_ARM64_DISTINCT_NEON_TYPES"`

`-G "Visual Studio 17 2022"`や`-A ARM64`のように見てすぐ意図が分かりそうなオプションは省略して、それ以外の主に`-D`で指定するオプションについて説明します。

### BUILD_SHARED_LIBS=ON

動的参照用のdllとlibをビルドするか、静的参照用のlibをビルドするかを選択します。共有DLLにするかどうかというオプションなので、ONにするとdll,libになり、OFFにするとlibになります。

### BUILD_opencv_world=ON

OpenCV のすべてのモジュールを一つのライブラリ（opencv_world）に統合してビルドします。デフォルトでONのようですが、一応指定しています。

### CMAKE_INSTALL_PREFIX=install

インストール先のフォルダ名です。一連のコマンドを実行した後、この名前のフォルダが実行フォルダのサブフォルダに作成され、そこに成果物が出力されます。

### Windows SDKの問題を解決するために行った設定

VisualStudioでビルドすると、uint16x4_tとuint64x1_tの型変換に関するエラーが大量に発生します。フォーラムなどの議論を見ると、最新のWindows SDKのバグらしいという情報があります。 [参考](https://github.com/microsoft/vcpkg/issues/44310)

#### CMAKE_SYSTEM_VERSION=10.0.22621.0

最新のWindows SDKのバグらしいとのことで、以前のWindows SDKを使うようにバージョンを指定しています。これで問題は解消しました。

### fp16の問題を解決するために行った設定

VisualStudioでビルドすると、__fp16の型定義が無いというエラーが大量に発生します。フォーラムなどの議論を見ると、どうやらVisualStudioのARM64コンパイラはFP16にちゃんと対応できていないらしく、FP16を無効にする方向で設定を変更していく必要がありそうです。

そのため、以下の設定を行いました。理解した範囲で解説を付けますが、正しく理解しているかどうかは分かりません。冒頭記載の通り、とにかく上手く行った設定を紹介するという位置づけです。

#### CPU_BASELINE=NEON

NEON命令を使うようにすることで、FP16関連の処理を不要にする、ようです。

#### ENABLE_FP16=OFF

処理としてFP16を使用しないようにしている、ようです。

#### CMAKE_CXX_FLAGS="/D_ARM64_DISTINCT_NEON_TYPES"

型を明確にすることで、FP16を使わない型でビルドを通せるようにする、ようです。コンパイルエラーを直接解決できたのはこの設定でした。

## ビルド

生成されたコードに対して、次のコマンドを順に実行し、ビルドします。

```
cmake --build . --config Release
cmake --build . --target INSTALL --config Release
```

2つ目だけでも良かった気もしますが、参考にしたサイトがこの方法を使っていたので、念のため2つのコマンドを順に実行しました。

## 成果物を取得

ビルドに成功したので、次のファイルを取り出して使います。

1. `Install\ARM64\vc17\bin\opencv_world4100.dll`
1. `Install\ARM64\vc17\lib\opencv_world4100.lib`

このファイルを使ったところ、無事ARM64でも動作しています。できました！

# まとめ

理解は浅いかもしれませんが、なんとかOpenCV v4系をARM64向けにVisual Studioでビルドすることが出来ました。色々とWeb上の情報を当たりましたが、これと全く同じ内容をまとめてくれているサイトは無く、断片的な情報を集めて何とかする羽目になったので、記事にまとめました。同じ目に遭っている人の助けになれば嬉しいです。