Build fails: "Undefined symbols for architecture x86_64"

• Aug 13, 2020 - 16:33
Reported version
4.x-dev
Type
Development
Frequency
Once
Severity
S1 - Blocker
Reproducibility
Always
Status
closed
Regression
No
Workaround
Yes
Project

I am trying to build MuseScore, but the build fails with this error:
Undefined symbols for architecture x86_64:
"qInitResources_mtest()", referenced from:
initMyResources() in libtestutils.a(testutils.o)
"qInitResources_musescorefonts_Free()", referenced from:
initMyResources() in libtestutils.a(testutils.o)
"qInitResources_musescorefonts_MScore()", referenced from:
initMyResources() in libtestutils.a(testutils.o)
"qInitResources_musescorefonts_Bravura()", referenced from:
initMyResources() in libtestutils.a(testutils.o)
"qInitResources_musescorefonts_MuseJazz()", referenced from:
initMyResources() in libtestutils.a(testutils.o)
"qInitResources_musescorefonts_FreeSerif()", referenced from:
initMyResources() in libtestutils.a(testutils.o)
"qInitResources_musescorefonts_Gootville()", referenced from:
initMyResources() in libtestutils.a(testutils.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

It seems to me that the error has to do with the file mtest/testutils.cpp. In that file, we see this code:

static void initMyResources()
{
    Q_INIT_RESOURCE(mtest);
    Q_INIT_RESOURCE(musescorefonts_MScore);
    Q_INIT_RESOURCE(musescorefonts_Gootville);
    Q_INIT_RESOURCE(musescorefonts_Bravura);
    Q_INIT_RESOURCE(musescorefonts_MuseJazz);
    Q_INIT_RESOURCE(musescorefonts_FreeSerif);
    Q_INIT_RESOURCE(musescorefonts_Free);
}

This is what I have done, trying to follow the compile instructions:

  • fork and clone MuseScore from GitHub
  • create build.debug directory in MuseScore directory
  • in that directory cmake .. -GXcode -DCMAKE_BUILD_TYPE=Debug to configure
  • and then cmake --build .

What I also find remarkable, is the discrepancy between the code here above (from test/testutils.cpp) and some code found in main/main.cpp:

static void initResources()
{
#ifdef Q_OS_MAC
    Q_INIT_RESOURCE(musescore);
    Q_INIT_RESOURCE(qml);
    Q_INIT_RESOURCE(musescorefonts_Mac);
    Q_INIT_RESOURCE(shortcut_Mac);
#else
    Q_INIT_RESOURCE(musescore);
    Q_INIT_RESOURCE(qml);
    Q_INIT_RESOURCE(musescorefonts_MScore);
    Q_INIT_RESOURCE(musescorefonts_Gootville);
    Q_INIT_RESOURCE(musescorefonts_Bravura);
    Q_INIT_RESOURCE(musescorefonts_MuseJazz);
    Q_INIT_RESOURCE(musescorefonts_Campania);
    Q_INIT_RESOURCE(musescorefonts_FreeSerif);
    Q_INIT_RESOURCE(musescorefonts_Free);
    Q_INIT_RESOURCE(shortcut);
#endif
}
  • in main/main.cpp a differentiation is made for macOS, and for the other platforms seven font resources are initialized;
  • but in test/testutils.cpp, no differentiation is made, and only six font resources are initialized.

When I change test/testutils.cpp according to main/main.cpp, the errors about the fonts go away, but the following line still causes an error:
Q_INIT_RESOURCE(mtest);

Version info: I am trying to build a clone of a fork of the master branch on macOS 10.15.6 with Xcode 11.6.


Comments

The mtests used to build cleanly on macOS before https://github.com/musescore/MuseScore/pull/5649, and they still do if building with a version of Qt prior to 5.11. You might try modifying this line to something that evaluates to false, in order to force CMake to use QT5_ADD_RESOURCES rather than qtquick_compiler_add_resources. Interestingly enough, however, qtquick_compiler_add_resources seems to work just fine when called from mscore/CMakeLists.txt.

Workaround No Yes

When I change the code around this line to the following, it works. But I am not sure if this is a good solution. I could also have decided to use Qt 5.9.9, but here I read that this version is known to have problems with macOS 10.15 Catalina, so that doesn't seem a good idea to me.

if (Qt5Widgets_VERSION VERSION_GREATER_EQUAL "5.11.0" AND NOT APPLE)
      find_package(Qt5QuickCompiler)
      qtquick_compiler_add_resources(qrc_files ${PROJECT_SOURCE_DIR}/mtest/mtest.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-MScore.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-Gootville.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-Bravura.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-MuseJazz.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-Free.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-FreeSerif.qrc
      )
else (Qt5Widgets_VERSION VERSION_GREATER_EQUAL "5.11.0" AND NOT APPLE)
      QT5_ADD_RESOURCES(qrc_files ${PROJECT_SOURCE_DIR}/mtest/mtest.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-MScore.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-Gootville.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-Bravura.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-MuseJazz.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-Free.qrc
            ${PROJECT_SOURCE_DIR}/mscore/musescorefonts-FreeSerif.qrc
      )
endif (Qt5Widgets_VERSION VERSION_GREATER_EQUAL "5.11.0" AND NOT APPLE)

All versions of Qt greater than or equal to 5.11 give the issue. I know of no problems with Qt 5.9.9 and macOS Catalina, despite that claim on the build instructions page, so anyone should be able to use that.

Good point, never did that. But if that method works in the "normal" sources (which it does), it got to work in mtests too, the real issue got to be something different

The issue is that for some reason, on some systems, qtquick_compiler_add_resources is not working when called from mtest/CMakeLists.txt, although it does work when called from mscore/CMakeLists.txt.

I have Qt 5.12.9. Actually I just did cmake --build . , in an attempt to get MuseScore built. Apparently, that command also builds the mtests, which makes the whole build process fail, because of that issue with qtquick_compiler_add_resources.

So I believe that the good news is, that we have probably isolated the issue, namely that qtquick_compiler_add_resources when called from mtest/CMakeLists.txt doesn't work, on Mac anyway, maybe also in Windows. Is that the right conclusion? How that problem has to be solved will be a tough one I think...

Is there a way that I can just build the MuseScore app only, without the mtests? (Sorry if that's a dumb question, I have not yet much experience with cmake et cetera... I actually come from iOS development.)

Could it be because building the mtests does not involve the QtQuick compiler, and so the resources don't end up getting linked? Best just to use QT5_ADD_RESOURCES in mtest/CMakeLists.txt for all versions of Qt.