Error linking static boost_filesystem library with Qt Creator - qt

I am getting an error when trying to link a static boost_filesystem library with QMake.
I know that my boost install is working, because I can link to it no problem outside of QMake like this:
g++ -o my_file my_file.cpp -IC:\boost_1_55_0\boost_1_55_0 -LC:\boost_1_55_0\boost_1_55_0\stage\lib -lboost_system -lboost_filesystem
I tried linking Qt with boost_filesystem like this at first, but it seems that it could not find the libraries:
LIBS += -LC:\boost_1_55_0\boost_1_55_0\stage\lib -lboost_system -lboost_filesystem
"-lboost_system not found -lboost_filesystem not found"
I read something about how you need to specify absolute paths to static libs when using QMake, so I've changes my LIBS line in my .pro to the following:
LIBS += "C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_system-mgw48-mt-1_55.a" \
"C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_filesystem-mgw48-mt-1_55.a"
The libraries are found with this method, however I get the following error message:
undefined reference to boost::system::generic_category()
I was under the impression that this error only happen when boost_system isn't linked! I seems like it is linked though, because it finds the proper library for it, and I know my install of boost is good because the same library links fine (with the same compiler) outside of Qt Creator.
Here's the include in mainwindow.h:
include <boost/filesystem.hpp>
Here the full .pro:
QT += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
QMAKE_CXXFLAGS += -std=c++11
TARGET = Downloader
TEMPLATE = app
INCLUDEPATH += C:\boost_1_55_0\boost_1_55_0
LIBS += "C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_system-mgw48-mt-1_55.a" \
"C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_filesystem-mgw48-mt-1_55.a"
SOURCES += main.cpp\
mainwindow.cpp\
rar_process.cpp\
HEADERS += mainwindow.h\
rar_process.h\
FORMS += mainwindow.ui
RESOURCES += \
graphics.qrc
And here's the full compiler output:
C:\Qt\Qt5.1.1\5.1.1\mingw48_32\bin\qmake.exe -spec win32-g++ -o Makefile ..\qt- downloader\Downloader.pro
C:/Qt/Qt5.1.1/Tools/mingw48_32/bin/mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory 'C:/Users/Patrick/Desktop/cpp/build-Downloader- Desktop_Qt_5_1_1_MinGW_32bit-Release'
g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o release\Downloader.exe release/main.o release/mainwindow.o release/rar_process.o release/qrc_graphics.o release/moc_mainwindow.o release/moc_rar_process.o -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 -lqtmain C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_system-mgw48-mt-1_55.a C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_filesystem-mgw48-mt-1_55.a - LC:\Qt\Qt5.1.1\5.1.1\mingw48_32\lib -lQt5Widgets -lQt5Network -lQt5Gui -lQt5Core
release/main.o:main.cpp:(.text.startup+0x1a): undefined reference to `boost::system::generic_category()'
release/main.o:main.cpp:(.text.startup+0x24): undefined reference to `boost::system::generic_category()'
Makefile.Release:86: recipe for target 'release\Downloader.exe' failed
c:/qt/qt5.1.1/tools/mingw48_32/bin/../lib/gcc/i686-w64-mingw32/4.8.0/../../../../i686- w64-mingw32/bin/ld.exe: release/main.o: bad reloc address 0x24 in section `.text.startup'
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: *** [release\Downloader.exe] Error 1
mingw32-make[1]: Leaving directory 'C:/Users/Patrick/Desktop/cpp/build-Downloader- Desktop_Qt_5_1_1_MinGW_32bit-Release'
makefile:34: recipe for target 'release' failed

GCC is very sensitive to the order in which you specify libraries during the linking stage. For example, if libA.a depends on libB.a and an executable App depends on both, then you'd have to invoke linker in the following way:
gcc main.o object1.o ... object2.o -lA -lB -o App
This implies that you have to change it to:
LIBS += "C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_filesystem-mgw48-mt-1_55.a" \
"C:\boost_1_55_0\boost_1_55_0\stage\lib\libboost_system-mgw48-mt-1_55.a"
To be cross-platform, it's recommended to make your build more robust:
Boost_VERSION = 1_55
COMPILER = mgw48
win32-g++* {
LIBS += $$(Boost_DIR)/stage/lib/libboost_filesystem-$${COMPILER}-mt-$${Boost_VERSION}.a \
$$(Boost_DIR)/stage/lib/libboost_system-$${COMPILER}-mt-$${Boost_VERSION}.a
PRE_TARGETDEPS += $$(Boost_DIR)/stage/lib/libboost_filesystem-$${COMPILER}-mt-$${Boost_VERSION}.a \
$$(Boost_DIR)/stage/lib/libboost_system-$${COMPILER}-mt-$${Boost_VERSION}.a
}
linux-g++* {
LIBS += -L$$(Boost_DIR)/stage/lib -lboost_filesystem-$${COMPILER}-mt-$${Boost_VERSION} \
-lboost_system-$${COMPILER}-mt-$${Boost_VERSION}
PRE_TARGETDEPS += $$(Boost_DIR)/stage/lib/libboost_filesystem-$${COMPILER}-mt-$${Boost_VERSION}.a \
$$(Boost_DIR)/stage/lib/libboost_system-$${COMPILER}-mt-$${Boost_VERSION}.a
}
NOTE: Boost_DIR would be treated as an environment variable here. So that you can flexibly build it on any system without hardcoding the system-dependent path to Boost. This is general practice in professional software development: try to hardcode as little as possible in your build system, whatever it is. Furthermore, it's reasonable to even make Boost_VERSION environment variable too. All you'd have to change then, are brackets to parentheses, i.e. $${Boost_VERSION} to $$(Boost_VERSION).
Finally, notice that I've used forward slash / as a path separator for both Windows and Linux. Backward slash \ is not only deprecated in QMake, but it is also discouraged in general. Once again, be cross-platform: simply let QMake handle the conversion.

Apparently boost-system will not link against mingw gcc 4.8.0 if it was built with mingw gcc 4.8.1.
I re-built boost with mingw gcc 4.8.0 and linked against those libs, and now it works!

Related

Compile OpenNN with Qt in Windows and Mingw 5.30

Im trying to compile the openNN Project with Qt.
Im using qt precompiled mingw32 for windows and the last opennn 3.1 projekt sources.
Opennn comes already with .pro Project files for direct use with qt creator/qmake.
However when i try to compile it i get the following errors:
D:/Projekte/opennn_build/opennn/release\libopennn.a(testing_analysis.o):testing_analysis.cpp:(.text+0xfc): undefined reference to `omp_get_num_threads'
D:/Projekte/opennn_build/opennn/release\libopennn.a(testing_analysis.o):testing_analysis.cpp:(.text+0x103): undefined reference to `omp_get_thread_num'
D:/Projekte/opennn_build/opennn/release\libopennn.a(testing_analysis.o):testing_analysis.cpp:(.text+0x22f): undefined reference to `GOMP_loop_dynamic_start'
D:/Projekte/opennn_build/opennn/release\libopennn.a(testing_analysis.o):testing_analysis.cpp:(.text+0x3d3): undefined reference to `GOMP_loop_dynamic_next'
D:/Projekte/opennn_build/opennn/release\libopennn.a(testing_analysis.o):testing_analysis.cpp:(.text+0x3e0): undefined reference to `GOMP_loop_end_nowait'
D:/Projekte/opennn_build/opennn/release\libopennn.a(testing_analysis.o):testing_analysis.cpp:(.text+0x64b): undefined reference to `GOMP_loop_dynamic_start'
it seems to be connected to openmp, however the *.pro files of opennn already contain the always suggested lines:
QMAKE_CXXFLAGS+= -fopenmp
QMAKE_LFLAGS += -fopenmp
trying to add the following didnt help either
LIBS+= -fopenmp
i need to make it work with qt, because i wanted to add it to an already existing qt project later.
solution:
edit in openn/tests/tests.pro
and the "exampletitle".pro file of each example in openn/examples/"exampletitle"/
change:
win32-g++{
QMAKE_LFLAGS += -static-libgcc
QMAKE_LFLAGS += -static-libstdc++
QMAKE_LFLAGS += -static
}
to
win32-g++{
QMAKE_LFLAGS += -static-libgcc
QMAKE_LFLAGS += -static-libstdc++
QMAKE_LFLAGS += -static
LIBS += -fopenmp
}

How to create a Qt Creator project (.pro) file equivalent to existing Makefile

There is a project which is build via make command, where the Makefile is provided. Following are the Makefile contents:
TARGETT=gnulinux
OROPATH=/usr/local
CXXFLAGS=-I${OROPATH}/include -DOROCOS_TARGET=${TARGETT} -Wall
LDFLAGS=-L${OROPATH}/lib -Wl,-rpath ${OROPATH}/lib -lorocos-taskbrowser-${TARGETT} -lorocos-rtt-${TARGETT}
all: main
main.o: main.cpp
$(CXX) -c main.cpp $(CXXFLAGS)
AHRS.o: AHRS.cpp AHRS.h
$(CXX) -c AHRS.cpp $(CXXFLAGS)
main: main.o AHRS.o
$(CXX) -g -o main main.o AHRS.o $(CXXFLAGS) $(LDFLAGS)
clean:
rm -f main orocos.log .tb_history *.o
But I'm used to use QtCreator. I know that QtCreator constructs its own makefile from the project (.pro) file during build process. So, I think, relevant information must be copied from the Makefile contents (above) into a Qt Creator project file to allow QtCreator to generate the compatible makefile. Right?
Given the Makefile above, how should the .pro file look like?
And in the end of this process I'll be able to work from QtCreator.
Given the Makefile above, how should the .pro file look like?
Like this:
TEMPLATE = app
TARGET = AHRS # the desired filename of the executable goes here
OROPATH = /usr/local
INCLUDEPATH += $${OROPATH}/include
O_TARGET = gnulinux
DEFINES += OROCOS_TARGET=$${O_TARGET}
QMAKE_RPATHDIR += -L$${OROPATH}/lib
LIBS += -L$${OROPATH}/lib
LIBS += -lorocos-taskbrowser-$${O_TARGET} -lorocos-rtt-$${O_TARGET}
SOURCES += main.cpp AHRS.cpp
HEADERS += AHRS.h
Note that Qt Creator doesn't construct anything. qmake does. The project files are qmake projects, not Qt Creator projects. You don't need Qt Creator at all to build your project. You can do it from the command line using nothing but Qt and the compiler/binutils:
# assume that the source is in AHRS-source subfolder
mkdir AHRS
cd AHRS
/path/to/Qt/bin/qmake ../AHRS-source
make -j
# now we can run it
./AHRS

Makefile made by qmake only works on my pc

For a university project we made an OpenGL application which uses Qt for the GUI. When I use qmake -spec macx-g++ project.pro I can make a Makefile, and if I then do make it correctly makes the application. However, when I then send the complete folder to the other person in the project and he does make he gets the error
Makefile:209: warning: overriding commands for target `moc_window.cpp'
Makefile:203: warning: ignoring old commands for target `moc_window.cpp'
make: *** No rule to make target `/usr/lib64/qt-3.3/mkspecs/default/qmake.conf', needed by `Makefile'. Stop.
However, when in the same folder he does qmake; make it does work correctly. The problem is that when handing the code in we don't know if the professor has qmake available, so we would like it to work by only using make. Are we missing something that should be addded to have the Makefile made with qmake work, without having to do qmake again? Our .pro file is below.
TEMPLATE = app
TARGET = smoke
QT = core gui opengl
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
SOURCES += \
fluids.cpp \
simulation.cpp \
visualization.cpp \
window.cpp \
myglwidget.cpp \
vector.cpp \
grid.cpp \
scalar.cpp
HEADERS += \
window.h \
myglwidget.h \
simulation.h \
vector.h \
grid.h \
visualization.h \
scalar.h
INCLUDEPATH += fftw-2.1.5/include /usr/local/include include
LIBS += -L"$$_PRO_FILE_PWD_/fftw-2.1.5/lib" -lrfftw -lfftw -framework OpenGL -framework GLUT -stdlib=libc++
QMAKE_CXXFLAGS += -stdlib=libc++
QMAKE_CXXFLAGS += -std=c++11
FORMS += \
window.ui
The build directory is not portable. It is only ever meant to work on the system where you executed qmake, and for the particular Qt install that you ran qmake from. Recall that each Qt install has its own qmake, so e.g. if you have three Qt versions, each provides its own qmake that you must use to build a project using that version.
The project you ship should contain the .pro file, the sources, and whatever else the build calls for, like icon files, resources, etc.
The recipient, to build it, should:
Create a build folder.
cd into the build folder.
qmake /path/to/sources/project.pro && make -j
That's how you distribute and build Qt projects.
why does qmake not build the application directly?
Why do you not make your own shoes? The reasons are the same. Don't reinvent the wheel.
Of course, engineers sometimes have an itch to scratch. Enter Qt Build System (qbs). If your project's build is given as a .qbs file, then you do:
Create a build root folder.
cd into the build root folder.
qbs -f /path/to/sources/project.qbs - this builds the project.

