ま、そんなところで。

ニッチな技術系メモとか、車輪を再発明してみたりとか.

MacOS MojaveでCmakeがOpenMPを見つけてくれない件

CmakeをupdateしたらOpenMPが見つからないぞ!?

MacOpenMPを使ったクロスプラットフォームC++コードを書くことがありまして、 HomebrewでlibompをインストールしてCMakeLists.txtをコツコツとかきあげて、 なんとかビルド実行できる環境になったわけです.

ところが、Cmakeが古いのが気になってHomebrewで 3.12にupgradeしたところ、 OpenMPを見つけてくれなくなりました。。

テストでfind_packageしてみるけれども見つからない・・・

HomebrewのFomuraでlibompをインストールした後に表示されるご指示の通り、必要なマクロ変数とオプションを定義してfind_packageしてやってるわけです。

# libompのインストール先パスをbrewコマンドを実行して取得する.
execute_process(COMMAND brew --prefix libomp
                OUTPUT_VARIABLE OpenMP_HOME
                OUTPUT_STRIP_TRAILING_WHITESPACE)  
message(STATUS "OpenMP Root : ${OpenMP_HOME}")

# OpenMPのfindに必要な変数設定
set(OpenMP_C_LIB_NAMES "omp")
set(OpenMP_CXX_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY "${OpenMP_HOME}/lib/")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -Wno-unused-command-line-argument -I${OpenMP_HOME}/include -lomp -L${OpenMP_omp_LIBRARY}") 
set(OpenMP_C_FLAGS "-fopenmp -Wno-unused-command-line-argument -I${OpenMP_HOME}/include -lomp -L${OpenMP_omp_LIBRARY}")

# libompをlookup
find_package(OpenMP)

message(STATUS "OpenMP_C_Found   : ${OpenMP_C_FOUND}")
message(STATUS "OpenMP_CXX_Found : ${OpenMP_CXX_FOUND}")

if (OpenMP_FOUND)
message(STATUS "YES!! OpenMP found.")
else (OpenMP_FOUND)
message(STATUS "No!!   OpenMP did not find.")
endif (OpenMP_FOUND)

ところが!

ちゃんとsetを行ってるのに、なぜか OpenMP_CXX_FLAGSOpenMP_C_FLAGS が設定されてないんですね。。
初回実行すると「OpenMP did not find.」なんですが 、なぜか2回目以降は値が設定されてて「OpenMP found.」。。。

何故に初回だけがダメなのか・・・!?

それ変数やない、キャッシュ変数や・・

なんでやねん!と首を傾げながら何気なくCMakeCache.txtを流し読みしてて気づきました。。
なんてこった・・CMakeCache.txt内に OpenMP_CXX_FLAGSOpenMP_C_FLAGS があるじゃあないですか・・・orz

OpenMP_CXX_FLAGSOpenMP_C_FLAGS はキャッシュ変数になっていたんですね。
キャッシュ変数はフツーにsetするのではダメで、書き込むときには FORCE オプションをつけて 強制的に書き込んでやる必要があった、というオチ。

以下の通り変更するとちゃんと見つかるようになりました。

# libompのインストール先パスをbrewコマンドを実行して取得する.
execute_process(COMMAND brew --prefix libomp
                OUTPUT_VARIABLE OpenMP_HOME
                OUTPUT_STRIP_TRAILING_WHITESPACE)  
message(STATUS "OpenMP Root : ${OpenMP_HOME}")
# OpenMPのインストールチェック
set(OpenMP_C_LIB_NAMES "omp")
set(OpenMP_CXX_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY "${OpenMP_HOME}/lib/")
# キャッシュ変数なのでFORCEオプションをつける
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -Wno-unused-command-line-argument -I${OpenMP_HOME}/include -lomp -L${OpenMP_omp_LIBRARY}" CACHE STRING "" FORCE) 
# 同じくキャッシュ変数なのでFORCEオプションをつける
set(OpenMP_C_FLAGS "-fopenmp -Wno-unused-command-line-argument -I${OpenMP_HOME}/include -lomp -L${OpenMP_omp_LIBRARY}" CACHE STRING "" FORCE)

# libompがインストールされているかどうか.
find_package(OpenMP)
# 見つかったか?
message(STATUS "OpenMP_C_Found   : ${OpenMP_C_FOUND}")
message(STATUS "OpenMP_CXX_Found : ${OpenMP_CXX_FOUND}")

if (OpenMP_FOUND)
message(STATUS "YES!! OpenMP found.")
else (OpenMP_FOUND)
message(STATUS "No!!   OpenMP did not find.")
endif (OpenMP_FOUND)

これ、説明がないとちょっとわかんないですよねぇ。。。


参考記事