TL;DR
If you want a quick and easy HOWTO, then see HOWTO: Port serialplot to OS X. It is a must less painful read.
Preamble
A (now not so – it’s grown exponentially) brief HOW-TO for /serialplot, which is for Windows/Linux – but which may compile and work on OS X. That is the idea anyway.
As it turned out, compiling and building was the easy part. Bundling the Qt and Qwt frameworks into the application turned out to be the mind-blowing part.
Not to be confused with /SerialPlot, a Qt application written explicitly for OS X, see Compiling Qt SerialPlot (for OS X).
Note: Using OS X 10.13.6 High Sierra
Application and script: /serialplot_OS_X_port
Backstory
Whilst following Paul McWhorter’s IMU BNO055 course, I had a requirement for a serial plotter application, one that was better than the paltry offering built into the Arduino IDE (it autoscales too much and isn’t particularly configurable). In the video course, SerialPlot (/serialplot) is used, a nicely functional Qt based Windows and Linux application, but there is no OS X port…
See also
- SerialPlot – a Qt adventure on OS X
- Compiling Qt SerialPlot (for OS X)
- HOWTO: Port serialplot to OS X
Links
Qt Docs
- Qt for macOS – Specific Issues – not used
- Qt for macOS – Deployment – very useful, also covers
macdeployqt
Stack Exchange
Many, many, many…
- This comment, for
otool -D
to see the install name. - How do I link libraries with rpath in Xcode? and my answer
- Qt 5.4 application bundled for OSX crashes when launched
Initial housekeeping
First, some setup and preparation is required:
- Download and install QtCreator. You can install QtCreator 4.5 from the repository
- Create a workspace, i.e.
~/qtcode
- Download, and unzip
serialplot
. Copy it into the workspace - Download, bunzip2 and untar
qwt-6.2.0
. Copy it into the workspace. Rename the directory toqwt
. - Install Qt5, using
brew
:brew install qt5
Build notes
So, why not give /serialplot a try on OS X?
Immediately, one will receive an error upon running qmake
in a terminal:
$ /usr/local/Cellar/qt@4/4.8.7_6.reinstall/bin/qmake serialplot.pro Project MESSAGE: Warning: unknown QT: serialport Error: unknown command "icons" for "rcc" Run 'rcc --help' for usage. Error: [rcc v9.16.0] unknown command "icons" for "rcc" $
This is because QtSerialPort
is only available in Qt5 (include/QtSerialPort
), not Qt4. So you need to use qmake
from Qt5, not Qt4, as I did above.
In QtCreator, selecting Qt5 kit (and running qmake
) I got
:-1: error: failed to parse default search paths from compiler output
From Qt@5.5 works, but not Qt ensure that in Manage kits, Build and Run, that Qt5 is using Clang as a compiler for both C and C++, and is not using GCC. It is GCC that gives this error… once Clang is selected, then run qmake
again and the issue should disappear.
Strangely, when I reverted back to GCC, the issue of the default search paths did not reappear.
Trying a build I got
macx-g++ -F/usr/local/Cellar/qt@5/5.15.2/lib -o main.o ../serialplot/src/main.cpp In file included from ../serialplot/src/main.cpp:25: ../serialplot/src/mainwindow.h:35:10: fatal error: 'qwt_plot_curve.h' file not found #include <qwt_plot_curve.h> ^~~~~~~~~~~~~~~~~~ 1 error generated. make: *** [main.o] Error 1 04:58:18: The process "/usr/bin/make" exited with code 2. Error while building/deploying project serialplot (kit: Qt5) When executing step "Make" 04:58:18: Elapsed time: 00:03.
Copy qwt-6.2.0
into the workspace (untar and rename to qwt
):
$ bunzip2 qwt-6.2.0.tar.bz2 $ tar xvf qwt-6.2.0.tar $ mv qwt-6.2.0 qwt
Add to serialplot.pro
INCLUDEPATH += $$PWD/../qwt/src
then upon retrying a build, you get the following error
../serialplot/src/plot.cpp:277:49: error: member access into incomplete type 'QwtScaleMap' auto paintDist = sw->scaleDraw()->scaleMap().pDist(); ^ /Users/macbook/qtcode/serialplot/../qwt/src/qwt_plot_item.h:17:7: note: forward declaration of 'QwtScaleMap' class QwtScaleMap; ^ ../serialplot/src/plot.cpp:278:49: error: member access into incomplete type 'QwtScaleMap' auto scaleDist = sw->scaleDraw()->scaleMap().sDist(); ^ /Users/macbook/qtcode/serialplot/../qwt/src/qwt_plot_item.h:17:7: note: forward declaration of 'QwtScaleMap' class QwtScaleMap; ^ 9 warnings and 2 errors generated. make: *** [plot.o] Error 1 05:42:19: The process "/usr/bin/make" exited with code 2. Error while building/deploying project serialplot (kit: Qt5) When executing step "Make" 05:42:19: Elapsed time: 00:12.
Adding
include(../qwt/qwtbuild.pri)
Just seemed to make things worse, with lots of errors appearing – although the 2 errors above vanished. I’m not sure if that is because they were fixed, or they hadn’t been arrived at (I suspect the latter).
Maybe add all three .pri
files from qwt-6.2.0??? I didn’t try this. I ended up removing the include(../qwt/qwtbuild.pri)
line.
Compiling qwt
I thought I’d compile qwt-6.2.0
. Remember to change the directory name to just qwt
so that it matches the name of the qwt.pro
file. In QtCreator, using Qt5, initially I got the same error as before
:-1: error: failed to parse default search paths from compiler output
Again, in Project mode (left hand sidebar), Manage Kits-> Kit tab-> Select Qt5 kit and then select Clang for both the C and C++ compliers:
Remarkably, qwt
compiled/built without an error.
However, I was unsure how to perform make install
, from within QtCreator, so I reverted to a terminal. Interestingly, even though qmake
and make
(i.e. Build) had already been run in QtCreator, there was no Makefile
in the qwt
directory. So I had to run qmake
again, this time in the terminal:
/usr/local/Cellar/qt@5/5.15.2/bin/qmake
and then make install
.
Back to serialplot
Returning to serialplot
, the same two issues persisted (forward declaration
and member access to incomplete type
).
I wondered if it was to do with my addition of the line to serialplot.pro
INCLUDEPATH += $$PWD/../qwt/src
After all, it was not mentioned in the serialplot
documentation. According to the docs, if you build and install qwt
, then you must:
And set
BUILD_QWT
cmake option tofalse
.
Apparently, see Setting CMake variables in QtCreator, you do this in Manage kits > Build and Run>Select the Qt kit,
Find CMake Configuration and click the Change… button and then add
I removed the INCLUDEPATH
line from serialplot.pro
and hit Build. The same fatal error: 'qwt_plot_curve.h' file not found
error returned.
I reinstated the INCLUDEPATH
line in serialplot.pro and predictably, I got the two other errors (forward declaration
and member access to incomplete type
).
A nice explanation of forward declarations is given in this post on Forward Declaration of Class and Incomplete Type
forward declaration allows to declare pointer to incomplete class,
but as soon you need access functionality of incomplete class you have to provide complete declaration (include file).
This usually works well if you do not define classes in the same file and keep class implementation in cpp file// b.h header file
// forward declaration
class A;class B {
public:
A* pA; // pointer of A is fine}
// B. cpp file
#include b.h
#include a.h // Complete declaration of aB b;
b.pA = new A;
The errors were in plot.cpp
, so I added the line
#include <qwt_scale_map.h>
which fixed the issue with plot.cpp
. Moving on, I now got a number of other errors, this time in zoomer.cpp
Adding
#include <qwt_text.h>
and then
#include <QPainter> #include <QPainterPath> #include <QStack>
The next errors were in scrollzoomer.cpp
Adding
#include <QStack>
The next errors were in plotmenu.cpp
, adding
#include <QDebug>
The next errors were in barchart.cpp
, adding
#include <qwt_text.h>
Then, also in barchart.cpp
,
/Users/macbook/qtcode/serialplot/src/barchart.cpp:82: error: use of undeclared identifier 'fabs' const double barHeight = fabs(y2 - y1); ^
See When do I use fabs and when is it sufficient to use std::abs?, which suggests that fabs()
is declared in math.h
.
Adding in barchart.cpp
,
#include "math.h"
Finally, all of the compile errors were fixed, leaving me with linker errors:
ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
There were a lot of them…
Undefined symbols for architecture x86_64: "QwtPlotGrid::enableXMin(bool)", referenced from: Plot::showMinorGrid(bool) in plot.o "QwtPlotGrid::enableYMin(bool)", referenced from: Plot::showMinorGrid(bool) in plot.o "QwtPlotGrid::setPen(QColor const&, double, Qt::PenStyle)", referenced from: Plot::darkBackground(bool) in plot.o "QwtPlotGrid::enableX(bool)", referenced from: Plot::showGrid(bool) in plot.o "QwtPlotGrid::enableY(bool)", referenced from: Plot::showGrid(bool) in plot.o "QwtPlotGrid::QwtPlotGrid()", referenced from: Plot::Plot(QWidget*) in plot.o "QwtPlotGrid::~QwtPlotGrid()", referenced from: Plot::Plot(QWidget*) in plot.o Plot::~Plot() in plot.o "QwtPlotItem::setVisible(bool)", referenced from: Plot::showLegend(bool) in plot.o Plot::showDemoIndicator(bool) in plot.o Plot::showNoChannel(bool) in plot.o vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o ... "QwtPlotItem::itemChanged()", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotItem::updateLegend(QwtPlotItem const*, QList const&)", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotItem::legendChanged()", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotItem::setItemAttribute(QwtPlotItem::ItemAttribute, bool)", referenced from: PlotManager::onChannelInfoChanged(QModelIndex const&, QModelIndex const&, QVector const&) in plotmanager.o "QwtPlotItem::hide()", referenced from: Plot::Plot(QWidget*) in plot.o "QwtPlotItem::attach(QwtPlot*)", referenced from: Plot::Plot(QWidget*) in plot.o PlotManager::setMulti(bool) in plotmanager.o PlotManager::_addCurve(QwtPlotCurve*) in plotmanager.o BarPlot::BarPlot(Stream*, PlotMenu*, QWidget*) in barplot.o "QwtPlotItem::detach()", referenced from: PlotManager::setMulti(bool) in plotmanager.o "QwtPlotItem::setTitle(QString const&)", referenced from: PlotManager::onChannelInfoChanged(QModelIndex const&, QModelIndex const&, QVector const&) in plotmanager.o "QwtPlotCurve::setSamples(QwtSeriesData*)", referenced from: PlotManager::addCurve(QString, XFrameBuffer const*, FrameBuffer const*) in plotmanager.o "QwtPlotCurve::setPen(QColor const&, double, Qt::PenStyle)", referenced from: PlotManager::onChannelInfoChanged(QModelIndex const&, QModelIndex const&, QVector const&) in plotmanager.o PlotManager::_addCurve(QwtPlotCurve*) in plotmanager.o "QwtPlotCurve::setSymbol(QwtSymbol*)", referenced from: Plot::updateSymbols() in plot.o "QwtPlotCurve::QwtPlotCurve(QString const&)", referenced from: PlotManager::addCurve(QString, XFrameBuffer const*, FrameBuffer const*) in plotmanager.o "QwtScaleDraw::setLabelRotation(double)", referenced from: BarScaleDraw::BarScaleDraw(Stream const*) in barscaledraw.o "QwtScaleDraw::setLabelAlignment(QFlags)", referenced from: BarScaleDraw::BarScaleDraw(Stream const*) in barscaledraw.o "QwtScaleDraw::QwtScaleDraw()", referenced from: BarScaleDraw::BarScaleDraw(Stream const*) in barscaledraw.o "QwtScaleDraw::~QwtScaleDraw()", referenced from: BarScaleDraw::BarScaleDraw(Stream const*) in barscaledraw.o BarScaleDraw::~BarScaleDraw() in barscaledraw.o "QwtPlotLayout::setCanvasMargin(int, int)", referenced from: ScrollZoomer::updateScrollBars() in scrollzoomer.o "QwtPlotLayout::setAlignCanvasToScale(int, bool)", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtPlotLayout::setAlignCanvasToScales(bool)", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtPlotPicker::move(QPoint const&)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotPicker::plot()", referenced from: ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o "QwtPlotPicker::append(QPoint const&)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotPicker::canvas()", referenced from: ScrollZoomer::scrollBar(Qt::Orientation) in scrollzoomer.o ScrollZoomer::setCornerWidget(QWidget*) in scrollzoomer.o ScrollZoomer::eventFilter(QObject*, QEvent*) in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o "QwtPlotZoomer::qt_metacall(QMetaObject::Call, int, void**)", referenced from: ScrollZoomer::qt_metacall(QMetaObject::Call, int, void**) in moc_scrollzoomer.o "QwtPlotZoomer::qt_metacast(char const*)", referenced from: ScrollZoomer::qt_metacast(char const*) in moc_scrollzoomer.o "QwtPlotZoomer::setZoomBase(QRectF const&)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotZoomer::setZoomBase(bool)", referenced from: ScrollZoomer::setZoomBase(bool) in scrollzoomer.o "QwtPlotZoomer::setZoomStack(QStack const&, int)", referenced from: ScrollZoomer::setZoomBase(bool) in scrollzoomer.o ScrollZoomer::moveTo(QPointF const&) in scrollzoomer.o "QwtPlotZoomer::staticMetaObject", referenced from: QObject::connect(std::__1::enable_if<(QtPrivate::FunctionPointer<Plot::Plot(QWidget*)::$_0>::ArgumentCount) == (-(1)), QMetaObject::Connection>::type, QtPrivate::FunctionPointer::Object const*, void (QwtPlotZoomer::*)(QRectF const&), QObject const*, Plot::Plot(QWidget*)::$_0, Qt::ConnectionType) in plot.o ScrollZoomer::staticMetaObject in moc_scrollzoomer.o "QwtPlotZoomer::widgetKeyPressEvent(QKeyEvent*)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotZoomer::widgetMouseReleaseEvent(QMouseEvent*)", referenced from: Zoomer::widgetMouseReleaseEvent(QMouseEvent*) in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPlotZoomer::end(bool)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotZoomer::zoom(QRectF const&)", referenced from: Zoomer::zoom(QRectF const&) in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPlotZoomer::zoom(int)", referenced from: Zoomer::zoom(int) in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPlotZoomer::begin()", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotZoomer::moveBy(double, double)", referenced from: Zoomer::widgetMouseMoveEvent(QMouseEvent*) in zoomer.o "QwtPlotZoomer::zoomed(QRectF const&)", referenced from: Plot::Plot(QWidget*) in plot.o ScrollZoomer::scrollBarMoved(Qt::Orientation, double, double) in scrollzoomer.o "QwtPlotZoomer::setAxes(int, int)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotZoomer::QwtPlotZoomer(QWidget*, bool)", referenced from: ScrollZoomer::ScrollZoomer(QWidget*) in scrollzoomer.o "QwtPlotZoomer::~QwtPlotZoomer()", referenced from: ScrollZoomer::ScrollZoomer(QWidget*) in scrollzoomer.o ScrollZoomer::~ScrollZoomer() in scrollzoomer.o "QwtScaleWidget::setMinBorderDist(int, int)", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtScaleWidget::scaleDraw()", referenced from: Plot::calcSymbolSize() in plot.o ScalePicker::updateSnapPoints() in scalepicker.o ScalePicker::position(double) const in scalepicker.o "QwtColumnSymbol::setPalette(QPalette const&)", referenced from: BarChart::specialSymbol(int, QPointF const&) const in barchart.o "QwtColumnSymbol::setLineWidth(int)", referenced from: BarChart::specialSymbol(int, QPointF const&) const in barchart.o "QwtColumnSymbol::setFrameStyle(QwtColumnSymbol::FrameStyle)", referenced from: BarChart::specialSymbol(int, QPointF const&) const in barchart.o "QwtColumnSymbol::QwtColumnSymbol(QwtColumnSymbol::Style)", referenced from: BarChart::specialSymbol(int, QPointF const&) const in barchart.o "QwtPlotBarChart::setSamples(QVector const&)", referenced from: BarChart::resample() in barchart.o "QwtPlotBarChart::QwtPlotBarChart(QString const&)", referenced from: BarChart::BarChart(Stream const*) in barchart.o BarChart::BarChart(Stream const*) in barchart.o "QwtPlotBarChart::~QwtPlotBarChart()", referenced from: construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::~QwtPlotBarChart()", referenced from: construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::~QwtPlotBarChart()", referenced from: BarChart::~BarChart() in barplot.o BarChart::BarChart(Stream const*) in barchart.o BarChart::BarChart(Stream const*) in barchart.o BarChart::~BarChart() in barchart.o BarChart::~BarChart() in moc_barplot.o "QwtPlotRenderer::QwtPlotRenderer(QObject*)", referenced from: PlotManager::exportSvg(QString) const in plotmanager.o "QwtPlotRenderer::~QwtPlotRenderer()", referenced from: PlotManager::exportSvg(QString) const in plotmanager.o "QwtPlotTextLabel::setText(QwtText const&)", referenced from: Plot::Plot(QWidget*) in plot.o "QwtPlotTextLabel::QwtPlotTextLabel()", referenced from: Plot::Plot(QWidget*) in plot.o "QwtPlotTextLabel::~QwtPlotTextLabel()", referenced from: Plot::Plot(QWidget*) in plot.o Plot::~Plot() in plot.o "QwtWidgetOverlay::paintEvent(QPaintEvent*)", referenced from: vtable for PlotOverlay in scalepicker.o vtable for ScaleOverlay in scalepicker.o vtable for PlotSnapshotOverlay in moc_plotsnapshotoverlay.o "QwtWidgetOverlay::eventFilter(QObject*, QEvent*)", referenced from: vtable for PlotOverlay in scalepicker.o vtable for ScaleOverlay in scalepicker.o vtable for PlotSnapshotOverlay in moc_plotsnapshotoverlay.o "QwtWidgetOverlay::resizeEvent(QResizeEvent*)", referenced from: vtable for PlotOverlay in scalepicker.o vtable for ScaleOverlay in scalepicker.o vtable for PlotSnapshotOverlay in moc_plotsnapshotoverlay.o "QwtWidgetOverlay::updateOverlay()", referenced from: ScalePicker::eventFilter(QObject*, QEvent*) in scalepicker.o PlotSnapshotOverlay::PlotSnapshotOverlay(QWidget*, QColor)::$_0::operator()() const in plotsnapshotoverlay.o "QwtWidgetOverlay::QwtWidgetOverlay(QWidget*)", referenced from: PlotOverlay::PlotOverlay(QWidget*, ScalePicker*) in scalepicker.o ScaleOverlay::ScaleOverlay(QWidget*, ScalePicker*) in scalepicker.o PlotSnapshotOverlay::PlotSnapshotOverlay(QWidget*, QColor) in plotsnapshotoverlay.o "QwtWidgetOverlay::~QwtWidgetOverlay()", referenced from: PlotOverlay::~PlotOverlay() in scalepicker.o ScaleOverlay::~ScaleOverlay() in scalepicker.o PlotSnapshotOverlay::PlotSnapshotOverlay(QWidget*, QColor) in plotsnapshotoverlay.o PlotSnapshotOverlay::~PlotSnapshotOverlay() in moc_plotsnapshotoverlay.o "QwtPlotLegendItem::setTextPen(QPen const&)", referenced from: Plot::darkBackground(bool) in plot.o "QwtPlotLegendItem::QwtPlotLegendItem()", referenced from: Plot::Plot(QWidget*) in plot.o "QwtPlotLegendItem::~QwtPlotLegendItem()", referenced from: Plot::Plot(QWidget*) in plot.o Plot::~Plot() in plot.o "QwtPlotSeriesItem::dataChanged()", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotSeriesItem::updateScaleDiv(QwtScaleDiv const&, QwtScaleDiv const&)", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotSeriesItem::~QwtPlotSeriesItem()", referenced from: construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotSeriesItem::~QwtPlotSeriesItem()", referenced from: construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtAbstractScaleDraw::enableComponent(QwtAbstractScaleDraw::ScaleComponent, bool)", referenced from: BarScaleDraw::BarScaleDraw(Stream const*) in barscaledraw.o "QwtAbstractScaleDraw::invalidateCache()", referenced from: BarScaleDraw::BarScaleDraw(Stream const*)::$_0::operator()() const in barscaledraw.o "QwtAbstractScaleDraw::scaleMap()", referenced from: Plot::calcSymbolSize() in plot.o ScalePicker::updateSnapPoints() in scalepicker.o ScalePicker::position(double) const in scalepicker.o "QwtPlotAbstractBarChart::setSpacing(int)", referenced from: BarChart::BarChart(Stream const*) in barchart.o BarChart::BarChart(Stream const*) in barchart.o "QwtPlotAbstractBarChart::~QwtPlotAbstractBarChart()", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o "QwtPlotAbstractBarChart::~QwtPlotAbstractBarChart()", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o "QwtPlot::axisWidget(int)", referenced from: Plot::calcSymbolSize() in plot.o ScrollZoomer::rescale() in scrollzoomer.o ScaleZoomer::ScaleZoomer(QwtPlot*, QwtPlotZoomer*) in scalezoomer.o "QwtPlot::drawCanvas(QPainter*)", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::plotLayout()", referenced from: ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o "QwtPlot::eventFilter(QObject*, QEvent*)", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::qt_metacall(QMetaObject::Call, int, void**)", referenced from: Plot::qt_metacall(QMetaObject::Call, int, void**) in moc_plot.o BarPlot::qt_metacall(QMetaObject::Call, int, void**) in moc_barplot.o "QwtPlot::qt_metacast(char const*)", referenced from: Plot::qt_metacast(char const*) in moc_plot.o BarPlot::qt_metacast(char const*) in moc_barplot.o "QwtPlot::resizeEvent(QResizeEvent*)", referenced from: Plot::resizeEvent(QResizeEvent*) in plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::itemAttached(QwtPlotItem*, bool)", referenced from: Plot::Plot(QWidget*) in plot.o "QwtPlot::setAxisScale(int, double, double, double)", referenced from: Plot::resetAxes() in plot.o ScrollZoomer::rescale() in scrollzoomer.o BarPlot::update() in barplot.o BarPlot::setYAxis(bool, double, double) in barplot.o "QwtPlot::updateLayout()", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::updateLegend(QwtPlotItem const*)", referenced from: PlotManager::onChannelInfoChanged(QModelIndex const&, QModelIndex const&, QVector const&) in plotmanager.o "QwtPlot::updateLegend()", referenced from: PlotManager::onChannelInfoChanged(QModelIndex const&, QModelIndex const&, QVector const&) in plotmanager.o "QwtPlot::setAutoReplot(bool)", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtPlot::setAxisMaxMinor(int, int)", referenced from: BarPlot::BarPlot(Stream*, PlotMenu*, QWidget*) in barplot.o "QwtPlot::setAxisAutoScale(int, bool)", referenced from: Plot::resetAxes() in plot.o BarPlot::setYAxis(bool, double, double) in barplot.o "QwtPlot::setAxisScaleDraw(int, QwtScaleDraw*)", referenced from: BarPlot::BarPlot(Stream*, PlotMenu*, QWidget*) in barplot.o "QwtPlot::staticMetaObject", referenced from: QObject::connect(std::__1::enable_if<(QtPrivate::FunctionPointer<Plot::Plot(QWidget*)::$_1>::ArgumentCount) == (-(1)), QMetaObject::Connection>::type, QtPrivate::FunctionPointer::Object const*, void (QwtPlot::*)(QwtPlotItem*, bool), QObject const*, Plot::Plot(QWidget*)::$_1, Qt::ConnectionType) in plot.o Plot::staticMetaObject in moc_plot.o BarPlot::staticMetaObject in moc_barplot.o "QwtPlot::setCanvasBackground(QBrush const&)", referenced from: Plot::darkBackground(bool) in plot.o BarPlot::darkBackground(bool) in barplot.o "QwtPlot::event(QEvent*)", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::canvas()", referenced from: Plot::Plot(QWidget*) in plot.o Plot::flashSnapshotOverlay(bool) in plot.o ScaleZoomer::ScaleZoomer(QwtPlot*, QwtPlotZoomer*) in scalezoomer.o "QwtPlot::replot()", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::QwtPlot(QWidget*)", referenced from: Plot::Plot(QWidget*) in plot.o BarPlot::BarPlot(Stream*, PlotMenu*, QWidget*) in barplot.o "QwtPlot::~QwtPlot()", referenced from: Plot::Plot(QWidget*) in plot.o Plot::~Plot() in plot.o BarPlot::BarPlot(Stream*, PlotMenu*, QWidget*) in barplot.o BarPlot::~BarPlot() in moc_barplot.o "QwtText::setRenderFlags(int)", referenced from: Plot::Plot(QWidget*) in plot.o "QwtText::setBorderRadius(double)", referenced from: Plot::Plot(QWidget*) in plot.o "QwtText::setBackgroundBrush(QBrush const&)", referenced from: Plot::Plot(QWidget*) in plot.o "QwtText::setText(QString const&, QwtText::TextFormat)", referenced from: Zoomer::trackerTextF(QPointF const&) const in zoomer.o "QwtText::setColor(QColor const&)", referenced from: Plot::Plot(QWidget*) in plot.o "QwtText::QwtText(QString const&, QwtText::TextFormat)", referenced from: Plot::Plot(QWidget*) in plot.o Zoomer::valueTrackerRect(QFont const&) const in zoomer.o ScalePicker::trackerText() const in scalepicker.o BarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const in barchart.o BarScaleDraw::label(double) const in barscaledraw.o "QwtText::~QwtText()", referenced from: Plot::Plot(QWidget*) in plot.o Zoomer::trackerTextF(QPointF const&) const in zoomer.o Zoomer::valueTrackerRect(QFont const&) const in zoomer.o ScalePicker::drawPlotOverlay(QPainter*) in scalepicker.o BarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const in barchart.o "QwtPicker::transition(QEvent const*)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::eventFilter(QObject*, QEvent*)", referenced from: ScrollZoomer::eventFilter(QObject*, QEvent*) in scrollzoomer.o "QwtPicker::parentWidget()", referenced from: Zoomer::widgetMousePressEvent(QMouseEvent*) in zoomer.o Zoomer::widgetMouseReleaseEvent(QMouseEvent*) in zoomer.o "QwtPicker::setTrackerPen(QPen const&)", referenced from: Plot::darkBackground(bool) in plot.o "QwtPicker::updateDisplay()", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::setTrackerMode(QwtPicker::DisplayMode)", referenced from: Zoomer::Zoomer(QWidget*, bool) in zoomer.o "QwtPicker::setRubberBandPen(QPen const&)", referenced from: Plot::darkBackground(bool) in plot.o "QwtPicker::stretchSelection(QSize const&, QSize const&)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::widgetEnterEvent(QEvent*)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::widgetLeaveEvent(QEvent*)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::widgetWheelEvent(QWheelEvent*)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::widgetMouseMoveEvent(QMouseEvent*)", referenced from: Zoomer::widgetMouseMoveEvent(QMouseEvent*) in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPicker::widgetKeyReleaseEvent(QKeyEvent*)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::widgetMousePressEvent(QMouseEvent*)", referenced from: Zoomer::widgetMousePressEvent(QMouseEvent*) in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent*)", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::reset()", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::remove()", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtSymbol::QwtSymbol(QwtSymbol::Style, QBrush const&, QPen const&, QSize const&)", referenced from: Plot::updateSymbols() in plot.o "QwtPlotDict::itemList(int) const", referenced from: Plot::updateSymbols() in plot.o "QwtPlotItem::legendData() const", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotItem::legendIcon(int, QSizeF const&) const", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotItem::getCanvasMarginHint(QwtScaleMap const&, QwtScaleMap const&, QRectF const&, double&, double&, double&, double&) const", referenced from: construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotItem::rtti() const", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotItem::isVisible() const", referenced from: PlotManager::setMulti(bool) in plotmanager.o PlotManager::checkNoVisChannels()::$_1::operator()(QwtPlotCurve*) const in plotmanager.o "QwtScaleDiv::lowerBound() const", referenced from: ScaleZoomer::bottomPicked(double, double) in scalezoomer.o ScaleZoomer::leftPicked(double, double) in scalezoomer.o "QwtScaleDiv::upperBound() const", referenced from: ScaleZoomer::bottomPicked(double, double) in scalezoomer.o ScaleZoomer::leftPicked(double, double) in scalezoomer.o "QwtScaleDiv::isIncreasing() const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o "QwtScaleDiv::ticks(int) const", referenced from: ScalePicker::updateSnapPoints() in scalepicker.o "QwtPlotCurve::pen() const", referenced from: Plot::updateSymbols() in plot.o "QwtScaleDraw::drawBackbone(QPainter*) const", referenced from: vtable for BarScaleDraw in barscaledraw.o "QwtScaleDraw::extent(QFont const&) const", referenced from: vtable for BarScaleDraw in barscaledraw.o "QwtScaleDraw::drawTick(QPainter*, double, double) const", referenced from: vtable for BarScaleDraw in barscaledraw.o "QwtScaleDraw::drawLabel(QPainter*, double) const", referenced from: vtable for BarScaleDraw in barscaledraw.o "QwtPlotLayout::canvasMargin(int) const", referenced from: ScrollZoomer::updateScrollBars() in scrollzoomer.o "QwtPlotLayout::alignCanvasToScale(int) const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtPlotPicker::trackerText(QPoint const&) const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotPicker::invTransform(QRect const&) const", referenced from: Zoomer::trackerTextF(QPointF const&) const in zoomer.o "QwtPlotPicker::invTransform(QPoint const&) const", referenced from: Zoomer::drawValues(QPainter*) const in zoomer.o Zoomer::widgetMousePressEvent(QMouseEvent*) in zoomer.o Zoomer::widgetMouseMoveEvent(QMouseEvent*) in zoomer.o "QwtPlotPicker::trackerTextF(QPointF const&) const", referenced from: Zoomer::trackerTextF(QPointF const&) const in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPlotPicker::xAxis() const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o ScrollZoomer::layoutScrollBars(QRect const&) in scrollzoomer.o "QwtPlotPicker::yAxis() const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o ScrollZoomer::layoutScrollBars(QRect const&) in scrollzoomer.o "QwtPlotPicker::scaleRect() const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtPlotPicker::transform(QPointF const&) const", referenced from: Zoomer::drawValues(QPainter*) const in zoomer.o "QwtPlotZoomer::minZoomSize() const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotZoomer::zoomRectIndex() const", referenced from: Zoomer::zoom(int) in zoomer.o Zoomer::zoom(QRectF const&) in zoomer.o ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::moveTo(QPointF const&) in scrollzoomer.o "QwtPlotZoomer::accept(QPolygon&) const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotZoomer::zoomBase() const", referenced from: Plot::calcSymbolSize() in plot.o ScrollZoomer::setZoomBase(bool) in scrollzoomer.o ScrollZoomer::needScrollBar(Qt::Orientation) const in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o ScrollZoomer::moveTo(QPointF const&) in scrollzoomer.o "QwtPlotZoomer::zoomRect() const", referenced from: ScrollZoomer::needScrollBar(Qt::Orientation) const in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o ScrollZoomer::scrollBarMoved(Qt::Orientation, double, double) in scrollzoomer.o ScrollZoomer::moveTo(QPointF const&) in scrollzoomer.o "QwtPlotZoomer::zoomStack() const", referenced from: ScrollZoomer::setZoomBase(bool) in scrollzoomer.o ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::moveTo(QPointF const&) in scrollzoomer.o "QwtScaleWidget::getBorderDistHint(int&, int&) const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtScaleWidget::alignment() const", referenced from: ScalePicker::drawPlotOverlay(QPainter*) in scalepicker.o ScalePicker::drawScaleOverlay(QPainter*) in scalepicker.o ScalePicker::positionPx(QMouseEvent*) in scalepicker.o ScalePicker::posCanvasPx(double) const in scalepicker.o ScalePicker::pickTrackerTextRect(QPainter*, QRect, QSizeF) const in scalepicker.o ScalePicker::trackerTextRect(QPainter*, int, QSizeF) const in scalepicker.o "QwtEventPattern::mouseMatch(QwtEventPattern::MousePattern const&, QMouseEvent const*) const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtEventPattern::keyMatch(QwtEventPattern::KeyPattern const&, QKeyEvent const*) const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPlotBarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const", referenced from: BarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::drawSeries(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, int, int) const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::legendData() const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::legendIcon(int, QSizeF const&) const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::boundingRect() const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::specialSymbol(int, QPointF const&) const", referenced from: construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::rtti() const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::drawBar(QPainter*, int, QPointF const&, QwtColumnRect const&) const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotBarChart::barTitle(int) const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "QwtPlotRenderer::render(QwtPlot*, QPainter*, QRectF const&) const", referenced from: PlotManager::exportSvg(QString) const in plotmanager.o "QwtWidgetOverlay::maskHint() const", referenced from: vtable for PlotOverlay in scalepicker.o vtable for ScaleOverlay in scalepicker.o vtable for PlotSnapshotOverlay in moc_plotsnapshotoverlay.o "QwtPlotSeriesItem::boundingRect() const", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtPlotSeriesItem::draw(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&) const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "QwtAbstractScaleDraw::draw(QPainter*, QPalette const&) const", referenced from: vtable for BarScaleDraw in barscaledraw.o "QwtAbstractScaleDraw::scaleDiv() const", referenced from: ScalePicker::updateSnapPoints() in scalepicker.o "QwtPlotAbstractBarChart::sampleWidth(QwtScaleMap const&, double, double, double) const", referenced from: BarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const in barchart.o "QwtPlotAbstractBarChart::getCanvasMarginHint(QwtScaleMap const&, QwtScaleMap const&, QRectF const&, double&, double&, double&, double&) const", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o "QwtPlotAbstractBarChart::baseline() const", referenced from: BarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const in barchart.o "QwtPlot::autoReplot() const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o "QwtPlot::infoToItem(QVariant const&) const", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::itemToInfo(QwtPlotItem*) const", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::axisScaleDiv(int) const", referenced from: ScrollZoomer::rescale() in scrollzoomer.o ScrollZoomer::updateScrollBars() in scrollzoomer.o ScaleZoomer::bottomPicked(double, double) in scalezoomer.o ScaleZoomer::leftPicked(double, double) in scalezoomer.o "QwtPlot::minimumSizeHint() const", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::canvasBackground() const", referenced from: Plot::updateSymbols() in plot.o "QwtPlot::getCanvasMarginsHint(QwtScaleMap const*, QRectF const&, double&, double&, double&, double&) const", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::sizeHint() const", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::canvasMap(int) const", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtPlot::drawItems(QPainter*, QRectF const&, QwtScaleMap const*) const", referenced from: vtable for Plot in moc_plot.o vtable for BarPlot in moc_barplot.o "QwtText::draw(QPainter*, QRectF const&) const", referenced from: ScalePicker::drawPlotOverlay(QPainter*) in scalepicker.o BarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const in barchart.o "QwtText::text() const", referenced from: Zoomer::trackerTextF(QPointF const&) const in zoomer.o "QwtText::textSize(QFont const&) const", referenced from: Zoomer::valueTrackerRect(QFont const&) const in zoomer.o ScalePicker::drawPlotOverlay(QPainter*) in scalepicker.o "QwtText::textSize() const", referenced from: BarChart::drawSample(QPainter*, QwtScaleMap const&, QwtScaleMap const&, QRectF const&, QwtInterval const&, int, QPointF const&) const in barchart.o "QwtPicker::drawTracker(QPainter*) const", referenced from: Zoomer::drawTracker(QPainter*) const in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPicker::trackerMask() const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::trackerRect(QFont const&) const", referenced from: Zoomer::trackerRect(QFont const&) const in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPicker::rubberBandPen() const", referenced from: Zoomer::drawValues(QPainter*) const in zoomer.o "QwtPicker::adjustedPoints(QPolygon const&) const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::drawRubberBand(QPainter*) const", referenced from: Zoomer::drawRubberBand(QPainter*) const in zoomer.o vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPicker::rubberBandMask() const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o "QwtPicker::trackerPosition() const", referenced from: Zoomer::drawValues(QPainter*) const in zoomer.o Zoomer::valueTrackerRect(QFont const&) const in zoomer.o "QwtPicker::isActive() const", referenced from: Zoomer::trackerTextF(QPointF const&) const in zoomer.o Zoomer::drawTracker(QPainter*) const in zoomer.o Zoomer::trackerRect(QFont const&) const in zoomer.o "QwtPicker::pickArea() const", referenced from: vtable for ScrollZoomer in moc_scrollzoomer.o vtable for Zoomer in moc_zoomer.o "QwtPicker::selection() const", referenced from: Zoomer::trackerTextF(QPointF const&) const in zoomer.o Zoomer::rubberBandMask() const in zoomer.o "typeinfo for QwtScaleDraw", referenced from: typeinfo for BarScaleDraw in barscaledraw.o "typeinfo for QwtPlotZoomer", referenced from: typeinfo for ScrollZoomer in moc_scrollzoomer.o "typeinfo for QwtPlotBarChart", referenced from: construction vtable for QwtPlotBarChart-in-BarChart in barchart.o typeinfo for BarChart in barchart.o "typeinfo for QwtWidgetOverlay", referenced from: typeinfo for PlotOverlay in scalepicker.o typeinfo for ScaleOverlay in scalepicker.o typeinfo for PlotSnapshotOverlay in moc_plotsnapshotoverlay.o "typeinfo for QwtPlotSeriesItem", referenced from: construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "typeinfo for QwtPlotAbstractBarChart", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o "typeinfo for QwtPlot", referenced from: typeinfo for Plot in moc_plot.o typeinfo for BarPlot in moc_barplot.o "non-virtual thunk to QwtPlotBarChart::~QwtPlotBarChart()", referenced from: construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "non-virtual thunk to QwtPlotBarChart::~QwtPlotBarChart()", referenced from: construction vtable for QwtPlotBarChart-in-BarChart in barchart.o "virtual thunk to QwtPlotSeriesItem::~QwtPlotSeriesItem()", referenced from: construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "virtual thunk to QwtPlotSeriesItem::~QwtPlotSeriesItem()", referenced from: construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o "virtual thunk to QwtPlotAbstractBarChart::~QwtPlotAbstractBarChart()", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o "virtual thunk to QwtPlotAbstractBarChart::~QwtPlotAbstractBarChart()", referenced from: construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o "virtual thunk to QwtPlotSeriesItem::dataChanged()", referenced from: vtable for BarChart in barchart.o construction vtable for QwtPlotBarChart-in-BarChart in barchart.o construction vtable for QwtPlotAbstractBarChart-in-BarChart in barchart.o construction vtable for QwtPlotSeriesItem-in-BarChart in barchart.o
See Xcode build failure “Undefined symbols for architecture x86_64”
This is because the qwt.framework
is not being seen, neither in /Library/Frameworks/
which points to /usr/local/Cellar/qwt/6.1.6_1/lib
, nor the qwt (6.2.0) framework that was created above and which is in ~/qtworkspace/qwt/lib
:
Add the following line to serialplot.pro
(taken from the SerialPlot.pro
file for the OS X version of SerialPlot – /SerialPlot):
mac: LIBS += -F$$PWD/../qwt/lib/ -framework qwt
Re-run qmake
and then Build.
Now the compiler/linker command, generated by QtCreator, is
/Library/Developer/CommandLineTools/usr/bin/clang++ -stdlib=libc++ -headerpad_max_install_names -arch x86_64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -mmacosx-version-min=10.13 -Wl,-rpath,@executable_path/../Frameworks -o serialplot.app/Contents/MacOS/serialplot main.o mainwindow.o portcontrol.o plot.o zoomer.o scrollzoomer.o scrollbar.o hidabletabwidget.o scalepicker.o scalezoomer.o portlist.o snapshot.o snapshotview.o snapshotmanager.o plotsnapshotoverlay.o commandpanel.o commandwidget.o commandedit.o dataformatpanel.o plotcontrolpanel.o recordpanel.o datarecorder.o tooltipfilter.o sneakylineedit.o stream.o streamchannel.o channelinfomodel.o ringbuffer.o indexbuffer.o linindexbuffer.o readonlybuffer.o framebufferseries.o numberformatbox.o endiannessbox.o abstractreader.o binarystreamreader.o binarystreamreadersettings.o asciireader.o asciireadersettings.o demoreader.o demoreadersettings.o framedreader.o framedreadersettings.o plotmanager.o plotmenu.o barplot.o barchart.o barscaledraw.o numberformat.o updatechecker.o versionnumber.o updatecheckdialog.o samplepack.o source.o sink.o samplecounter.o ledwidget.o datatextview.o bpslabel.o qrc_icons.o moc_mainwindow.o moc_portcontrol.o moc_plot.o moc_hidabletabwidget.o moc_scalepicker.o moc_scalezoomer.o moc_portlist.o moc_snapshotview.o moc_snapshotmanager.o moc_snapshot.o moc_plotsnapshotoverlay.o moc_commandpanel.o moc_commandwidget.o moc_commandedit.o moc_dataformatpanel.o moc_sneakylineedit.o moc_plotcontrolpanel.o moc_numberformatbox.o moc_endiannessbox.o moc_framedreadersettings.o moc_abstractreader.o moc_binarystreamreader.o moc_binarystreamreadersettings.o moc_asciireadersettings.o moc_asciireader.o moc_demoreader.o moc_framedreader.o moc_plotmanager.o moc_recordpanel.o moc_updatechecker.o moc_updatecheckdialog.o moc_demoreadersettings.o moc_datatextview.o moc_bpslabel.o moc_barplot.o moc_channelinfomodel.o moc_datarecorder.o moc_ledwidget.o moc_plotmenu.o moc_samplecounter.o moc_scrollbar.o moc_scrollzoomer.o moc_stream.o moc_zoomer.o -F/usr/local/Cellar/qt@5/5.15.2/lib -F/Users/macbook/qtcode/serialplot/../qwt/lib/ -framework qwt -framework QtSvg -framework QtWidgets -framework QtGui -framework AppKit -framework Metal -framework QtSerialPort -framework QtNetwork -framework QtCore -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL
The options
-F/Users/macbook/qtcode/serialplot/../qwt/lib/ -framework qwt
were previously missing.
Now the application compiles. However, I couldn’t find the application binary in the ~qtcode/serialplot/
directory. Nevertheless, it can be seen from the crash below, that the application binary is in ~/qtcode/build-serialplot-Qt5-Debug
.
Running the application from within QtCreator gave this crash
Starting /Users/macbook/qtcode/build-serialplot-Qt5-Debug/serialplot.app/Contents/MacOS/serialplot... dyld: Library not loaded: qwt.framework/Versions/6/qwt Referenced from: /Users/macbook/qtcode/build-serialplot-Qt5-Debug/serialplot.app/Contents/MacOS/serialplot Reason: Incompatible library version: serialplot requires version 6.2.0 or later, but qwt provides version 6.0.0 The program has unexpectedly finished. The process was ended forcefully. /Users/macbook/qtcode/build-serialplot-Qt5-Debug/serialplot.app/Contents/MacOS/serialplot crashed.
So there exists a version mismatch of the qwt.framework
.
Side thought on the headers
Thinking back to all of the qwt
header #include
lines added to the various source files… I have a sneaky suspicion that if I had added the line
mac: LIBS += -F$$PWD/../qwt/lib/ -framework qwt
to the serialplot.pro
file earlier (i.e. at the beginning) then those #include
lines may not have been needed. I am not sure though, and this would need to be verified. Either that, or the line
INCLUDEPATH += $$PWD/../qwt/src
would not have been necessary, as a .framework
already contains the header files, under, for example, qwt.framework/Versions/6/Headers/
.
More on this later, see A do over – revisiting the sidenote below.
Fixing the version issue
Two thoughts on the version mismatch.
- Why, and where does it state that,
serialplot
requiresqwt
version 6.2.0? Where is this information held, and is it possible to edit it? - The
qwt
that we made above is version 6.2.0 so why does it think it is 6.0.0 ? Where is this information held, and is it possible to edit it?
Framework Programming Guide – Framework versions. According to this, a minor number should not cause incompatibility, so is x.2.0 a minor number, or a major number?
In Platform notes, the framework version is specified by:
FRAMEWORK_HEADERS.version = Versions FRAMEWORK_HEADERS.files = path/to/header_one.h path/to/header_two.h FRAMEWORK_HEADERS.path = Headers QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
In qwtconfig.pri
QWT_VER_MAJ = 6 QWT_VER_MIN = 2 QWT_VER_PAT = 0 QWT_VERSION = $${QWT_VER_MAJ}.$${QWT_VER_MIN}.$${QWT_VER_PAT}
So that would appear to be in order.
This is very interesting: Qt for macOS – Deployment
Running otool
on the qwt
framework that we have just created
$ cd ~/qtcode/qwt/lib $ otool -L qwt.framework/qwt qwt.framework/qwt: qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0)
So, that is correct too. So, I might be assumed that QtCreator is running the binary against some other qwt.framework
in a different location… possibly that which is in /Library/Frameworks
$ cd /Library/Frameworks/ $ otool -L qwt.framework/qwt qwt.framework/qwt: qwt.framework/Versions/6/qwt (compatibility version 6.0.0, current version 6.0.1)
Moving the qwt.framework
just created to /Library/Frameworks
seemed to fix the issue, and the application ran!
Amazing..!
Bundle the qwt framework inside the app (optional)
From Linking the Application to Qt as Frameworks, put the qwt.framework
in <app bundle>/Contents/Frameworks
, using the Finder to drag and drop. But this alone is not sufficient, else you get the same version errors.
This is the correct method to copy the framework to the app bundle:
mkdir serialplot.app/Contents/Frameworks #cp -R /path/to/qwt/lib/qwt.framework serialplot.app/Contents/Frameworks cp -R ~/qtcode/qwt/lib/qwt.framework serialplot.app/Contents/Frameworks
Then set the identification names for the frameworks
install_name_tool -id @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
Then ensure that the application also knows where to find the library,
#install_name_tool -change path/to/qwt/lib/qwt.framework/Versions/6/qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt plugandpaint.app/Contents/MacOS/plugandpaint install_name_tool -change ~/qtcode/qwt/lib/qwt.framework/Versions/6/qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/MacOS/serialplot
Note that the Qt page has a typo MacOs
, which should be MacOS
Then check
$ cd serialplot.app/Contents/Frameworks/ $ otool -L qwt.framework/qwt qwt.framework/qwt: @executable_path/../Frameworks/qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0)
This still did not work correctly… hmmm, missing something.
Another attempt
The process seems to be:
$ cd ~qtcode/build-serialplot-Qt5-Debug $ otool -L serialplot.app/Contents/MacOS/serialplot $ install_name_tool -id @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt $ install_name_tool -change /Library/Frameworks/qwt.framework/Versions/6/qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/MacOS/serialplot $ otool -L serialplot.app/Contents/MacOS/serialplot
Note:
otool -L
is usually run upon the application binary, rather than the library/framework (unless you need to find subsequent dependancies that the framework has).- Rather than using the directory where
qwt
was built, i.e.~/qtcode/qwt/lib/qwt.framework/Versions/6/qwt
, you use the/Library/Frameworks
directory, which is whereserialplot
actually looks to find the framework. This should be determined by the first time that you run:
$ otool -L serialplot.app/Contents/MacOS/serialplot
However, I found no path was specified to the qwt.framework
, which is odd (?):
$ otool -L serialplot.app/Contents/MacOS/serialplot serialplot.app/Contents/MacOS/serialplot: qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0) /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/opt/qt@5/lib/QtSerialPort.framework/Versions/5/QtSerialPort (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
I found that the same was true with SerialPlot (see Compiling Qt SerialPlot (for OS X))
$ otool -L SerialPlot.app/Contents/MacOS/SerialPlot SerialPlot.app/Contents/MacOS/SerialPlot: /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1455.255.0) qwt.framework/Versions/6/qwt (compatibility version 6.0.0, current version 6.0.1) /usr/local/lib/libqextserialport.1.dylib (compatibility version 1.2.0, current version 1.2.0) /usr/local/opt/qt@4/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.8.0, current version 4.8.7) /usr/local/opt/qt@4/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.8.0, current version 4.8.7) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
So why was qwt
not prefixed by /System/Library/Frameworks/
, or with any path? Very strange. [Edit: whatever the reason, the output of otool -L
should be used as the first argument to -change
]
See:
- install-name-tool does not add path to library when viewed through otool? – which is useful. The OP also made the same mistake as I did, of running
otool
upon the library rather than the app. - install_name_tool difference between -change and -id
Apparently, the -id
is only for the linker, and as we are after that stage, so -change
is the option to use. [Edit: this answer implies the opposite – ignore it]
However, I tried
$ install_name_tool -change qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt $ install_name_tool -change qwt.framework/Versions/6/qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt $ install_name_tool -change serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
That is to say, I used -change
upon:
qwt
qwt.framework/Versions/6/qwt
serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
- Plus previously:
/Library/Frameworks/qwt.framework/Versions/6/qwt
~/qtcode/qwt/lib/qwt.framework/Versions/6/qwt
And they all showed the same pathless qwt.framework
in the output of otool -L
This answer to Using install_name_tool what’s going wrong? suggests using rpath
, so combining with Fun with rpath, otool, and install_name_tool
$ install_name_tool -add_rpath @executable_path/../Frameworks serialplot.app/Contents/MacOS/serialplot error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool: for: serialplot.app/Contents/MacOS/serialplot (for architecture x86_64) option "-add_rpath @executable_path/../Frameworks" would duplicate path, file already has LC_RPATH for: @executable_path/../Frameworks $
So, rpath
was already set correctly.
Then
$ install_name_tool -change qwt.framework/Versions/6/qwt @rpath/qwt.framework/Versions/6/qwt serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
Then I noticed my mistake! The last argument wasn’t the path to the application binary, d’oh! Unbelievable! I had been consistently entering the last argument incorrectly. I had been using
serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
instead of
serialplot.app/Contents/MacOS/serialplot
Oh the shame!!!!
Correctly entering the command this time:
$ install_name_tool -change qwt.framework/Versions/6/qwt @rpath/qwt.framework/Versions/6/qwt serialplot.app/Contents/MacOS/serialplot
This produced the desired output in otool -L
$ otool -L serialplot.app/Contents/MacOS/serialplot serialplot.app/Contents/MacOS/serialplot: @rpath/qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0) /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/opt/qt@5/lib/QtSerialPort.framework/Versions/5/QtSerialPort (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) $
And now the application ran as expected.
Going through my bash history, I had got the command correct once:
$ install_name_tool -change /Library/Frameworks/qwt.framework/Versions/6/qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/MacOS/serialplot
However, I can only assume that as the otool -L
output showed qwt.framework/Versions/6/qwt
, then the /Library/Frameworks/
prefix had made it fail. Perhaps this command would have worked (check this!!!)
$ install_name_tool -change qwt.framework/Versions/6/qwt @executable_path/../Frameworks/qwt.framework/Versions/6/qwt serialplot.app/Contents/MacOS/serialplot
Also see Adding external libraries deploying QT app mac OSX
See also Fun with rpath, otool, and install_name_tool and https://www.unix.com/man-page/osx/1/install_name_tool/
From the man page:
install_name_tool [-change old new ] file
where:
old
– the name/output given byotool -L
new
– the relative path, either to@rpath
or@executable_path
file
– the path to the application binary
Summary of embedding
Links:
- This answer to Adding external libraries deploying QT app mac OSX,
- this article, and really,
- just this answer to install-name-tool does not add path to library when viewed through otool?, helped.
Remember to use:
- the name of the library, as shown in the output of
otool -L
, as the first argument - the relative path, with
@executable_path
or with@rpath
as the second argument - the the path of the binary executable as the third argument
Note that there is a makedeployqt
script for Qt, links:
- this answer to Adding external libraries deploying QT app mac OSX
- Deploying QT and OpenCV application on Mac OS X, linked to by Adding external libraries deploying QT app mac OSX
- was there one more?
Other related links
To embed the rest of the Qt frameworks
Running otool -L
to see what else needs embedding:
$ otool -L serialplot.app/Contents/MacOS/serialplot serialplot.app/Contents/MacOS/serialplot: @rpath/qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0) /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/opt/qt@5/lib/QtSerialPort.framework/Versions/5/QtSerialPort (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
There are three principal Qt frameworks:
QtSvg
QtWidgets
QtGui
plus
QtSerialPort
, which (according to the indentation) seems to needQtNetwork
QtCore
However, it is (currently) unclear as to what the indentation really means, for example:
- Why QtSerialPort is without indentation
- Why QtCore and QtNetwork are indented under QtSerialPort
[Edit: This indentation is due to WordPress, not the output of otool -L
]
You to run otool -L
on the frameworks to be sure.
Copy the Qt5 frameworks to serialplot.app/Contents/Frameworks
, (either in the Finder (not recommended(check?)) or) using a cp -R
in a terminal. The frameworks will be either in /Library/Frameworks/
if you had installed them there, or in /usr/local/lib
, or /usr/local/Cellar/qt@5/5.12.5/lib
if installed with brew
. Remember to use the Qt5 and not the Qt4 frameworks:
/usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework /usr/local/Cellar/qt@5/5.15.2/lib/QtNetwork.framework /usr/local/Cellar/qt@5/5.15.2/lib/QtSerialPort.framework /usr/local/Cellar/qt@5/5.15.2/lib/QtSvg.framework /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework
So, for just the first three Qt frameworks listed by otool -L
, the commands would be
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg serialplot.app/Contents/MacOS/serialplot $ install_name_tool -change /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/MacOS/serialplot $ install_name_tool -change /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/MacOS/serialplot
However, we also know that QtGui
also depends upon QtCore
:
$ otool -L serialplot.app/Contents/Frameworks/QtGui.framework/QtGui serialplot.app/Contents/Frameworks/QtGui.framework/QtGui: /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1247.4.1) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1560.12.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 50.1.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
So we need to point QtGui
to QtCore
as well, in the same manner that serialplot
binary is pointed to the Qt frameworks:
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui
Likewise QtSvg
depends upon QtWidgets
, QtGui
and QtCore
$ otool -L serialplot.app/Contents/Frameworks/QtSvg.framework/QtSvg serialplot.app/Contents/Frameworks/QtSvg.framework/QtSvg: /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
And QtWidgets
depends upon QtGui
and QtCore
$ otool -L serialplot.app/Contents/Frameworks/QtWidgets.framework/QtWidgets serialplot.app/Contents/Frameworks/QtWidgets.framework/QtWidgets: /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
So dealing with these five dependancies, in turn:
For QtSvg
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg
For QtWidgets
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets
Now add the other three framework dependancies to the application binary
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtSerialPort.framework/Versions/5/QtSerialPort @rpath/QtSerialPort.framework/Versions/5/QtSerialPort serialplot.app/Contents/MacOS/serialplot $ install_name_tool -change /usr/local/opt/qt@5/lib/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork.framework/Versions/5/QtNetwork serialplot.app/Contents/MacOS/serialplot $ install_name_tool -change /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/MacOS/serialplot
Now QtSerialPort
depends only on QtCore
$ otool -L serialplot.app/Contents/Frameworks/QtSerialPort.framework/QtSerialPort serialplot.app/Contents/Frameworks/QtSerialPort.framework/QtSerialPort: /usr/local/opt/qt@5/lib/QtSerialPort.framework/Versions/5/QtSerialPort (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
and QtNetwork
depends only upon QtCore
$ otool -L serialplot.app/Contents/Frameworks/QtNetwork.framework/QtNetwork serialplot.app/Contents/Frameworks/QtNetwork.framework/QtNetwork: /usr/local/opt/qt@5/lib/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.220.15) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 934.0.0) /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration (compatibility version 1.0.0, current version 963.200.27) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /System/Library/Frameworks/GSS.framework/Versions/A/GSS (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork (compatibility version 1.0.0, current version 975.0.3)
So, adding these dependancies should be easy
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtSerialPort.framework/Versions/5/QtSerialPort
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtNetwork.framework/Versions/5/QtNetwork
As a sanity check QtCore
has no “Qt” dependancies:
$ otool -L serialplot.app/Contents/Frameworks/QtCore.framework/QtCore serialplot.app/Contents/Frameworks/QtCore.framework/QtCore: /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.220.15) /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 50.1.0) /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 934.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1560.12.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
So, all in all, these are the commands all together, for the six Qt frameworks:
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg serialplot.app/Contents/MacOS/serialplot
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/MacOS/serialplot
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/MacOS/serialplot
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtSerialPort.framework/Versions/5/QtSerialPort @rpath/QtSerialPort.framework/Versions/5/QtSerialPort serialplot.app/Contents/MacOS/serialplot
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork.framework/Versions/5/QtNetwork serialplot.app/Contents/MacOS/serialplot
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/MacOS/serialplot
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtSerialPort.framework/Versions/5/QtSerialPort
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtNetwork.framework/Versions/5/QtNetwork
Note you have to change (i.e. enable) the write permissions before running install_name_tool
upon each of the frameworks, see install_name_tool: can’t open input file: *.dylib for writing (Permission denied). Like this:
chmod +w serialplot.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui
Don’t forget to set the permissions back to read only once you have used install_name_tool
.
To check that the paths have been set correctly, now re-run otool -L
on the binary and the bundled frameworks
$ otool -L serialplot.app/Contents/MacOS/serialplot $ otool -L serialplot.app/Contents/Frameworks/QtGui.framework/QtGui $ otool -L serialplot.app/Contents/Frameworks/QtCore.framework/QtCore $ otool -L serialplot.app/Contents/Frameworks/QtSvg.framework/QtSvg $ otool -L serialplot.app/Contents/Frameworks/QtWidgets.framework/QtWidgets $ otool -L serialplot.app/Contents/Frameworks/QtSerialPort.framework/QtSerialPort $ otool -L serialplot.app/Contents/Frameworks/QtNetwork.framework/QtNetwork
The output should be as follows:
serialplot.app/Contents/MacOS/serialplot: @rpath/qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0) @rpath/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2) @rpath/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) @rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) @rpath/QtSerialPort.framework/Versions/5/QtSerialPort (compatibility version 5.15.0, current version 5.15.2) @rpath/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.15.0, current version 5.15.2) @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) serialplot.app/Contents/Frameworks/QtGui.framework/QtGui: /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1247.4.1) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1560.12.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 50.1.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) serialplot.app/Contents/Frameworks/QtCore.framework/QtCore: /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.220.15) /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 50.1.0) /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 934.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1560.12.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) serialplot.app/Contents/Frameworks/QtSvg.framework/QtSvg: /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2) @rpath/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) @rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) serialplot.app/Contents/Frameworks/QtWidgets.framework/QtWidgets: /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) @rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) serialplot.app/Contents/Frameworks/QtSerialPort.framework/QtSerialPort: /usr/local/opt/qt@5/lib/QtSerialPort.framework/Versions/5/QtSerialPort (compatibility version 5.15.0, current version 5.15.2) @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) serialplot.app/Contents/Frameworks/QtNetwork.framework/QtNetwork: /usr/local/opt/qt@5/lib/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.15.0, current version 5.15.2) @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.220.15) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 934.0.0) /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration (compatibility version 1.0.0, current version 963.200.27) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) /System/Library/Frameworks/GSS.framework/Versions/A/GSS (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork (compatibility version 1.0.0, current version 975.0.3)
When I ran the application now, I got a crash
Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Application Specific Information: abort() called Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x00007fff504c1b66 __pthread_kill + 10 1 libsystem_pthread.dylib 0x00007fff5068c080 pthread_kill + 333 2 libsystem_c.dylib 0x00007fff5041d1ae abort + 127 3 org.qt-project.QtCore 0x00000001026d5479 0x1026bd000 + 99449 4 org.qt-project.QtCore 0x00000001026d6bc4 QMessageLogger::fatal(char const*, ...) const + 202 5 org.qt-project.QtGui 0x0000000101f7b6b9 QGuiApplicationPrivate::createPlatformIntegration() + 7193 6 org.qt-project.QtGui 0x0000000101f7b6db QGuiApplicationPrivate::createEventDispatcher() + 27 7 org.qt-project.QtCore 0x00000001028b514f QCoreApplicationPrivate::init() + 1599 8 org.qt-project.QtGui 0x0000000101f75e39 QGuiApplicationPrivate::init() + 57 9 org.qt-project.QtWidgets 0x000000010199eb1a QApplicationPrivate::init() + 26 10 GOL.serialplot 0x00000001015949ff main + 47 (main.cpp:74) 11 libdyld.dylib 0x00007fff50371015 start + 1
Notice though, that for the frameworks, the absolute path (/usr/local/opt...
) is still used, instead of @rpath
. For example, the output of otool -L
shows, for QtGui
$ otool -L serialplot.app/Contents/Frameworks/QtGui.framework/QtGui serialplot.app/Contents/Frameworks/QtGui.framework/QtGui: /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2)
To fix this we need to use -id
to set the library identifier of each of the libraries that you’re bundling inside your application to an @rpath
-relative value. So for QtGui
$ install_name_tool -id @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui
Now otool -L
shows the correct output, using @rpath
.
$ otool -L serialplot.app/Contents/Frameworks/QtGui.framework/QtGui serialplot.app/Contents/Frameworks/QtGui.framework/QtGui: @rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2)
Doing the same for the other five:
$ install_name_tool -id @rpath/QtSvg.framework/Versions/5/QtSvg serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg $ install_name_tool -id @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore $ install_name_tool -id @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets $ install_name_tool -id @rpath/QtSerialPort.framework/Versions/5/QtSerialPort serialplot.app/Contents/Frameworks/QtSerialPort.framework/Versions/5/QtSerialPort $ install_name_tool -id @rpath/QtNetwork.framework/Versions/5/QtNetwork serialplot.app/Contents/Frameworks/QtNetwork.framework/Versions/5/QtNetwork
Checking with
$ otool -L serialplot.app/Contents/Frameworks/QtSvg.framework/QtSvg
$ otool -L serialplot.app/Contents/Frameworks/QtCore.framework/QtCore
$ otool -L serialplot.app/Contents/Frameworks/QtWidgets.framework/QtWidgets
$ otool -L serialplot.app/Contents/Frameworks/QtSerialPort.framework/QtSerialPort
$ otool -L serialplot.app/Contents/Frameworks/QtNetwork.framework/QtNetwork
However, I still got a application crash, when running.
Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Application Specific Information: abort() called Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x00007fff504c1b66 __pthread_kill + 10 1 libsystem_pthread.dylib 0x00007fff5068c080 pthread_kill + 333 2 libsystem_c.dylib 0x00007fff5041d1ae abort + 127 3 org.qt-project.QtCore 0x000000010298b479 0x102973000 + 99449 4 org.qt-project.QtCore 0x000000010298cbc4 QMessageLogger::fatal(char const*, ...) const + 202 5 org.qt-project.QtGui 0x00000001022336b9 QGuiApplicationPrivate::createPlatformIntegration() + 7193 6 org.qt-project.QtGui 0x00000001022336db QGuiApplicationPrivate::createEventDispatcher() + 27 7 org.qt-project.QtCore 0x0000000102b6b14f QCoreApplicationPrivate::init() + 1599 8 org.qt-project.QtGui 0x000000010222de39 QGuiApplicationPrivate::init() + 57 9 org.qt-project.QtWidgets 0x0000000101c55b1a QApplicationPrivate::init() + 26 10 GOL.serialplot 0x00000001018559ff main + 47 (main.cpp:74) 11 libdyld.dylib 0x00007fff50371015 start + 1
Hmmm… annoying!!!!
Trying again, but this time not bundling QtCore… it worked (even without the -id @rpath
). So there is an issue with QtCore being bundled. However, not bundling QtCore but still doing the -id @rpath
caused a crash (check this!!!!).
Sanity checks
As a sanity check, I hid QtNetwork and QtSerialPort on the system (by renaming the files in /usr/local/Cellar/qt@5/5.15.2/lib/
, i.e. prefixing with -
), after doing a build bundle excluding QtCore, and it worked.
As a further sanity check, I then hid QtGui on the system and the application crashed, looking for QtGui.
Correctly bundling frameworks for qwt
Another sanity check, I checked qwt
for its dependencies
$ otool -L serialplot.app/Contents/Frameworks/qwt.framework/qwt serialplot.app/Contents/Frameworks/qwt.framework/qwt: qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0) /usr/local/opt/qt@5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtOpenGL.framework/Versions/5/QtOpenGL (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/opt/qt@5/lib/QtConcurrent.framework/Versions/5/QtConcurrent (compatibility version 5.15.0, current version 5.15.2) /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) $
Note the Qt frameworks referenced by qwt
(in bold), plus the three new libraries which are as yet not bundled (in bold and italics):
- QtConcurrent
- QtPrintSupport
- QtOpenGL
In addition to needing to set the references of qwt
to the already bundled Qt libraries (QtCore, QtGui, QtSvg and QtWidgets), the three new libraries would require setting with install_name_tool -change
as well.
Note also, that unlike the other frameworks, qwt
uses the opt
path and not the Cellar
path.
Setting qwt
to look for the bundled QtGui
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
Revealed that QtPrintSupport also calls QtGui…
Dyld Error Message: Library not loaded: /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui Referenced from: /usr/local/opt/qt@5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport Reason: image not found
So, we have to repeat the whole dependency process for the additional three frameworks: QtConcurrent, QtPrintSupport and QtOpenGL:
QtConcurrent -> Core
$ otool -L /usr/local/opt/qt5/lib/QtConcurrent.framework/Versions/5/QtConcurrent /usr/local/opt/qt5/lib/QtConcurrent.framework/Versions/5/QtConcurrent: /usr/local/opt/qt@5/lib/QtConcurrent.framework/Versions/5/QtConcurrent (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
QtPrintSupport -> Widgets, Gui and Core
$ otool -L /usr/local/opt/qt5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport /usr/local/opt/qt5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport: /usr/local/opt/qt@5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5) /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 50.1.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
QtOpenGL -> Widgets, Gui and Core
$ otool -L /usr/local/opt/qt5/lib/QtOpenGL.framework/Versions/5/QtOpenGL /usr/local/opt/qt5/lib/QtOpenGL.framework/Versions/5/QtOpenGL: /usr/local/opt/qt@5/lib/QtOpenGL.framework/Versions/5/QtOpenGL (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2) /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106) /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0) /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
At least there is no further proliferation of Qt frameworks, apart from the three new frameworks.
So to fix all of these new qwt
related issues (note the use of the script below, see Automating the embedding), we need to:
- Copy the additional frameworks over
- Change dependencies to the application binary (I am not sure if this is necessary as the application binary calls
qwt
, it doesn’t call QtConcurrent, QtPrintSupport nor QtOpenGL directly. However, no harm is caused by linking them) - Change dependancies of
qwt
- Change dependancies of the new libraries
- Add the
-id
to use@rpath
for the name libraries (optional – this seems to cause an application runtime crash) - Check the
otool -L
outputs
So copy the new frameworks as before…
Copy the Qt5 frameworks to serialplot.app/Contents/Frameworks
, (either in the Finder (not recommended(check?)) or) using a cp -R
in a terminal. The frameworks will be either in /Library/Frameworks/
if you had installed them there, or in /usr/local/lib
, or /usr/local/Cellar/qt@5/5.12.5/lib
if installed with brew
. Remember to use the Qt5 and not the Qt4 frameworks:
/usr/local/Cellar/qt@5/5.15.2/lib/QtConcurrent.framework /usr/local/Cellar/qt@5/5.15.2/lib/QtPrintSupport.framework /usr/local/Cellar/qt@5/5.15.2/lib/QtOpenGL.framework
Linking the new frameworks to the application binary (I’m almost sure that this step is not necessary, because they aren’t listed in the output of otool -L
for the application binary)
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent serialplot.app/Contents/MacOS/serialplot $ install_name_tool -change /usr/local/opt/qt@5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport serialplot.app/Contents/MacOS/serialplot $ install_name_tool -change /usr/local/opt/qt@5/lib}/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL serialplot.app/Contents/MacOS/serialplot
Setting qwt
to look for the bundled QtGui
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
Likewise for QtCore, QtWidgets, QtSvg
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt $ install_name_tool -change /usr/local/opt/qt@5/lib/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt $ install_name_tool -change /usr/local/opt/qt@5/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
And then for the three new frameworks, QtConcurrent, QtPrintSupport and QtOpenGL
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt $ install_name_tool -change /usr/local/opt/qt@5/lib/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt $ install_name_tool -change /usr/local/opt/qt@5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport serialplot.app/Contents/Frameworks/qwt.framework/Versions/6/qwt
Now fix the references for the three new frameworks.
QtConcurrent
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtConcurrent.framework/Versions/5/QtConcurrent
QtPrintSupport
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport
QtOpenGL
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtOpenGL.framework/Versions/5/QtOpenGL $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets serialplot.app/Contents/Frameworks/QtOpenGL.framework/Versions/5/QtOpenGL $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtOpenGL.framework/Versions/5/QtOpenGL
However, still there was a crash. However (again), if QtCore was omitted from the bundle, and the install_name_tool commands, there was no crash.
Embedding libqcocoa.dylib
So, there seems to be an issue with the QtCore being bundled. See Qt 5.4 application bundled for OSX crashes when launched:
it can’t find the platform plugin (libqcocoa.dylib). Plugins are not linked at build time, so otool won’t show them. You must bundle the platform plugin (and other plugins if you need them) with the application, where libqcocoa.dylib goes to Foo.app/Contents/PlugIns/platforms, and run the usual install_name_tool procedure on each plugin.
You might also want to try the “macdeployqt” tool shipped with Qt. That works fine at least for the not too complex deployment scenarios (in Qt 4 times it was worse)
So, either we find the cocoa lib, or we could just use macdeployqt
, but the latter seems to be a cheat. We need to see how to do this manually.
From Qt for macOS – Deployment – Qt Plugins:
Qt Plugins
All Qt GUI applications require a plugin that implements the Qt Platform Abstraction (QPA) layer in Qt 5. For macOS, the name of the platform plugin is
libqcocoa.dylib
. This file must be located within a specific subdirectory (by default,platforms
) under your distribution directory. Alternatively, it is possible to adjust the search path Qt uses to find its plugins, as described below.
So, translating the third sentence into English means:
/usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib
So copy this to serialplot.app/Contents/PlugIns/platforms
.
Note: There is a difference in capitalisation of plugins
and PlugIns
.
Note: It is strange that embedded QtCore can’t see libqcocoa.dylib
on the filesystem, whereas the QtCore in the Qt installation can.
Note: Rather annoyingly, otool -L
doesn’t show up any plugin dependencies, and therefore, as libqcocoa.dylib
is a plugin (rather than a normal framework or library), libqcocoa.dylib
doesn’t show up in the output of otool -L
. In fact, I’m not sure how you are supposed to know that it is even required, as it doesn’t even appear in the application crash log. Only by reading Qt for macOS – Deployment – Qt Plugins (or StackOverflow) would you find out.
This post likewise does not specific exactly what has to be done with install_name_tool, whether it is -change or -id, and upon which Qt frameworks. Is it all of them, or just QtCore?:
I have located the libqcocoa.dylib to be present in Qt/5.9.1/clang_64/lib/plugins/platforms and had to copy it to my.app/Contents/plugins/platforms and additionally modify the references to the Qt installed libraries to use the ones in my package (using the install_name_tool)
Assuming that all of the Qt frameworks need to reference libqcocoa, then fix their references:
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtSvg.framework/Versions/5/QtSvg $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtSerialPort.framework/Versions/5/QtSerialPort $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtNetwork.framework/Versions/5/QtNetwork $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtConcurrent.framework/Versions/5/QtConcurrent $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport $ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/plugins/platforms/libqcocoa.dylib @rpath/../PlugIns/platforms/libqcocoa.dylib serialplot.app/Contents/Frameworks/QtOpenGL.framework/Versions/5/QtOpenGL
Now the application will run!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUCCESS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUCCESS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUCCESS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUCCESS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUCCESS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUCCESS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Testing
Now, test it on another Mac which does not have Qt5 nor qwt installed.
A note on path changes
It should be noted that there is a disparity on the paths to the frameworks.
The serialplot
application binary (and qwt
) depends upon frameworks in /usr/local/opt/qt@5/lib/
, whereas the Qt libraries depend upon frameworks under the path /usr/local/Cellar/qt@5/5.15.2/lib/QtCore
Automating the embedding
Note this answer, has a script, fix_paths_mac.py, to fix the paths – I haven’t tried it though.
Also, /macdylibbundler
macdeployqt
- This post, from Mac OS Deployment – libqcoca.dylib might be useful
- Qt for macOS – Deployment
- Deploying QT and OpenCV application on Mac OS X
Scripts
Here are four rough Bourne shell scripts, which copy and set the references for:
- Qt frameworks for application binary only
- Qt frameworks for application binary and Qwt
- Qt frameworks for application binary and Qwt, without QtCore
- Qt frameworks for application binary and Qwt, as well as Qwt framework itself and
libqcocoa.dylib
.
Note: before running the scripts, you must:
- Create the
serialplot.app/Contents/Frameworks
directory manually - Copy over the
qwt
framework manually - Run
install_name_tool -change qwt.framework/Versions/6/qwt @rpath/qwt.framework/Versions/6/qwt serialplot.app/Contents/MacOS/serialplot
Also
- Just change
app_name
as required (to include the full path if required – else execute in the same directory as the application (bundle)) - Set the copy flag (
do_copy
) if you want to automatically copy the Qt frameworks
Just the Qt frameworks
This script copies over, and sets the references for, only the Qt frameworks that the application binary depends upon.
Comes with one option for copy (do_copy
):
#!/bin/sh app_name='serialplot' path_opt='/usr/local/opt/qt@5/lib' path_brew='/usr/local/Cellar/qt@5/5.15.2/lib' app_path="${app_name}.app/Contents/MacOS/${app_name}" app_frame_path="${app_name}.app/Contents/Frameworks" do_copy="false" # Copy if [ "$do_copy" = "true" ] then cp -R ${path_brew}/QtCore.framework $app_frame_path cp -R ${path_brew}/QtGui.framework $app_frame_path cp -R ${path_brew}/QtNetwork.framework $app_frame_path cp -R ${path_brew}/QtSerialPort.framework $app_frame_path cp -R ${path_brew}/QtSvg.framework $app_frame_path cp -R ${path_brew}/QtWidgets.framework $app_frame_path fi # Change # Change app binary install_name_tool -change ${path_opt}/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg $app_path install_name_tool -change ${path_opt}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets $app_path install_name_tool -change ${path_opt}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui $app_path install_name_tool -change ${path_opt}/QtSerialPort.framework/Versions/5/QtSerialPort @rpath/QtSerialPort.framework/Versions/5/QtSerialPort $app_path install_name_tool -change ${path_opt}/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork.framework/Versions/5/QtNetwork $app_path install_name_tool -change ${path_opt}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore $app_path # Change QtGui chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui # Change QtSvg chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg # Change QtWidgets chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets # Change QtSerialPort chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort # Change QtNetwork chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork # Check otool -L ${app_path} echo echo otool -L ${app_frame_path}/QtGui.framework/QtGui echo echo otool -L ${app_frame_path}/QtCore.framework/QtCore echo echo otool -L ${app_frame_path}/QtSvg.framework/QtSvg echo echo otool -L ${app_frame_path}/QtWidgets.framework/QtWidgets echo echo otool -L ${app_frame_path}/QtSerialPort.framework/QtSerialPort echo echo otool -L ${app_frame_path}/QtNetwork.framework/QtNetwork
Changing the id (insert before the # Check
). However, running these commands causes the serialplot
application to crash at runtime – so they can, and should, be omitted.
# Change id chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod +w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -id @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -id @rpath/QtSvg.framework/Versions/5/QtSvg ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -id @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtCore.framework/Versions/5/QtCore install_name_tool -id @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -id @rpath/QtSerialPort.framework/Versions/5/QtSerialPort ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -id @rpath/QtNetwork.framework/Versions/5/QtNetwork ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork
Qt and qwt frameworks
This script copies over, and sets the references for, the Qt frameworks that both the application binary and qwt
depend upon. It does not copy over qwt
though.
Comes with options for copy (do_copy
), id (do_id
) and qwt (do_qwt
):
#!/bin/sh app_name='serialplot' path_opt='/usr/local/opt/qt@5/lib' path_brew='/usr/local/Cellar/qt@5/5.15.2/lib' app_path="${app_name}.app/Contents/MacOS/${app_name}" app_frame_path="${app_name}.app/Contents/Frameworks" do_copy="true" do_qwt="true" do_id="false" # Copy if [ "X$do_copy" = "Xtrue" ] then cp -R ${path_brew}/QtCore.framework $app_frame_path cp -R ${path_brew}/QtGui.framework $app_frame_path cp -R ${path_brew}/QtNetwork.framework $app_frame_path cp -R ${path_brew}/QtSerialPort.framework $app_frame_path cp -R ${path_brew}/QtSvg.framework $app_frame_path cp -R ${path_brew}/QtWidgets.framework $app_frame_path if [ "X$do_qwt" = "Xtrue" ] then cp -R ${path_brew}/QtConcurrent.framework $app_frame_path cp -R ${path_brew}/QtPrintSupport.framework $app_frame_path cp -R ${path_brew}/QtOpenGL.framework $app_frame_path fi fi # Change # Change app binary install_name_tool -change ${path_opt}/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg $app_path install_name_tool -change ${path_opt}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets $app_path install_name_tool -change ${path_opt}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui $app_path install_name_tool -change ${path_opt}/QtSerialPort.framework/Versions/5/QtSerialPort @rpath/QtSerialPort.framework/Versions/5/QtSerialPort $app_path install_name_tool -change ${path_opt}/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork.framework/Versions/5/QtNetwork $app_path install_name_tool -change ${path_opt}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore $app_path if [ "X$do_qwt" = "Xtrue" ] then install_name_tool -change ${path_opt}/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent $app_path install_name_tool -change ${path_opt}/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport $app_path install_name_tool -change ${path_opt}/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL $app_path fi # Change QtGui chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui # Change QtSvg chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg # Change QtWidgets chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets # Change QtSerialPort chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort # Change QtNetwork chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork # Change qwt if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport ${app_frame_path}/qwt.framework/Versions/6/qwt chmod -w ${app_frame_path}/qwt.framework/Versions/6/qwt fi # Change QtConcurrent if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod -w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent fi # Change QtPrintSupport if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod -w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport fi # Change QtOpenGL if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL chmod -w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL fi # Change id if [ "X$do_id" = "Xtrue" ] then chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod +w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -id @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -id @rpath/QtSvg.framework/Versions/5/QtSvg ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -id @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtCore.framework/Versions/5/QtCore install_name_tool -id @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -id @rpath/QtSerialPort.framework/Versions/5/QtSerialPort ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -id @rpath/QtNetwork.framework/Versions/5/QtNetwork ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/qwt.framework/Versions/6/qwt chmod +w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod +w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod +w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -id @rpath/qwt.framework/Versions/6/qwt ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -id @rpath/QtConcurrent.framework/Versions/5/QtConcurrent ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent install_name_tool -id @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -id @rpath/QtOpenGL.framework/Versions/5/QtOpenGL ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL chmod -w ${app_frame_path}/qwt.framework/Versions/6/qwt chmod -w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod -w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod -w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL fi fi # Check otool -L ${app_path} echo echo otool -L ${app_frame_path}/QtGui.framework/QtGui echo echo otool -L ${app_frame_path}/QtCore.framework/QtCore echo echo otool -L ${app_frame_path}/QtSvg.framework/QtSvg echo echo otool -L ${app_frame_path}/QtWidgets.framework/QtWidgets echo echo otool -L ${app_frame_path}/QtSerialPort.framework/QtSerialPort echo echo otool -L ${app_frame_path}/QtNetwork.framework/QtNetwork if [ "X$do_qwt" = "Xtrue" ] then echo echo otool -L ${app_frame_path}/qwt.framework/qwt echo echo otool -L ${app_frame_path}/QtConcurrent.framework/QtConcurrent echo echo otool -L ${app_frame_path}/QtPrintSupport.framework/QtPrintSupport echo echo otool -L ${app_frame_path}/QtOpenGL.framework/QtOpenGL fi
Qt and qwt frameworks – No QtCore
This script copies over, and sets the references for, the Qt frameworks that both the application binary and qwt
depend upon. It does not copy over qwt
though. However is does not copy over, not set the references for, QtCore – that is to say QtCore is not bundled.
Comes with options for copy (do_copy
), id (do_id
) and qwt (do_qwt
):
#!/bin/sh app_name='serialplot' path_opt='/usr/local/opt/qt@5/lib' path_brew='/usr/local/Cellar/qt@5/5.15.2/lib' app_path="${app_name}.app/Contents/MacOS/${app_name}" app_frame_path="${app_name}.app/Contents/Frameworks" do_copy="true" do_qwt="true" do_id="false" # Copy if [ "X$do_copy" = "Xtrue" ] then # cp -R ${path_brew}/QtCore.framework $app_frame_path cp -R ${path_brew}/QtGui.framework $app_frame_path cp -R ${path_brew}/QtNetwork.framework $app_frame_path cp -R ${path_brew}/QtSerialPort.framework $app_frame_path cp -R ${path_brew}/QtSvg.framework $app_frame_path cp -R ${path_brew}/QtWidgets.framework $app_frame_path if [ "X$do_qwt" = "Xtrue" ] then cp -R ${path_brew}/QtConcurrent.framework $app_frame_path cp -R ${path_brew}/QtPrintSupport.framework $app_frame_path cp -R ${path_brew}/QtOpenGL.framework $app_frame_path fi fi # Change # Change app binary install_name_tool -change ${path_opt}/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg $app_path install_name_tool -change ${path_opt}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets $app_path install_name_tool -change ${path_opt}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui $app_path install_name_tool -change ${path_opt}/QtSerialPort.framework/Versions/5/QtSerialPort @rpath/QtSerialPort.framework/Versions/5/QtSerialPort $app_path install_name_tool -change ${path_opt}/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork.framework/Versions/5/QtNetwork $app_path #install_name_tool -change ${path_opt}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore $app_path if [ "X$do_qwt" = "Xtrue" ] then install_name_tool -change ${path_opt}/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent $app_path install_name_tool -change ${path_opt}/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport $app_path install_name_tool -change ${path_opt}/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL $app_path fi # Change QtGui chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui #install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui # Change QtSvg chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg #install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg # Change QtWidgets chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets #install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets # Change QtSerialPort chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort #install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort # Change QtNetwork chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork #install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork # Change qwt if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/qwt.framework/Versions/6/qwt # install_name_tool -change ${path_opt}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${path_opt}/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport ${app_frame_path}/qwt.framework/Versions/6/qwt chmod -w ${app_frame_path}/qwt.framework/Versions/6/qwt fi # Change QtConcurrent if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent # install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod -w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent fi # Change QtPrintSupport if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport # install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod -w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport fi # Change QtOpenGL if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL # install_name_tool -change ${path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL chmod -w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL fi # Change id if [ "X$do_id" = "Xtrue" ] then chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets #chmod +w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -id @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -id @rpath/QtSvg.framework/Versions/5/QtSvg ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg #install_name_tool -id @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtCore.framework/Versions/5/QtCore install_name_tool -id @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -id @rpath/QtSerialPort.framework/Versions/5/QtSerialPort ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -id @rpath/QtNetwork.framework/Versions/5/QtNetwork ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets #chmod -w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/qwt.framework/Versions/6/qwt chmod +w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod +w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod +w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -id @rpath/qwt.framework/Versions/6/qwt ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -id @rpath/QtConcurrent.framework/Versions/5/QtConcurrent ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent install_name_tool -id @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -id @rpath/QtOpenGL.framework/Versions/5/QtOpenGL ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL chmod -w ${app_frame_path}/qwt.framework/Versions/6/qwt chmod -w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod -w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod -w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL fi fi # Check otool -L ${app_path} echo echo otool -L ${app_frame_path}/QtGui.framework/QtGui echo echo #otool -L ${app_frame_path}/QtCore.framework/QtCore echo echo otool -L ${app_frame_path}/QtSvg.framework/QtSvg echo echo otool -L ${app_frame_path}/QtWidgets.framework/QtWidgets echo echo otool -L ${app_frame_path}/QtSerialPort.framework/QtSerialPort echo echo otool -L ${app_frame_path}/QtNetwork.framework/QtNetwork if [ "X$do_qwt" = "Xtrue" ] then echo echo otool -L ${app_frame_path}/qwt.framework/qwt echo echo otool -L ${app_frame_path}/QtConcurrent.framework/QtConcurrent echo echo otool -L ${app_frame_path}/QtPrintSupport.framework/QtPrintSupport echo echo otool -L ${app_frame_path}/QtOpenGL.framework/QtOpenGL fi
Complete script
This script is available at /serialplot_OS_X_port.
- Run from the directory containing
serialplot.app
,- unless you change
app_bundle_path
to the full path, i.e./Users/username/qtcodeworkspace/serialplot
- unless you change
- Create the
serialplot.app/Contents/Frameworks
directory manually- unless <nothing>
- Copy
qwt.framework
over manually first toserialplot.app/Contents/Frameworks
, and run , and runinstall_name_tool -change qwt.framework/Versions/6/qwt @rpath/qwt.framework/Versions/6/qwt serialplot.app/Contents/MacOS/serialplot
- unless you set
do_qwt_copy
totrue
. - You may need to change
path_qwt
if theqwt
source directory doesn’t share the same parent folder as the directory containing the application bundle
- unless you set
- Copy the Qt frameworks over manually first to
serialplot.app/Contents/Frameworks
,- unless you set
do_copy
totrue
.
- unless you set
- Leave
do_id
asfalse
- Setting the
-id
causes the application to crash (reason unknown)
- Setting the
- Leave
do_qwt
astrue
- This sets the
qwt.framework
to point to the bundled Qt frameworks
- This sets the
- Leave
do_cocoa
astrue
- This copies over
libqcocoa.dylib
– ifdo_copy
istrue
- This sets the Qt frameworks to point to
libqcocoa.dylib
- This copies over
do_core
does nothing (yet)- It was meant for a test to leave
QtCore.framework
unbundled – to prevent the crash caused by the unbundledlibqcocoa.dylib
- It was meant for a test to leave
#!/bin/sh # Paths (change these) application='serialplot' app_bundle_path='.' qt_brew_path='/usr/local/Cellar/qt@5/5.15.2' lib_path_opt='/usr/local/opt/qt@5/lib' # Paths (try not to change these) app_name="${app_bundle_path}/${application}" lib_path_brew="${qt_brew_path}/lib" path_cocoa="${qt_brew_path}/plugins/platforms" app_path="${app_name}.app/Contents/MacOS/${app_name}" app_frame_path="${app_name}.app/Contents/Frameworks" plugplat='PlugIns/platforms' app_plugin_path="${app_name}.app/Contents/${plugplat}" path_qwt="${app_bundle_path}/../qwt/lib" # Flags do_copy="true" do_qwt="true" do_id="false" do_cocoa="true" do_qwt_copy="false" do_core='true' # Copy if [ "X$do_copy" = "Xtrue" ] then mkdir -p $app_frame_path cp -R ${lib_path_brew}/QtCore.framework $app_frame_path cp -R ${lib_path_brew}/QtGui.framework $app_frame_path cp -R ${lib_path_brew}/QtNetwork.framework $app_frame_path cp -R ${lib_path_brew}/QtSerialPort.framework $app_frame_path cp -R ${lib_path_brew}/QtSvg.framework $app_frame_path cp -R ${lib_path_brew}/QtWidgets.framework $app_frame_path if [ "X$do_qwt" = "Xtrue" ] then cp -R ${lib_path_brew}/QtConcurrent.framework $app_frame_path cp -R ${lib_path_brew}/QtPrintSupport.framework $app_frame_path cp -R ${lib_path_brew}/QtOpenGL.framework $app_frame_path fi if [ "X$do_cocoa" = "Xtrue" ] then mkdir -p $app_plugin_path cp -R ${path_cocoa}/libqcocoa.dylib $app_plugin_path fi if [ "X$do_qwt_copy" = "Xtrue" ] then cp -R ${path_qwt}/qwt.framework $app_frame_path fi fi # Change # Change app binary install_name_tool -change ${lib_path_opt}/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg $app_path install_name_tool -change ${lib_path_opt}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets $app_path install_name_tool -change ${lib_path_opt}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui $app_path install_name_tool -change ${lib_path_opt}/QtSerialPort.framework/Versions/5/QtSerialPort @rpath/QtSerialPort.framework/Versions/5/QtSerialPort $app_path install_name_tool -change ${lib_path_opt}/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork.framework/Versions/5/QtNetwork $app_path install_name_tool -change ${lib_path_opt}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore $app_path # These three commands may not be required as the application binary does not call them directly, only via qwt if [ "X$do_qwt" = "Xtrue" ] then install_name_tool -change ${lib_path_opt}/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent $app_path install_name_tool -change ${lib_path_opt}/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport $app_path install_name_tool -change ${lib_path_opt}/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL $app_path fi if [ "X$do_qwt_copy" = "Xtrue" ] then install_name_tool -change qwt.framework/Versions/6/qwt @rpath/qwt.framework/Versions/6/qwt $app_binary_path fi # Change QtGui chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui # Change QtSvg chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${lib_path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${lib_path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg # Change QtWidgets chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${lib_path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets # Change QtSerialPort chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort # Change QtNetwork chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork # Change qwt if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${lib_path_opt}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${lib_path_opt}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${lib_path_opt}/QtSvg.framework/Versions/5/QtSvg @rpath/QtSvg.framework/Versions/5/QtSvg ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${lib_path_opt}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${lib_path_opt}/QtOpenGL.framework/Versions/5/QtOpenGL @rpath/QtOpenGL.framework/Versions/5/QtOpenGL ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${lib_path_opt}/QtConcurrent.framework/Versions/5/QtConcurrent @rpath/QtConcurrent.framework/Versions/5/QtConcurrent ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -change ${lib_path_opt}/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport ${app_frame_path}/qwt.framework/Versions/6/qwt chmod -w ${app_frame_path}/qwt.framework/Versions/6/qwt fi # Change QtConcurrent if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod -w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent fi # Change QtPrintSupport if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${lib_path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${lib_path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod -w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport fi # Change QtOpenGL if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${lib_path_brew}/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${lib_path_brew}/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${lib_path_brew}/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL chmod -w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL fi # Change id if [ "X$do_id" = "Xtrue" ] then chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod +w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -id @rpath/QtGui.framework/Versions/5/QtGui ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -id @rpath/QtSvg.framework/Versions/5/QtSvg ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -id @rpath/QtCore.framework/Versions/5/QtCore ${app_frame_path}/QtCore.framework/Versions/5/QtCore install_name_tool -id @rpath/QtWidgets.framework/Versions/5/QtWidgets ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -id @rpath/QtSerialPort.framework/Versions/5/QtSerialPort ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -id @rpath/QtNetwork.framework/Versions/5/QtNetwork ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/qwt.framework/Versions/6/qwt chmod +w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod +w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod +w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -id @rpath/qwt.framework/Versions/6/qwt ${app_frame_path}/qwt.framework/Versions/6/qwt install_name_tool -id @rpath/QtConcurrent.framework/Versions/5/QtConcurrent ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent install_name_tool -id @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -id @rpath/QtOpenGL.framework/Versions/5/QtOpenGL ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL chmod -w ${app_frame_path}/qwt.framework/Versions/6/qwt chmod -w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod -w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod -w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL fi fi # Change all libs for cocoa if [ "X$do_cocoa" = "Xtrue" ] then chmod +w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod +w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod +w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod +w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod +w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod +w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtGui.framework/Versions/5/QtGui install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtCore.framework/Versions/5/QtCore install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork chmod -w ${app_frame_path}/QtGui.framework/Versions/5/QtGui chmod -w ${app_frame_path}/QtSvg.framework/Versions/5/QtSvg chmod -w ${app_frame_path}/QtWidgets.framework/Versions/5/QtWidgets chmod -w ${app_frame_path}/QtCore.framework/Versions/5/QtCore chmod -w ${app_frame_path}/QtSerialPort.framework/Versions/5/QtSerialPort chmod -w ${app_frame_path}/QtNetwork.framework/Versions/5/QtNetwork if [ "X$do_qwt" = "Xtrue" ] then chmod +w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod +w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod +w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport install_name_tool -change ${path_cocoa}/libqcocoa.dylib @rpath/../${plugplat}/libqcocoa.dylib ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL chmod -w ${app_frame_path}/QtConcurrent.framework/Versions/5/QtConcurrent chmod -w ${app_frame_path}/QtPrintSupport.framework/Versions/5/QtPrintSupport chmod -w ${app_frame_path}/QtOpenGL.framework/Versions/5/QtOpenGL fi fi # Check otool -L ${app_path} echo echo otool -L ${app_frame_path}/QtGui.framework/QtGui echo echo otool -L ${app_frame_path}/QtCore.framework/QtCore echo echo otool -L ${app_frame_path}/QtSvg.framework/QtSvg echo echo otool -L ${app_frame_path}/QtWidgets.framework/QtWidgets echo echo otool -L ${app_frame_path}/QtSerialPort.framework/QtSerialPort echo echo otool -L ${app_frame_path}/QtNetwork.framework/QtNetwork if [ "X$do_qwt" = "Xtrue" ] then echo echo otool -L ${app_frame_path}/qwt.framework/qwt echo echo otool -L ${app_frame_path}/QtConcurrent.framework/QtConcurrent echo echo otool -L ${app_frame_path}/QtPrintSupport.framework/QtPrintSupport echo echo otool -L ${app_frame_path}/QtOpenGL.framework/QtOpenGL fi
A do over – revisiting the side note
I decided to check the side thought/sneaky suspicion mentioned above, see Side thought on the headers, regarding the line
mac: LIBS += -F$$PWD/../qwt/lib/ -framework qwt
After copying serialplot to a new workspace and opening in QtCreator, and selecting the Qt5 kit (with clang already selected as the compiler) I got this error/warning:
:-1: warning: "/Library/Developer/CommandLineTools/usr/bin/clang" is used by qmake, but "/usr/bin/clang" is configured in the kit. Please update your kit or choose a mkspec for qmake that matches your target environment better.
Ignoring that for the moment, and running qmake
and Build I got the same first error as before, as expected
/Users/macbook/qtcode/serialplot/src/mainwindow.h:35: error: 'qwt_plot_curve.h' file not found #include <qwt_plot_curve.h> ^~~~~~~~~~~~~~~~~~
Adding the following line to serialplot.pro
mac: LIBS += -F$$PWD/../qwt/lib/ -framework qwt
and then Rebuild
Same error, however, the path was to the qwt (6.2.0) source. Changing it to /Library/Frameworks/
mac: LIBS += -F/Library/Frameworks/ -framework qwt
However, the same error for the qwt_plot_curve.h
header file.
So my theory about the Qwt framework containing the header files (which it does, including qwt_plot_curve.h
), did not work. So, it seems as if
INCLUDEPATH += $$PWD/../qwt/src
is required after all.
How about
INCLUDEPATH += /Library/Frameworks/qwt.framework/Headers
which would mean that the source files are not required, only the framework.
That certainly worked… for a while, until
/Users/macbook/qtcode/serialplot/src/plot.cpp:277: error: member access into incomplete type 'QwtScaleMap' auto paintDist = sw->scaleDraw()->scaleMap().pDist(); ^
Which was the same as before, and requires the addition of the #include
lines to multiple files – yawn! So there is not much of an advantage to specifying the actual framework…
This is the end, my friend.