c++ - 链接到项目找不到头文件

标签 c++ ubuntu cmake makefile static-libraries

我想制作一个简单的静态库,并从另一个项目链接到它。创建库的三个源文件(都在同一目录中):main1.cppheader1.hheader2.hmain1.cpp 包含行 #include "header1.h",而 header1.h 包含行 #include "header2.h”。为了创建库,我在我的 CMakeLists.txt 文件中使用了 add_library(foo STATIC main1.cpp)。运行 cmake,然后 make 按预期创建文件 libfoo.a

然后我有另一个项目,有一个文件 main2.cpp,其中包含行 #include "header1.h"。在这个项目的 CMakeLists.txt 文件中,我使用 add_executable(bar main2.cpp)target_link_libraries(bar foo.a) 来创建链接到我的静态库的可执行文件。然后我复制 foo.aheader1.h 文件并将它们放在与该项目相同的目录中。

问题是,在编译第二个项目时,出现以下错误:

header1.h: fatal error: header2.h: No such file or directory

所以它告诉我无法找到 header2.h,即使它在 header1.h 中被引用。但是,我会想到建库时foo.a的内容会包含header2.h的所有内容?当我想构建第二个项目时,我当然不应该包含第一个项目的所有头文件吗?

谢谢:)

最佳答案

简短回答:您将需要所有公开您希望库导出的功能的头文件。换句话说,如果头文件包含仅在库中使用的函数,则不需要公开这些头文件,除非您公开的某些头文件包含该头文件。

库包含的内容和头文件的内容之间似乎有些脱节。为简单起见,我们将头文件的用途限制为具有函数原型(prototype)(稍后将删除这种简化)。头文件的目的是告诉您的新代码(不是库的一部分)函数的外观,如名称、参数和返回类型。当您编译新应用程序时,如果没有此信息,它将不知道如何处理诸如如何传递参数和如何处理返回值之类的事情。请注意,我没有在头文件中说明函数的作用,就像在函数的机器代码中一样。这就是图书馆的内容。您需要这两个部分才能正确编译您的应用程序。

这可以扩展到您在头文件中找到的其他内容,例如结构。关键思想是您的应用程序仍然需要一些信息,例如函数原型(prototype)和结构定义。

您还需要记住#include 的作用。在其最简单的形式中,它只是抓取指定文件的内容。因此,如果一个头文件包含另一个头文件,则第二个头文件的内容也会被抓取。

请注意,无论是静态库还是共享库,这都适用。


下一部分可能不是您想要做的,但它是 future 访问者和您自己可能会觉得有用的信息:

现在假设 header1.h 包含您希望公开的函数,而 header2.h 仅包含您希望内部的函数。然后不要让 header1.h 包含 header2.h 你应该将它们单独包含在源文件中,将它们包装在另一个你可以包含的头文件中,或者有 header2.h 如果依赖项允许,则包含 header1.h。这样您只需为您的库用户提供 header1.h。这并不是说他们不能使用 header2.h 中的函数,因为它们仍然会被库公开,因为头文件不控制它,但这会使它稍微有点困难使用它们。如果你想真正阻止图书馆用户使用你不打算公开的功能,请查看此 SO question .

关于c++ - 链接到项目找不到头文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31391731/

相关文章:

c++ - 在 constexpr 构造函数中获取一个特殊的指针值(类似于 "second"nullptr)

Docker Nginx 主机无法解析

cmake - Rust on Windows CMake 问题

opencv - CMakeLists.txt CMAKE_PREFIX_PATH 处的 CMake 错误

c++ - move 构造函数与复制省略。哪一个会被调用?

c++ - 如何从 qmlRegisterSingletonType 的回调中访问 QML 加载项?

c++ - 使用坐标和 time_t 的时钟程序

ubuntu - Gitlab CI 免费共享运行器来配置 Ubuntu 而不是 CoreOS?

linux - 如何创建一个 debian 软件包,在更新软件包时仅更新所需的文件

c++ - cmake 不使用 boost 多线程库