So here is a problem I have observed for a while, and several users have reported that to me: the problem is that for some reasons and only for some projects, when I do a ‘build’ in Eclipse CDT, it does a ‘full’ build. It does not only build the changed files, it builds all or many files in the project.
I expect that only the changed files will be rebuild. Instead, it compiles many files it should not compile/build, with the result that a build takes a very long time. That’s clearly wrong, and not what I expect. So what is causing this problem?
The issue is present in multiple Eclipse version (Kepler, Luna), with different Eclipse distributions (Kinetis Design Studio v2.0.0 and v3.0.0) with different make utilities. In all my projects I’m using the GNU ARM Eclipse plugins, but I doubt that this is the problem. I believe it might be more of a CDT problem instead.
The first observation was: The issue seems not to happen for ‘fresh’ projects, but happens for ‘older’ projects or some projects I have received from other users. It is even more strange, that the number of files unnecessary recompiled seems to be kind of random: sometimes it just triggers a new linking phase, sometimes it seems to affect only one or a few files, sometimes it seems to rebuild pretty much all of them. And things might even change depending on which files I change.
First I thought there might be something wrong with the file dates, as make needs to rebuild something when a source file is newer than the object file, or if the header file is newer than the source file using it. I had once a machine where the host clock was going wild, resulting in strange file time stamps. But on my current machine everything was OK.
Debugging Make Files?
If the files are not newer, maybe some do not exist? Checking them on the file system, object files all where there, all with newer file dates than the source files. So I started to see what kind of debug information I can get from make. Make has a –debug option (see https://www.gnu.org/software/make/manual/html_node/Options-Summary.html) which is very useful for debugging make files.
The only thing I found was that somehow some object files do not exist:
Reading makefiles... Updating goal targets.... File 'all' does not exist. File 'FRDM-K64F_Demo.elf' does not exist. File 'Sources/Joystick.o' does not exist. Must remake target 'Sources/Joystick.o'. Building file: ../Sources/Joystick.c
But they *do* exist before running the build! Strange. So something is deleting them, and somehow it must be the build process? But I have not seen any ‘rm’ or ‘del’ in the make logs.
Then, I thought it might be related to ‘Build Automatically’ setting:
‘Build automatically’ actually does not make any difference, as this functionality seems not be implemented in CDT: that would allow that the system would automatically build my application after I have changed and saved my file. So this was a Red Herring :-(.
External or Internal Builder?
What I noticed was that using the Eclipse Internal Builder does not have this problem. The problem only happened with using the external builder (external make):
With the internal builder, Eclipse uses its own built-in make utility, while with the external builder the build process uses an external make. So I thought that I have found a problem in make: Using different make executables did not make any difference :-(.
Actually, that ‘external builder’ was triggering something. After poking around this issue for a few days, finally I received a tip from Rock Li (thanks!): The issue seems to be related to the Refresh Policy setting in the project, which only affects external builders: If the refresh is set for an non-existing (or wrong directory), other than the project root directory itself, these strange rebuilds of files are happening:
And to my surprise: Deleting that wrong directory and using the project folder instead fixed the issue!
So the question is: what is this ‘Refresh Policy’ used for? As indicated in the dialog itself, it is only used if using an external builder (which is the case for my project). That refresh is executed after the build process, to make sure the Eclipse project knows about all the new files (object files, make files, etc) generated. But if that setting is wrong, wrong things might happen :-(.
And now I realize why I had some strange things with some projects, and not with others. That above project I had probably created as FRDM_K64F_Test, and then later renamed to FRDM_K64F_Demo, but that Refresh Policy setting did not get updated.
If your external make build in Eclipse CDT is taking too long and building too many files, then check what is specified in the Project settings, under Refresh Policy. If you have a wrong folder listed there, then this is very likely causing that problem.
I’m not sure if this is a problem of CDT, make or anything else. I just notice if I set the folder to the correct one, the issue goes away :-). If anyone has an explanation of what is happening, please comment :-).
Happy Building 🙂