How to avoid std::filesystem linker errors with Qt? - qt

I would like to use the std::filesystem with Qt 5.12.0 with the g++ version Ubuntu 8.2.0-7ubuntu1, but getting linker errors:
g++ -lstdc++fs -Wl,-rpath,/home/user/Qt/5.12.0/gcc_64/lib -o qf_filesystem_test main.o -L/home/user/Qt/5.12.0/gcc_64/lib -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
/usr/bin/ld: main.o: in function `std::filesystem::exists(std::filesystem::__cxx11::path const&)':
/usr/include/c++/8/bits/fs_ops.h:121: undefined reference to `std::filesystem::status(std::filesystem::__cxx11::path const&)'
/usr/bin/ld: main.o: in function `std::filesystem::__cxx11::path::path<char*, std::filesystem::__cxx11::path>(char* const&, std::filesystem::__cxx11::path::format)':
/usr/include/c++/8/bits/fs_path.h:183: undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status
make: *** [Makefile:257: qf_filesystem_test] Error 1
22:12:16: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project qf_filesystem_test (kit: Desktop Qt 5.12.0 GCC 64bit)
When executing step "Make"
After some googling, I found that I need to use the linker flag -lstdc++fs. My code builds perfectly with the command g++ main.cpp -std=c++17 -lstdc++fs, but I can't seem to make it work inside Qt Creator. My simple test code is the following:
#include <iostream>
#include <filesystem>
int main(int argc, char *argv[])
{
if(1 < argc)
{
std::cout << argv[1] << " does ";
if(!std::filesystem::exists(std::filesystem::path(argv[1]))) std::cout << "not ";
std::cout << "exist!" << std::endl;
}
return 0;
}
My .pro file looks like this:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = qf_filesystem_test
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++17
QMAKE_LFLAGS += -lstdc++fs
SOURCES += main.cpp
After some tests with g++ It seems to me, that the problem is caused by the order of the g++ flags, because Qt puts the -lstdc++fs to the front.
Why do I need to still use this flag? I thought that g++8 already supports C++17 and this flag is only needed if I want to use the std::experimental::filesystem.
How could I make my code build in Qt Creator?

<filesystem> is a separate library for GCC 8 (see this question). Your issue, as you suspected, is in the order of the flags. Poking about a bit in the docs hints that QMAKE_LFLAGS is more for linker flags than library loads, which is why it gets passed early (e.g. -O3).
Using LIBS += -lstdc++fs should work instead.
Credit to this reddit response for this solution.

Related

C/C++ undefined reference for sqlite3's functions using CLion with CMAKE

CMAKE's file has this code:
cmake_minimum_required(VERSION 3.6)
project(HelloSqliteC)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.c)
add_executable(HelloSqliteC ${SOURCE_FILES})
The file main.c has this code:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
int main() {
sqlite3 *db;
int rc;
rc = sqlite3_open("database.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s!\n", sqlite3_errmsg(db));
} else {
fprintf(stderr, "Opened database successfully!\n");
}
sqlite3_close(db);
return 0;
}
When I've trying compiling:
/home/marcus/ide/clion/clion-2016.3.1/bin/cmake/bin/cmake --build /home/marcus/projects/native/HelloSqliteC/cmake-build-debug --target HelloSqliteC -- -j 4
[ 50%] Building C object CMakeFiles/HelloSqliteC.dir/main.c.o
[100%] Linking C executable HelloSqliteC
CMakeFiles/HelloSqliteC.dir/main.c.o: In function `main':
/home/marcus/projects/native/HelloSqliteC/main.c:13: undefined reference to `sqlite3_open'
/home/marcus/projects/native/HelloSqliteC/main.c:16: undefined reference to `sqlite3_errmsg'
/home/marcus/projects/native/HelloSqliteC/main.c:21: undefined reference to `sqlite3_close'
collect2: error: ld returned 1 exit status
CMakeFiles/HelloSqliteC.dir/build.make:94: recipe for target 'HelloSqliteC' failed
make[3]: *** [HelloSqliteC] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/HelloSqliteC.dir/all' failed
make[2]: *** [CMakeFiles/HelloSqliteC.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/HelloSqliteC.dir/rule' failed
make[1]: *** [CMakeFiles/HelloSqliteC.dir/rule] Error 2
Makefile:118: recipe for target 'HelloSqliteC' failed
make: *** [HelloSqliteC] Error 2
I tried solve this issue using different ways, but no success.
I'm using CLion C/C++, my OS is Ubuntu 16.04 and I install sqlite3 using autoconf.
For test, I used the main.c above and compiled in command line with "-l sqlite3" using GCC and I had success, but I want use CLion.
Help me, thanks.
I also use CLion C/C++. The OS is Ubuntu 18.04.
But I want to compile the main.cpp.
The CMakelist.txt is:
cmake_minimum_required(VERSION 3.13)
project(ProjectName)
set(CMAKE_CXX_STANDARD 14)
add_executable(student main.cpp)
target_link_libraries(ProjectName LINK_PUBLIC sqlite3)
It works successfully.
I solved this issue with this target_link_libraries(HelloSqlite3 LINK_PUBLIC sqlite3) or target_link_libraries(projectName LINK_PUBLIC libraryName).
CLion uses CMake for all the building and project configuration. You have to manually modify CMakeLists.txt. In fact this is a CMake question.
This line in your CMakeLists.txt will solve your problem:
add_compile_options(-l sqlite3)
But actually CMake has a more sophisticated dependency discovery system. Read How To Find Libraries to learn this.

Qt5 and MacOS X

I've installed Qt5 on my Mac OS X Yosemite from MacPorts.
If I compile this simple file
#include <QtGui>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QLabel lbl("Hello World!");
lbl.show();
return app.exec();
}
I'll get error
Undefined symbols for architecture x86_64:
"QApplication::exec()", referenced from:
_main in main.o
"QApplication::QApplication(int&, char**, int)", referenced from:
_main in main.o
"QApplication::~QApplication()", referenced from:
_main in main.o
"QLabel::QLabel(QString const&, QWidget*, QFlags<Qt::WindowType>)", referenced from:
_main in main.o
"QLabel::~QLabel()", referenced from:
_main in main.o
"QWidget::show()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [123.app/Contents/MacOS/123] Error 1
I've change QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
to QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9
or QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.10
in file /opt/local/share/qt5/mkspecs/macx-clang/qmake.conf
but it has no result.
Hard to know exactly without more information, but check that you are adding in widgets in your .pro file:
QT += gui core
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
You may have to run qmake explicitly if you aren't using qtcreator. Also, wouldn't you be showing a main window instead of a QLabel? I haven't checked if that's legit doable code, but maybe you should start showing a main window and verify that works first. QTCreator has a project template for a new Qt Widgets Application. Also check to see that macports is installing the latest qt5 version in the event it's a bad path or config on their part.

Installing/using SDL for Qt

I'm trying to install the SDL library for Qt 5.1 on Windows 7, but I'm stuck. I'm a total newbie with using external libraries so please bear with me, I figured this sort of thing would be pretty basic to set up.
I downloaded the SDL-devel-1.2.15-mingw32.tar.gz (Mingw32) file, extracted it, and in my project's PRO file I added:
INCLUDEPATH += "C:\SDL\SDL-1.2.15\include\SDL"
LIBS += "C:\SDL\SDL-1.2.15\bin\SDL.dll"
Now when I try to compile this:
#include <iostream>
#include <stdlib.h>
#include "SDL.h"
using namespace std;
int main()
{
SDL_Init( SDL_INIT_EVERYTHING );
cout << "Hello World!" << endl;
return 0;
}
I get this:
crt0_c.c:-1: error: undefined reference to `WinMain#16'
collect2.exe:-1: error: error: ld returned 1 exit status
Compiling with SDL and g++ cannot find -lSDLmain etc
Undefined reference to WinMain#16 when using SDL
I am sure one of those is also applicable to your question.
SDL should be prevented from overloading main method. To do so, add the following piece of code wherever you include SDL headers.
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#ifdef __MINGW32__
#undef main /* Prevents SDL from overriding main() */
#endif
To make it working in your case, your project.pro file should be like this:
LIBS += -LC:\SDL-devel-1.2.15-mingw32\SDL-1.2.15\lib -llibSDL
INCLUDEPATH +=C:\SDL-devel-1.2.15-mingw32\SDL-1.2.15\include
As it is eveident from my code, I am using sdl version 1.2.15, 32-bit for mingw compiler on Windows 8.
Reference:
To find a good tutorial about the SDL ffmpeg integration, you can refer to dranger.

