バージョン 0.5 の時点で、私のメモリ ライブラリはシステム全体のインストールと CMake の 273
をサポートするようになりました .
何時間もの試行錯誤を経てこのライブラリを作成したので、ここに記録します。この投稿では、ライブラリを他のプロジェクトで簡単に使用できるようにインストールする方法を紹介します。特に、システムは、インストールされた複数のバージョンと複数の構成を処理できます。
この投稿全体を通して、3.x CMake バージョンと既存の CMake プロジェクトを想定しています。
セットアップ
チュートリアルの範囲として、次の CMake 構造を持つライブラリがあるとします。
- include/
- my_library/
- header-a.hpp
- header-b.hpp
- config.hpp
- ...
- src/
- source-a.cpp
- source-b.cpp
- config.hpp.in
- ...
- CMakeLists.txt
- example/
- example-a.cpp
- ...
- CMakeLists.txt
- tool/
- tool.cpp
- CMakeLists.txt
- test/
- test.cpp
- CMakeLists.txt
- CMakeLists.txt
- ...
そのため、さまざまなヘッダー ファイルとソース ファイルで構成されるライブラリがあります。また、いくつかの例、ツール、単体テストも付属しています。
ライブラリ、例、およびツールには、それぞれ独自の 282
があります。 サブディレクトリでターゲットと関連コードを定義します。ルート 293
構成オプションを定義し、サブディレクトリを追加します。
構成はファイル 300
に設定されます 319
に前処理されます 321
に含まれています .
ルート CMakeLists.txt は次のようになります:
cmake_minimum_required(VERSION 3.0)
project(MY_LIBRARY)
# define library version (update: apparently you can also do it in project()!)
set(MY_LIBRARY_VERSION_MAJOR 1 CACHE STRING "major version" FORCE)
set(MY_LIBRARY_VERSION_MINOR 0 CACHE STRING "minor version" FORCE)
set(MY_LIBRARY_VERSION ${MY_LIBRARY_VERSION_MAJOR}.${MY_LIBRARY_VERSION_MINOR} CACHE STRING "version" FORCE)
# some options
option(MY_LIBRARY_USE_FANCY_NEW_CLASS "whether or not to use fancy new class" ON)
option(MY_LIBRARY_DEBUG_MODE "whether or not debug mode is activated" OFF)
# add subdiretories
add_subdirectory(src)
add_subdirectory(example)
add_subdirectory(tool)
add_subdirectory(test)
336
経由で使用できるいくつかのオプションを定義します または同様の 349
.
そして 359
:
# set headers
set(header_path "${MY_LIBRARY_SOURCE_DIR}/include/my_library")
set(header ${header_path}/header-a.hpp
${header_path}/header-b.hpp
${header_path}/config.hpp
...)
# set source files
set(src source-a.cpp
source-b.cpp
...)
# configure config.hpp.in
configure_file("config.hpp.in" "${CMAKE_CURRENT_BINARY_DIR}/config_impl.hpp")
# define library target
add_library(my_library ${header} ${src})
target_include_directories(my_library PUBLIC ${MY_LIBRARY_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR})
最初に、すべてのヘッダーとソース ファイルのリストを変数で定義します。これは後で役立ちます。
362
も生成します 372
内に含めることができます 現在のバイナリディレクトリで、指定されたファイルでライブラリを定義します.その 383
インクルード ディレクトリは 両方 391
サブフォルダと現在のバイナリ ディレクトリ。後者は、生成された 406
にアクセスするために必要です。 .
もう一方の 419
クライアント コードで 428
を呼び出せるようになりました ライブラリ フォルダの 435
を呼び出します .これにより、インクルード パスも設定され、441
が許可されます。
しかし、それをインストールして 452
をサポートしたい .
インストール
ライブラリを使用するには、次のものをインストールする必要があります:ヘッダー ファイル、ツールの実行可能ファイル、およびビルドされたライブラリ。これは、466
コマンドです。ファイルを 476
にコピーするだけです。 (487
Linux では) 499
を入力するとき ターミナルでコマンドを実行してください。
まず、ルート CMakeLists.txt で場所を変数として定義します:
set(tool_dest "bin")
set(include_dest "include/my_library-${MY_LIBRARY_VERSION}")
set(main_lib_dest "lib/my_library-${MY_LIBRARY_VERSION}")
次に 501
を追加します コマンド:
# in tool/CMakeLists.txt
install(TARGETS my_library_tool DESTINATION "${tool_dest}")
# in src/CMakeLists.txt
install(TARGETS my_library DESTINATION "${main_lib_dest}")
install(FILES ${header} DESTINATION "${include_dest}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/config_impl.hpp DESTINATION "${include_dest}")
これにより、ツールの実行可能ファイルが 515
の下にインストールされます 、 528
の下のヘッダー ライブラリ自体は 535
の下にあります .これは、上で設定した目標の 1 つをすでに満たしています。異なるライブラリ バージョンは、異なる場所にインストールされるため、競合が発生しません。バージョンはフォルダの一部です。
ただし、これはライブラリのさまざまな構成を処理しません。その場所に存在できるのは 1 つだけです。もちろん、バージョンに対して行ったように構成ごとに一意の識別子を追加することでこれを防ぐことができますが、これはほとんどのファイルには不要です。
再びツールを無視すると、構成に依存するファイルは 2 つだけです。ビルドされたライブラリと生成された 543
です。 ライブラリ オプションに対応するマクロが設定されているため、構成に応じて、これら 2 つのファイルのみを別の場所に配置する必要があります。
しかし、識別子として何を使用するのでしょうか?
558
の値を選択しました .562
の値のコンパイラ フラグが既に選択されています 、 572
、 588
および 594
.他のすべてのオプションをそれに結合することも理にかなっています.
したがって、新しい変数 607
を追加します ルート CMakeLists.txt:
set(lib_dest ${main_lib_dest}/${CMAKE_BUILD_TYPE}")
615
の宛先も変更します そして 625
630
をターゲットに .これにより、これらの 2 つのファイルが構成に応じて異なるフォルダーに配置され、複数の構成をインストールできるようになります。たとえば、645
ライブラリは 658
の下にインストールされます など
ターゲットのエクスポート
現在のセットアップでは、ライブラリを使用するために必要なものはすべてインストールされていますが、他の CMake ベースのプロジェクトに統合することはできません。インクルード ディレクトリを手動で指定し、ネイティブ ライブラリに手動でリンクする必要があります。
これは快適ではありません。
CMake はエクスポートする機能を提供します ただし、ターゲットをエクスポートすると、現在のプロジェクトで定義されているかのように、ターゲットを他の CMake プロジェクトで再利用できます。これを有効にするには、ファイル 666
インストール時に作成されます。これには、インストールされたビルド ファイルと構成への参照を含むすべてのターゲットの定義が含まれています。ユーザーは 670
を実行するだけで済みます。 そのファイルであり、通常どおりターゲットを使用できます。
my_library のエクスポートを有効にするには 2 つのことを行う必要があります:
- まず、ターゲットごとに、それがエクスポート グループに追加されることを指定します。これは、
689
を追加することによって実現されます。694
で たとえば、メイン ライブラリ ターゲットの場合、ターゲット インストール コマンドは次のようになります:
install(TARGETS my_library EXPORT my_library DESTINATION "${lib_dest}")
- 次に、エクスポート グループもインストールする必要があります。これは、
708
で実行できます。 ルート713
で呼び出されるコマンド .ターゲットは721
のビルドタイプ固有の場所を参照するため ライブラリ ファイルはビルド タイプに依存し、730
にインストールされます。 :
install(EXPORT my_library DESTINATION "${lib_dest}")
ただし、まだ小さな問題があります:ライブラリは 743
を設定しています リンクされたターゲットに、インストール前のソースが保存されているディレクトリに渡されます!また、ビルド用のインクルード ディレクトリが間違っているため、ディレクトリを変更できません。
ジェネレータ式という名前の醜い機能 ここで助けてください。ライブラリがインストールされているか、現在ビルド中であるかにかかわらず、異なるインクルード ディレクトリを設定できます。756
の呼び出し 769
で 次のように変更する必要があります:
target_include_directories(my_library PUBLIC
$<BUILD_INTERFACE:${MY_LIBRARY_SOURCE_DIR}/include> # for headers when building
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # for config_impl.hpp when building
$<INSTALL_INTERFACE:${include_dest}> # for client in install mode
$<INSTALL_INTERFACE:${lib_dest}> # for config_impl.hpp in install mode)
これで 773
ができました ライブラリを 781
の宛先として使用するために含める必要があるタイプ いつものように。しかし、行く前に 792
を追加してください。 ステートメント、パッケージ サポートを有効にして自動化しましょう。
最終ステップ:パッケージング
CMake は 807
を提供します ここでは詳しく説明しませんが、その基本的な形式はここで役立ちます。
816
と書くと 、 822
という名前のファイルを探しに行きます (特に) 832
という名前のディレクトリ 848
の下 (多くの中 その他)
インストール ディレクトリ名 852
- 863
- この表現に一致します。
875
を指定するだけです file.ファイルの内容は、883
の呼び出しスクリプトで利用できるようになります。 .通常、ターゲットを定義するコードが含まれていますが、そのコードは既にあります!それは 899
にあります 900
によって作成されたファイル .911
するだけです。 920
の中 ファイル。
ここでは、ビルド タイプを照合することもできます。現在のビルド タイプと一致するエクスポート ファイルのバージョンを含めます。
# my_library-config.cmake - package configuration file
get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${SELF_DIR}/${CMAKE_BUILD_TYPE}/my_library.cmake)
このファイルはライブラリ リポジトリ内に保存できます。インストールすることを忘れないでください。931
のすぐ横で実行できます。 コマンド:
install(FILES my_library-config.cmake DESTINATION ${main_lib_dest})
install(EXPORT ...)
これで、クライアントは 946
を呼び出すことができます ライブラリが検索され、見つかります (957
の場合) がインストールされている)、エクスポートされたすべてのターゲットが利用可能になり、単純な 968
が許可されます .これは、一致するビルド タイプのライブラリ バージョンにリンクします。
いいね。
シュガーの追加:バージョン管理
インストールされたライブラリのバージョン互換性チェックは、良い点の 1 つです。これは、974
でもサポートされています。 、2 番目の引数としてバージョンを指定できます。
チェックは 987
という名前のファイルによって行われます (または類似) 997
のように 、現在のセットアップで提供してインストールする必要があります。
要求されたバージョンを 1000
の形式で取得します 変数 1010
を設定する必要があります また、1021
でフル バージョンを設定する必要があります。 .しない ことの 1 つ get は、インストールされているライブラリのバージョンです。そのため、ルート 1039
で定義されているバージョン変数を参照する必要があります。 インストール前に構成する必要があります。
メジャー バージョンの一致とそれ以降のマイナー バージョンが必要な簡単なスクリプトを次に示します。
# my_library-config-version.cmake - checks version: major must match, minor must be less than or equal
set(PACKAGE_VERSION @MY_LIBRARY_VERSION@)
if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "@MY_LIBRARY_VERSION_MAJOR@")
if ("${PACKAGE_FIND_VERSION_MINOR}" EQUAL "@MY_LIBRARY_VERSION_MINOR@")
set(PACKAGE_VERSION_EXACT TRUE)
elseif("${PACKAGE_FIND_VERSION_MINOR}" LESS "@MY_LIBRARY_VERSION_MINOR@")
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
else()
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
構成 (1044
を置き換えるため) -正しいバージョンの変数) で、インストールはルートの CMakeLists.txt で行われます:
configure_file(my_library-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/my_library-config-version.cmake @ONLY)
install(FILES my_library-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/my_library-config-version.cmake DESTINATION ${main_lib_dest})
install(EXPORT ...)
1057
になりました 1066
形式の呼び出し 1.0 または互換性のある (「互換性がある」と定義した) ライブラリ バージョンを探します。
まとめ
要約すると、インストールと 1073
をサポートするために CMake では、次のことを行う必要があります:
- <リ>
呼び出しを 1089
に変更します 1099
を使用するように および 1103
正しいインクルード ディレクトリを設定するジェネレータ式。インストール モードでは、これはヘッダー ファイルがインストールされる場所です (すぐ下を参照)。
ヘッダー ファイルを 1119
にインストールします 1120
経由 .
構成されたヘッダー ファイル (または構成/ビルド タイプに応じて他のすべてのヘッダー ファイル) を 1132
にインストールします。 1142
経由 .
ライブラリ ターゲットを 1159
にインストールします。 1161
経由 .これにより、エクスポート グループにも追加されます。
1176
という名前のファイルを定義します 対応する 1186
のみを含む ファイル(上記を参照してください。コピーして貼り付けるだけです)。 1191
も定義します バージョンの互換性チェックについては上記と同様です。
1203
を介して正しいバージョンを使用するように、バージョン インストール ファイルを構成します。 構成されたバージョンのインストール ファイルと 1215
をインストールします。 1221
へのファイル 1234
経由 .
エクスポート グループを 1240
にインストールします 1255
経由 .
クライアントは次のように書くだけです:
find_package(my_library 1.0 REQUIRED)
target_link_libraries(client_target PUBLIC my_library)
また、適切なライブラリ バージョンが自動的に検出され、一致するビルド タイプのライブラリにリンクされます。
実際の完全な例については、メモリ自体のソース コードを参照してください。同様のディレクトリ構造を提供しますが、CMake に依存するものは 1269
に配置されることに注意してください。