Qt6 migration and CI Actions#1
Open
naelolaiz wants to merge 7 commits into
Open
Conversation
Add a top-level CMake entrypoint for the imported CLAM tree, build the core/audio/processing libraries, and enable the NetworkEditor Qt targets with Qt6 compatibility headers. Remove C++ constructs rejected by C++17 and update the NetworkEditor/monitor sources for Qt6 APIs.
Replace SMSTools-qt4/ with a Qt6-only SMSTools/ tree built by CMake. All Q3* widgets are swapped for their modern equivalents (Q3FileDialog, Q3ListBox, Q3Frame, Q3Process, Q3WhatsThis, Q3PopupMenu, Q3ButtonGroup, Q3TextBrowser, Q3MainWindow), removed-in-Qt6 helpers are replaced (QGLColormap is shimmed in QtPalette.hxx, setPaletteBackgroundColor / setPaletteForegroundColor become a small QPalette helper in PaletteHelpers.hxx, QToolTip::add/remove become setToolTip, QPushButton::setPixmap becomes setIcon, QFontMetrics::width becomes horizontalAdvance, QString::sprintf becomes QString::asprintf, QPainter::resetXForm becomes resetTransform, QGLWidget OpenGL widgets inherit from QOpenGLWidget), and Qt3-style API calls are replaced (ascii -> toStdString, setOn/isOn -> setChecked/isChecked, setMargin -> setContentsMargins, currentItem/setCurrentItem -> currentIndex/setCurrentIndex on QComboBox, setMaxValue/maxValue -> setMaximum/maximum, setSteps -> setSingleStep + setPageStep, QTimer::start(ms,true) -> setSingleShot + start(ms), reparent -> setParent + move, QGridLayout addMultiCell* -> addLayout/addWidget, new QHBoxLayout(parentLayout) -> new QHBoxLayout + parent->addLayout). uic-generated connections in QtSMSTools.ui, SMSConfigDlg.ui and ScoreEditorDlg.ui have been moved into the dialog constructors so the typed-pointer connect() resolves against the QtSMS form class rather than QMainWindow / QDialog. SMSTools/CMakeLists.txt produces three executables (SMSConsole and SMSBatch with no Qt dependency; SMSTools as the Qt GUI) plus three static helper libraries. The top-level build opts in via -DCLAM_BUILD_SMSTOOLS=ON. CMAKE-MIGRATION.md is updated to describe the new target and drop SMSTools from the remaining-work list. Assisted by Claude Opus 4.7
Wrap each engine call (LoadConfiguration / LoadAnalysis / LoadTransformationScore / Store* / Analyze / Transform / Synthesize / ExtractMelody) in a small guard() helper that catches std::exception and surfaces the message via QMessageBox::critical instead of letting an unhandled CLAM::Err abort the process. The previous behaviour aborted the GUI with a terminate() backtrace when, for example, a transformation-score XML used an unexpected element. Assisted by Claude Opus 4.7
Rewrite ~234 legacy Qt3-style includes across 87 NetworkEditor sources to their Qt6 forms: <QtGui/QFoo> -> <QFoo> <QtOpenGL/QGLWidget> -> <QOpenGLWidget> <QtSvg/QSvgWidget> -> <QSvgWidget> <QtDesigner/QDesignerExportWidget> -> <QtUiPlugin/QDesignerExportWidget> Inheriting widgets renamed accordingly (QGLWidget -> QOpenGLWidget in Spectrogram, Tonnetz, KeySpace, QFirstPerson). With every consumer migrated, cmake/ClamQtCompat.cmake and the clam_generate_qt_compat_headers() calls in the top-level, NetworkEditor and SMSTools CMakeLists are removed; the build no longer generates the fake QtGui/QtOpenGL/QtSvg/QtDesigner forward-header tree. Assisted by Claude Opus 4.7
Add a GitHub Actions workflow that, on push / PR / manual dispatch,
installs the project's apt build dependencies on ubuntu-latest
(xerces-c, fftw3, sndfile, vorbis, mad, jack, portaudio, alsa, GLU,
LADSPA SDK, Qt6 base + svg + opengl + tools), then runs:
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCLAM_BUILD_LIBRARIES=ON -DCLAM_BUILD_GUI_APPS=ON \
-DCLAM_BUILD_SMSTOOLS=ON
cmake --build build
so both the GUI applications (NetworkEditor, SMSTools) and the
non-Qt console tools (SMSBatch, SMSConsole) are exercised by CI.
Assisted by Claude Opus 4.7
naelolaiz
force-pushed
the
qt6_migration_and_ci
branch
2 times, most recently
from
May 21, 2026 00:21
4a3ef8d to
a387d43
Compare
…STools
Address the warning categories surfaced by the Ubuntu CI build.
Real bugs uncovered by warnings:
- Stats.hxx: `if (mCenterOfGravities[order-1] = NULL)` was an
assignment (always-false truth value) so the body never ran and the
per-order CenterOfGravity was never lazily allocated. Switched to
`== nullptr` and use nullptr in the surrounding loop too.
- Navigator.hxx: header guard typo `#ifndef __NAVIGATOR__ / #define
__NAVEGATOR__` corrected so the include guard actually works.
- ProcessingBox::mousePressEvent had the precedence trap
`!event->modifiers() & Qt::ControlModifier`; now uses the existing
controlPressed flag.
Unused / unused-but-set variables: marked [[maybe_unused]] with a
brief comment when they look like vestiges of an incomplete feature
(Vocoder bin-domain partners, SpectralCombDelta/Partializer outMag,
Deesser maxMag, SpectralNotch harmonic, CleanTracks contAt,
ChordSegmentator underMaxIndex, AudioBufferMixer portSize,
BufferedSDIFFileReader iterationsSinceLastExecution, SMSBase
"old segmentator" defaults, KeySpace::DrawLabels missing-render-call
hint, TextBox::itemChange dead local, etc.). CircularPeakPicking
restored `c = y0` and uses `c` in the ymax formula so code and comment
agree.
catch-value: every `catch (Foo e)` → `catch (const Foo&)` in CLAM core
(Flags, LadspaNetworkExporter, BinaryAudioOp, SegmentSMSMorph,
LV2NetworkPlayer) and SMSTools (SDIFSerializer, SMSBase, SMS, SMSBatch).
sign-compare: signed/unsigned loop variables converted to `auto` so
the type matches the size() / Size() expression they compare against
(AudioMixer, AudioBufferMixer, EnvelopeExtractor, FDCombFilter,
LoopingSDIFFileReader). ProcessingBox::getItemRegion uses
static_cast<int> on the unsigned member counts;
BufferedSDIFFileReader and MultiChannelAudioFileReader use std::size_t
casts.
unused-function: ProcessingBox debug-helper statics and
vmqt/Message.hxx tagged [[maybe_unused]].
reorder: SDIFOut constructor's initialiser list reordered to match the
header (and mpFile = nullptr).
parentheses: BufferedSDIFFileReader::Configure assignment wrapped in
explicit parens.
return-type: SDIFOut::Do() returns false explicitly with a TODO noting
the stream-mode path was never finished.
switch: QSynthKnob::mouseMoveEvent's switch handles QDialMode.
format-security: MIDIReader::Error uses printf("%s", str).
unused-result: NetworkEditor main checks QTranslator::load before
installing the translator.
extern-init: LadspaNetworkExporter's clam_library_marker wrapped in an
extern "C" block.
overloaded-virtual: added `using Processing::Do;` /
`using FrameTransformation::Do;` /
`using SMSBase::StoreOutputSound{,Residual,Sinusoidal};` so derived
classes do not silently hide their base-class overloads.
deprecated-declarations:
- QKeyCombination: Qt::CTRL + Qt::Key_X → Qt::CTRL | Qt::Key_X across
RichTextEditor (8 shortcuts).
- QTextCharFormat::setFontFamily → setFontFamilies({...}).
- QMessageBox positional-int constructor and 8-arg static question()
replaced with the StandardButtons overloads (Message.hxx,
ShowMessage.cxx, MainWindow::askUserSaveChanges).
- QMouseEvent::x()/y() → position() (PlotController::GetXY,
DisplaySurface).
AutoGen: removed the empty NetworkEditor/src/widgets/Configurator.cxx
placeholder. Configurator is a header-only Q_OBJECT class; AUTOMOC
picks the header up directly, so the empty .cxx had no purpose since
its 2011 SVN move.
Also dropped the C-style functional casts I introduced earlier in the
Qt6 port (BPFEditorDisplaySurface, DisplaySurface, ScoreEditorDlg,
Ruler) in favour of static_cast<T>(...), const auto and structured
bindings; factored the duplicated mouse-event-to-view-coords math in
BPFEditorDisplaySurface into a single helper.
Assisted by Claude Opus 4.7
Summarises what CLAM is, lists the libraries (clam_core / clam_processing / clam_audioio) and the four applications produced by this branch's build (NetworkEditor, SMSTools, SMSBatch, SMSConsole), and documents: - the apt dependency list that mirrors the CI workflow - cmake / cmake --build incantations for the three build profiles (libraries only / +NetworkEditor / +SMSTools) - the CLAM_BUILD_* and CLAM_WITH_* CMake option matrix - a manual quick-test recipe for the SMSTools GUI against the bundled example-data - pointers to the CI workflow and to CMAKE-MIGRATION.md
naelolaiz
force-pushed
the
qt6_migration_and_ci
branch
from
May 21, 2026 01:58
a387d43 to
3c6ce9b
Compare
Member
|
@naelolaiz, should we do a chat? |
Member
Author
|
Hi @vokimon!, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the CLAM tree up to a modern build: top-level CMake (replacing SCons), C++17 across all libraries, and a Qt6 port of NetworkEditor and SMSTools. Adds a GitHub Actions workflow that builds everything on
ubuntu-latest.What's in here
CMake build for CLAM core/processing/audioio. Top-level
CMakeLists.txtopts in viaCLAM_BUILD_LIBRARIES=ON(default). Optional features (CLAM_WITH_LV2,WITH_ID3,WITH_JACK,WITH_MAD,WITH_PORTAUDIO,WITH_ALSA, …) hard-fail at configure time when ON but the dep is missing, with the symmetric pattern across all backends (LV2 used to slip through configure and explode at compile — fixed).NetworkEditor ported to Qt6, built by the same CMake (
CLAM_BUILD_GUI_APPS=ON). Targets produced:clam_qtmonitors(the reusable monitor widget library) and theNetworkEditorexecutable. The legacy<QtGui/QFoo>/<QtOpenGL/QGLWidget>/<QtSvg/QSvgWidget>includes were rewritten to their Qt6 paths across ~87 sources; the temporary compat-shim header tree (cmake/ClamQtCompat.cmake) introduced mid-port is gone now that the includes are direct.SMSTools ported to Qt6 as a fresh tree (
CLAM_BUILD_SMSTOOLS=ON). Replaces the Qt3Support-eraSMSTools-qt4/. AllQ3*widgets swapped for modern equivalents; Qt3-era helpers (QPaletteshimmed via a smallPaletteHelpers.hxx,QToolTip::add→setToolTip,setPixmap→setIcon,QFontMetrics::width→horizontalAdvance,QGLWidget→QOpenGLWidget,QTimer::start(ms, true)→setSingleShot+start(ms), etc.). UI signal/slot wiring moved into the dialog constructors so Qt6uic's typed-pointerconnect()resolves against the form subclass. Three executables produced:SMSConsole,SMSBatch(no Qt), andSMSTools(Qt GUI).Graceful error handling. Engine calls in SMSTools's Qt slots (
LoadConfiguration,LoadAnalysis,LoadTransformationScore, theStore*variants,Analyze,Transform,Synthesize,ExtractMelody) are wrapped in a smallguard()helper that catchesstd::exceptionand surfaces the message viaQMessageBox::critical, instead of letting an uncaughtCLAM::Errterminate()the process.CI workflow.
.github/workflows/build.ymlinstalls the project's apt build deps onubuntu-latest(xerces-c, fftw3, sndfile, vorbis, mad, id3, lv2, jack, portaudio, alsa, GLU, LADSPA SDK, Qt6 base + svg + opengl + tools), runs cmake configure with all options ON, and builds. A trailing step lists the produced binaries so a green run visibly proves all four (NetworkEditor,SMSTools,SMSBatch,SMSConsole) linked.Warning sweep. The Ubuntu CI build went from ~146 warnings to clean. Three real bugs were uncovered in the process:
Stats.hxx:if (mCenterOfGravities[order-1] = NULL)(assignment, always-false) →== nullptr. The per-orderCenterOfGravitywas never actually being lazily allocated.Navigator.hxx: header guard typo#ifndef __NAVIGATOR__ / #define __NAVEGATOR__corrected so the include guard actually guards.ProcessingBox::mousePressEvent: precedence trap!event->modifiers() & Qt::ControlModifier(parsed as(!modifiers()) & Ctrl) replaced with the already-definedcontrolPressedflag.The cleanup intentionally preserves "suspicious-vestige" variables with
[[maybe_unused]]+ a brief comment rather than silently deleting them — the warning is gone but the signal for future readers stays.Notes
throw (X)) were removed because the language drops them in C++17; the only observable side-effect is that exceptions other than the declared one no longer triggerterminate()at the function boundary (they propagate normally and are caught by the SMSToolsguard()wrapper described above).registerstorage-class qualifiers inCLAM_Math.hxxwere removed; modern compilers had been ignoring the keyword for decades and C++17 made the spelling illegal.SMSTools-qt4/tree has been removed and replaced bySMSTools/.Annotator/,Voice2MIDI/and a couple of other apps still rely on SCons and have not been touched here. SeeCMAKE-MIGRATION.mdfor the up-to-date status.Test plan
.github/workflows/build.ymlpasses onubuntu-latest.cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCLAM_BUILD_LIBRARIES=ON -DCLAM_BUILD_GUI_APPS=ON -DCLAM_BUILD_SMSTOOLS=ON && cmake --build buildsucceeds with zero compiler warnings../build/NetworkEditor/NetworkEditorlaunches and lets you drop aProcessingbox; port-hover tooltips show the right type name (the prior dangling-pointer garbage is gone); the box drags from anywhere on its body, not only the title strip../build/SMSTools/SMSToolslaunches; loadsSMSTools/example-data/Elvis-config.xml, runs Analyze → Apply (any transformation score fromclam_data/SMSTests/*-transf.xml) → Synthesize, and surfaces XML/load errors asQMessageBoxdialogs instead of aborting.