私はCMakeを初めて使用するので、次の問題で誰かが手伝ってくれるかどうか尋ねたいと思います。
C++のソースファイルとヘッダーファイルがそれぞれのフォルダーにあるので、それらを再帰的に検索するCMakeテキストファイルを作成します。
現在、私はこのようにしています:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(CarDetectorDAISY)
file(GLOB_RECURSE SRCS *.cpp)
file(GLOB_RECURSE HDRS *.h)
ADD_EXECUTABLE(stereo_framework ${SRCS} ${HDRS})
TARGET_LINK_LIBRARIES(stereo_framework)
これは私のCarDetectorDAISY.slnソリューションファイルを作成し、それをビルドしようとすると、ヘッダーファイルが見つからないというエラーが表示されます(そのようなファイルまたはディレクトリはありません)。
誰かが私を助けてくれると本当にありがたいです。ありがとう。
おそらく1つ以上の _include_directories
_ 呼び出しがありません。 _add_executable
_呼び出しでファイルのリストにヘッダーを追加しても、実際にはコンパイラの検索パスに追加されません。これは、IDEでプロジェクトのフォルダー構造にのみ追加される便利な機能です。
したがって、ルートに/my_lib/foo.hがあり、それをソースファイルに次のように含めたいとします。
_#include "my_lib/foo.h"
_
次に、CMakeLists.txtで次のことを行う必要があります。
_include_directories(${CMAKE_SOURCE_DIR})
_
もしあなたが代わりにしたいなら
_#include "foo.h"
_
次に、CMakeLists.txtで、
_include_directories(${CMAKE_SOURCE_DIR}/my_lib)
_
file(GLOB...)
はソースのリストを収集するための推奨される方法ではありません-各ファイルをCMakeLists.txtに明示的に追加するだけです。これにより、後でソースファイルを追加または削除した場合、CMakeLists.txtが変更され、次回ビルドしようとするとCMakeが自動的に再実行されます。 file
のドキュメントから:
ソースツリーからソースファイルのリストを収集するためにGLOBを使用することはお勧めしません。ソースが追加または削除されたときにCMakeLists.txtファイルが変更されていない場合、生成されたビルドシステムは、CMakeに再生成を依頼するタイミングを認識できません。
私の答えはほとんどハックですが、すべてのディレクトリを手動で追加したくない場合に便利です。
このマクロは、すべてのサブディレクトリ(およびそのサブディレクトリなど)を再帰的にスキャンします。ディレクトリにヘッダー(.h)ファイルが含まれている場合、return_list
にそのパスが追加されます。このリストはtarget_include_directories
で使用できます。
MARO(HEADER_DIRECTORIES return_list)
FILE(GLOB_RECURSE new_list *.h)
SET(dir_list "")
FOREACH(file_path ${new_list})
GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
SET(dir_list ${dir_list} ${dir_path})
ENDFOREACH()
LIST(REMOVE_DUPLICATES dir_list)
SET(${return_list} ${dir_list})
ENDMACRO()
使用法:
HEADER_DIRECTORIES(header_dir_list)
list(LENGTH header_dir_list header_dir_list_count)
message(STATUS "[INFO] Found ${header_dir_list_count} header directories.")
target_include_directories(
my_program
PUBLIC
${header_dir_list} # Recursive
)
マクロクレジット: Christoph
Cmake 3.10でテスト済み
フレーザーの答えの1つのポイントをさらに明確にするために:
ヘッダーをADD_EXECUTABLE
に渡してはいけません。
その理由は、たとえばLinuxで意図されているコンパイルコマンドが次のとおりであるためです。
gcc main.c mylib.c
ではなく:
gcc main.c mylib.c mylib.h
次に、Cプリプロセッサはmylib.c
を解析し、#include "mylib.h"
を確認して、それらのファイルの検索パスを使用します。
代わりにinclude_directories
を使用して、代わりにcppプリプロセッサー検索パスを変更します。これは正しいアプローチです。 GCCでは、これは-I
フラグをコマンドラインに追加することを意味します。
gcc -Inew/path/to/search/for/headers main.c mylib.c