我遇到了包含文件的奇怪问题,以及Eclipse的构建过程和错误报告之间的明显脱节。我将给出重现此问题的详细步骤,以便我们尽快缩小原因。
用于C / C ++ Linux开发人员的Eclipse 3.7.1(Indigo SR1),Ubuntu 10.10 64位这一切都始于我导入一个现有的项目“自己做得很好”:我认为Eclipse会大大帮助导航文件并弄清楚是什么做的。但是,在Eclipse的视图中,某些#include
d系统头文件似乎没有正确的效果。这非常令人费解,在调查过程中,我设法在一个小沙盒中重现了这个问题。
第一步:使用File: New: C Project
示例创建一个新的C项目(Hello World ANSI C Project
)。参数为Executable: Hello World ANSI C Project/Linux GCC
,其余Empty
项目设置为Linux GCC
,GNU Autotools
设置为Hello World ANSI C Autotools Project
。称之为“你好”。一定要自动生成makefile(高级设置,我相信这是默认设置)。
第二步:调整包含路径。使用Project: Properties: C/C++ General: Paths and Symbols: Includes: GNU C
,将搜索路径设置为/usr/local/include
,/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include
,/usr/include
。第二条路径取决于您安装的gcc的确切版本。只要构建路径至少包含/usr/include
。
现在,如果你打开hello.c
,它看起来很简单,除了return EXIT_SUCCESS;
之外,Eclipse非常高兴,它无法解析EXIT_SUCCESS
。将EXIT_SUCCESS
替换为零(0
),Eclipse将全部清除。选择Project: Build Project
以生成可执行文件。
打开命令行窗口并深入查看Eclipse工作区文件夹的hello/Debug
子文件夹。在那里,您可以使用行./hello
运行可执行文件。
现在开始变得有趣了。修改hello.c
以阅读其后半部分:
#include <fcntl.h>
int main(void) {
printf("Hello World!\n");
int zz = SPLICE_F_MOVE;
printf("zz (SPLICE_F_MOVE) is '%d'\n", zz);
printf("Bye World!\n");
return 0;
}
int zz...
行上会出现错误:"Symbol 'SPLICE_F_MOVE' could not be resolved"
。如果您构建项目,您将在控制台视图中收到类似的错误:"error: 'SPLICE_F_MOVE' undeclared"
。
现在,如果您将序言改为:
#define _GNU_SOURCE
#include <fcntl.h>
您仍然在int zz
行(在编辑器中)收到错误,但该项目将正确构建!您可以通过在先前打开的命令行窗口中运行二进制文件来确认这一点。这真的很奇怪,因为/usr/include/fcntl.h
的检查会显示#include
s <bits/fcntl.h>
,而后一个标题#define
s SPLICE_F_MOVE
(和其他一些人)在由#ifdef __USE_GNU
守卫的区块中__USE_GNU
获得#define
d,如果_GNU_SOURCE
是#define
d)。为什么地球上的#define _GNU_SOURCE
不是在工作空间视角中正确传播的?
简而言之,这就是我的问题:为什么编辑器(以及所有Eclipse CDT)报告错误(显然是拒绝正确处理包含),但底层构建成功了?
答案 0 :(得分:1)
我在使用GNU和非GNU兼容工具链进行交叉编译各种微控制器时遇到了类似的问题。 CDT报告了许多错误,但实际构建工作完美,即使所有标题包含都正确地位于项目设置中。
问题在于CDT如何与您的make系统构建区别开来。 CDT是一个独立的词法分析器,解析器和预处理器,并不使用您用于构建的工具链。一旦将项目设置设置为与构建工具的命令行参数生成的项目设置相匹配,这通常可以正常工作,但是许多工具链经常包含隐藏的隐式定义作为其编译器/预处理器本身的一部分。 implict / hidden定义的文档在我的经验中通常是粗略的和不完整的,因此几乎不可能确定为给定的工具链设置哪些定义(有时甚至依赖于构建选项)以及它们的含义。虽然你可能看起来已经设置了所有正确的定义来达到你遇到问题的那个,但我通常会发现(特别是对于GNU)有一些你错过了阻止交换机被处理的方式你预期。
当我调试这样的东西时,我首先确保在项目目录中找到任何标题,如果它们的名称与其他目录中的名称相匹配,那么我会慢慢开始将标题包文件夹中的标题移动到我的项目文件夹中。 CDT没有很好地指出它首先解析哪个头文件的可能版本,并且它经常在你最不期望的时候提取系统环境设置,但是它确实首先在你的项目文件夹中查找头文件(如果你没有不要将项目设置中的系统标题路径设置为优先级。通过将系统头从您正在查看的位置移动到项目目录,您可以确切地知道CDT正在解析哪个头文件。此外,如果在执行移动后重建索引,然后在Eclipse中打开文件,CDT将通过灰化或折叠标头中未启用的分支来指示它认为启用或禁用的开关。按照这个过程每次都为我解决了这个问题,揭示了我有相同标题的多个副本的路径,意外重复的标题,在意外的开关下定义或包含等等。
答案 1 :(得分:0)
我有同样的问题,但是甚至没有做任何复杂的事情来制作它 - 我刚刚制作了你所描述的类型的hello world项目并得到了同样的错误。但请注意,在我的情况下,可能是由于cygwin的安装错误 - 例如,我有其他错误,无法包含.h文件,以及完全删除/重新安装cygwin删除那些错误,但“符号......无法解决”错误仍然存在。
然后我决定制作一个第二个这样的项目,他们都在“问题”视图中报告了这样的错误,但只有一个的项目实际上显示了编辑器中的错误下划线等(!)
答案 2 :(得分:0)
也许这个问题来自Ijndigo本身。您是否尝试过使用最新的Indigo SR2?我在日食bugzilla中为Indigo和它的SR1打开了一些bug。