CMAKE_UNITY_BUILD and compiled QML files - anonymous namespace collisions

I found some discussion around problems with anonymous namespaces and using CMAKE_UNITY_BUILD from about a year ago [1]. I’m using CMake 3.21 and the project runs Qt’s QtQuick compiler over all of the QML source files to generate cpp. It seems to be strictly those files that have compilation errors when I try to enable the unity build. Many other non-qml-based source files have anonymous namespaces and they seem to be just fine.

EDIT: I just used basic default settings and batch mode.

e.g.

C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCBottomSelectionTray_qml.cpp(1082) : error C2084: function 'QV4::ReturnedValue `anonymous-namespace'::jsfunction_53(QV4::ExecutionEngine *)' already has a body
        C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCUpDownSpinner_qml.cpp(1313) : see previous definition of 'jsfunction_53'
C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCBottomSelectionTray_qml.cpp(1097) : error C2084: function 'QV4::ReturnedValue `anonymous-namespace'::jsfunction_54(QV4::ExecutionEngine *)' already has a body
        C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCUpDownSpinner_qml.cpp(1336) : see previous definition of 'jsfunction_54'
C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCBottomSelectionTray_qml.cpp(1105) : error C2084: function 'QV4::ReturnedValue `anonymous-namespace'::jsfunction_55(QV4::ExecutionEngine *)' already has a body
        C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCUpDownSpinner_qml.cpp(1401) : see previous definition of 'jsfunction_55'
C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCBottomSelectionTray_qml.cpp(1120) : error C2084: function 'QV4::ReturnedValue `anonymous-namespace'::jsfunction_56(QV4::ExecutionEngine *)' already has a body
        C:/Projects/build-AEPP-VS2013-Debug/eSW/Qt/QtCommon/BCControls/BCUpDownSpinner_qml.cpp(1478) : see previous definition of 'jsfunction_56'

Is it best to avoid unity builds completely in cases like this? I was just trying out various ways to speed up build times.

[1] https://gitlab.kitware.com/cmake/cmake/-/issues/21477

It seems that the codegen is not structured in such a way where the generated code is expected to “see” other generated code. I suggest filing an issue with Qt to make the source more robust.

1 Like

I feel a little silly now. I can confirm this is not an issue with the latest version of Qt that I tried: 6.2.4. I have to support Qt5.6 and Qt 6.2.x so this issue with Qt5.6 prevents me from taking advantage. That is, unless there is a way to prevent unity builds for entire targets. So far I’ve only seen the ability to change individual source file properties to have them get skipped in the unity build - e.g.

set_source_files_properties(FileImporter.cpp ImportLegacyYBFileWatcher.cpp PROPERTIES
    SKIP_UNITY_BUILD_INCLUSION TRUE
    )

It’s too bad you have to go back quite that far. Qt made a bunch of changes to the Qt QML and Qt Quick (previously QtDeclarative, collectively) modules around Qt 5.7, deprecating and dumping some older compatibility code. I wouldn’t be surprised if even Qt 5.9 (the next LTS release) no longer exhibited this bug, but Qt 5.6 is really old at this point (released Mar 16, 2016).

Yes, it is very unfortunate. If I say much more I’ll get in trouble but I agree with you 100%.

1 Like

Oh, believe me, I’ve been there. There was a time less than 2 years ago when one application I worked on was still clinging to Qt 5.2 compatibility! (For no reason other than the fact that the build servers hadn’t been upgraded since they were set up in 2014!)

As you say, it’s unfortunate. Though, at the same time, I could be wrong about Qt 5.9. It’s plausible this is something the Qt devs only discovered (and fixed) while they were migrating their own build systems to CMake for Qt 6.