327

約1年前、CMakeのヘッダーの依存関係について質問しました。

私は最近、CMakeがそれらのヘッダーファイルをプロジェクトの外部にあると見なしたことが問題のように思われることに気付きました。少なくとも、Code :: Blocksプロジェクトを生成する場合、ヘッダーファイルはプロジェクト内に表示されません(ソースファイルは表示されます)。したがって、CMakeはこれらのヘッダーをプロジェクトの外部にあると見なし、依存関係でそれらを追跡しないように思われます。

CMakeチュートリアルでのクイック検索は、include_directories私が望むことをしていないように見えることだけを指摘しました...

特定のディレクトリに含まれるヘッダーが含まれていること、およびそれらのヘッダーが生成されたMakefileによって追跡される必要があることをCMakeに通知する適切な方法は何ですか?

4

10 に答える 10

350

2つのことをしなければなりません。

まず、含めるディレクトリを追加します。

target_include_directories(test PRIVATE ${YOUR_DIRECTORY})

をサポートせずに非常に古いバージョンのCMake(2.8.10以前)で立ち往生している場合は、代わりtarget_include_directoriesにレガシーを使用することもできます。include_directories

include_directories(${YOUR_DIRECTORY})

次に、現在のターゲットのソースファイルのリストにヘッダーファイルを追加する必要があります。次に例を示します。

set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})

このように、ヘッダーファイルは、Makefileに依存関係として表示されます。また、生成されたVisual Studioプロジェクト(生成されている場合)にも依存関係として表示されます。

これらのヘッダーファイルをいくつかのターゲットに使用する方法:

set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)

add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})
于 2012-12-04T13:09:31.407 に答える
95

まず、コンパイルコマンドラインに関してinclude_directories()ディレクトリを追加するようにCMakeに指示するために使用します。-I次に、add_executable()またはadd_library()呼び出しのヘッダーをリストします。

例として、プロジェクトのソースがにsrcあり、からのヘッダーが必要な場合はinclude、次のように実行できます。

include_directories(include)

add_executable(MyExec
  src/main.c
  src/other_source.c
  include/header1.h
  include/header2.h
)
于 2012-12-04T13:10:33.703 に答える
32

追加しinclude_directories("/your/path/here")ます。

gccこれは、オプションで呼び出すのと似てい-I/your/path/here/ます。

パスを二重引用符で囲んでください。他の人はそれについて言及しませんでした、そしてそれは私を2日間立ち往生させました。したがって、この回答は、CMakeを初めて使用し、非常に混乱している人々を対象としています。

于 2019-04-18T09:30:27.737 に答える
26

CMakeは、Makefileを作成する他の方法(makeやqmakeなど)と比較すると、スクリプト言語に似ています。Pythonのようにクールではありませんが、それでもです。

さまざまなオープンソースプロジェクトで人々がディレクトリをどのように含めるかを見ると、「適切な方法」のようなものはありません。しかし、それを行うには2つの方法があります。

  1. 粗いinclude_directoriesは、現在のプロジェクトと、一連のadd_subdirectoryコマンドを介して追加する他のすべての子孫プロジェクトにディレクトリを追加します。時々人々はそのようなアプローチが遺産であると言います。

  2. より洗練された方法は、target_include_directoriesを使用することです。これにより、(おそらく)不必要な継承やさまざまなインクルードディレクトリの衝突なしに、特定のプロジェクト/ターゲットのディレクトリを追加できます。また、微妙な構成を実行し、このコマンドに次のマーカーのいずれかを追加することもできます。

PRIVATE-この指定されたビルドターゲットにのみ使用します

PUBLIC-指定されたターゲットおよびこのプロジェクトにリンクするターゲットに使用します

インターフェース-現在のプロジェクトにリンクしているターゲットにのみ使用します

PS:

  1. どちらのコマンドでも、ディレクトリをSYSTEMとしてマークして、指定したディレクトリに警告が含まれるのはあなたのビジネスではないというヒントを与えることができます。

  2. 同様の答えは、他のコマンドのペアtarget_compile_definitions / add_definitionstarget_compile_options / CMAKE_C_FLAGS

于 2017-08-11T13:49:21.527 に答える
11

私も同じ問題を抱えていました。

私のプロジェクトディレクトリは次のようになりました。

    --project
    ---Classes
    ----Application
    -----.h and .c files
    ----OtherFolders
    --main.cpp

そして、私がそれらすべてのフォルダにファイルを含めるために使用したもの:

    file(GLOB source_files CONFIGURE_DEPENDS
            "*.h"
            "*.cpp"
            "Classes/*/*.cpp"
            "Classes/*/*.h"
    )

    add_executable(Server ${source_files})

