ターゲットとの作業

概要

教育:10分
演習:15分
質問

  • ターゲットはどのように機能しますか?

目標

  • ターゲットを設定する方法を知っている

  • リンクとインターフェイスのプロパティを理解しています

  • インターフェースターゲットを作る

今、あなたはどのように知っていますかcmakeの三行を使用して単一のファイルをコンパイルするには。 しかし、依存関係を持つファイルが1つ以上ある場合はどうなりますか? あなたはあなたのプロジェクトの構造についてCMakeに伝えることができる必要があります、そしてそれはあなたがそれを構築するのを助けます。 これを行うには、ターゲットが必要になります。すでにターゲットを見てきました:

add_executable(myexample simple.cpp)

これは、myexampleという名前の”実行可能な”ターゲットを作成します。 ターゲット名は一意でなければなりません(実際に必要な場合は、実行可能ファイル名をターゲット名以外のものに設定する方法があります)。

ターゲットは他の言語の”オブジェクト”によく似ています; プロパティ(メンバ変数)を持っています。 たとえば、SOURCESsimple.cppが含まれます。別のタイプのターゲットはライブラリです:

add_library(mylibrary simplelib.cpp)

キーワードを追加できますSTATICSHAREDMODULEBUILD_SHARED_LIBSでユーザーが選択可能な「自動」ライブラリのソートです。

ビルドされていないライブラリも作成できます。 後でそれについての詳細は、一度我々は我々がターゲットで何ができるかを参照してください。

リンク

複数のターゲットがあれば、それらの関係をtarget_link_librariesPUBLICPRIVATEINTERFACEのいずれか。 ライブラリを作るときにこのキーワードを忘れないでください! CMakeは、このターゲットの古い互換モードになります。あなたはライブラリを持っています、my_libmy_lib.hppmy_lib.cpp。 コンパイルには少なくともC++14が必要です。 その後、my_exemy_libmy_exec++14以上でコンパイP>

Answer

これはヘッダーに依存します。 ヘッダーにC++14が含まれている場合、これは公開要件です-ライブラリとそのユーザーの両方がそれを必要とします。 ただし、ヘッダーがすべてのバージョンのC++で有効であり、my_lib.cpp内の実装のみがC++14を必要とする場合、これはPRIVATE要件

  • ユーザーは強制的にC++14モードにする必要はありません。たぶん、あなたはユーザーがC++14を持っている必要がありますが、あなたのライブラリはどのバージョンのC++でもコンパイルできます。これはINTERFACE要件になります。P>

パブリックおよびプライベート継承の例

図1: パブリック、プライベート、およびインターフェイスの例。 myprogrammylibraryを介して三つのライブラリitseesを構築します;プライベートライブラリはそれに影響しません。”private”プロパティは、そのターゲットをビルドするときに何が起こるかを制御し、これにリンクされた”interface”propertiestellターゲットは、ビルド時に何をすべきかを制御します。 PUBLICキーワードは、両方のpropertyfieldsを同時に入力します。

例1: 実行すると、INCLUDE_DIRECTORIESTargetAmydirINTERFACEINTERFACE_INCLUDE_DIRECTORIESPUBLICを使用すると、両方のプロパティが同時に追加されます。C++標準プロパティがあります-CXX_STANDARD。 このプロパティを設定することができ、CMakeのmanypropertiesと同様に、設定されている場合はCMAKE_CXX_STANDARD変数からデフォルト値を取得しますが、インター C++11インターフェイスターゲットとC++14インターフェイスターゲットがあり、両方にリンクされている場合はどうなりますか?ところで、これを処理する方法があります-ターゲットをコンパイルするために必要な最小限のコンパイル機能を指定することができます; cxx_std_11CXX_STANDARDCXX_STANDARDtarget_compile_featuresCOMPILE_FEATURESINTERFACE_COMPILE_FEATURESを埋めることができます。

試してみてください

このリポジトリを取得し、例に移動します。 正しくビルドするCMakeListsを作成してみてください。

git clone https://github.com/hsf-training/hsf-training-cmake-webpage.gitcd hsf-training-cmake-webpage/code/01-simple

ここのファイルは次のとおりです。

  • simple_lib。cpp:MYLIB_PRIVATEMYLIB_PUBLIC定義されているコンパイルする必要があります。
  • simple_example.cpp:でコンパイルする必要がありますMYLIB_PUBLICMYLIB_PRIVATE

定義を設定するために使用しますsimple_lib

ターゲットに設定できるもの

  • target_link_libraries:他のターゲット;ライブラリ名を直接渡すこともできます
  • target_include_directories: Include directories
  • target_compile_features: The compiler features you need activated, like cxx_std_11
  • target_compile_definitions: Definitions
  • target_compile_options: More general compile flags
  • target_link_directories: Don’t use, give full paths instead (CMake 3.13+)
  • target_link_options: General link flags (CMake 3.13+)
  • target_sources: Add source files

See more commands here.

他のタイプのターゲット

あなたは本当にターゲットによって終了され、すでにあなたがターゲットの観点からyourprogramsを記述する方法を計画してい それは素晴らしいです! しかし、あなたはすぐにターゲット言語が便利ですが、あなたは私たちがカバーしてきたものよりもいくつかの余分な柔軟性を必要とする二つの状況にまず、概念的にはターゲットでなければならないライブラリがあるかもしれませんが、実際にはanybuiltコンポーネントを持っていません-“ヘッダー専用”ライブラ これらはCMakeのインターフェイスライブラリと呼ばれ、次のように記述します:p>

add_library(some_header_only_lib INTERFACE)

ソースファイルを追加する必要はありませんでした。 これで、INTERFACEプロパティを設定できます(ビルドされたコンポーネントがないため)。2番目の状況は、使用したいビルド済みのライブラリがある場合です。 これはCMakeでanimportedライブラリと呼ばれ、キーワードIMPORTEDINTERFACE::ALIAS::)。 ほとんどの場合、あなたは輸入されます他の場所からの図書館、そしてあなた自身のものを作ることはありません。P>

インターフェイスIMPORETED

INTERFACE IMPORTEDはどうですか?違いは2つのことになります:

  1. IMPORTEDターゲットはエクスポートできません。 ターゲットを保存すると、インポートされたターゲットを保存することはできません。
  2. IMPORTEDSYSTEMIMPORTEDターゲットは、yourpackageの直接の一部ではないものを表す必要があります。P>

より多くの読書

  • 現代のCMakeの基礎に基づいて
  • CMakeのドキュメントも参照してください

キーポイント

  • ライブラリと実行可能ファイルがターゲットです。

  • ターゲットには多くの有用な特性があります。

  • ターゲットは、他のターゲットにリンクすることができます。

  • リンク時にターゲットのどの部分を継承するかを制御できます。

  • 変数を作る代わりにインターフェイスターゲットを作ることができます。

コメントを残す

メールアドレスが公開されることはありません。