大约一年前,我问过CMake中的头依赖关系。

我最近意识到,问题似乎是CMake认为这些头文件是项目的外部文件。至少,在生成Code::Blocks项目时,头文件不会出现在项目中(源文件会出现)。因此,在我看来,CMake认为这些头文件是项目的外部,并没有在依赖项中跟踪它们。

在CMake教程中快速搜索只指向include_directories,这似乎不是我想要的…

向CMake发出特定目录包含要包含的头文件,以及生成的Makefile应该跟踪这些头文件的正确方法是什么?


当前回答

我使用的是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)

通过这样做,程序编译成功。

其他回答

如果与其他创建Makefile的方法(例如make或qmake)相比,CMake更像是一种脚本语言。它不像Python那样酷,但仍然很酷。

如果在各种开源项目中寻找人们如何包含目录,就没有“适当的方法”这样的东西。但是有两种方法。

Crude include_directories will append a directory to the current project and all other descendant projects which you will append via a series of add_subdirectory commands. Sometimes people say that such approach is legacy. A more elegant way is with target_include_directories. It allows to append a directory for a specific project/target without (maybe) unnecessary inheritance or clashing of various include directories. Also allow to perform even a subtle configuration and append one of the following markers for this command.

PRIVATE -仅用于此指定的构建目标

PUBLIC -用于指定目标和与此项目相关的目标

INTERFACE——仅用于与当前项目链接的目标

PS:

这两个命令都允许将目录标记为SYSTEM,以提示指定的目录是否包含警告与您无关。 类似的答案是其他成对的命令target_compile_definitions/add_definitions, target_compile_options/CMAKE_C_FLAGS

我也有同样的问题。

我的项目目录是这样的:

    --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})

这完全奏效了。

不要忘记包含${CMAKE_CURRENT_LIST_DIR}。 这就是给我带来麻烦的原因。

示例应该是这样的:

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

PUBLIC用于您想要包含在父项目中的依赖项。 对于那些你不喜欢的人来说是私密的。

首先,使用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
)

必须做两件事。

首先添加要包含的目录:

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项目,头文件也将作为依赖项出现在生成的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})