Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

"build.ninja:1370: bad $-escape" when building with Qt6 + CMake + Ninja



  • Hello,

    I'm porting a project from Qt5 to Qt6. The build system is written in CMake, and the generator we usually use is Ninja (although the bug I'm reporting about here has also be found to be present when using Makefiles).

    When generating the build system, I get the following error :

    (...)
    -- Configuring done
    -- Generating done
    CMake Error:
      Running
    
       '/usr/bin/ninja' '-C' '/home/graslany/Anatoscope/LearnBuild' '-t' 'recompact'
    
      failed with:
    
       ninja: error: build.ninja:1385: bad $-escape (literal $ must be written as $$)
        FLAGS = -g -fPIC   -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -D$<$<NOT:$...
                             ^ near here
    

    There are actually many broken compilation instructions in the ninja.build file. For instance this (I have [mask]'ed specific names):

    build [masked]/ThemeUtility.cpp.o: CXX_COMPILER__[masked]_Debug [masked]/ThemeUtility.cpp || cmake_object_order_depends_target_[masked]
      DEFINES = -D[masked]_PLUGINS_SUBDIR=\"\" -D[masked]_EXPORTS -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_OPENGL_LIB -DQT_PRINTSUPPORT_LIB -DQT_QMLMODELS_LIB -DQT_QML_DEBUG -DQT_QML_LIB -DQT_QUICKCONTROLS2_LIB -DQT_QUICK_LIB -DQT_WIDGETS_LIB [masked]
      DEP_FILE = [masked]/ThemeUtility.cpp.o.d
      FLAGS = -g -fPIC   -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -D$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> -Wno-deprecated-declarations -fPIC -pthread -std=gnu++17
      INCLUDES = [masked] -isystem /opt/Qt/6.0.2/gcc_64/include/QtPrintSupport -isystem /opt/Qt/6.0.2/gcc_64/mkspecs/linux-g++
      OBJECT_DIR = [masked]
      OBJECT_FILE_DIR = [masked]
    

    It seems to me that all the $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG> are CMake Generator Expressions which should be substituted with actual values when CMake generates the Ninja build system. This obvisouly did not happen here.

    I could track the origin of this expression to a Qt CMake file, namely Qt/6.0.2/gcc_64/lib/cmake/Qt6Core/Qt6CoreConfigExtras.cmake:24:

    set_property(TARGET Qt6::Core APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG>)
    

    The CMake doc is pretty vague about the places where such expressions are allowed. However in the case of INTERFACE_COMPILE_DEFINITIONS, it is said to be allowed by the documentation.

    I have found a temporary and dirty workaround that allows me to continue working by editing the Qt Files locally by hand, but this is obviously not satisfying. I've replaced the aforementioned CMake set_property call with this:

        if (CMAKE_BUILD_TYPE)
            if (NOT "$(CMAKE_BUILD_TYPE}" STREQUAL "Debug")
                set_property(TARGET Qt6::Core APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS QT_NO_DEBUG)
            endif()
        else()
            set_property(TARGET Qt6::Core APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG>)
        endif()
    

    Would you please help me find out why this expression is not replaced and what the proper fix would be?


Log in to reply