Search code examples
c++eclipseeclipse-cdt

In Eclipse 4.6.3+CDT, how do I ensure the indexer ranks project headers before system ones?


(NOTE: This is not a question about UNRESOLVED symbols; this is a question about INCORRECTLY RESOVLED symbols, and further, it is an indexer problem, not a build problem. Our builds are done externally and work fine; we use Eclipse as an editor only, after doing a CDT import of the project.)

We are developing a Linux shared library using Eclipse neon.3 (4.6.3) and the CDT. The library is EVENTUALLY installed to the local system, and a test app built against it, but this is not a daily occurrence. However, once installed, those need to remain where they are.

The problem is that the indexer is finding the headers in /usr/local instead of the ones in the project under development. This is exasperating, because going to a class definition winds up opening an obsolete version in a system directory. Assuming you don't notice, you then make a bunch of changes, go to save, and get a big complaint about editing a read-only file, at which point you notice the problem.

I have been able to disable everything, and try manually adding all the paths, but then the problem is that the indexer can't find the C++ Standard Library headers, and the location of those potentially varies.

What is the most compact, constrained, and correct method for ensuring the indexer will always find headers within the project before it goes poking around in /usr/local?

Constraints:

  1. Because the library's header files are used from within both its later-linked applications and its own internal code, these header files use include directives of this form:

    #include <my-lib/subsystem/ThingyDingy.h>
    
  2. Toolchain-specific headers such as the C++ Standard Library should be auto-discovered.

  3. Sadly, we use, and will need to continue to use, Boost. This means the "all header variants" option, etc., need to stay on.

Freedoms:

  1. If there is a sane way to exclude /usr/local/my-lib from ever being indexed for any reason, that is acceptable (e.g., it does not even need to be a fallback, any use of it at all for any reason is utterly undesirable).

  2. Heuristic magic tricks can be dumped, for all I care, so long as the Standard Library and Boost can still be found and properly indexed.

Open to all suggestions, but please, please ensure you are very familiar with Eclipse neon.3 (4.6.3) with the current CDT. We are absolutely drowning in bad suggestions from ancient versions. Additionally, we didn't use to have nearly this much trouble with this, and it is possible that it is a recent regression, though I think the question of the BEST way to do this still stands either way.

We're going insane fighting our tools. Send help. Please.


Solution

  • You need to change the order of the providers in Project Settings -> C/C++ General -> Preprocessor Include Paths -> Providers.

    Change it so that CDT GCC Built-in Compiler Setting is below, and therefore lower priority, than project local settings.

    Here is my MCVE. On my machine I have /usr/include/arpa/ftp.h which has amongst others, the following definitions:

    #define PRELIM      1   /* positive preliminary */
    #define TYPE_A      1   /* ASCII */
    

    If I create a main.c with these contents:

    #include <arpa/ftp.h>
    
    #ifdef TYPE_A
    #error Wrong ftp.h!
    #endif
    
    #if PRELIM != 8
    #error Wrong ftp.h!
    #endif
    
    int main() {}
    

    And my "overridden" ftp.h in my project in include/arpa/ftp.h with the same contents, except PRELIM now == 8 and TYPE_A is commented out.

    And a Makefile like this:

    all:
        gcc main.c -o main -Iinclude
    

    If I build without the -Iinclude, I get #error Wrong ftp.h! and with the -Iinclude everything works fine.

    However, if I open my editor I get the two #ifdef blocks enabled, and therefore CDT is reporting an error.

    Then go to Project Settings -> C/C++ General -> Paths and Symbols -> Includes tab and add my project's include directory to the Include directories.

    Still fails, because of the order of processing.

    Then go to Project Settings -> C/C++ General -> Preprocessor Include Paths -> Providers tab and move CDT GCC Built-in Compiler Settings below CDT Managed Build Settings Entries

    As shown: enter image description here

    Here is a before and after settings change:enter image description here