目次
(1)find_package(catkin 必須コンポーネント ...)
(3)add_executable( src1 src2 ...) (簡単な書き方)
(4)target_link_libraries( lib1 lib2 ...) (簡単な書き方、libは依存ライブラリへのパス)
まず第一に、CMakeLists.txt はソース コードの文字列と見なすことができることを知っておく必要があります。CMakeLists.txt にはいくつかの「システム変数」が付属しています。その中の各コマンドは「関数」であり、関数も同様です「変数」、これらの「関数」を通じて Cmake にいくつかの要件や構成を提示し、メイクファイル上で一連の自動「書き込み」を実行し、最後に make を使用します。 Makefile を使用してソース コードをコンパイルするコマンド。
これらの「システム変数」の一部は、CMakeLists.txt に明示的に書き込まれません。たとえば、パッケージ A のヘッダー ファイル パスは変数 A_INCLUDE_DIRS で表されます。これは「システム変数」であり、「関数 (コマンド)」を介して渡すことができます。 )" の find_package。パッケージ A のヘッダー ファイル パスを自動的に検索し、それを「関数の戻り値」として変数 A_INCLUDE_DIRS に書き込むように cmake ツールに指示します。これにより、後続の CMakeLists.txt で変数 A_INCLUDE_DIRS を明示的に使用できるようになります。この「システム変数」は通常、${A_INCLUDE_DIRS} の形式を使用して参照されます。
(1)find_package(catkin 必須コンポーネント ...)
(抜粋 [1]) find_package は、指定された検索パス内の Findxxx.cmake ファイルと xxxConfig.cmake ファイルを優先順位に従って検索するように cmake に指示します (xxx はライブラリの名前を表します。大文字と小文字が区別されることに特に注意してください) -sensitive), this 2 つのファイルには基本的に違いはありません。cmake はこれら 2 つのファイルのいずれかを見つけることができ、ライブラリを正常に使用できます。つまり、ライブラリの組み込み Cmake 変数を使用できます。ライブラリ ヘッダー ファイルとライブラリ ファイルのパス情報が含まれます。通常、ライブラリの作成者はこれら 2 つのファイルを提供しますが、インストール後にこれらのファイルが見つからない場合もあります。cmake.. コマンドを実行すると、Cmake は CMakeLists.txt 内のコードを読み取って実行します。find_package() コマンドが実行されると、Cmake は特定のパスから Findxxx.cmake ファイルまたは xxxConfig.cmake ファイルを見つけます。任意のファイルを見つけてからこのファイルを実行すると、このファイルの実行後にいくつかの Cmake 変数が設定されます。Cmake は次の変数を使用します (NAME はライブラリの名前を表します。たとえば、Opencv を使用して Opencv ライブラリを表すことができます)。
<NAME>_FOUND //是否找到该库的标志位 <NAME>_INCLUDE_DIRS or <NAME>_INCLUDES //该库的头文件地址 <NAME>_LIBRARIES or <NAME>_LIBS //该库的静态或者动态链接文件地址 <NAME>_DEFINITIONS //不懂这个
一般に使用されるのは、xxx_FOUND、xxx_INCLUDE_DIRS、xxx_LIBS で、それぞれライブラリ フラグ、ライブラリ ヘッダー ファイル パス、ライブラリ ファイル パスが見つかったかどうかを表します。find_package() には、モジュール モードと構成モードの 2 つのモードがあり、それぞれ上記の Findxxx.cmake および xxxConfig.cmake ファイルに対応します。cmake はデフォルトでモジュール モードを優先し、代わりに Config モードを使用します。
モジュール モード (Findxxx.cmake ファイルのみを検索):
Cmake は、 CMAKE_MODULE_PATHで指定されたパスの検索を優先します。CMakeLists.txt に Findxxx.cmake を保存するパスとして CMAKE_MODULE_PATH が設定されていない場合、つまり、次の指示はありません。
set(CMAKE_MODULE_PATH "Findxxx.cmake文件所在的路径")
この場合、Cmake は CMAKE_MODULE_PATH で指定されたパスを検索せず、2 番目に優先されるパスである<CMAKE_ROOT>/share/cmake-xy/Mdodulesを検索します (注: xy はバージョン番号を表します。私の場合は 3.10)。CMAKE_ROOT は、Cmake をインストールするときのシステム パスです。インストール パスを指定しなかったため、システムのデフォルト パスです。私のシステム (ubuntu16.04) では、システムのデフォルト パスは /usr/loacl です。インストール中に使用した場合は、
cmake -DCMAKE_INSTALL_PREFIX=自己dir路径
そして、CMAKE_ROOTはこの時点で書いたパスを表します。Findxxx.cmake ファイルが第 1 優先のパス検索で見つからない場合は、第 2 優先のパスで検索されると述べました。Cmake が両方のパスで Findxxx.cmake ファイルを見つけられない場合。その後、Cmake は Config モードに入ります。
構成モード (xxxConfig.cmake ファイルのみを検索):
Cmake はxxx_DIR で指定されたパスの検索を優先します。この cmake 変数が CMakeLists.txt に設定されていない場合。つまり、次のような指示はありません。
set(xxx_DIR "xxxConfig.cmkae文件所在的路径")
このとき、Cmake は xxx_DIR で指定されたパスを検索せず、2 番目に優先されるパス (/usr/local/lib/cmake/xxx/ にある xxxConfig.cmake ファイル) を自動的に検索します。
上記は主に Cmake の検索モードについて説明しています。Cmake が 2 つのモードで提供されるパス内に対応する Findxxx.cmake および xxxConfig.cmake ファイルを見つけられない場合、システムは最上位のエラー メッセージを表示します。
要約:
- まず簡単に言うと、find_package はいくつかのパッケージ パス、ヘッダー ファイル パス、その他の情報を見つけるために使用されます。たとえば、A の CMakeList.txt で find_package(B) を設定します。このコマンドは cmake にそのプロジェクトを直接知らせることはありませんA は B に依存する必要があります。これは、cmake に B を見つけて関連する変数を返すように指示するだけです。
- set コマンドを使用して、必要なライブラリ パス (実際には、対応する Findxxx.cmake および xxxConfig.cmake ファイル パス) を手動で設定できます。この機能は非常に重要です。1 つ目は、システムが何らかの理由で必要なライブラリ ファイルを見つけられない場合です。手動で指定する必要があります。2 番目: PCL1.7 と PCL1.8 が共存する場合など、システムに特定のライブラリの複数のバージョンが含まれている場合、set コマンドを使用して必要なライブラリを手動で選択できます。
ROS での使用:
find_package の標準コマンド形式は次のとおりです。
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
ROS では、CMakeList.txt を書くときに、少なくとも "catkin" パッケージを探すように指定する必要がありますが、自分で書いた他の catkin_packages に依存する必要がある場合は、catkin パッケージの COMPONENTS として探すのが最善です。のような:
独自の catkin_package を catkin の COMPONENTS として扱うことの利点は、自分または他のシステムによって記述されたこれらの catkin_package パッケージのインクルード パス、ライブラリ パスなどが、catkin_ 変数に自動的に追加されることです。つまり、catkin_INCLUDE_DIRS には catkin パッケージ自体が含まれるだけではありませんインクルード パスには、上記のすべての COMPONENTS (コンポーネント) のパスも含まれます。同様に、catkin_LIBRARIES にはこれらのコンポーネントのライブラリ パスも含まれており、非常に便利です。
たとえば、catkin パッケージ A が catkin パッケージ B のヘッダー ファイル bh を呼び出す場合、パッケージ A の CMakeList.txt と find_package に書き込むだけで済みます。
find_package(catkin REQUIRED COMPONENTS B)
そして、B が A より前にビルドされるように依存関係を宣言します。
add_dependencies(<A的target> <依赖的B的target>)
これでBのヘッダファイルは正常に利用できるようになります。通常、bh と対応する b.cpp は A の実行可能ファイルの構築に参加するため、A の CMakeList.txt ファイルの include_directories (B_INCLUDE_DIRS) を使用して bh への参照を示し、target_link_libraries (A_target B_LIBRARIES) を使用してリンクを示します。図書館B。
ただし、B を catkin のコンポーネントとして使用する場合は、手動で追加せずに、次のようにデフォルトのコマンドを使用します。
include_directories( ${catkin_INCLUDE_DIRS})
target_link_libraries(<A的target> ${catkin_LIBRARIES})
注: したがって、上の 2 つの文ではパッケージ B を指定する必要はありませんが、find_package でパッケージ B を指定する必要があり、この方法でのみ B の変数を catkin_variables に追加して一緒に使用できます。
この点の詳細な説明については、公式の説明http://wiki.ros.org/catkin/CMakeLists.txtを参照することをお勧めします。
(2)include_directories()
このコマンドが解決する主な問題は、パッケージ A の *.cpp ファイルで #include <opencv/cv.h> などのヘッダー ファイルが呼び出された場合、gcc はヘッダー ファイルをどこで見つけるかということです。
#include "/usr/local/include/opencv/cv.h" を使用して、ヘッダー ファイルのアドレスを直接かつ明示的に指定できますが、これは明らかに標準化されていません。A の CMakeList.txt ルート ディレクトリで指定できます。つまり、コマンド:
include_directories(/usr/local/include)
/usr/local/include に基づいてヘッダー ファイル opencv/cv.h を探すようにシステムに通知します。
また、find_package() コマンドと組み合わせると、必要なヘッダー ファイルのパスを自動的に入力することができ、非常に便利です (たとえば、opencv の場合、次のコマンドを使用すると、ヘッダー ファイルのパスが自動的に検索されます)。
find_package(opencv REQUIRED)
include_directories(${OPENCV_INCLUDE_DIRS})
注意点:
- パッケージ A 自体のヘッダー フォルダー インクルードも (存在する場合) 入力する必要があり、他のパッケージのパスより前にある必要があります。
- catkin タイプに付属するパッケージの場合は、find_package で指定した後、それに対応して include_directories に ${catkin_INCLUDE_DIRS} を記述するだけで、それらすべてを参照できます。
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
include_directories(
#下面的include指的就是自身的头文件文件夹
include
#下面的是find_package指令返回的头文件路径
${catkin_INCLUDE_DIRS}
)
(3)add_executable(<name> src1 src2 ...) (簡易的な書き方)
add_executable 命令を使用して、gcc に <name> という名前の実行可能ファイルを生成するように指示します。この実行可能ファイルは、src1、src2... によってコンパイルおよび生成されます。<name> のコンパイルに関係するすべてのファイルがリストされている必要があることに注意してください。
たとえば、パッケージ A の src フォルダー内に 3 つのファイル test.cpp math.cpp matrix.cpp があり、include フォルダー内に 2 つのヘッダー ファイル math.h math.h があり、それらは test.cpp (main 関数付き) 内にあります。使用する
#include"math.h"
#include"matrix.h"
Math.cpp math.cpp が呼び出され、テストとして <name> を使用して実行可能ファイルを生成するときに、次の情報を入力する必要があります。
add_executable(test src/test.cpp src/math.cpp src/matrix.cpp )
テスト実行ファイルを生成する過程で、src/test.cpp、src/math.cpp、src/matrix.cpp の 3 つのファイルの obj ファイルを相互にリンクする必要があるためです。
(4)target_link_libraries(<name> lib1 lib2 ...) (簡単な書き方、lib は依存ライブラリへのパス)
このコマンドは、add_executable コマンドの後に配置する必要があります。add_executable が実行されると、name という名前のバイナリ ファイルが生成されます。この時点では、実行可能ファイルは完全には生成されていません。たとえば、name のソース コードは、次のブースト ライブラリを呼び出します。ヘッダー ファイルを生成し、生成後に name の最終的な実行可能ファイルを作成する場合、最終的な実行可能ファイルを生成する前に、そのファイルをブースト ライブラリ ファイルにリンクする必要があります。
add_executable の機能は、生成されたばかりの名前を、パッケージが依存する他の外部ライブラリ ファイル (lib1 lib2...) とリンクして最終的な実行可能ファイルを生成するように cmake に指示することです。スクリーンショットを撮って出力を確認します
主要なコマンドの概要:
基本的な構成を完了するには、これらのコマンドを入力します。CMakeList.txt は、基本的にコンパイル手順に従って、コンパイル プロセスをいくつかの段階に分割していることがわかります。
ステップ 1. 依存パッケージ (ライブラリとヘッダー ファイル) のパスを見つける
|
find_package() |
ステップ 2. 独自のソース コードのヘッダー ファイルへのパスを指定します。
|
include_directories() |
ステップ 3. 独自のソース コードをオブジェクト ファイルにコンパイルする
|
add_executable() |
ステップ 4. ターゲット ファイルを他のライブラリ ファイルにリンクする
|
target_link_libraries() |
したがって、cmake がエラーを報告する場合、エラーを分類して、パッケージが見つからない (find_package に問題がある可能性がある)、ヘッダー ファイルが見つからない (include_directories)、またはリンクが失敗したのかを判断できます。比較的包括的な内容です。
次の記事では、その他の関連する設定コマンドについて説明します。いくつかのコマンドは必須ではありませんが、非常に一般的に使用されますが、非常に重要でもあります。ポータル: https://blog.csdn.net/u012057432/article/details/103353547
参考リンク:
[1] https://blog.csdn.net/chengde6896383/article/details/86497016 find_package 原則