我正在尝试使用 make 构建一个文件。当我第一次运行 cmake .. 然后运行 make 命令时,出现致命错误:cdas/errnoname.h:没有这样的文件或目录。于是我找到了这个文件的副本,并将其复制到了src文件夹下的cdas/errnoname.h中。现在我再次运行此命令,但失败并显示 -
/root/project/src/pickle.cpp:27:10: fatal error: cdas/errnoname.h: No such file or directory
27 | #include <cdas/errnoname.h>
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [src/CMakeFiles/fuse-cpp-ramfs.dir/build.make:202: src/CMakeFiles/fuse-cpp-ramfs.dir/pickle.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:145: src/CMakeFiles/fuse-cpp-ramfs.dir/all] Error 2
但是src目录下的cdas文件夹中有一个名为errnoname.h的文件。我确保将其复制到那里。
src
├── ckpt.cpp
├── CMakeLists.txt
├── <Other .cpp and .h Files>
├── main.cpp
├── Makefile
├── cdas
│ └── errnoname.h
├── pickle.cpp
├── <Other .cpp and .h files>
现在有些人可能会说在包含时使用“”而不是<>。但问题是,当我将文件复制到 src 文件夹下的 cdas 目录时,它在另一台机器上运行。并且添加“”会导致编译中出现一些其他问题。
如何修复此错误? C编译器在第一次运行后是否看不到这个文件?它仍在查看文件的某些旧副本吗?为什么它在一台机器上工作,但现在在另一台机器上工作,即使机器配置相同
如果您需要任何其他详细信息,请告诉我。
上面的注释中有很多注释,但我认为了解
""
和 <>
#include
指令之间的区别很有用。 幸运的是,学习起来很简单。
首先要了解的是,两者之间没有区别这是 C/C++ 标准强制要求的。 也就是说,如何处理这两种形式的
#include
完全取决于各个编译器。 例如,编译器以相同的方式对待它们是明确可以接受的。 或者,非常不同。 因此,最终您可能需要查阅编译器的文档以确切了解它是如何工作的。
但是,大多数当前编译器实现都是这样处理它们的:当使用
<>
时,编译器通过首先按给定的顺序查找 -I
命令行选项给出的每个目录来查找标头,然后如果还没有发现它在一些预定义的系统头目录集中查找。 像 GCC(以及从 GCC 继承它们的 clang)这样的编译器有特殊的标志,允许您将搜索路径添加到“系统头目录”列表中,但这种事情只有在您做非常花哨的事情时才有用。 请务必注意,这些目录是唯一被搜索的目录。
使用
""
时,编译器首先在当前工作目录中查找,如果没有找到,则使用与<>
相同的算法。 因此,您可以将 ""
视为编译器,假装您提供了 -I.
作为编译行上的第一个 -I
选项。
作为提示:我同意上面的评论,建议您查看实际的编译器行以更好地理解行为,但这些评论没有描述如何做到这一点。 如果您将 Makefile 生成器与 CMake 一起使用,则可以通过将
VERBOSE=1
添加到 make
命令行来实现: make VERBOSE=1 ...