はじめに
自作ツールに対してCUnitでの単体テストを導入したはいいんですが、どの環境でもCUnitが無いとビルドが出来ない。
これは使い勝手が悪すぎるので対策を検索したところ、タイトルのような使い方が出来そうなので備忘録。
CMake、サポートされているパッケージはfind_packageで検索
OpenSSLのような一般的なライブラリはcmake本家で処理が用意されているようで、find_package(OpenSSL REQUIRED)
のように対象の名前を指定してfind_packageしてあげればOKです。
例えばOpenSSLなら、OPENSSL_INCLUDE_DIR
でヘッダーパスが取れるなど。
ただし、これはあくまで用意されたものに対しての話な模様。find_package(CUnit REQUIRED)
と書いたところで「FindCUnit.cmakeなんてないからCUnit見つからんよ!」と怒られます。そんな時の話
CMake Error at lib/src/CMakeLists.txt:5 (find_package):
By not providing "FindCUnit.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "CUnit", but
CMake did not find one.
Could not find a package configuration file provided by "CUnit" with any of
the following names:
CUnitConfig.cmake
cunit-config.cmake
Add the installation prefix of "CUnit" to CMAKE_PREFIX_PATH or set
"CUnit_DIR" to a directory containing one of the above files. If "CUnit"
provides a separate development package or SDK, be sure it has been
installed.
自作に対してはfind_package_handle_standard_argsを使う
調べてみると、サポート外のパッケージ名に対しては以下のようにFindPackageHandleStandardArgsを利用して設定を与えることが出来ました。
# ヘッダーパスを検索
find_path(CUNIT_INCLUDE_DIR NAMES CUnit/CUnit.h)
# 使いたいライブラリのパスを検索
find_library(CUNIT_LIBRARY NAMES cunit)
# Optionを指定してfind_package
find_package_handle_standard_args(CUnit DEFAULT_MSG CUNIT_LIBRARY CUNIT_INCLUDE_DIR)
後は通常のfind_packageのようにXXX_FOUND等が使えるようになります。例えばCUnitがインストールされている時だけビルドしたいなら、CUNIT_FOUNDで処理をくくってあげればOK
(サンプルに非推奨のコマンドを記載しているのはよろしくないですが、本筋じゃないのでスルーしてください(-_-;))
IF(CUNIT_FOUND)
include_directories("${PROJECT_SOURCE_DIR}/lib/include")
include_directories(${CUNIT_INCLUDEDIR})
link_directories("${PROJECT_SOURCE_DIR}/lib/src")
link_directories(${CUNIT_LIBDIR})
add_executable(test_main main.c)
target_link_libraries(test_main ${CUNIT_LIBRARY})
ENDIF(CUNIT_FOUND)
あるべき姿:ライブラリ側がcmake.configを作成してあげる
@yumetodo さんより「本来はライブラリ側がxxx-config.cmakeを生成するべき」とコメントいただきました。
先ほど紹介したやり方は「CMakeで見つからないライブラリを取り込みたい」でしたが、cmakeで作ったライブラリだったらあるべき姿は「find_packageで見つかるようにしよう!」が正しいですね。
というわけでやり方を追記
ライブラリ作成者側がやること:install対象にconfig.cmakeを追加するだけ
どうするんだろうと調べたところ、想像以上に簡単に導入が出来ました。やり方としては「ライブラリにEXPORTを指定してFILEの記載を追加する」だけ。
これだけでOKです。
# ライブラリのインストール記述。EXPORT encrypt_api-exportを追記
install(TARGETS encrypt_api
EXPORT encrypt_api-export
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION include)
# 新規追加。FILEでファイル名を、DESTINATIONでインストール先を指定するだけ。EXPORTはライブラリに合わせる
install(EXPORT encrypt_api-export
FILE encrypt_api-config.cmake
DESTINATION share/cmake/encrypt_api/
)
ライブラリ利用者側がやること:
find_packageしてtarget_link_librariesするだけなのでらくちんです。
find_package(encrypt_api REQUIRED)
target_link_libraries(encrypted_vim encrypt_api)
参考
調べるとっかかり: ありきたりなCMakeのプロジェクト作成 for C++
本題の参考元: adobkin/FindCUnit.cmake
cmake.configの参考:お手軽な xxx-config.cmake の作成方法