Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

building from source master (818c059811aba0f0b4fddab55df801b80cdbe8e4) fails due to unconditional qt5 calls and missing Qt6OpenGL links #1727

Open
balducci opened this issue Oct 12, 2024 · 10 comments

Comments

@balducci
Copy link
Contributor

Avogadro version: git master

  • Avogadrolibs: git master, 818c059
  • Qt: 6.7.3

Desktop version:

  • OS: gnu linux
  • Version: custom system, kernel-6.10.8
  • Compiler: gcc/g++

Describe the bug
During build of avogadrolibs from source (git master, 818c059) the link step of libAvogadroMoleQueue.so fails with:

    [ 51%] Linking CXX shared library ../../lib/libAvogadroMoleQueue.so
    cd /home/balducci/tmp/install-us-d/avogadrolibs-4707.d/avogadrolibs-4707/avogadro/molequeue && /opt/stow.d/versions/cmake-3.31.0-rc1/usr/bin/cmake -E cmake_link_script CMakeFiles/MoleQueue.dir/link.txt --verbose=1
    /usr/bin/ld: CMakeFiles/MoleQueue.dir/MoleQueue_autogen/mocs_compilation.cpp.o: in function `QList<QRegExp>::erase(QList<QRegExp>::const_iterator, QList<QRegExp>::const_iterator) [clone .isra.0]':
    mocs_compilation.cpp:(.text+0x1628): undefined reference to `QRegExp::~QRegExp()'
    /usr/bin/ld: CMakeFiles/MoleQueue.dir/MoleQueue_autogen/mocs_compilation.cpp.o: in function `QtPrivate::QDataStreamOperatorForType<QRegExp, true>::dataStreamIn(QtPrivate::QMetaTypeInterface const*, QDataStream&, void*)':
    mocs_compilation.cpp:(.text._ZN9QtPrivate26QDataStreamOperatorForTypeI7QRegExpLb1EE12dataStreamInEPKNS_18QMetaTypeInterfaceER11QDataStreamPv[_ZN9QtPrivate26QDataStreamOperatorForTypeI7QRegExpLb1EE12dataStreamInEPKNS_18QMetaTypeInterfaceER11QDataStreamPv]+0x7): undefined reference to `operator>>(QDataStream&, QRegExp&)'
    /usr/bin/ld: CMakeFiles/MoleQueue.dir/MoleQueue_autogen/mocs_compilation.cpp.o: in function `QtPrivate::QDataStreamOperatorForType<QRegExp, true>::dataStreamOut(QtPrivate::QMetaTypeInterface const*, QDataStream&, void const*)':
    mocs_compilation.cpp:(.text._ZN9QtPrivate26QDataStreamOperatorForTypeI7QRegExpLb1EE13dataStreamOutEPKNS_18QMetaTypeInterfaceER11QDataStreamPKv[_ZN9QtPrivate26QDataStreamOperatorForTypeI7QRegExpLb1EE13dataStreamOutEPKNS_18QMetaTypeInterfaceER11QDataStreamPKv]+0x7): undefined reference to `operator<<(QDataStream&, QRegExp const&)'

[...flood of identical  "undefined reference to `QRegExp::~QRegExp()'" errors]-

Apparently, mocs_compilation.cpp is using qt5 calls despite me running the build with -DQT_VERSION=6; as a workaround, I can complete the build successfully by adding libQt6Core5Compat.so to the link command, but maybe you want to fix the mocs_compilation.cpp source.