how to install opencv_contrib on ubuntu?

I got opencv_contrib pack files from github https://github.com/Itseez/opencv_contrib
and built it successfully as the README says ,
$ cmake -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..
then I typed make install to generate .so files (Did I misunderstand this command here?) .
But when I use qt to compile this example docs.opencv.org/master/db/d56/tutorial_capture_graycode_pattern.html#gsc.tab=0
it comes error like
undefined reference to `cv::structured_light::GrayCodePattern::Params::Params()'
what should I do?
the following things I've added it in .pro
INCLUDEPATH += /home/tau/opencv/opencv-3.1.0/include /home/tau/opencv/opencv_contrib/modules/structured_light/include
LIBS += -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -lopencv_video -lopencv_videoio-lopencv_structured_light

How to solve undefined reference errors when linking log4cxx in qmake project

It's the second day I'm trying to marry Qt5, MinGW and log4cxx.
Even after I've compiled everything successfully, linked apr, apr-util and log4cxx libraries, ld gives me a bunch of "undefined reference" problems.
It looks like different settings were specified during log4cxx compilation (I'm using ant).
Was anyone able to successfully compile and use log4cxx with MinGW?
Environment:
log4cxx trunk
apr 1.4.6
apr-util 1.5.2
latest MinGW
I'm using Qt 5 with latest MinGW as a compiler
What I've done:
compiled log4cxx using ant with the following command: "ant
-Dcompiler=gcc -Dfind=false -DLOG4CXX_STATIC=1 -Dlib.type=static"
added result libraries to my project in pro file: "LIBS +=
-L../log4cxx/lib LIBS += -llibapr-1 -llibaprutil-1 -lliblog4cxx"
And now, as I try to link my project, I'm getting the next:
*C:/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'C:/Work/SPP_Development/AutoHaul/Sub-systems/TCS/Source/build-SimulatorEngine-Standalone_MinGW-Debug'
g++ -Wl,-subsystem,windows -mthreads -o debug\SimulatorEngine.exe object_script.SimulatorEngine.Debug -lmingw32 -lqtmaind -L../log4cxx/lib -llibapr-1 -llibaprutil-1 -lliblog4cxx -LC:\Qt\Qt5.0.1\5.0.1\mingw47_32\lib -lQt5XmlPatternsd -lQt5Widgetsd -lQt5Networkd -lQt5Xmld -lQt5Guid -lQt5Cored -llibEGLd -llibGLESv2d -lgdi32 -luser32
Makefile.Debug:200: recipe for target 'debug\SimulatorEngine.exe' failed
mingw32-make[1]: Leaving directory 'C:/Work/SPP_Development/AutoHaul/Sub-systems/TCS/Source/build-SimulatorEngine-Standalone_MinGW-Debug'
Makefile:34: recipe for target 'debug' failed
../log4cxx/lib/liblog4cxx.lib(mutex.o): In function `ZN7log4cxx7helpers5MutexC2ERNS0_4PoolE':
c:/Work/log4cxx/apache-log4cxx-trunc/src/main/cpp/mutex.cpp:35: undefined reference to `apr_thread_mutex_create#12'
../log4cxx/lib/liblog4cxx.lib(mutex.o): In function `ZN7log4cxx7helpers5MutexC2EP10apr_pool_t':
c:/Work/log4cxx/apache-log4cxx-trunc/src/main/cpp/mutex.cpp:45: undefined reference to `apr_thread_mutex_create#12'
../log4cxx/lib/liblog4cxx.lib(mutex.o): In function `ZN7log4cxx7helpers5MutexD2Ev':
c:/Work/log4cxx/apache-log4cxx-trunc/src/main/cpp/mutex.cpp:55: undefined reference to `apr_thread_mutex_destroy#4'*
It looks like log4cxx library cannot findfunctions declared and defined in the apr library by whatever reason.
Is there any way to analyze the problem further to see why is this happening?
I will describe the 1st problem you have and give the solution for it. If it does not solve your problem, do not revert back because that would be just the 1st step of fixing process, and I will gradually expand the answer to solve more incoming issues as long as you provide relevant feedback on each fix until we finally nail it down. So, lets begin.
First of all, you add libraries into LIBS variable in a wrong way. You have 2 options to do it right:
#1
LIBS += $${PWD}/../log4cxx/lib/libapr-1.a
LIBS += $${PWD}/../log4cxx/lib/libaprutil-1.a
LIBS += $${PWD}/../log4cxx/lib/liblog4cxx-1.a
#2
LIBS += -L$${PWD}/../log4cxx/lib
LIBS += -lapr-1
LIBS += -laprutil-1
LIBS += -llog4cxx-1
NOTE: Of course one liner is possible too:
LIBS += -L$${PWD}/../log4cxx/lib -lapr-1 -laprutil-1 -llog4cxx-1
NOTE: Using line continuation (\) for readability is possible too:
LIBS += -L$${PWD}/../log4cxx/lib \
-lapr-1 \
-laprutil-1 \
-llog4cxx-1
You need to take care of the proper link order: liblog4cxx depends on libapr*, so the libapr entries need to come after liblog4cxx:
LIBS += -L../log4cxx/lib \
-llog4cxx-1 \
-lapr-1 \
-laprutil-1
The reason is that dependencies are resolved left to right, so that in your case the apr libraries have been read, and forgotten, when log4cxx comes along that has some external symbols that need resolving. ld won't read the apr libraries again (has to do with cyclic dependency issues, and historical reasons).
To test if this works, you can try running the command
g++ -Wl,-subsystem,windows -mthreads -o debug\SimulatorEngine.exe object_script.SimulatorEngine.Debug -lmingw32 -lqtmaind -L../log4cxx/lib -lliblog4cxx -llibapr-1 -llibaprutil-1 -LC:\Qt\Qt5.0.1\5.0.1\mingw47_32\lib -lQt5XmlPatternsd -lQt5Widgetsd -lQt5Networkd -lQt5Xmld -lQt5Guid -lQt5Cored -llibEGLd -llibGLESv2d -lgdi32 -luser32
from the directory
C:/Work/SPP_Development/AutoHaul/Sub-systems/TCS/Source/build-SimulatorEngine-Standalone_MinGW-Debug
yourself first. But perhaps just modifying the .pro file is simplest.

Resources