そしてそれは完全に機能しました。

于 2018-06-24T09:36:31.603 に答える
9

プロジェクトの構造

.
├── CMakeLists.txt
├── external //We simulate that code is provided by an "external" library outside of src
│   ├── CMakeLists.txt
│   ├── conversion.cpp
│   ├── conversion.hpp
│   └── README.md
├── src
│   ├── CMakeLists.txt
│   ├── evolution   //propagates the system in a time step
│   │   ├── CMakeLists.txt
│   │   ├── evolution.cpp
│   │   └── evolution.hpp
│   ├── initial    //produces the initial state
│   │   ├── CMakeLists.txt
│   │   ├── initial.cpp
│   │   └── initial.hpp
│   ├── io   //contains a function to print a row
│   │   ├── CMakeLists.txt
│   │   ├── io.cpp
│   │   └── io.hpp
│   ├── main.cpp      //the main function
│   └── parser   //parses the command-line input
│       ├── CMakeLists.txt
│       ├── parser.cpp
│       └── parser.hpp
└── tests  //contains two unit tests using the Catch2 library
    ├── catch.hpp
    ├── CMakeLists.txt
    └── test.cpp

どうやってするの

1.トップレベルのCMakeLists.txtは、レシピ1と非常によく似ており、関数とマクロを使用したコードの再利用

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
  
project(recipe-07 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
  ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
  ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
  ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})

# defines targets and sources
add_subdirectory(src)

# contains an "external" library we will link to
add_subdirectory(external)

# enable testing and define tests
enable_testing()
add_subdirectory(tests)

2.ターゲットとソースはsrc/CMakeLists.txtで定義されています(変換ターゲットを除く)

add_executable(automata main.cpp)
  
add_subdirectory(evolution)
add_subdirectory(initial)
add_subdirectory(io)
add_subdirectory(parser)

target_link_libraries(automata
  PRIVATE
    conversion
    evolution
    initial
    io
    parser
  )

3.変換ライブラリはexternal/CMakeLists.txtで定義されています

add_library(conversion "")

target_sources(conversion
  PRIVATE
    ${CMAKE_CURRENT_LIST_DIR}/conversion.cpp
  PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}/conversion.hpp
  )

target_include_directories(conversion
  PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}
  )

4. src / CMakeLists.txtファイルはさらにサブディレクトリを追加し、サブディレクトリにはCMakeLists.txtファイルが含まれます。それらはすべて構造が似ています。src / Evolution / CMakeLists.txtには、次のものが含まれています。

add_library(evolution "")

target_sources(evolution
  PRIVATE
    evolution.cpp
  PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}/evolution.hpp
  )
target_include_directories(evolution
  PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}
  )

5.単体テストはtests/CMakeLists.txtに登録されています

add_executable(cpp_test test.cpp)

target_link_libraries(cpp_test evolution)

add_test(
  NAME
    test_evolution
  COMMAND
    $<TARGET_FILE:cpp_test>
  )

それを実行する方法

$ mkdir -p build
$ cd build
$ cmake ..
$ cmake --build .

参照:https ://github.com/sun1211/cmake_with_add_subdirectory

于 2021-07-13T10:14:31.750 に答える
2

これは私のために働いた:

set(SOURCE main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE})

# target_include_directories must be added AFTER add_executable
target_include_directories(${PROJECT_NAME} PUBLIC ${INTERNAL_INCLUDES})
于 2020-07-24T14:58:48.123 に答える
0

さらに別の選択肢:

set_property(
    TARGET MyApp
    APPEND PROPERTY
        INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/src"
)  
于 2021-06-22T14:52:53.043 に答える
0

を含めることを忘れないでください${CMAKE_CURRENT_LIST_DIR}。それが私にとって問題を引き起こしていたものです。

例は次のようになります。

target_include_directories(projectname
    PUBLIC "${CMAKE_CURRENT_LIST_DIR}/include"                          
)

親プロジェクトに含めたい依存関係のPUBLIC。あなたがしていないもののためのプライベート。

于 2021-11-20T20:24:27.597 に答える
-2

私はCLionを使用しています。また、私のプロジェクト構造は次のとおりです。

--main.cpp
--Class.cpp
--Class.h
--CMakeLists.txt

CMakeLists.txt 変更前:

add_executable(ProjectName main.cpp)

CMakeLists.txt 変更後:

add_executable(ProjectName main.cpp Class.cpp Class.h)

これを行うことにより、プログラムは正常にコンパイルされました。

于 2021-03-18T19:08:26.503 に答える