mlpackは,C++向けの強力な機械学習ライブラリです.
機械学習などで有効な様々なアルゴリズムを利用することができます.
私は,Windows上のMSVCを用いた環境でCMakeを利用することでmlpcakを導入しました.(なぜかGCCコンパイラを用いた環境ではうまくいきませんでした.)
以下のコードをコンパイルしようとしたときに,問題が発生しました.
何が起こったか
コンパイルを行おうとしたところ,以下のようなエラーが発生したのです.
[build] main.obj : error LNK2019: 未解決の外部シンボル wrapper2_sasum_ が関数 "double __cdecl arma::blas::asum<double>(unsigned __int64,double const *)" (??$asum@N@blas@arma@@YAN_KPEBN@Z) で参照されました [C:\Users\userName\source\repos\LernMlpack\build\main.vcxproj]
[build] main.obj : error LNK2019: 未解決の外部シンボル wrapper2_dasum_ が関数 "double __cdecl arma::blas::asum<double>(unsigned __int64,double const *)" (??$asum@N@blas@arma@@YAN_KPEBN@Z) で参照されました [C:\Users\userName\source\repos\LernMlpack\build\main.vcxproj]
[build] main.obj : error LNK2019: 未解決の外部シンボル wrapper2_snrm2_ が関数 "double __cdecl arma::blas::nrm2<double>(unsigned __int64,double const *)" (??$nrm2@N@blas@arma@@YAN_KPEBN@Z) で参照されました [C:\Users\userName\source\repos\LernMlpack\build\main.vcxproj]
[build] main.obj : error LNK2019: 未解決の外部シンボル wrapper2_dnrm2_ が関数 "double __cdecl arma::blas::nrm2<double>(unsigned __int64,double const *)" (??$nrm2@N@blas@arma@@YAN_KPEBN@Z) で参照されました [C:\Users\userName\source\repos\LernMlpack\build\main.vcxproj]
[build] main.obj : error LNK2019: 未解決の外部シンボル wrapper2_sgesdd_ が関数 "void __cdecl arma::lapack::gesdd<double>(char *,int *,int *,double *,int *,double *,double *,int *,double *,int *,double *,int *,int *,int *)" (??$gesdd@N@lapack@arma@@YAXPEADPEAH1PEAN1221212111@Z) で参照されました [C:\Users\userName\source\repos\LernMlpack\build\main.vcxproj]
[build] main.obj : error LNK2019: 未解決の外部シンボル wrapper2_dgesdd_ が関数 "void __cdecl arma::lapack::gesdd<double>(char *,int *,int *,double *,int *,double *,double *,int *,double *,int *,double *,int *,int *,int *)" (??$gesdd@N@lapack@arma@@YAXPEADPEAH1PEAN1221212111@Z) で参照されました [C:\Users\userName\source\repos\LernMlpack\build\main.vcxproj]
[build] C:\Users\userName\source\repos\LernMlpack\build\Debug\main.exe : fatal error LNK1120: 6 件の未解決の外部参照 [C:\Users\satou_2pdwzw9\source\repos\LernMlpack\build\main.vcxproj]
[proc] コマンド "C:\Program Files\CMake\bin\cmake.EXE" --build c:/Users/userName/source/repos/LernMlpack/build --config Debug --target ALL_BUILD -j 12 -- はコード 1 で終了しました
私の環境
CMakeLists.txt,vcpkg.jsonは,それぞれ以下のように設定していました.
cmake_minimum_required(VERSION 3.20)
project(MeanShiftTest LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(main main.cpp)
find_path(MLPACK_INCLUDE_DIRS "mlpack.hpp")
target_include_directories(main PRIVATE ${MLPACK_INCLUDE_DIRS})
{
"name": "meanshift-test",
"version-string": "0.1.0",
"dependencies": [
"mlpack"
]
}
解決策1
生成AIのGeminiに質問したところ,以下のように指摘されました.
- Armadilloがデフォルトで使用しようとするラッパー関数(
wrapper2_...)が見つからないのが原因 - Windows + vcpkg環境ではよく発生する
-
CMakeLists.txtを修正して、「Armadilloのラッパーを経由せずに、直接BLAS/LAPACK(OpenBLASなど)を呼ぶ」設定に変更するのが最も確実な修正方法
これに従って,vcpkg.jsonはそのままで、以下のようにCMakeLists.txtを修正したところ,うまくいきました.
cmake_minimum_required(VERSION 3.20)
project(MeanShiftTest LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(main main.cpp)
find_path(MLPACK_INCLUDE_DIRS "mlpack.hpp")
target_include_directories(main PRIVATE ${MLPACK_INCLUDE_DIRS})
# BLASとLAPACKを明示的に検索 (ここを追加)
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
# リンク設定
target_link_libraries(main PRIVATE
${BLAS_LIBRARIES} # ここを追加
${LAPACK_LIBRARIES} # ここを追加
)
# コンパイル定義の追加 (ここが最も重要)
# "Armadilloのラッパーを使わず、直接BLAS/LAPACKを呼べ" という指示
target_compile_definitions(main PRIVATE ARMA_DONT_USE_WRAPPER)
解決策2【追記】【より良い】
再び調べてみたところ、以下のような記事がヒットしました。
この記事の最後の方では、wrapを無効化することなしにコンパイルに成功していました。そこで、もう少し詳しく調べてみたところ、vcpkg.jsonはそのままに、`CMakeLists.txtを以下のように設定することでコンパイルに成功しました。
cmake_minimum_required(VERSION 3.20)
project(YourProject)
set(CMAKE_CXX_STANDARD 20)
find_path(MLPACK_INCLUDE_DIRS "mlpack.hpp")
find_package(Armadillo CONFIG REQUIRED)
add_executable(main main.cpp)
target_include_directories(main PRIVATE ${MLPACK_INCLUDE_DIRS})
target_link_libraries(main PRIVATE armadillo)
いかがでしたか?
これでうまくいかない場合は、いちどbuildフォルダを丸ごと削除し、VSCodeを再起動することをお勧めします。私自身、キャッシュが残っていたせいで失敗するということがかなり多くありました。それでもうまくいかない場合は、Armadilloの配下で動いている線形代数のためのライブラリのBLASの種類を明示し、vcpkgでもインストールするのが良いと思います。openblasというライブラリがいいらしいです。