1

I've seen several similar posts but have been unable to fix my specific problem.

I want to use oscpack, described here, http://www.rossbencina.com/code/oscpack

and downloaded here, https://github.com/hecomi/qml-osc and then clicked on the button 'clone or download', then 'Download ZIP' link.

Note: the link I had previously, 'https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/oscpack/oscpack_1_1_0.zip' was incorrect.

Note2: I also installed oscpack on my Ubuntu 18.04 system:

$ sudo apt-get -y install liboscpack-dev liboscpack1

After including this library in my project - the moment I add the header files, and - I get multiple undefined reference errors; for example:

undefined reference to `UdpSocket::Connect(IpEndpointName const&)'

I get the errors regardless of whether I use:

LIBS += -L"/developer/3rdPartyLibs/osc/lib" -loscpack # from the downloaded ZIP file

or

LIBS += -L"/usr/lib/x86_64-linux-gnu" -loscpack  # from the linux package

in my SampleProject.pro file.

I saw a very similar post/problem here: Linking a static library to my project on Visual Studio 2010

And I believe I have the same error, and that the solution is similar (it's just that I'm developing on Ubuntu 18.04 instead of Windows). I just haven't figured out how to give the linker what it needs. I expect that the linker can't find the library associated with 'sys/sockets.h', but I don't know where to find it either. I'm using Qt Creator 4.10.2, with Qt_5_13_2_GCC_64bit-Debug.

If you're not familiar with QtCreator but know what command-line arguments need to be passed to ld (and/or g++), that would still be a great help - I can try to figure out where to add that in the IDE.

I suspect no additional information will be required for this problem, but just in case, the code is below.

Thanks!

minimal project (main.qml):

import QtQuick 2.13
import QtQuick.Controls 2.5
import QtQml 2.13
import OSC 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Scroll")


    Rectangle {
        width: 360
        height: 360
        Text {
            id: message
            anchors.centerIn: parent
        }
        OSCReceiver {
            port: 3333
            onMessage: {
                message.text = address + ' : ' + msg;
            }
        }
        OSCSender {
            id: osc
            ip: '127.0.0.1'
            port: 3333
        }
        Timer {
            property int cnt: 0
            interval: 1000/60
            running: true
            repeat: true
            onTriggered: {
                osc.send('/Hoge/cnt', ++cnt);
            }
        }
    }
}

project file (SampleProject.pro):

QT += quick

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp

RESOURCES += qml.qrc

LIBS += -L"/developer/3rdPartyLibs/osc/lib" -loscpack   # add for oscpack

INCLUDEPATH += /developer/3rdPartyLibs/osc              # add for oscpack
include(/developer/3rdPartyLibs/osc/osc.pri)            # add for oscpack

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

and main.cpp file:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include <osc_receiver.h> // add for oscpack
#include <osc_sender.h>   // add for oscpack

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<OSCReceiver>("OSC", 1, 0, "OSCReceiver"); // add for oscpack
    qmlRegisterType<OSCSender>("OSC", 1, 0, "OSCSender");     // add for oscpack

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

This is the output:

14:27:49: Running steps for project SampleProject... 14:27:49: Configuration unchanged, skipping qmake step. 14:27:50: Starting: "/usr/bin/make" -j8 g++ -Wl,-rpath,/opt/Qt/5.13.2/gcc_64/lib -o SampleProject main.o osc_sender.o osc_receiver.o qrc_qml.o moc_osc_sender.o moc_osc_receiver.o -L/developer/3rdPartyLibs/osc/lib -loscpack /opt/Qt/5.13.2/gcc_64/lib/libQt5Quick.so /opt/Qt/5.13.2/gcc_64/lib/libQt5Gui.so /opt/Qt/5.13.2/gcc_64/lib/libQt5Qml.so /opt/Qt/5.13.2/gcc_64/lib/libQt5Network.so /opt/Qt/5.13.2/gcc_64/lib/libQt5Core.so -lGL -lpthread -loscpack osc_sender.o: In function OSCSender::setIp(QString const&)': /developer/builds/qt/build-SampleProject-Desktop_Qt_5_13_2_GCC_64bit-Debug/../../../3rdPartyLibs/osc/osc_sender.cpp:21: undefined reference toUdpSocket::Connect(IpEndpointName const&)' osc_sender.o: In function OSCSender::setPort(int)': /developer/builds/qt/build-SampleProject-Desktop_Qt_5_13_2_GCC_64bit-Debug/Makefile:255: recipe for target 'SampleProject' failed ../../../3rdPartyLibs/osc/osc_sender.cpp:38: undefined reference toUdpSocket::Connect(IpEndpointName const&)' osc_sender.o: In function OSCSender::send(QString const&, QString const&)': /developer/builds/qt/build-SampleProject-Desktop_Qt_5_13_2_GCC_64bit-Debug/../../../3rdPartyLibs/osc/osc_sender.cpp:55 ... ...many similar lines... ... undefined reference toSocketReceiveMultiplexer::~SocketReceiveMultiplexer()' /developer/builds/qt/build-SampleProject-Desktop_Qt_5_13_2_GCC_64bit-Debug/../../../3rdPartyLibs/osc/include/ip/UdpSocket.h:166: undefined reference to UdpSocket::~UdpSocket()' osc_receiver.o: In functionUdpListeningReceiveSocket::Run()': /developer/builds/qt/build-SampleProject-Desktop_Qt_5_13_2_GCC_64bit-Debug/../../../3rdPartyLibs/osc/include/ip/UdpSocket.h:169: undefined reference to SocketReceiveMultiplexer::Run()' osc_receiver.o:(.data.rel.ro._ZTI25UdpListeningReceiveSocket[_ZTI25UdpListeningReceiveSocket]+0x10): undefined reference totypeinfo for UdpSocket' collect2: error: ld returned 1 exit status make: *** [SampleProject] Error 1 14:27:51: The process "/usr/bin/make" exited with code 2.

Marcelo
  • 99
  • 10
  • provide a [mre] – eyllanesc Dec 14 '19 at 04:54
  • There is always one and only one reason for `undefined reference` error - there is a declaration of class/function but the linker can't find an implementation. The zip you've provided doesn't include the lib itself. What is `-loscpack`? Where did you get the library? Also the package doesn't include `osc.pri` so where did you get it? The `main.qml` file you've provided - what that have to show us? It doesn't use some osc items. Please clarify your question. – folibis Dec 14 '19 at 13:52
  • @folibis Hello, First of all, I wanted to apologize for the late reply. I did hang around but suspected the 'viewed' counter was updated every time I refreshed, so I started monitoring from my home page in the questions section, and that simply showed a 0 - a newb error. You are correct, that link I put earlier was only a subset of file, as you mentioned; I edited my post and corrected that. No header/library files are now missing. – Marcelo Dec 14 '19 at 18:52
  • @folibis Regarding what I'm trying to show, is that I get errors as soon as I add the "include ("OSC", ... into the project file. I could include some code trying to actually use oscpack (I removed 99% of my code), but the errors don't seem to change. I got errors as soon as I tried to use their library. I'll gladly add some calls to the library if that will clarify - let me know. – Marcelo Dec 14 '19 at 18:55
  • @eyllanesc Hi, I did try to create the minimal reproducible example, as best I could. I did make a mistake with the downloaded file - but that's corrected. This code should generate the errors I listed. Let me know if there is anything specific I should add/changne - thanks! – Marcelo Dec 14 '19 at 18:56
  • You should find `oscpack` libs and headers in your OS tree, likely `/usr/lib/...` Then verify those paths are correctly set in Qt. – Ripi2 Dec 14 '19 at 19:06
  • @Ripi2 Hi, I did verify the /usr/... paths with ( $ sudo dpkg -L liboscpack-dev ) and ( $ sudo dpkg -L liboscpack1 ), I then checked what was contained in those dirs. That's how I came up with ( LIBS += -L"/usr/lib/x86_64-linux-gnu" -loscpack ). In order to set Qt up correctly, is there anything else I should do beyond setting the LIBS parameter in the .pro file? – Marcelo Dec 14 '19 at 19:33
  • Hello. I recently edited my post and changed main.qml. Before, I was trying to show that the errors had nothing to do with the main.qml code, but with the inclusion of the library itself. But that might not have been helpful. The main.qml showing now should simply implement a test case of the library. – Marcelo Dec 14 '19 at 20:18

1 Answers1

2

Explanation

The problem is the misunderstanding of how libraries are linked in C++. The qml-osc project to integrate oscpack uses a static link (so it is not necessary to link it dynamically) but unfortunately liboscpack.a is very old generating the problem you observe.

Solution

Considering the above I have made fork of qml-osc eliminating the dependence of the static library so a dynamic link must be used.

Considering the above you must follow the following steps:

  1. install liboscpack-dev
sudo apt-get install liboscpack-dev
  1. Clean your project so that it has the following structure(You can download the files from here):
├── 59331063.pro
├── main.cpp
├── main.qml
└── qml.qrc

Where the .pro is as follows:

QT += quick
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
RESOURCES += qml.qrc

INCLUDEPATH += /usr/include/oscpack
LIBS += -loscpack 
include($$PWD/3rdPartyLibs/qml-osc/osc.pri)
  1. Then create a folder called 3rdPartyLibs and clone my repository:
mkdir 3rdPartyLibs && cd 3rdPartyLibs && git clone https://github.com/eyllanesc/qml-osc.git

In the end the project must have the following structure:

├── 3rdPartyLibs
│   └── qml-osc
│       ├── LICENSE
│       ├── osc.pri
│       ├── osc_receiver.cpp
│       ├── osc_receiver.h
│       ├── osc_sender.cpp
│       ├── osc_sender.h
│       └── README.md
├── 59331063.pro
├── main.cpp
├── main.qml
└── qml.qrc

At the moment I do not have access to a machine with ubuntu so to test my previous procedure I have used the following Dockerfile

FROM ubuntu:18.04

MAINTAINER eyllanesc <e.yllanescucho@gmail.com>

RUN apt-get update && \
    apt-get autoclean

RUN apt-get update && apt-get install \
  -y --no-install-recommends \
  git \
  ca-certificates \
  build-essential \ 
  qt5-default \
  qtdeclarative5-dev \
  qml-module-qtquick-controls \
  qml-module-qtquick-controls2 \
  qml-module-qtquick-window2  \
  liboscpack-dev

COPY app app

RUN mkdir app/3rdPartyLibs && \
    cd app/3rdPartyLibs && \
    git clone https://github.com/eyllanesc/qml-osc.git

RUN mkdir app/build && \
    cd app/build && \
    qmake .. && \
    make

CMD app/build/59331063

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Hi . Thank you so much! I haven't used Docker before but I see the value of it. I'm going to install it and work through your solution. It will likely take me a while - I will post when I have results. – Marcelo Dec 14 '19 at 21:07
  • @Marcelo You do not need to use docker, just use the steps I have indicated. I used docker because I didn't use ubuntu so one way to test the project was to use docker – eyllanesc Dec 14 '19 at 21:13
  • Thanks!! I got it working just fine the way you set it up. I will still learn about Docker, since is seems very useful, and will incorporate this into the larger project. Have a great weekend. – Marcelo Dec 14 '19 at 22:21