Eclipse CDT在头文件更改时无法构建项目

17
我使用的是Eclipse Platform 3.7.2和CDT 8.0.2。在进行“Build All”时,来自其他工作区项目的标头文件不被视为依赖项,因此没有重新构建。我的应用程序中有一个helloworld应用程序和一个静态库项目。在“Project Properties->c/c++general->Paths and Symbols->References”选项卡中,将静态库设置为引用,并勾选“Active”。这是我更改的唯一设置。
顺便说一下,我完全不明白为什么Eclipse在Project Properties下还有额外的“Project References”顶级项目。
无论如何,我尝试了内部生成器和外部生成器,还结合了“首选项->c++->Build->仅当Eclipse资源更改时才构建构建配置”的全局设置的组合……
谢谢你对此的任何看法。
更新: 在构建Proj2(Proj1是该库)所依赖的项目时,以下是控制台输出。 调用'make all',但它仅重新链接,而不重新编译Main.cpp,正如它应该做的那样。 有人熟悉由Eclipse生成的makefile吗?再次感谢。
**** Build of configuration Debug for project Proj2 ****

make all 
Building target: Proj2
Invoking: Cross G++ Linker
g++ -L"/home/user/.eclipse-workspace/Proj1/Debug" -o "Proj2"  ./Main.o   -lProj1
Finished building target: Proj2


**** Build Finished ****

编辑:这已经是1.5年前的内容了,但我想补充一下,Eclipse已经为此提交了一个bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=375800


我在使用较新版本的eclipse/CDT时看到了同样的问题。据我了解,构建正在生成包含在makefile中的.d头文件依赖项,但是那些规则是不正确的。规则目标是.d文件本身而不是.o文件...这似乎是由于使用了-MT选项不正确地设置了.d目标所致。 我没有看到改变这种情况的方法-您是否曾经能够解决此问题? - salty
我无法解决。另请参见我提交的Eclipse错误,下面有链接。 - haelix
我目前也遇到了同样的问题。我更喜欢将导出的头文件放在根目录下的/include目录中,如果我更改其中一个头文件,那么如何让使用特定头文件的源代码知道它已经更改了呢? - CashCow
看看Eclipse的bug。与此同时,有人发布了一些解决方法。 - haelix
3个回答

7
这个问题存在一个错误: https://bugs.eclipse.org/bugs/show_bug.cgi?id=375800 同时也有一种有效和整洁的解决方法(原提出者已经知道)。因此我只是交叉链接到实际答案 :) https://bugs.eclipse.org/bugs/show_bug.cgi?id=375800#c11 所有功劳归于Krzysztof Czaińsk。
在你的C或C++编译器设置项目中,在标志后面添加-MT ${OUTPUT_PREFIX}${OUTPUT}
${COMMAND} ${FLAGS} -MT ${OUTPUT_PREFIX}${OUTPUT} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

这将创建正确的 .d 文件。


补充说明:这个解决方法有一个副作用。在执行干净的 make all 命令之后,需要运行两次才会显示无需更新。但这仍然比在更改后不编译要好。


我知道,我去年就报告了。:) 自那时以来已经被几个人确认过了。我编辑了问题描述,使这更加明显。 - haelix
我一定会尝试这个解决方法,应该非常有用。如果对我有效,我会更新的。 - haelix
这对我很有效。每次更改定义值时都必须清理非常令人沮丧。谢谢! - DCurro

1
最安全的做法是先“清理”主项目,然后重新构建。通常情况下,当我知道主项目中使用修改后头文件的文件时,我只需“touch”这些文件,然后重新构建。对我来说,“touch”就是在一行上添加一个空格,通常是文件顶部的#include之一。然后该文件将被重新构建并获取修改后的头文件。可能使用该头文件的其他文件不会被重新构建,因此这很危险。例如,如果您更改了方法调用的签名并以这种方式重新构建,则只有一个文件将正确调用新方法。从其他源文件调用可能会导致程序陷入困境。当然,重建速度是优势。特别是在进行单元测试时,我知道我将运行哪些测试,因此我只需触摸相关文件,重新构建并运行。为了安全起见,我总是进行一次清理/构建周期。通常我会等到需要更多咖啡的时候再进行。

1
如果你找到了更好或更简单的方法,请告诉我。这是我发现的唯一让我的代码正确编译的方法。我曾经尝试过使用“项目属性->C/C++常规->路径和符号”,然后使用“引用”选项卡。我勾选了我所依赖的库。不幸的是,它把事情搞糟了,花了我一个小时才恢复正常,所以我以后避免使用这个面板,但我认为这应该是解决库依赖关系的地方。 - Tod
请查看上面Jan的答案。它解决了我的问题。 - DCurro

0

只是想提出一个问题,您是否仍然需要在客户端代码中包含静态库的头文件?如果是这样,我认为您需要在客户端项目属性的includes选项卡中添加头文件。否则,我不确定您如何实际访问客户端中的静态库实现。

至于两个references选项卡,我认为C/C++通用选项卡可以针对不同的配置单独定义,而更通用的选项卡适用于任何配置。

更新:
我建议使用您提到的更通用的reference选项卡。这应该确保您的客户端无论当前选择的配置或所引用的项目是什么,都能引用其他项目。

另一个更新:
我刚刚意识到你提到的唯一更改是references设置。这可能是一个长期的尝试,但我也会检查静态库的包含路径是否实际显示在项目设置的包含选项卡中(可能是)。我知道编译时使用了正确的包含路径,但Eclipse(可能)使用选项卡来确定包含依赖项,以决定启动客户端项目的重新编译。也许值得检查“源位置”选项卡,并尝试将头文件位置添加为源位置。

enter image description here


设置项目引用会将-I(包含路径)添加到g ++编译器参数中,并添加-lProjName进行链接。否则,我无法编译。我可以进行干净的构建并且可以工作,但是当库头文件更改时,构建全部就不起作用了。我的客户端项目编译器就是不被调用。 - haelix
你好!即使使用更通用的“引用”选项卡也无济于事,当被依赖项目的头文件发生更改时,依赖项目并不会重新编译。它只是重新链接库。请参见更新的问题。 - haelix
再仔细想一下,为什么静态库的头文件可以改变而不必重新编译库本身呢?我认为发生的情况是构建器检查静态库二进制文件是否已更改。如果没有更改,则无需重新编译依赖项目。新头文件中发生了哪些变化? - Mike G
该库本身正在重新编译。构建器正在检查库二进制文件是否已更改,并进行重新链接。但是,由于包含头文件,cpp文件也应该重新编译。 - haelix
好的,听起来确实像是个bug。再读一遍你的问题,静态库的包含目录实际上出现在客户端设置中的include选项卡中了吗?(请检查我的答案更新中的图片。) - Mike G
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接