:: error: collect2: ld returned 1 exit status with QT and opengl

I'm trying to use a QGLWidget in a QT application, and I've added the "QT += opengl" line into the .pro file but I am now getting :: error: collect2: ld returned 1 exit status when I attempt to compile my program
the compile output shows the following,
Running build steps for project MapEditor...
Configuration unchanged, skipping qmake step.
Starting: "C:/Qt/2010.05/mingw/bin/mingw32-make.exe" -w
mingw32-make: Entering directory `C:/Qt/2010.05/MapEditor-build-desktop'
C:/Qt/2010.05/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory `C:/Qt/2010.05/MapEditor-build-desktop'
g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -mthreads -Wl -Wl,-subsystem,windows -o debug\MapEditor.exe debug/Main.o debug/window.o debug/glwidget.o debug/moc_window.o debug/moc_glwidget.o -L"c:\Qt\2010.05\qt\lib" -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 -lqtmaind -lQtOpenGLd4 -lQtGuid4 -lQtCored4
mingw32-make[1]: Leaving directory `C:/Qt/2010.05/MapEditor-build-desktop'
mingw32-make: Leaving directory `C:/Qt/2010.05/MapEditor-build-desktop'
debug/moc_glwidget.o:moc_glwidget.cpp:(.rdata$_ZTV8GLWidget[vtable for GLWidget]+0x14): undefined reference to `GLWidget::~GLWidget()'
debug/moc_glwidget.o:moc_glwidget.cpp:(.rdata$_ZTV8GLWidget[vtable for GLWidget]+0x18): undefined reference to `GLWidget::~GLWidget()'
debug/moc_glwidget.o:moc_glwidget.cpp:(.rdata$_ZTV8GLWidget[vtable for GLWidget]+0x118): undefined reference to `non-virtual thunk to GLWidget::~GLWidget()'
debug/moc_glwidget.o:moc_glwidget.cpp:(.rdata$_ZTV8GLWidget[vtable for GLWidget]+0x11c): undefined reference to `non-virtual thunk to GLWidget::~GLWidget()'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [debug\MapEditor.exe] Error 1
mingw32-make: *** [debug] Error 2
The process "C:/Qt/2010.05/mingw/bin/mingw32-make.exe" exited with code %2.
Error while building project MapEditor (target: Desktop)
When executing build step 'Make'
and my .pro file contains the following,
TARGET = MapEditor
TEMPLATE =app
QT += opengl
SOURCES += \
Main.cpp \
window.cpp \
glwidget.cpp
HEADERS += \
window.h \
glwidget.h
Check you .pro file (i.e. project file) that u have added all the class files and header files in SOURCES and HEADERS tags.[For this purpose run qmake command from build menubar options]
Also check that u have declared the Q_OBJECT macro in the starting of your glwidget class.
It looks like some file is missing. Did you add this to your header?
#include <QtOpenGL>

