Eclipse 编译成功但仍然给出语义错误
Posted
技术标签:
【中文标题】Eclipse 编译成功但仍然给出语义错误【英文标题】:Eclipse compiles successfully but still gives semantic errors 【发布时间】:2013-05-23 02:23:58 【问题描述】:注意:这显然是 *** 上经常出现的问题,但是 - 就我所见 - 要么人们永远找不到方法,要么他们的解决方案对我不起作用
问题:
我正在使用 Eclipse Juno ADT。在我尝试更新 NDK 之前,一切正常。我用新版本(即ndk-r8e
)替换了我的ndk
文件夹(即ndk-r8d
),并且在我的Paths and Symbols
配置中,我将包含的内容从g++ 4.6 更改为4.7。
它似乎破坏了我的索引:我可以编译我的代码,但是 Eclipse 给出了语义错误,就像 [1] 和 [2] 中的错误。错误主要来自OpenCV4android使用的符号,如distance
、pt
、queryIdx
和trainIdx
。
当我尝试备份到旧配置时,索引仍然损坏!我找不到改变这种情况的方法。
我尝试过的
清理项目 “索引”子菜单中的重建、刷新和所有其他选项(在项目上“右键单击”时) 在首选项中禁用/启用索引器 验证trainIdx
等符号仅出现在我的 OpenCV4Android 中,包括在 Paths and Symbols
部分中。
在Paths and Symbols
部分更改我的包含顺序。我基本上尝试将 OpenCV 包含在开头和结尾。
一些观察
什么不工作
我认为它是 CDT 索引,原因如下:
在命令行中,我可以使用ndk-build clean
和ndk-build
构建我的项目。
当我启动 Eclipse 时,在我打开一个 C++ 文件(来自 jni
文件夹)之前,我没有任何错误。
我总是可以构建项目,但是只要我打开了一个C++文件,我就不能再运行应用程序了,因为很多Field '<name>' could not be resolved.
如果我不打开 C++ 文件,Eclipse 不会报告任何错误,并且可以成功构建和部署 Android 应用程序。
有趣的事实
以下代码在line
、queryIdx
、pt
上报告错误:
cv::line(mRgb, keypointsA[matches[i].queryIdx].pt, keypointsB[matches[i].trainIdx].pt, cv::Scalar(255, 0, 0, 255), 1, 8, 0);
如果我这样写,它可以工作:
cv::DMatch tmpMatch = matches[i];
cv::KeyPoint queryKp = keypointsA[tmpMatch.queryIdx];
cv::KeyPoint trainKp = keypointsB[tmpMatch.trainIdx];
cv::line(mRgb, queryKp.pt, trainKp.pt, cv::Scalar(255, 0, 0, 255), 1, 8, 0);
并不是所有的 OpenCV 函数都未解析:只有 pt
、queryIdx
和 trainIdx
是。
任何评论将不胜感激。
【问题讨论】:
打开eclipse的问题透视图。它应该显示大量错误(每个条目旁边带有红色标记的条目)。删除所有条目并重建您的应用程序。我有同样的问题,这真的很无聊 @blackbelt Blackbelt 提供了一个快速解决方案,如果您再次遇到该问题(并且有一两个条目只是困扰您)。 这是 S.O 问题应该是什么样的完美示例。很好地划分为“问题”、“什么不起作用”、“我尝试过的”等。也许我们应该将新注册的用户作为一个例子。 【参考方案1】:在 Eclipse 环境中选择的项目首选项中,转到 C/C++ 常规 -> 代码分析 -> 启动。确保两个复选框都未选中。关闭并重新打开项目或重新启动 eclipse 并重建项目。
【讨论】:
是的,Eclipse中Android gcc的on-the-fly代码分析器似乎还不成熟。 这不是解决方案本身,但我最终不得不这样做。 它是“目前”的解决方案 @AlexCohn +1 愿上帝保佑你,这个问题让我疯狂了一整天【参考方案2】:由于 Eclipse 上的 Android 本机代码索引不完整,我设法以以下不直观的方式在我的 NDK 项目中启用索引,无论您使用ndk-build
还是普通的make
甚至cmake
,它都应该工作。我正在使用开普勒,但它也应该适用于旧版本。
正确使用您的工具链
右键项目->Properties
->C/C++ Build
->Tool Chain Editor
->取消选中Display compatible toolchains only
。
在同一窗口中,将Current toolchain
设置为Linux GCC
。
在同一窗口中,将Current builder
设置为Android Builder
,如果使用ndk-build
,则设置为Gnu Make Builder
,否则设置为Gnu Make Builder
(此步骤可能有误,如有错误请提前见谅)。
右键单击项目 -> Properties
-> C/C++ Build
-> Build Variables
-> 确保 Build command
为您的项目读取正确的命令;如果不是,请取消选中 Use default build command
并更正它(可能是您想要的 ndk-build
或 make -j5
)。如果您在单独的终端中构建本机代码,则可以跳过此步骤。
制作一个独立的工具链,这可能是在一个地方获取 STL 源代码的最简洁方式
转到 NDK 根目录。运行以下命令(根据您的喜好调整设置)。如果您没有对--install-dir
的写入权限,请添加sudo
,因为脚本会静默失败。
./build/tools/make-standalone-toolchain.sh \
--platform=android-14 \
--install-dir=/opt/android-toolchain \
--toolchain=arm-linux-androideabi-4.8
这是假设您使用 GNU-STL。如果您使用另一个 C/C++ 库,则需要调整上述命令,可能还需要调整下一个命令中的包含路径。
为您的项目添加必要的包含路径
右键单击项目 -> Properties
-> C/C++ General
-> Paths and Symbols
-> 转到 Includes
选项卡 -> 从 Languages
中选择 GNU C++
-> 单击 Add
并添加以下路径(假设您将独立工具链安装到/opt/android-toolchain
):
/opt/android-toolchain/include/
/opt/android-toolchain/include/c++/4.8/
/opt/android-toolchain/include/c++/4.8/arm-linux-androideabi/
/opt/android-toolchain/lib/gcc/arm-linux-androideabi/4.8/include/
/opt/android-toolchain/include/c++/4.8/backward/
/opt/android-toolchain/lib/gcc/arm-linux-androideabi/4.8/include-fixed/
/opt/android-toolchain/sysroot/usr/include/
在这里,您可以添加所需的每个包含路径。事实上,我为 Android 构建了我的 OpenCV 并安装在独立工具链中,因此我在其中包含以下内容:
/opt/android-toolchain/sysroot/usr/share/opencv/sdk/native/jni/include/
现在,索引应该可以工作了。您还应该能够运行ndk-build
(或make
,如果这是您的构建方法),然后将您的项目部署到Eclipse 中的设备上。
为什么?
在 Eclipse 上的 Android 本机开发是不完整的,因为索引不能开箱即用。这是由于必须支持多种架构(ARMv7、Intel 等)、多个 STL 选项、多个 Android 版本等。这就是为什么你有基于 make
的裸露的 ndk-build
和整个 NDK 结构,这也是为什么 NDK 开发非常不干净,而且很少有大量的原生 Android 项目存在。
一个大的 Android 项目是 OpenCV,他们必须开发一个 1500 多行的 CMake 脚本才能正确编译 Android。在某些时候,他们试图将该脚本导出为基于 CMake 的 Android 构建系统,但它无法跟上 NDK 系统的变化并被放弃。这种支持应该在 NDK 本身内部。
默认的 NDK 构建系统应该只是独立的工具链,所有不同的架构/C++ 库都有自己的工具链,但以存储空间为代价,但具有简洁、直观和良好实践的优势。然后,您可以合并任何在其他地方也使用过、经过测试且众所周知的标准交叉编译系统,例如 CMake。您可以并且在我看来您应该使用 NDK 的 make-standalone-toolchain
命令来执行此操作,如上所示。但最后,这只是我的看法。如果您对ndk-build
感到满意,请继续。
【讨论】:
我猜想 Android.mk 和整个 ndk-build 系统的主要 存在理由 是它是从 Android 系统树中删除的。起初,谷歌认为人们根本不需要 C/C++ 来开发他们的应用程序,只需要作为系统库。后来,他们提供了 NDK,但它仍然被只与系统树构建相关的工具污染。 这是有道理的。但是,我发现一开始就看到对 C++ 的非必要支持是很幼稚的。以游戏为例,很明显它们是移动应用程序世界的重要组成部分,它们实际上是 %99 的原生代码。可能还有其他类似的应用程序(例如图像处理或使用视觉效果)。所以最终,他们应该为原生开发提供强大而简单的支持。 嗯,大约 14 年的 NDK 比 3 年前要强大得多、功能丰富且简单得多。我应该说我不同意您对独立工具链的偏好。移植大量现有的基于 make 的项目是完美的,但它不能满足为 arm/mips/x86 等编译的需要。我发现对于本土项目,设置Android.mk
文件层次结构并启用是值得的快速简便ndk-build
。顺便说一句,有一个非常有帮助的CMake adaptation for Android NDK。它确实使用独立的工具链。
关于另一个话题,那个CMake适配是我在原答案中谈到的:它是从OpenCV Android CMake脚本导出的,最后一次提交是在2012年。原脚本(可以是OpenCV repo 中找到的)从那时起已经发展和发展了很多。但是可以使用 5 行 CMake 工具链脚本来设置您的 sysroot 来实现类似(但更简单)的功能。
对了,在一个无关的话题上,帮自己一个忙,改用vim+YCM进行c/c++开发。 Eclipse 确实不是一个很好的工具。【参考方案3】:
实际上很难说是什么问题。以下是一些建议:
-
尝试导入并构建
hello-jni
(它位于jni
的samples
文件夹中)。如果它运行没有问题,那么问题在于将 OpenCV 链接到您的项目。
您似乎忘记更新project properties -> c/c++ build -> environment
中的android-ndk
位置。这是问题Issue with build Android NDK project的链接。
从控制台构建您的项目 (ndk-build -B
),手动删除 Eclipse 中的所有错误(在 Problems
视图中选择所有错误,然后单击 delete)并尝试立即运行项目。有时这种“hack”可以帮助我运行项目。
关闭Eclipse并删除文件夹path-to-your-workspace/.metadata/.plugins/org.eclipse.cdt.core
(先备份)。
【讨论】:
感谢您的帮助。我明天试试1.
。对于2.
,我已经更新了。我目前正在使用3.
运行该项目,但我每次都需要这样做,因为同样的错误会再次出现。我想我已经尝试过4.
,但我明天会再试一次!
4.
不起作用。对于1.
,我在hello-jni.c
中有错误:Method 'NewStringUTF' could not be resolved
。有什么新想法吗?
更有趣的是,我安装了一个新版本的 Eclipse-ADT 来导入我的项目,它也有同样的错误。然后我尝试在这个新的 Eclipse 中导入hello-jni
,它有同样的错误。我的问题可能与我的 Ubuntu 有关吗?在过去的几个月里,一切都运行良好......
我确实没有,因为还没有 NDK 集成... =)
@JonesV,是的,我说“不会有”。这是来自 Google 的 Android IDE,它显然会拥有它。 Read this.【参考方案4】:
转到首选项 > C/C++ > 语言映射 > 添加(源 C 文件并选择 GNU C)对 C++ 执行相同操作
【讨论】:
【参考方案5】:我有同样的问题。我已经设置了所有正确的包含路径,但是在打开 .c/.cpp 或 .h 文件后,它会开始将所有内容标记为“未解决”。 这对我有用... 前往: 首选项 -> C/C++ -> 索引器 检查编辑器中打开的索引源和头文件。
【讨论】:
【参考方案6】:和很多人一样,我也有同样的问题。
我按照 Ayberk Özgür 帖子中的步骤进行操作,这很有意义。尽管我还必须确保在所有三种语言下都包含包含:GNU C、GNU C++ 和汇编。可能是因为我没有使用独立的工具链。
我起初只在 GNU C 和 GNU C++ 语言下包含我的内容。这让我仍然有未解决的包括错误。直到我在汇编语言下分配了我的包含,我的错误才消失。
我不知道为什么 eclipse 只搜索我项目中包含的汇编程序。我也不知道这部分解决方案如何适用于更大更复杂的项目。
希望这会有所帮助。
【讨论】:
【参考方案7】:Eclipse CDT 与 OpenCV 库一起工作时,我遇到了类似的情况。程序正确编译时,我收到了几条错误消息。我将“window->preferences->Indexer”“索引器的构建配置”框中的索引器设置更改为“使用活动配置”,这解决了我的问题。
【讨论】:
【参考方案8】:我刚刚花了大约 3 小时来解决这个 Eclipse NDK 索引问题!..
它的工作原理:确保您在 Application.mk 文件中只指定了一个 cpu 架构。
否则 .metadata/.plugins/com.android.ide.eclipse.ndk/*.pathInfo 文件将不会由 NDK 构建生成。此文件包含来自 Project -> Properties -> C/C++ General -> Paths and Symbols -> Includes 的内置值(仅制作 .pathInfo 文件并不能解决问题)
【讨论】:
以上是关于Eclipse 编译成功但仍然给出语义错误的主要内容,如果未能解决你的问题,请参考以下文章
Eclipse ADT 22.6.2 仍然给出错误“java.lang.NullPointerException”
在 Maven 中成功构建仍然在 Eclipse 中显示错误