How can I make CLion accept or ignore my per-source-file -include-pch arguments?

My project uses precompiled headers.  Some .cpp files have their own corresponding .pch files (unlike in what I understand to be the more ordinary scheme, where there is just one .pch for the entire project).  I set this up with a set_source_files_properties call, like so:

set_source_files_properties(${some_cpp_file_name} PROPERTIES

COMPILE_FLAGS "-include-pch ${some_pch_file_name}"

OBJECT_DEPENDS "${some_pch_file_name}")


And elsewhere there are add_custom_command calls and such that set up the creation of the PCH files.

When I build from the command line without involving CLion, everything works fine.  The dependency relationships I've specified cause the .pch files to be built before the corresponding .cpp.o files are built.  So when Clang is given the -include-pch argument pointing to the .pch file, it correctly finds that file.

But when I load the CMakeLists.txt in CLion, I get many errors like this (I've snipped out lots of details):


Error:Configuration someprojectname [RelWithDebInfo]

Compiler exited with error code 1: clang++ -xc++ [many flags snipped] -include-pch /somepath/somepch.pch -v -dD -E


[0;1;31merror: [0munable to read PCH file /somepath/somepch.pch: 'No such file or directory'[0m


CLion is trying to run Clang with my per-source-file options, including "-include-pch", without having actually built the .pch files yet.  I guess it is incorrectly ignoring the OBJECT_DEPENDS relationship expressed in the statement pasted above.  This happens during loading of the project/CMakeLists.txt, not during building.  In fact building might fix the problem, by supplying the missing .pch files.

Is there a workaround for this?  I don't really expect CLion to fully support my setup in the near future...  although if there's a way right now for me to make it do so then of course that's welcome too.  But if I could just force it to leave out the -include-pch argument when it's doing its -E thing, then I think things would probably be okay.  I mean I just want it to think it has succeeded in whatever analysis it's trying to do, and to refrain from cluttering up my CMake error listing with this foolishness.  I don't care whether it sees exactly the same set of headers I'm using at compilation.  I'm not building space shuttle software here; some sloppiness is acceptable.

1 comment
Comment actions Permalink

Well alright I found a ridiculous workaround.  I cloned the source code for LLVM and Clang and built both and then altered Clang's main() function (it's in a driver.cpp somewhere I think) with this bit of extra crud that erases -include-pch options when the PCH file seems to be missing:

#include <unistd.h>

bool fileExists(const char* path)
    return access(path, F_OK) != -1;

int main(int argc_, const char **argv_)
    for (int i = 0; i < argc_; ++i)
        if (std::strcmp(argv_[i], "-include-pch") == 0 && i + 1 < argc_ && !fileExists(argv_[i + 1]))
            const_cast<char**>(argv_)[i][0] = const_cast<char**>(argv_)[i + 1][0] = '\0';



Pretty silly.  I should have been able to do this by wrapping my existing Clang in a Bash script I guess, but that turned out not to work, because CLion runs its -E analysis with a Clang that it finds via some behind-the-scenes magic, and not with the Clang command you give in CMakeLists.txt.  Even wrapping the Clang command in a C++ program (one that simply passes all its arguments to the real Clang) didn't work.  I was unable to get in the way of whatever magic CLion was using to find the real Clang program.  So I just changed the real Clang program itself.  Seems to have worked okay, so far.  :(


Please sign in to leave a comment.