【问题标题】:Skeleton project for CMakeCMake 的骨架项目
【发布时间】:2018-02-12 20:55:00
【问题描述】:

我第一次尝试将 CMake 用于一个项目,需要一些帮助以我喜欢的方式设置项目。我可能做错了一切,所以请多多包涵。我目前有以下目录结构:

/CMakeLists.txt
/main/CMakeLists.txt
      main.cc
/libfoo/CMakeLists.txt
        libfoo.h
        libfoo.cc

libfoo 是一个 git 子模块,它也应该包含在其他项目中。我的 CMakeLists.txt 文件如下:

/CMakeLists.txt:

cmake_minimum_required (VERSION 3.10)
project(server)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_subdirectory(main)
add_subdirectory(libfoo)

/main/CMakeLists.txt:

set(MAIN_SRCS
    "main.cc"
) 
add_executable(server
    ${MAIN_SRCS}
)
target_link_libraries(server
    libfoo
)

/libfoo/CMakeLists.txt:

cmake_minimum_required (VERSION 3.10)
project(libfoo)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(LIBFOO_SRCS
    "libfoo.cc"
    "libfoo.h"
)
add_library(libfoo STATIC
    ${LIBFOO_SRCS}
)

我现在的main.cc非常简单:

#include "libfoo.h"

int main(int argc, char** argv) {
  return 0;
}

但是,由于未找到 libfoo.h 标头,因此当前无法编译。因此,我的问题是:

  1. 为什么libfoo.h 标头不可见,因为我已将库添加为可执行文件的 target_link_library?

  2. 有没有更好的方法来设置 CMakeLists.txt 文件?

  3. 我希望libfoo.h 库所需的包含目录采用#include "libfoo/libfoo.h" 的形式,这样我可以避免将来发生文件名冲突。如何做到这一点?

【问题讨论】:

  • 使用 include_directories 为您的 *.h 文件添加路径
  • 您可能还应该指定target_include_directorieslibfoo
  • 我认为${LIBFOO_SRCS} 应该是来源。 "libfoo.h" 不是源文件,不应在 add_library 中列出。大概吧。
  • @nwp 在 CMake 中,您通常会在源列表中同时包含 .cpp 和 .h 文件。
  • 第二条@VTT 评论,另外您可能希望确保使用PUBLIC 标志,以便消费者也获得包含目录。

标签: c++ cmake


【解决方案1】:

通过设置变量CMAKE_INCLUDE_CURRENT_DIR,当处理文件libfoo/CMakeLists.txt 时,您会自动包含目录libfoo/(用于搜索头文件)。

但是,与include_directories 命令一样,这不会影响父目录:处理CMakeLists.txt 时不包括libfoo/。例如,请参阅那个问题:No such file or directory using cmake

您可以设置变量CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE,因此libfoo/ 将作为包含目录“附加”到libfoo/CMakeLists.txt 中创建的任何目标。因此,与此类目标(在您的情况下为libfoo)的链接将传播包含目录。

CMakeLists.txt

# This will include current directory when building a target
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# This will *attach* current directory as include directory to the target
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

(请注意,仅在*CMakeLists.txt 中设置变量就足够了:所有变量都会自动传播到子目录。)


我希望 libfoo.h 库所需的包含目录采用 #include "libfoo/libfoo.h" 形式

所以你需要有一个文件<some-dir>/libfoo/libfoo.h 并包含<some-dir>

【讨论】:

    最近更新 更多