Undefined reference to ...
-
I am a (somewhat) experienced user of Qt, having developed several apps over a few years. However, I am now determined to resolve a conundrum that I have dodged from the beginning - namely re-using libraries of utilities I have developed over many years for use (in multiple programming environments) to do common tasks. To date I have simply included versions of the library codes explicitly within Qt projects - and suffered 1) the nightmare of keeping multiple versions of library routines up-to-date across multiple Qt projects and 2) foregoing the advantage of common C++ add-on packages such as Boost.
The platform is Windows 10, the most recent Qt package, and the g++ compiler from a recent (but perhaps not latest) version of MinGW.
I have browsed many of the prior instances of users that have bumped into this error, but none of the solutions have been effective for me. I have verified (with > 99% confidence) that the same compiler is used both within and outside Qt. I have also confirmed that Qt "finds" the correct library (at any rate, if I manually change the name of the actual library file I get an error that the library can't be found).
To help me resolve this, I stubbed out a pretty simple Qt app to use one class (MyFile) out of one commonly-used self-developed library (genlib). Outside Qt, and now within any integrated or GUI environment, I also have a test routine that tests the various operations of this class (called MyFile). Below is command line that ultimately generates this test routine. Note that MyFile is built using the standard Boost extensions to C++. Note also that I have simply unpacked the single-command line into multiple lines for readability.
g++
-o
testmyfile.exe
testmyfile.o
utils.o
-LC:\Boost\lib
-L....\lib\gcc_dll
-lgenlib
-lboost_system-mgw62-mt-1_62
-lboost_filesystem-mgw62-mt-1_62This works and produces the functional test routine, testmyfile.exe.
For the Qt app, if I remove any reference to MyFile, Qt correctly produces a functional app (without MyFile functionality).
The corresponding link command from Qt that attempts to create my corresponding Qt test app is
g++
-Wl,-subsystem,windows
-mthreads
-o
debug\NewMath.exe
debug/window.o
debug/mainapp.o
debug/newmain.o
debug/moc_window.o
debug/moc_mainapp.o
-lmingw32
-LC:\Qt\Qt5.9.1\5.9.1\mingw53_32\lib
C:\Qt\Qt5.9.1\5.9.1\mingw53_32\lib\libqtmaind.a
-LC:\utils\my_sql\my_sql\lib
-LC:\utils\postgresql\pgsql\lib
-lshell32
-L....\lib\gcc_dll
-lgenlib
C:\Qt\Qt5.9.1\5.9.1\mingw53_32\lib\libQt5Widgetsd.a
C:\Qt\Qt5.9.1\5.9.1\mingw53_32\lib\libQt5Multimediad.a
C:\Qt\Qt5.9.1\5.9.1\mingw53_32\lib\libQt5Guid.a
C:\Qt\Qt5.9.1\5.9.1\mingw53_32\lib\libQt5Networkd.a
C:\Qt\Qt5.9.1\5.9.1\mingw53_32\lib\libQt5Cored.aThat command produces the error:
debug/window.o: In function
ZN6Window11setupWindowEv': C:\Users\mhkel\Documents\Mike\src\Qt\NewMath/window.cpp:44: undefined reference to
MyFile::MyFile()'
(plus about 14 other undefined references to MyFile components.Any clues what I am doing wrong? I assume if I can resolve this specific issue, I will be able to resolve the subsequent issues with finding the Boost libraries and other libraries I want to use.
Thanks for any help.
-
Hi
Maybe its a silly question, but does the genlib export the class?
http://www.mingw.org/wiki/sampledllclass __declspec(dllexport) MyClass {
-
No, I have never explicitly "exported" a class - nor am I actually familiar with the concept. As mentioned in my initial post, I have successfully built many non-Qt apps by means completely analogous to that described in my initial post. Also, I build apps under CodeBlocks and using WxWidgets and this particular MyFile object is used in essentially every app I've every made. I will add this explicit export to my code, but am baffled why it is important here if I've never encountered it before.
-
Well, this is embarrassing. I expressed high confidence that I was using the same compiler both within and outside Qt - I was mistaken. I had tried to manually add a kit that used the MinGW compiler and set it as the default kit. Unfortunately, I was somehow not completely successful it that effort - Qt was still using its internal compiler instead of what I thought I had configured it to use. Of course, had I been successful in that attempt, I would probably still have failed because then the linker would have undefined references to all of Qt's internal libraries :(
I tweaked my Windows PATH environmental variable so it found the Qt compiler first and recompiled my genlib library. Now Qt does find the necessary MyFile references, but fails (as expected) on the Boost libraries.
Is there a better way forward than the following plan? Rrecall all the hoops I jumped through building the Boost libraries (and all the other libraries I sometimes use), recompile them using Qt's internal g++ compiler, and then set things up so the Qt compiler is the compiler used for all non-Qt work?
-
Hi
- File object is used in essentially every app I've every made
You mean by directly including the .cpp/h files?
It sounds like you have not used lib/dlls before. ? (that you build your self)
Note that:
"If you pass the -no-undefined and --enable-runtime-pseudo-reloc options to the linker, you don't have to add dllimport or dllexport attributes to the source code that the DLL is made with"
(from the link)
So not always needed.Basically its a system to hide/show symbols from the DLL. If they are not exported they are private to the DLL.
https://msdn.microsoft.com/en-us/library/ms235636.aspx - File object is used in essentially every app I've every made
-
@drmhkelley said in Undefined reference to ...:
hi
MinGW compiler and set it as the default kit
This mingw compiler is ca the same as used in Qt? Qt dlls are build with a certain version and if
too big version difference, it might not work.Cant you use the version that comes with Qt?
-
Thanks for your help
In order ...
I don't directly include the .cpp files, but I do of course use the .h files. The compiler finds them via an appropriate "-Isomeincludelocation" argument. The dlls (or libs as desired) are found as in the example I provided through "-Lliblocation -llibrary" arguments. I have never seen or used the "-no-undefined" and "--enable-runtime-pseudo-reloc" that you mention. Somehow, they have always (until now) been found and used.
I am uncertain which version of MinGW I have, but I think it was the up-to-date version as of about November last year - haven;t specifically followed it. However, since it appears that I have to keep all libraries concurrently up-to-date, wouldn't I be better off just having one compiler - the one that Qt insists upon? I think I've had to download everything else as source code and build it locally. Unless I can do that with Qt, sounds like Qt wants to be in charge of all my library builds.
-
Hi
Np.
Maybe mingw default exports all symbols. Sounds like you never used the macros
and still used dlls? :)
https://stackoverflow.com/questions/22285240/mingw-use-declspecdllexport-or-attribute-visibilitydefault- wouldn't I be better off just having one compiler - the one that Qt insists upon? I
Yes you would. There are compatible to a point but a DLL made with a much different compiler version might not load in another.
Since Qt is made of Dlls, at some point the precompiled
Qt wont work with a different version of the compiler.
This rules applies when you want to use classes from the Dlls.
You can make a c api type DLL that exports functions and use with
any other compiler or even language. - wouldn't I be better off just having one compiler - the one that Qt insists upon? I
-
Hi,
To add to @mrjj, the problem with multiple compilers on Windows is that they all mangle the C++ symbol differently not to mention that import/export stuff which Qt provide macros to help with (See the Creating a Shared Library chapter of Qt's documentation). Thus basically, they are not compatible one with the other. The only exception is Visual Studio 2017 which is backward compatible with Visual Studio 2015.
That's why most of the pre-compiled SDKs usually provide two or more versions of their .dll and .lib files depending on how many compiler they want/can support.
Qt doesn't impose nor does it want to take in charge anything particular, it's working under the same constraints as other C++ frameworks.
-
All issues resolved.
For completeness, there were two largely independent suggestions made to resolve the undefined references.
-
Make sure the same compiler is used both for building the Qt libraries and for building my projects. The Qt 5.9.1 libraries as downloaded were compiled with MinGw version 5.3.0 - but my installed MinGw is version 6.3.x. That mismatch was the problem. I implemented and verified two solutions to this. First, I tweaked my PATH environmental variable to compile all personal libraries with the Qt-delivered g++. That resolved the issue. Second, I built Qt 5.9.1 from source using my installed and more recent versing of g++ from MinGW 6.3.x. IMPORTANT NOTE: There was a bug in one obscure header file that I had do fix in order for Qt to compile. I was also NOT able to build the qtlocation package - I don't need it and haven't tried to resolve that. I then defined a kit in QtCreator to use those newly build Qt libraries and my usual collection of personal libraries.
-
That was a lot of noise about "__declspec(dllexport)" and other sorts of tweaks to my library source code. All that led me down an unnecessary rabbit hole. I've never used or needed any of that stuff and still don't. All my libraries work just fine without that additional confusing complexity.
-