cgccgcc-plugins

How to get all system include path in a gcc plugin?


I'm doing a GCC Plugin to check a coding style for C and header files. I check the coding style at the compilation with :

register_callback(plugin_info->base_name, PLUGIN_START_UNIT, start_unit_callback, NULL);
register_callback(plugin_info->base_name, PLUGIN_INCLUDE_FILE, include_file_callback, NULL);

The first line is only to check C files and the second one is to check headers files (.h).

But then I have performance issue when it come to the header check. In fact, it checks the system headers too ! And I would like it does not do that. This is the list of headers file that GCC gets :

/usr/include/stdio.h
/usr/include/bits/libc-header-start.h
/usr/include/features.h
/usr/include/features-time64.h
/usr/include/bits/wordsize.h
/usr/include/bits/timesize.h
/usr/include/bits/wordsize.h
/usr/include/sys/cdefs.h
/usr/include/bits/wordsize.h
/usr/include/bits/long-double.h
/usr/include/gnu/stubs.h
/usr/include/gnu/stubs-64.h
/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/include/stddef.h
/usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/include/stdarg.h
/usr/include/bits/types.h
/usr/include/bits/wordsize.h
/usr/include/bits/timesize.h
/usr/include/bits/wordsize.h
/usr/include/bits/typesizes.h
/usr/include/bits/time64.h
/usr/include/bits/types/__fpos_t.h
/usr/include/bits/types/__mbstate_t.h
/usr/include/bits/types/__fpos64_t.h
/usr/include/bits/types/__FILE.h
/usr/include/bits/types/FILE.h
/usr/include/bits/types/struct_FILE.h
/usr/include/bits/stdio_lim.h
/usr/include/bits/floatn.h
/usr/include/bits/floatn-common.h
/usr/include/bits/long-double.h
test.h

The only include that I've made myself is the test.h, so it must not check the others files.

So do you know a way to extract all the system files included ?

I've tried to just skip all the includes from /usr/ and /lib/ but that is not a good practice.

I've tried to see if I could make the callback at another moment of the compilation, but it did not make well (It does not check for headers).

Thank you for reading me ! Hoping you could help me :)


Solution

  • So as a temporary option. Waiting for someone to have a better method, I've made this function :

    char **get_system_includes(void)
    {
        FILE *fp;
        char line[MAX_LINE_LENGTH];
        char **includes = (char**)xmalloc(sizeof(char *) * 1024);
        int includes_count = 0;
    
        fp = popen("echo | gcc -E -v - 2>&1 | awk '/#include </,/^End of search/'", "r");
        if (fp == NULL) {
            error("Could not get system includes");
            exit(1);
        }
    
        while (fgets(line, sizeof(line), fp) != NULL) {
            line[strcspn(line, "\n")] = 0;
    
            if (strstr(line, "#include <") != NULL
                || strstr(line, "End of search") != NULL)
                continue;
    
            char *start = line;
            for (; *start == ' ' || *start == '\t'; start++);
    
            includes[includes_count] = (char*)xmalloc(strlen(start) + 1);
            strcpy(includes[includes_count], start);
            includes_count++;
        }
    
        pclose(fp);
        includes[includes_count] = NULL;
        return includes;
    }
    

    Thanks to it, I can retrieve a vector of strings containing all the system includes dir I want to ignore.