Search code examples
cmakecudaideqt-creatorpreprocessor-directive

Set preprocessor symbol in QtCreator code model only


I'm working on a CMake-based project that contains both C++ and CUDA source files, and has some headers meant to be included by both languages.

For these header files, I'd like to see the result of highlighting and syntax checking as close as possible to what NVCC, the CUDA compiler, would see, so for example, I'd like to have the preprocessor symbol __CUDACC__ be defined.

It's important to me that CMake does not have such a symbol defined, because it's really an internal symbol of the NVCC toolchain that I need purely for syntax-checking purposes.

I've tried "Tools->C++->Additional preprocessor directives" and it seems to have no effect. I've also tried a file named CMakeLists.txt.config which seems to have no effect either.

I'd love a suggestion for this. To reiterate, I'm looking for a way to set a define (CPP symbol/macro) visible to to the syntax-checking system only.


Solution

  • I just discovered this post that reveals the correct answer to my original question. It turns out that during syntax checking Qt Creator defines the Q_CREATOR_RUN macro.

    So all is needed it check for its definition:

    #if defined(Q_CREATOR_RUN) || defined(__INTELLISENSE__)
    #  define IN_SYNTAX_CHECKER 1
    #else
    #  define IN_SYNTAX_CHECKER 0
    #endif
    

    In the example above, I'm also checking for whether __INTELLISENSE__ is defined, so that the same logic can be used in Visual Studio and VS Code too.


    [kept for archeology reasons - better answer above]

    After further digging I found an attribute specific to the Clang analyzer that is defined during the analysis performed for syntax checking but not during compilation.

    Note that this is purely because my project compiles with GCC, while QT Creator's syntax checking runs through Clang.

    // GCC and NVCC don't have __has_feature(), so we provide a fallback
    #ifndef __has_feature 
    #  define __has_feature(x) 0
    #endif
    
    #if __has_feature(attribute_analyzer_noreturn)
    #  define IN_SYNTAX_CHECKER 1
    #else
    #  define IN_SYNTAX_CHECKER 0
    #endif
    

    This allows a clumsy hack as follows, which may or may not be useful, depending on one's needs. Pretty much the idea is that much like you'd have Clang observe your code even if you compile with GCC, this achieves something similar for files inteded to be used with NVCC.

    #if IN_SYNTAX_CHECKER and !defined(__CUDACC__)
    #  define __CUDACC__
    #  include <cuda_device_runtime_api.h>
    #  include <optix_device.h>
    #endif
    

    However the substantial problem remains that when compiling with Clang, all the above falls flat on its face, because clang++, the compiler, also defines the same feature as enabled.

    What's needed to fix this is some kind of macro defined in the analyzer but not in Clang, and so far I've found none like this. At first I had hoped __clang_analyzer__ would fit this need, but according to my version of Qt Creator (6.0.2) the macro is not defined during syntax checking, so we're back to square one.