Bug 550753 - Indexer problem: file with the same name includes other file where folder name of the included file ends with the name of the folder of the including file
Summary: Indexer problem: file with the same name includes other file where folder nam...
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-indexer (show other bugs)
Version: 9.6.0   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-09-04 11:27 EDT by Wolfgang Petroschka CLA
Modified: 2020-09-04 15:20 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wolfgang Petroschka CLA 2019-09-04 11:27:47 EDT
If a file includes a file with the same name there is a problem if
the folder name of the included file ends with the name of the folder of the including file.
Jumping to the (correct) file with F3 (Open Declaration) does not work then.  The jump occurs to the beginning of the including file.
Also the indexer gets confused about contents (e.g. defined types) of the including file.


Project structure:

myproject/gnarlbar/foo.hpp
myproject/bar/foo.hpp

Content of myproject/gnarlbar/foo.hpp:

#ifndef FOO_HPP_
#define FOO_HPP_

#include "bar/foo.hpp"

#endif

If you click on bar/foo.hpp in the editor and hit F3 the cursor jumps to line 1 of the same file instead of into the file bar/foo.hpp.

If you change the name of the folder myproject/bar or the name of the file myproject/bar/foo.hpp (and adjust the include statement) then everything works fine.

If you change the name of the folder myproject/gnarlbar (so it does not end in "bar") or the name of the file myproject/gnarlbar/foo.hpp then everything works fine as well.
Comment 1 Nathan Ridge CLA 2019-09-08 01:15:27 EDT
How are you configuring your project's include paths? Without any include directories configured, '#include "bar/foo.hpp"' in 'myproject/gnarlbar/foo.hpp' shouldn't resolve at all, because as a plain relative path it would refer to 'myproject/gnarlbar/bar/foo.hpp' which doesn't exist.
Comment 2 Wolfgang Petroschka CLA 2019-09-09 05:33:50 EDT
> How are you configuring your project's include paths?

I didn't configure any include path.

> '#include "bar/foo.hpp"' in 'myproject/gnarlbar/foo.hpp' shouldn't resolve
> at all

It always works/worked for me. Unless there is this odd overlap in directory names.

Before we updated our tool chain recently, we used Eclipse Kepler and indexing also worked fine without project internal include path being configured.

The project we're working on contains 100+ libs and 10+ binaries. We're building with SCons. We never configured the project internal include paths in Eclipse still indexing worked generally fine - besides minor problems (unrelated to include path issues, e.g. templates with value parameters).

After switching to a current Eclipse version I tried to clean-up all indexer issues. Now I ran into this include path issue. If I rename the files or/and directories indexing works just fine - without configuring include paths. But maybe this is the real bug!?
Comment 3 Nathan Ridge CLA 2019-09-09 11:19:23 EDT
Do you have "Allow heuristic resolution of includes" checked in Preferences -> C/C++ -> Indexer?

