【问题标题】:In CLion, header only library: file "does not belong to any project target, code insight features might not work properly"在 CLion 中,仅标头库:文件“不属于任何项目目标,代码洞察功能可能无法正常工作”
【发布时间】:2018-02-25 00:14:32
【问题描述】:

我有一个使用 cmake 命令设置的仅标头库项目:

add_library(my_library INTERFACE)

我还加了

target_sources(my_library INTERFACE ${MY_LIRBARY_HEADER_FILES})

但是当我打开一个源文件时,我得到了警告:

此文件不属于任何项目目标,代码洞察功能可能无法正常工作

而且我失去了很多代码完成等功能。

什么是正确的设置方法,以便 CLion 在仅标头库上提供其常用功能?

【问题讨论】:

    标签: c++ cmake clion header-only


    【解决方案1】:

    小背景

    我遇到了同样的问题,尽管该项目不是仅标题,但是,来自 inc 文件夹的打开文件会引发上述警告,即使 CMake 文件清楚地将该文件夹标记为 include_directory

    *.hpp 文件不属于 ${SOURCE}

    include_directories("${PROJECT_SOURCE_DIR}/inc/")
    add_subdirectory(src)
    add_executable(${EXECUTABLE_NAME} main.cpp ${SOURCE})
    

    由于这是一个完全有效的 CMake 文件,并且将包含文件添加到源文件不是惯用的,因此我不想修改 CMake 文件。

    解决办法

    正如官方JetBrains Forum 所述,CMake 文件确实有效,并且由于 CLion 无法正确索引头文件而显示警告。从链接中提取的建议解决方法是右键单击文件夹和Mark directory as | Library Files/Project Sources and Headers.

    因此,此标头不包含在可执行文件中,并且 CLion 会通知您某些代码洞察功能可能无法正常工作。作为解决方法,您可以使用“将目录标记为”库文件/项目源和文件夹的标题。

    【讨论】:

    • 如果您不介意牺牲使用 Clion 构建的能力,您可以做得更好(我很高兴在命令行上构建并在 clion 中有正确的索引)。 CLion 为 cmake 提供了一个 CLION_IDE 环境变量,因此您可以将头文件添加到源数组 if ($ENV{CLION_IDE}),从而使 clion 正确索引所有内容(但会破坏您实际使用 Clion 集成构建的能力。
    • 值得注意的是:“标记为项目源”将无法正确处理包含目录等问题。
    • @ChrisKitching 但是你的 CMake 文件中有特定于 CLion 的东西,同时仍然使用命令行。那时,您不妨完全放弃 CMake 文件,只使用 Makefile 或在命令行上执行所有操作。另外,我在使用Mark directory as Project Sources and Headers 时从未遇到过不当行为。你到底有什么问题?
    • @ChrisKitching 我在执行此操作时没有遇到过这个缺点。您能否确认您仍然遇到此问题并发布另一条包含更多详细信息的评论或删除您之前的评论?
    • @xaxxon 你指的是哪个缺点? “标记为来源”不处理包括目录?我的第一条评论“破坏构建”?现在有些事情发生了变化:CMake 现在可以正确忽略源数组中的标题(可能是编辑答案)。 “标记为源”试图猜测将这些源逻辑“附加”到哪个目标以用于 clion 的索引。除了非常简单的项目之外,这通常会失败,从而导致索引失败。但是,现在还没有实际意义,因为您现在只需将所有内容转储到 CMake 目标源中,它就会正常工作。
    【解决方案2】:

    Clion 从 CMake 构建系统获取有关源文件的信息。当您将任何 cpp 文件添加到源列表时,CMake 会自动告知具有相同名称的标头。因此,如果 cpp/h 名称不同(或者您根本没有 cpp 文件),您应该手动包含标题。

    set(Sources my_lib.cpp)
    set(Headers header_of_my_lib.h)
    add_executable(superlib ${Sources} ${Headers})
    

    如果你没有任何可执行文件,你可以省略最后一行,CLion 仍然会知道文件

    【讨论】:

    • 请停止向可执行文件添加头文件。我的回答中描述了这个 JetBrains 错误的正确解决方法。
    • @sjaustirni CMake 不会感到困惑。有人争论 (Bahadir, Meeting C++ 2019) 头文件应该总是包含在可执行文件中。如果不出意外,这意味着用户的 IDE 在向 CMake 查询源文件时得到了正确的答案。
    • @cz 我承认没有看过演讲,但您不需要将头文件包含到可执行文件中,以便让您的 IDE 理解您的代码库并获得 Intellisense。如果您查看我对这个问题的回答,您可以了解如何在不使用头文件污染您的 CMake 目标的情况下做到这一点。
    • @sjaustirni 大约 9 分钟。开发人员的论点是头文件应该在 CMake 文件中,因为它让每个人都知道头文件属于哪个项目。他们还说它们不是必需的,并且 CMake 被编写为可以使用或不使用它们,但 IDE 应该使用它们(如果它们在那里)。
    • @c z 好点。这似乎是一个简洁的功能,谢谢。我的回答和第一条评论实际上早于这次谈话(显然,功能本身),所以我当时不可能知道它。我会考虑是否有时间更新我的答案:)
    【解决方案3】:

    此警告是一个 IDE 问题,Android Studio 无法识别当前目录如果它不包含任何源文件

    解决方法

    在有问题的目录下添加空源文件,例如empty_xxx.c,并在相应的CMakeList.txt中添加以下行

    add_library(${TARGET_NAME_XXX} SHARED ${SOME_DIR_HAVING_THIS_WARNING}/empty_xxx.c)
    

    将有助于消除此警告。

    【讨论】:

    • 您尝试接受的答案了吗?它没有工作吗?您应该不需要 cmake 解决方法。
    • 更具体地说,我看不到选项Mark directory as | Library Files/Project Sources and Headers
    • 可能是因为这个问题是关于 CLion 的。
    【解决方案4】:

    您可以像这样将头文件添加到您的项目中:

    set(SOURCE_FILES main.cpp MyClass1.cpp MyClass1.h MyClass2.cpp MyClass2.h)
    

    您也可以像这样通过多个步骤进行设置:

    set(SOURCE_FILES main.cpp)
    set(SOURCE_FILES ${SOURCE_FILES} MyClass1.cpp MyClass1.h)
    set(SOURCE_FILES ${SOURCE_FILES} MyClass2.cpp MyClass2.h)
    

    尽管如 cmets 中所述,您可能根本不应该将头文件添加到您的项目中。

    【讨论】:

    • SOURCE_FILES 是 cmake 中的一些魔法变量吗?我没有看到任何文档。
    • 提到here
    • 这并不意味着从 cmake 的角度来看,SOURCE_FILES 是一个需要设置的重要变量。
    • 也许如果 SOURCE_FILES 然后作为源列表添加到目标中,它会做一些事情,但没有它,我看不到任何说它本身的东西,做任何关于问题的事情询问。
    • 这不是“我有这种感觉”之类的东西。这是一个非常明确的“你做错了,现在你正在分享不良信息”之类的事情。您的回答是错误的,应该删除,因为其他人可能会相信您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    相关资源
    最近更新 更多