qt add path for 3rd party header and libraries

I am using qt and developing a desktop app that will run under win xp/vista.
I have a 3rd party library UserAgentLib (static, and shared). But I am not sure how to link in qt creator.
I have opened the *.pro file and added my library and header path.
The library is called UserAgentLib and the header file is called UserAgentLib.h
TARGET = Dialer
TEMPLATE = app
LIBS += D:\Projects\qtDialer\tools\lib\UserAgentLib
INCLUDEPATH += D:\Projects\qtDialer\tools\inc
SOURCES += main.cpp\
catdialer.cpp
HEADERS += catdialer.h
FORMS += catdialer.ui
I think it does find the header file, as I get about 100 errors for declarations in the UserAgentLib.h file. However, I don't think it is linking with the library.
Many thanks for any suggestions,
======================
I have create a very simple library in VS C++ 2008. Here is the code for the header and source file.
Header:
// mathslibrary.hpp
int add_numbers(const int a, const int b);
Source:
// mathslibrary.cpp
#include "mathslibrary.hpp"
int add_numbers(const int a, const int b)
{
return a + b;
}
I have compiled this into a library. And tested by linking with a WIN32 console application in VS 2008. The library worked as expected.
Now when I try and link with qt.
#include <QtCore/QCoreApplication>
#include <iostream>
#include "mathslibrary.hpp"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "add numbers 40 + 60 = " << add_numbers(40, 60) << std::endl;
return a.exec();
}
This is my qmake file:
QT -= gui
TARGET = testlibrary
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
LIBS = D:\Projects\TestLibrary\mathsLibrary\Debug\mathsLibrary.lib
INCLUDEPATH = D:\Projects\TestLibrary\mathsLibrary\
SOURCES += main.cpp
These are the errors I get when I try and build:
c:/Qt/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../libmingw32.a(main.o):main.c::-1: error: undefined reference to `WinMain#16'
:-1: error: collect2: ld returned 1 exit status
And these are the compile issues:
Running build steps for project testlibrary...
Creating gdb macros library...
Configuration unchanged, skipping QMake step.
Starting: C:/Qt/mingw/bin/mingw32-make.exe debug -w
mingw32-make: Entering directory `D:/Projects/TestQTLibrary/testlibrary'
C:/Qt/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory `D:/Projects/TestQTLibrary/testlibrary'
g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-subsystem,console -mthreads -Wl -o debug\testlibrary.exe -L"c:\Qt\qt\lib"
D:\Projects\TestLibrary\mathsLibrary\Debug\mathsLibrary.lib -lQtCored4
mingw32-make[1]: Leaving directory `D:/Projects/TestQTLibrary/testlibrary'
mingw32-make: Leaving directory `D:/Projects/TestQTLibrary/testlibrary'
c:/Qt/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../libmingw32.a(main.o):main.c:
(.text+0x104): undefined reference to `WinMain#16'
collect2: ld returned 1 exit status
mingw32-make[1]: * [debug\testlibrary.exe] Error 1
mingw32-make: * [debug] Error 2
Exited with code 2.
Error while building project testlibrary
When executing build step 'Make'
Many thanks for any advice,
Don't know if this changes anything, but maybe you have to define it like this:
LIBS += -LD:/Projects/qtDialer/tools/lib -lUserAgentLib
If you are getting compiler errors then your UserAgentLib.h probably didn't get included. You can test it with:
!exists( UserAgentLib.h ) {
error( "No UserAgentLib.h file found" )
}
You put the above in one of the .pro file and not the constructor.See this.
If the library didn't get linked (which is after your application has compiled well) -- then you need to tinker with your LIBS += ... line, though which appears fine on first glance.
Try this with the simple library first and then try it with the library you are actually trying to get working.
LIBS += D:\Projects\qtDialer\tools\lib\mathsLibrary.lib
In your .hpp file, add extern "C" before your function declarations:
// mathslibrary.hpp
extern "C" int add_numbers(const int a, const int b);
Rebuild the library from Visual Studio.
Now you should be able to compile your test app with Qt Creater. Then copy the corresponding dll into the directory with your new executable and give it a run.
As far as i understood, you generated a dll using MSVC and now you are trying to link it in Qt using mingw. right?
Object files and static libraries created with different compilers, or
even with significantly different releases of the same compiler, often
cannot be linked together. This issue is not specific to MinGW: many
other compilers are mutually incompatible. Build everything from
source with the same version of the same compiler if you can
chech this out : http://chadaustin.me/cppinterface.html

Resources