If so, try unchecking it. (If that then causes the '#include "bar/foo.hpp"' to become unresolved, try adding the project's root directory (or whichever directory "bar/foo.hpp" is relative to in your actual project) as an include path in the Project Properties.)
Comment 4 Wolfgang Petroschka CLA 2019-09-12 02:12:14 EDT
Yes, this option is checked.

If I uncheck the path (and others are unresolved).

This means the problem is in the "heuristic resolution of includes", right?
Comment 5 Nathan Ridge CLA 2019-09-12 20:53:32 EDT
It looks like (In reply to Wolfgang Petroschka from comment #4)
> This means the problem is in the "heuristic resolution of includes", right?

A heuristic will by definition give inaccurate results in some cases.

It looks like, in this case, the heuristic is for "bar/foo.hpp" to match any path that ends in "bar/foo.hpp", including "gnarlbar/foo.hpp".

Now, perhaps the heuristic could be improved. It might be better to only accept matches that start at a path element boundary, so that "bar/foo.hpp" matches "gnarl/bar/foo.hpp", but not "bar/foo.hpp". I think that's a reasonable suggestion, and we can use this bug report to track it.

But even a heuristic modified in that way will give inaccurate results for some projects. If you have multiple subdirectories named "bar" with "foo.hpp" in them, "bar/foo.hpp" may still be matched against the wrong one.

At the end of the day, if you want accurate results, my suggestion is to turn off heuristic resolution and specify the project's include paths in the project configuration. CDT provides some mechanisms that make it pretty easy for many projects. For example, there is a "build output parser" that will parse the output of the project's build and automatically pick out the "-I" directives and configure those directories as include paths.
Comment 6 Nathan Ridge CLA 2019-09-12 20:54:20 EDT
(In reply to Nathan Ridge from comment #5)
> It might be better to only
> accept matches that start at a path element boundary, so that "bar/foo.hpp"
> matches "gnarl/bar/foo.hpp", but not "bar/foo.hpp".

That should read 'but not "gnarlbar/foo.hpp"'.
Comment 7 Wolfgang Petroschka CLA 2019-09-13 07:55:02 EDT
> A heuristic will by definition give inaccurate results in some cases.

That's clear, of course

> It looks like, in this case, the heuristic is for "bar/foo.hpp" to
> match any path that ends in "bar/foo.hpp", including "gnarlbar/foo.hpp".

I think so, too.

> Now, perhaps the heuristic could be improved. It might be better to only
> accept matches that start at a path element boundary, so that
> "bar/foo.hpp" 
> matches "gnarl/bar/foo.hpp", but not "bar/foo.hpp". I think that's a 
> reasonable suggestion, and we can use this bug report to track it.

That would fix my problem.

> But even a heuristic modified in that way will give inaccurate results for 
> some projects. 

I agree and that's fine with me. Just in my case it is an unnecessarily inaccurate result.

> At the end of the day, if you want accurate results, my suggestion is to 
> turn off heuristic resolution and specify the project's include paths in
> the project configuration.

The thing is we have a SCons based build system which pick-ups include paths automagically. The project is quite big and has many include paths (100+) to configure. Currently everything works fine with Eclipse's magic - except in this situation. So this lazy approach is quite convenient.

It wouldn't be a big problem to let SCons dump all the include paths. But I think it would be a pain configuring them via the GUI as you can only enter one path at a time.

Also the project is quite dynamic so the paths change quite a lot, which would make it necessary to manually diff the configured include paths frequently.

Maybe I have to look into a solution to directly change the Eclipse project file instead of going through the UI.
Comment 8 Nathan Ridge CLA 2019-09-15 14:05:55 EDT
(In reply to Wolfgang Petroschka from comment #7)
> It wouldn't be a big problem to let SCons dump all the include paths. But I
> think it would be a pain configuring them via the GUI as you can only enter
> one path at a time.

This is why I suggested using the build output parser. It can be enabled in Project Properties -> C/C++ General -> Preprocessor Include Paths, Macros etc. -> Providers tab.

As long as you can get the build to output the compiler commands that are being executed (including their "-I" flags), this should configure the includes for you automatically, with no manual entry in the GUI required.
Comment 9 Wolfgang Petroschka CLA 2019-10-24 02:15:38 EDT
> This is why I suggested using the build output parser. It can be enabled in > Project Properties -> C/C++ General -> Preprocessor Include Paths, Macros
> etc. -> Providers tab.

Sorry, that sentence didn't register with my brain.

> As long as you can get the build to output the compiler commands that are
> being executed (including their "-I" flags), this should configure the
> includes for you automatically, with no manual entry in the GUI required.

I failed to get this to work with our cross-compiler, but that is probably my bad. Anyhow, we got the include paths in another way:
We wrote a little tool that dumps all include paths that are used throughout the build and added those.

This revealed another problem though:
As our project contains multiple libraries and executables to be built, they all use a different set of include paths. Now setting all the include path led to a completely confused indexer.

I guess our project structure is not really compatible with Eclipse.

As a workaround we now use a mix of heuristic include paths and configured external include directories of our libraries. That works alright.

It'd still be great if the "heuristic resolution of includes" would handle directory names a little more sophisticated by taken path separators into consideration.
Comment 10 Nathan Ridge CLA 2019-10-24 18:09:33 EDT
(In reply to Wolfgang Petroschka from comment #9)
> > As long as you can get the build to output the compiler commands that are
> > being executed (including their "-I" flags), this should configure the
> > includes for you automatically, with no manual entry in the GUI required.
> 
> I failed to get this to work with our cross-compiler, but that is probably
> my bad.

A common reason for the Build Output Parser not recognizing cross-compiler output with default settings, is that it expects the compiler executable name to be "gcc" (or "g++" or "clang" or "clang++"), whereas cross-compilers often add prefixes like "android-armeabi-gcc".

This is easy to fix: in the same Providers tab where you enable the Build Output Parser, if you click on it an options panel appears, and you can change the "Compiler command pattern" from the default regex to the actual name of your cross-compiler executable (or, if you prefer, a different regex that will match that).

> This revealed another problem though:
> As our project contains multiple libraries and executables to be built, they
> all use a different set of include paths. Now setting all the include path
> led to a completely confused indexer.
> 
> I guess our project structure is not really compatible with Eclipse.

Eclipse does support setting different include paths on a per-file basis, and the Build Output Parser will correctly take each compiler command and configure the include paths from it for that translation unit only.

> It'd still be great if the "heuristic resolution of includes" would handle
> directory names a little more sophisticated by taken path separators into
> consideration.

Yes, agreed. But perhaps the above can unblock you from using the Build Output Parser as well :)