Further on during the build, the link step of libAvogadroQtPlugins.so fails with:

    [100%]  [32m [1mLinking CXX shared library ../../lib/libAvogadroQtPlugins.so [0m
    cd /home/balducci/tmp/install-us-d/avogadrolibs-4707.d/avogadrolibs-4707/avogadro/qtplugins && /opt/stow.d/versions/cmake-3.31.0-rc1/usr/bin/cmake -E cmake_link_script CMakeFiles/QtPlugins.dir/link.txt --verbose=1
    /usr/bin/ld: ../../lib/avogadro2/staticplugins/OpenBabel.a(obprocess.cpp.o): in function `Avogadro::QtPlugins::OBProcess::optimizeGeometryReadLog()':
    obprocess.cpp:(.text+0x80e): undefined reference to `QRegExp::QRegExp(QString const&, Qt::CaseSensitivity, QRegExp::PatternSyntax)'
    /usr/bin/ld: obprocess.cpp:(.text+0x834): undefined reference to `QRegExp::lastIndexIn(QString const&, int, QRegExp::CaretMode) const'

    [...]

    /usr/bin/ld: ../../lib/avogadro2/staticplugins/PlayerTool.a(playertool.cpp.o): in function `Avogadro::QtPlugins::PlayerTool::setActiveWidget(QWidget*)':
    playertool.cpp:(.text+0x1d27): undefined reference to `QOpenGLWidget::staticMetaObject'
    /usr/bin/ld: ../../lib/avogadro2/staticplugins/PlayerTool.a(playertool.cpp.o): in function `Avogadro::QtPlugins::PlayerTool::recordMovie()':
    playertool.cpp:(.text+0x38d4): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    /usr/bin/ld: playertool.cpp:(.text+0x3ab3): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: playertool.cpp:(.text+0x3edf): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: playertool.cpp:(.text+0x3efa): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    /usr/bin/ld: playertool.cpp:(.text+0x44fd): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: playertool.cpp:(.text+0x4518): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    /usr/bin/ld: ../../lib/avogadro2/staticplugins/Surfaces.a(surfaces.cpp.o): in function `Avogadro::QtPlugins::Surfaces::movieFrame()':
    surfaces.cpp:(.text+0x893b): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: surfaces.cpp:(.text+0x8b20): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    collect2: error: ld returned 1 exit status

The origin of the first undefined reference error is the same as above: obprocess.cpp using qt5 call to QRegExp;
The QOpenGL* undef references are cured by adding libQt6OpenGLWidgets.so and libQt6OpenGL.so to the link command: I don't know if this is due to my configuration or it should be done in general.

Configuring the build with:

-DSPGLIB_LIBRARY=/usr/lib64/libsymspg.so
-DUSE_MMTF=OFF
-Dlibmsym_DIR=/usr/share/libmsym/cmake64
-DQT_VERSION=6

thanks for your valuable work
ciao
-gabriele

Copy link

welcome bot commented Oct 12, 2024

Thanks for opening your first issue here! Please try to include example files and screenshots if possible. If you're looking for support, please post on our forum: https://discuss.avogadro.cc/

@ghutchis
Copy link
Member

This looks like an issue with Molequeue. We've changed to have -DBUILD_MOLEQUEUE=OFF as the default. Can you try that please?

Note that Qt6 support is still unfinished. Please check with https://discuss.avogadro.cc/ for more details on the Qt6 work.

@balducci
Copy link
Contributor Author

This looks like an issue with Molequeue. We've changed to have -DBUILD_MOLEQUEUE=OFF as the default. Can you try that please?

I get the same error.
Actually, in the cloned tree the only files where BUILD_MOLEQUEUE occurs are:

.github/workflows/build_cmake.yml
.github/workflows/build_m1.yml
.github/workflows/build_qt6.yml

And if I run the build with -DBUILD_MOLEQUEUE=OFF, then in CMakeCache.txt I find:

//No help, variable specified on the command line.
BUILD_MOLEQUEUE:UNINITIALIZED=OFF

Are you sure that -DBUILD_MOLEQUEUE=OFF is actually implemented?
Indeed that would be useful while implementing qt6 suppport; I have already noticed that molequeue does not support (yet?) qt6 and, indeed, I build avogadro2 with -DQT_VERSION=6 and -DAvogadro_ENABLE_RPC=OFF; but it seems to me that presently there is no possibility to disable molequeue related code in the build of avogadrolibs.

Or am I missing something in the configuration?

Note that Qt6 support is still unfinished. Please check with https://discuss.avogadro.cc/ for more details on the Qt6 work.

yes, I'm aware of that
I reported precisely because I thought it might be useful in the process of implementing support for qt6

thanks a lot for your time

@ghutchis
Copy link
Member

Are you sure that -DBUILD_MOLEQUEUE=OFF is actually implemented?

Yes. It's a flag for the openchemistry directory, which builds everything.

I think I understand better what you're doing. You don't have qt5compat installed. It's a evidently a separate package, e.g. https://launchpad.net/ubuntu/+source/qt6-5compat

That's something that needs tweaking in the CMakeFiles - currently they expect it's installed.

@balducci
Copy link
Contributor Author

Are you sure that -DBUILD_MOLEQUEUE=OFF is actually implemented?

Yes. It's a flag for the openchemistry directory, which builds everything.

I think I understand better what you're doing.

OK, I think there was a misunderstanding.

I do not install the giant openchemistry project.

I only need avogadro2, whose dependency tree, restricted to the
packages included into the jumbo openchemistry project, is:

avogadro2
`-- avogadrolibs
    `-- avogadrogenerators

What I do is:

  • clone the single avogadrolibs repository (I also clone
    avogadrogenerators as a subdirectory of the former); configure,
    build and install it system wide
  • clone the single avogadro2 repository; configure (with cmake's
    AvogadroLibs_DIR pointing to the installed avogadrolibs stuff),
    build and install it

(of course, I also have all other non-openchemistry dependencies
available system wide)

Until recently, I also used to build/install molequeue (still as a
separate package), but presently molequeue doesn't support qt6, while
avogadrolibs/avogadro2 do not build cleanly vs qt5 (or, at least, I am
no more able to build them vs qt5 (I have both qt5 and qt6 available
on my system)): for this reason I build avogadro2 with
-DAvogadro_ENABLE_RPC=OFF.

This has worked for me since 2017 (with few adjustments from time to
time, mainly, but not only, due to problems with qt upgrades)

You don't have qt5compat installed. It's a evidently a separate package, e.g. https://launchpad.net/ubuntu/+source/qt6-5compat

Regarding the qt5compat package that you mention, I have checked, and
I do have all the libraries and headers which come with it, since I
install and maintain the whole qt-everywhere-src package
distribution

In the end, what I seem to understand is that one is supposed to install the
whole jumbo openchemistry project and not single components of it

After your reply I have seen that that configurable BUILD_MOLEQUEUE
cmake variable is actually defined and used in CMakeLists.txt of the
top directory of the jumbo openchemistry distribution: it probably
propagates in some way also to the avogadrolibs build; but, as far as
I can say, cannot be set and/or has not any effect if one builds
avogadrolibs as a separate package

I thank you very much for your time: now things are clearer

I think I'll keep installing avogadrolibs and avogadro2 separately as
single packages, with the small tweaks needed to make them find what
they need on the system

thanks a lot
ciao
gabriele

@ghutchis
Copy link
Member

Sorry for the comments about molequeue -- that's not the underlying issue.

clone the single avogadro2 repository;

I have no idea what that repository is. I guess you mean avogadroapp?

In the end, what I seem to understand is that one is supposed to install the
whole jumbo openchemistry project and not single components of it

The openchemistry repository helps building both avogadrolibs and avogadroapp - it's certainly the intended way to build it. There are a few related repositories, because it's easier to maintain data (e.g., fragments, translations, etc.) separately.

https://two.avogadro.cc/install/build.html

Regarding the qt5compat package that you mention, I have checked, and
I do have all the libraries and headers which come with it

Well, that's the main problem. Your qt6 build is complaining about QRegExp, which is in qt5compat -- we have not migrated all the calls to QRegularExpression because the syntax and use is different. So if qt5compat is not being linked somehow, you'll get the errors you see.

I'm less clear on the link error about QOpenGLWidget::grabFramebuffer

@matterhorn103
Copy link
Contributor

Sorry, if I'd seen this earlier I might have been able to help out a bit, as I've got Avogadro 2 successfully building on Qt6.

I made a Qt6 tracking thread on the forum, where I'll post more details on what I needed to do to get it compiling, but maybe I can also give some tips here.

Are you sure that -DBUILD_MOLEQUEUE=OFF is actually implemented?
Indeed that would be useful while implementing qt6 suppport; I have already noticed that molequeue does not support (yet?) qt6 and, indeed, I build avogadro2 with -DQT_VERSION=6 and -DAvogadro_ENABLE_RPC=OFF; but it seems to me that presently there is no possibility to disable molequeue related code in the build of avogadrolibs.

Geoff is right, you need to use the -DBUILD_MOLEQUEUE=OFF flag. And it does in fact disable building the Molequeue binary itself.

From experience, it really is much easier to compile if you base your build on the main openchemistry repo. You don't have to install the "jumbo openchemistry project" – I checked recently and you only need avogadrolibs and avogadroapp.

So you don't suffer by cloning the "jumbo" repo. You don't need to do the whole recursive clone thing; basically all you need is all the CMake stuff. So just do a normal clone.

That will create the directory structure with a bunch of empty folders, and then you can clone the repos for just the modules you need into the empty folders.

As I said, I spent some time playing around to see what is actually essential and to build the desktop application you really only need to clone OpenChemistry/avogadrolibs and OpenChemistry/avogadroapp. A few other third party things are needed, as is the translations repo I think, but they are pulled in automatically during the build so you don't need to worry about them. Everything else is entirely optional. You definitely don't even need the Molequeue code, as long as you use the flag.

The command I use to configure cmake is:

cmake -DQT_VERSION=6 -DBUILD_MOLEQUEUE=OFF -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -S ./openchemistry -B ./qt6

but I've tested and gcc/g++ work just fine too, as does using Ninja using -G Ninja.

You don't have qt5compat installed. It's a evidently a separate package, e.g. https://launchpad.net/ubuntu/+source/qt6-5compat

Yep, on Qt6 you need Qt5CoreCompat or whatever it's called on your distro. The full list of Qt modules you need seems to be:

  • QtCore
  • QtWidgets
  • QtGui
  • QtOpenGL
  • QtConcurrent
  • QtNetwork
  • QtSvg
  • For Qt6 add QtCore5Compat and QtOpenGLWidgets

On Tumbleweed these are all provided by separate packages with names of the pattern libQt6Core6, so it's worth checking you have all of them.

The dependence on QtCore5Compat and QtOpenGLWidgets is new for Qt6, so maybe that's what tripped you up.

I also found recently that I needed a patched version of rapidjson (that includes this PR) in order to build openbabel successfully, and I could get that by installing rapidjson-devel.

Apparently, mocs_compilation.cpp is using qt5 calls despite me running the build with -DQT_VERSION=6; as a workaround, I can complete the build successfully by adding libQt6Core5Compat.so to the link command, but maybe you want to fix the mocs_compilation.cpp source.

Further on during the build, the link step of libAvogadroQtPlugins.so fails with:

    [100%]  [32m [1mLinking CXX shared library ../../lib/libAvogadroQtPlugins.so [0m
    cd /home/balducci/tmp/install-us-d/avogadrolibs-4707.d/avogadrolibs-4707/avogadro/qtplugins && /opt/stow.d/versions/cmake-3.31.0-rc1/usr/bin/cmake -E cmake_link_script CMakeFiles/QtPlugins.dir/link.txt --verbose=1
    /usr/bin/ld: ../../lib/avogadro2/staticplugins/OpenBabel.a(obprocess.cpp.o): in function `Avogadro::QtPlugins::OBProcess::optimizeGeometryReadLog()':
    obprocess.cpp:(.text+0x80e): undefined reference to `QRegExp::QRegExp(QString const&, Qt::CaseSensitivity, QRegExp::PatternSyntax)'
    /usr/bin/ld: obprocess.cpp:(.text+0x834): undefined reference to `QRegExp::lastIndexIn(QString const&, int, QRegExp::CaretMode) const'

    [...]

    /usr/bin/ld: ../../lib/avogadro2/staticplugins/PlayerTool.a(playertool.cpp.o): in function `Avogadro::QtPlugins::PlayerTool::setActiveWidget(QWidget*)':
    playertool.cpp:(.text+0x1d27): undefined reference to `QOpenGLWidget::staticMetaObject'
    /usr/bin/ld: ../../lib/avogadro2/staticplugins/PlayerTool.a(playertool.cpp.o): in function `Avogadro::QtPlugins::PlayerTool::recordMovie()':
    playertool.cpp:(.text+0x38d4): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    /usr/bin/ld: playertool.cpp:(.text+0x3ab3): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: playertool.cpp:(.text+0x3edf): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: playertool.cpp:(.text+0x3efa): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    /usr/bin/ld: playertool.cpp:(.text+0x44fd): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: playertool.cpp:(.text+0x4518): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    /usr/bin/ld: ../../lib/avogadro2/staticplugins/Surfaces.a(surfaces.cpp.o): in function `Avogadro::QtPlugins::Surfaces::movieFrame()':
    surfaces.cpp:(.text+0x893b): undefined reference to `QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()'
    /usr/bin/ld: surfaces.cpp:(.text+0x8b20): undefined reference to `QOpenGLWidget::grabFramebuffer()'
    collect2: error: ld returned 1 exit status

When building from the openchemistry repo, I didn't have to do any of this. It's important to have them, but for me having qt6-qt5compat-devel, qt6-openglwidgets-devel and libQt6OpenGLWidgets6 installed was enough. I made the adjustments to the code necessary to bring them in a while ago, so it shouldn't need extra linking.

The origin of the first undefined reference error is the same as above: obprocess.cpp using qt5 call to QRegExp;

We are working on eliminating the QRegExp stuff, like Geoff said, but even with it in it builds successfully for me, and 95% of everything works as far as I can tell.

@balducci I'd really appreciate it if you'd let me know whether you can get it to build if you follow the same strategy as me, because if you can't that's really worth knowing.

@matterhorn103
Copy link
Contributor

I think I understand better what you're doing. You don't have qt5compat installed. It's a evidently a separate package, e.g. https://launchpad.net/ubuntu/+source/qt6-5compat

That's something that needs tweaking in the CMakeFiles - currently they expect it's installed.

I think I had to add that to get it to compile. I guess it's only needed for the deprecated stuff that we're taking out anyway? How crucial is it to get rid of it as a dependency?

@balducci
Copy link
Contributor Author

I have no idea what that repository is. I guess you mean avogadroapp?

yes, of course, sorry for the typo

@balducci
Copy link
Contributor Author

@balducci I'd really appreciate it if you'd let me know whether you can get it to build if you follow the same strategy as me, because if you can't that's really worth knowing.

thank you very much for spending the time to post this. From your comment it looks to me that your procedure is just exactly what I'd like. I'll try it out no doubt, but not in the short period (because I'm under heavy work pressure at the moment). I'll report here as soon as I'll get some result about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants