clangpch

How to disable PCH (precompiled headers) in clang?


I an compiling the output of yarpgen using clang++, and I keep encountering a file init.h.pch being generated, which takes up unnecessary disk space and slows down my compilation process. I want to disable the generation of this .pch file.

I ran the command clang++ * in the output directory of yarpgen, which contains driver.cpp func.cpp init.h. I expected that this command would compile the files without generating any precompiled header files, but init.h.pch keeps being created. How can I prevent this?


Solution

  • clang[++], like gcc[++], automatically generates a precompiled header if a header file is input for compilation. See:

    $ clang++ --version
    Ubuntu clang version 18.1.6 (++20240518023429+1118c2e05e67-1~exp1~20240518143527.144)
    Target: x86_64-pc-linux-gnu
    Thread model: posix
    InstalledDir: /usr/bin
    
    $ cat header.h
    #ifndef HEADER_H
    #define HEADER_H
    
    int foo();
    
    #endif
    
    $ ls *.h*
    header.h
    
    $ clang++ header.h
    clang++: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
    
    $ ls *.h*
    header.h  header.h.pch
    
    $ g++ header.h
    
    $ ls *.h*
    header.h  header.h.gch  header.h.pch
    

    Neither clang[++] not gcc[++] has an option to suppress the output of a precompiled header if you choose to input a header file. Likewise if you choose to input a .c, .c(c|pp|xx) or .o file, there is no option to instruct the compiler that it is not to be supposed to be compiled or linked as appropriate.

    The leading answer to the question commented on by @ScottMcPeak does not show that clang[++] must be explicitly directed to generate a precompiled header when a header file is input. The illustrative command in that answer:

    $ clang -c -o big-header.hh.pch big-header.hh
    

    uses the -o option redundantly to specify an output filename that is the same as the default. When a header file is input to the compiler the -o option merely has the usual effect of specifying the output filename, which would otherwise default:

    $ clang++ header.h -o header.pch
    clang++: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
    
    $ ls *.*h*
    header.h  header.h.gch  header.h.pch  header.pch
    

    You can prevent the generation of init.h.pch only by not directing clang++ to process init.h. Since it is a header file there is no reason to input it separately to compilation unless you intend to produce a pre-compiled header. Otherwise, you just #include it in any source files that require it.