I try to compile a little Qt project, but i get a linker error.
I want to make a small project which read Bluetooth Low Energy (BLE) Gatt characteristics. I have an embedded Board where the BLE works.
When I start the compiler i get theses warnings / Errors:
qtmain.lib(qtmain_winrt.obj):-1: Warnung: LNK4099: PDB "qtmain.pdb" wurde nicht mit "qtmain.lib(qtmain_winrt.obj)" oder an "C:\Users\Kennis\Documents\build-Bachlerorarbeit-Qt_5_11_2_for_UWP_64bit_MSVC_2017-Profile\release\qtmain.pdb" gefunden; Objekt wird verknüpft, als ob keine Debuginformationen vorhanden wären.
widget.obj:-1: error LNK2019: unresolved external symbol ""__declspec(dllimport) public: __cdecl QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(class QObject *)" (__imp_??0QBluetoothDeviceDiscoveryAgent##QEAA#PEAVQObject###Z)" referenced in function""public: __cdecl Widget::Widget(class QWidget *)" (??0Widget##QEAA#PEAVQWidget###Z)".
widget.obj:-1: error LNK2019: unresolved external symbol ""__declspec(dllimport) public: virtual __cdecl QBluetoothDeviceDiscoveryAgent::~QBluetoothDeviceDiscoveryAgent(void)" (__imp_??1QBluetoothDeviceDiscoveryAgent##UEAA#XZ)" referenced in function ""public: virtual void * __cdecl QBluetoothDeviceDiscoveryAgent::`scalar deleting destructor'(unsigned int)" (??_GQBluetoothDeviceDiscoveryAgent##UEAAPEAXI#Z)".
widget.obj:-1: error LNK2001: unresolved external symbol""public: virtual struct QMetaObject const * __cdecl QBluetoothDeviceDiscoveryAgent::metaObject(void)const " (?metaObject#QBluetoothDeviceDiscoveryAgent##UEBAPEBUQMetaObject##XZ)".
widget.obj:-1: error LNK2001: unresolved external symbol ""public: virtual struct QMetaObject const * __cdecl QBluetoothDeviceDiscoveryAgent::metaObject(void)const " (?metaObject#QBluetoothDeviceDiscoveryAgent##UEBAPEBUQMetaObject##XZ)".
widget.obj:-1: error LNK2001: unresolved external symbol ""public: virtual void * __cdecl QBluetoothDeviceDiscoveryAgent::qt_metacast(char const *)" (?qt_metacast#QBluetoothDeviceDiscoveryAgent##UEAAPEAXPEBD#Z)".
:
i work on Windows 10 with Qt5.11.2 for UWP 64bit (MSVC 2017).
without the line of the init of the Discovery Agent i´m able to compile the project.
I have started Qmake and rebuild multiple times.
main.cpp :
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp :
#include "widget.h"
#include "ui_widget.h"
#include <QtBluetooth/QBluetoothDeviceDiscoveryAgent>
#include <QtBluetooth/QBluetoothDeviceInfo>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
}
Widget::~Widget()
{
delete ui;
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtBluetooth/QBluetoothDeviceDiscoveryAgent>
#include <QtBluetooth/QBluetoothDeviceInfo>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
QBluetoothDeviceDiscoveryAgent *discoveryAgent;
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
bachelorarbeit.pro:
#-------------------------------------------------
#-------------------------------------------------
#
# Project created by QtCreator 2019-02-02T21:22:40
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Bachlerorarbeit
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact
warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain
version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the
APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
Related
I've been trying to install and properly link bit7z into my C++ code as I have to do a task for my internship which concludes in automatically zipping a certain directory and sending the zip-file out as an email. Right now the email is not interesting to me as I can't even get the base program. I just keep getting the Linker Error 2019 and I don't know what to do anymore. I'll provide as much info as I can.
I use Visual Studio 2019.
My .pro file:
TEMPLATE = app
TARGET = aixLogger
DESTDIR = ./Debug
CONFIG += debug console
DEPENDPATH += .
MOC_DIR += .
OBJECTS_DIR += debug
UI_DIR += GeneratedFiles
RCC_DIR += GeneratedFiles
LIBS += -D:/local/aretz/Programmierung/git-workplace/aixLogger/Dependencies/bit7z/lib -lbit7z
INCLUDEPATH += D:/local/aretz/Programmierung/git-workplace/aixLogger/Dependencies/bit7z/include
include(aixLogger.pri)
My .h
#pragma once
#include <qwidget.h>
#include <qobject.h>
#include <bit7z.hpp>
class AIXLogger : public QWidget
{
Q_OBJECT
public slots:
public:
void CompressDir();
void Execute();
};
My .cpp
#include <QCoreApplication>
#include <string>
#include <iostream>
#include <filesystem>
#include <bit7z.hpp>
#include "main.h"
#include "bitcompressor.hpp"
namespace fs = std::filesystem;
using namespace bit7z;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::string path = "C:/Users/aretz/Downloads/test";
for (const auto& entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
//return a.exec();
}
void AIXLogger::CompressDir() {
try {
Bit7zLibrary lib{ L"C:/Program Files/7-Zip/7z.dll" };
//BitCompressor compressor{ lib, BitFormat::Zip };
std::vector< std::wstring > files = { L"aretz/downloads/test/test1.txt", L"aretz/downloads/test/test1.txt" };
//Zip Archiv erstellen
//compressor.compress(files, L"output_archive.zip");
//Directory zippen
//compressor.compressDirectory(L"dir/path/", L"dir_archive.zip");
}
catch (const BitException& ex) {
//irgendwas mit &ex machen
}
}
void AIXLogger::Execute() {
CompressDir();
}
I'm also adding pictures of the properties I changed.
Additional DependenciesAdditional Library DirectoriesAdditional Include Directories
EDIT: Here is the actual Error I'm getting with just the line "Bit7zLibrary lib {L"C:/Program Files/7-Zip/7z.dll" };:
Error LNK2019 unresolved external symbol "public: __thiscall bit7z::Bit7zLibrary::Bit7zLibrary(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (??0Bit7zLibrary#bit7z##QAE#ABV?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###Z) referenced in function "public: void __thiscall AIXLogger::CompressDir(void)" (?CompressDir#AIXLogger##QAEXXZ) aixLogger D:\local\aretz\Programmierung\git-workplace\aixLogger\main.obj 1
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: virtual __thiscall bit7z::Bit7zLibrary::~Bit7zLibrary(void)" (??1Bit7zLibrary#bit7z##UAE#XZ) referenced in function "public: void __thiscall AIXLogger::CompressDir(void)" (?CompressDir#AIXLogger##QAEXXZ) aixLogger D:\local\aretz\Programmierung\git-workplace\aixLogger\main.obj 1
The problem you're having is that the linker cannot find the bit7z static library.
By default, the bit7z library is built to bit7z\bin\$(PlatformShortName)\, where $(PlatformShortName) is either x86 or x64 according to your target architecture.
However, you specified a different library directory (bit7z\lib\), which is wrong (unless you changed the directory where you output the built library).
You can fix it by changing the path to $(SolutionDir)Dependencies\bit7z\bin\$(PlatformShortName)\.
Also, please note that, on x86, the default library name is just bit7z.lib, while on x64 is bit7z64.lib.
Error when attempting to build code I copy-pasted directly from the QT for beginners wiki page.
error
main.obj:-1: error: LNK2019: unresolved external symbol "public: __cdecl Window::Window(class QWidget *)" (??0Window##QEAA#PEAVQWidget###Z) referenced in function main
debug\testempty.exe:-1: error: LNK1120: 1 unresolved externals
testempty.pro
TEMPLATE = app
TARGET = testempty
QT = core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
SOURCES += \
main.cpp \
window.cpp
HEADERS += \
window.h
window.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
class QPushButton;
class Window : public QWidget
{
public:
explicit Window(QWidget *parent = nullptr);
private:
QPushButton *m_button;
};
#endif // WINDOW_H
window.cpp
#include "window.h"
#include <QPushButton>
Window::Window(QWidget *parent) : QWidget(parent)
{
setFixedSize(100, 50);
m_button = new QPushButton("Hello World", this);
m_button->setGeometry(10, 10, 80, 30);
}
main.cpp
#include <QApplication>
#include "window.h"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Window window;
window.show();
return app.exec();
}
As for things I have already tried, I was instructed to build->clean all and try building again, but that made no difference.
Solution From a similar thread.
Right click on project > Clean
Right click on project > Run qmake
Right click on project > Build
Run
Why it works
The reason this worked is because Run qmake updates your Makefile. For some reason qt is not automatically updating paths when you make changes to your project such as adding or removing files. Running qmake forces qt to update the paths for your project which enables it to find the mainwindow.obj file. You probably could just run qmake and your problem would be solved.
I'm having troubles with using of external library, lets start from beginning.
I have some library trans2quik, wich consists of 3 files: trans2quik .dll/.lib/.h
So, I use Qt5.2, MSVC 2012 x64, win7. I create simple qt widget application, and link library, using "Add library" wizard, for generating LIBS, INCLUDEPATH, ect in my pro file. Then, when I call any function, I get unresolved extenal symbol error:
widget.obj:-1: error: LNK2019: unresolved external symbol __imp_TRANS2QUIK_CONNECT in function "public: __cdecl Widget::Widget(class QWidget *)" (??0Widget##QEAA#PEAVQWidget###Z)
The code follows:
PRO file:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = bot_test
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
win32: LIBS += -L$$PWD/ -lTRANS2QUIK
INCLUDEPATH += $$PWD/
DEPENDPATH += $$PWD/
widget.h file:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <Windows.h> //For LPSTR and DWORD
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
//Some vars for lib's function
LPSTR connectionParams;
LPSTR errorMsg;
DWORD errorMsgSize;
long *errorCode;
};
#endif // WIDGET_H
widget.cpp file:
#include "widget.h"
#include "trans2quik_api.h"
#pragma comment(lib, "TRANS2QUIK.lib")
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
TRANS2QUIK_CONNECT(connectionParams, errorCode, errorMsg, errorMsgSize);
}
So, the .lib and lib's .h files are in projects directory and LIB+= and INCLUDEPATH+= were generated by QtCreator, so I beliave it's not a problem. Hope for any halp, thank you in advance.
The problem is that you are trying to link againt a 32 bit trans2quik, whereas your application seems to be defined as 64 bit. Do not mix them. Either build 32 bit application, or use a 64 bit library.
All I have is a main.cpp:
#include "myclass.h"
#include <QApplication>
#include <QTextEdit>
#include <QtGui>
class Notepad : public QWidget {
Q_OBJECT
public:
Notepad();
private slots:
void quit();
private:
QTextEdit *textEdit;
QPushButton *quitButton;
};
Notepad::Notepad()
{
textEdit = new QTextEdit();
quitButton = new QPushButton(tr("Quit"));
connect(quitButton, SIGNAL(clicked()), this, SLOT(quit()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textEdit);
layout->addWidget(quitButton);
setLayout(layout);
setWindowTitle(tr("Notepad"));
}
void Notepad::quit()
{
QMessageBox messageBox;
messageBox.setWindowTitle(tr("Notepad"));
messageBox.setText(tr("Do you really want to quit?"));
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
messageBox.setDefaultButton(QMessageBox::No);
if(messageBox.exec() == QMessageBox::Yes)
qApp->quit();
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
return app.exec();
}
Error info:
1>main.obj : error LNK2001: Unresolvable external symbol "public: virtual struct QMetaObject const * __thiscall Notepad::metaObject(void)const " (?metaObject#Notepad##UBEPBUQMetaObject##XZ)
1>main.obj : error LNK2001: Unresolvable external symbol "public: virtual void * __thiscall Notepad::qt_metacast(char const *)" (?qt_metacast#Notepad##UAEPAXPBD#Z)
1>main.obj : error LNK2001: Unresolvable external symbol "public: virtual int __thiscall Notepad::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall#Notepad##UAEHW4Call#QMetaObject##HPAPAX#Z)
1>main.obj : error LNK2001: Unresolvable external symbol "public: static struct QMetaObject const Notepad::staticMetaObject" (?staticMetaObject#Notepad##2UQMetaObject##B)
I'm new to VS and Qt, Hope to find a solution to this, thanks.
The problem is likely that you have Q_OBJECT in your cpp file
class Notepad : public QWidget {
Q_OBJECT
To make it work you need to manually add moc step for your cpp to compilation process. Or move it to the header file, where it's done automatically
You use Q_OBJECT in your Notepad class, so you should moc it, compile the moc output and link with resulting .obj file.
Usually, classes are defined in header files, so you just run moc on the Notepad.h, make it generate moc_Notepad.cpp and compile the latter. In your case you should run moc on your main.cpp, generate something like main.moc and at the bottom of main.cpp add #include "main.moc".
I found my solution for this (FINALLY!) and thought I'd post it here.
I found this page: http://msdn.microsoft.com/en-us/library/aa267384%28v=vs.60%29.aspx
I'll paste the key piece here incase it disappears:
To use this run-time library
Single-threaded (libc.lib)
Multithreaded (libcmt.lib)
Multithreaded using DLL (msvcrt.lib)
Debug Single-threaded (libcd.lib)
Debug Multithreaded (libcmtd.lib)
Debug Multithreaded using DLL (msvcrtd.lib)
What this tells you is the runtile library you need, and which ones you don't.
So when I set release mode, Multi-threaded DLL (/MD), it didn't work for me, the issue was it had in the linker (under Input) the wrong values for the /NODEFAULTLIB, it had 3 entries, one of them being the one I was trying to use the msvcrt.lib. As soon as I changed it to: (leaving all the other values that weren't NODEFAULTLIB items)
/NODEFAULTLIB:libc.lib
/NODEFAULTLIB:libcmt.lib
/NODEFAULTLIB:libcd.lib
/NODEFAULTLIB:libcmtd.lib
/NODEFAULTLIB:msvcrtd.lib
(notice the absence of the one I'm interested it the non debug multithreaded dll lib msvcrt.lib)
It worked 110%!!!
Please like if you find useful, stack wasn't letting me post for a bit, hopefully it will let me post this one.
Basically I am following the basic example here. My .pro file contains QT += core network qtestlib. [Solved] testlib instead of typo qtestlib
When I include QVERIFY, It get the following linker error:
testwaypointlist.obj:-1: error: LNK2019: unresolved external symbol "bool __cdecl
QTest::qVerify(bool,char const *,char const *,char const *,int)"
(?qVerify#QTest##YA_N_NPBD11H#Z) referenced in function "private: void __thiscall
TestWaypointList::fillWaypoints(void)" (?fillWaypoints#TestWaypointList##AAEXXZ)
What files do I miss to link? Without QVERIFY the linker error disappears.
Header file:
#include <QObject>
#include <QtTest/QtTest>
#include "waypointlist.h"
//
// Testing the waypoint list
//
class TestWaypointList : public QObject
{
Q_OBJECT
private:
WaypointList _waypointList;
public:
explicit TestWaypointList(QObject *parent = 0);
private slots:
void fillWaypoints();
};
cpp:
//
// Fill the waypoint list
//
void TestWaypointList::fillWaypoints()
{
_waypointList = WaypointList();
.....
for (int i=0; i < TESTWPLISTCOUNT; i++) {
.....
TestWaypointList::_waypointList.updateOrAppend(id, timeframe);
}
QVERIFY(TestWaypointList::_waypointList.count() == 1); // causing the linker error
}
In your .pro file, you need to change QT += qtestlib to QT += testlib (note the absence of a "q").
Of note, you used to be able to do this: CONFIG += qtestlib, but according to the comment on this page, this is no longer the recommended way of linking to the test library.