Link external library with MSCV compiler
-
Hi everyone,
as a result of this question I switched from MinGW to MSCV to getQtBluetooth
working on Windows. This, however, resulted in a new problem: In my application I have an external library linked to the program using this code in the .pro file:LIBS += -L$$PWD/armadillo-3.930.0/lib/ -lblas_win32_MT LIBS += -L$$PWD/armadillo-3.930.0/lib/ -llapack_win32_MT
When I run the app with the MSCV compiler I get loads of
unresolved external symbol
errors from this library. I have read this is due to 'symbol visibilty' and that MSVC does not export any symbols by default in contrast to MinGW. This blog post provides more information on the topic.So my question is how can I make it work? How can I make MSCV recognize the library in Qt?
Thanks!
EDIT (more info):
in the lib file I have both .dll and .lib file, so the library should be MSCV compatible.An excerpt of the errors:
error: LNK2019: unresolved external symbol sdot_ referenced in function "double __cdecl arma::blas::dot<double>(unsigned int,double const *,double const *)" (??$dot@N@blas@arma@@YANIPEBN0@Z) error: LNK2019: unresolved external symbol ddot_ referenced in function "double __cdecl arma::blas::dot<double>(unsigned int,double const *,double const *)" (??$dot@N@blas@arma@@YANIPEBN0@Z) error: LNK2019: unresolved external symbol sgemv_ referenced in function "void __cdecl arma::blas::gemv<double>(char const *,int const *,int const *,double const *,double const *,int const *,double const *,int const *,double const *,double *,int const *)" (??$gemv@N@blas@arma@@YAXPEBDPEBH1PEBN21212PEAN1@Z) error: LNK1120: 28 unresolved externals
-
@JonB I think this is the problem and I think you are right. I just have very little experience with compilers and linkers. I assume the libraries are compiled with MinGW, because this was the compiler I switched from. Is there a way to compile them again for MSCV?
-
@elsa
I assumed they were MinGW because you used to have that working. If the third-party library is not offered in MSVC (.LIB
) form, you'd have to get the sources and try compiling the whole thing with MSVC, which I'm sure you won't want/can't do.I'll have a quick look around to see if you can combine MinGW libraries (are those
.a
instead of.lib
?) with MSVC stuff, but if I don't get back soon, I haven't found anything...EDIT Well you can start out reading the whole of https://stackoverflow.com/questions/2529770/how-to-use-libraries-compiled-with-mingw-in-msvc. I don't like the look of:
The libraries are compatible, but only if you supply a C interface. MSVC and g++ use different name-mangling schemes, so you cannot easily link C++ code created with one with code created by the other.
Finally, this mixed MinGW and Visual C++ linking generally works but for C modules and it does not work for C++, as far as I know.
And on our forum here, https://forum.qt.io/topic/75458/compatibility-libraries-generated-by-msvc-and-mingw , the venerable @SGaist wrote:
on Windows you can't mix and match libraries compiled with different compilers even if they all use Visual Studio. You have to build everything using the same compiler.
-
@JonB how do I do this? The code mentioned in my question was used for MinGW and doesn't work for MSCV, so how can I modify it? (I think these two lines link the .dll files, which are compatible with MinGW afaik, and for MSCV we need to explicitly tell it to choose the .lib files) You traditionally do not write the endings of the file name, so how can i specify it?
(and sorry for not replying right away, I can only post every 600s -.-) -
@elsa
I'm going to have to bow out, because I haven't used MinGW, I don't use Qt Creator/cmake
/C++, someone else may know better than I.I will say, I'm confused, because if the libraries are from that page it only talks about MSVC, so I don't even know how MinGW came into it.
I think you should:
- Establish what/where your library files, and whether they are MSVC or MinGW.
- Make sure however you configure your project to generate linker lines it's using the right linker and command-line options for whatever the correct files for it are. When you changed over from MinGW to MSVC you must have had to re-configure the makes from scratch I imagine, telling it which compiler/linker you're using, I imagine. I don't know, but those link library lines you show still look a bit gcc rather than msvc/link to me, but I could be mistaken.
- Make sure your "unresolved"s are not because you are actually trying to call any functions which are not documented as exported from the third-party libraries.
- Maybe find a couple of "typical" examples of the "unresolved external symbol errors" you are getting and show them here. It may give us an idea of just what sort of thing it's trying to find.
-
Hi
From page
http://arma.sourceforge.net/download.html
seems they used VS 2012.Did you compile a new version with the new visual studio ( i assume you didn't use 2012) and new VS cannot load old VS dlls.
what version of VS did u use ?
-
In https://forum.qt.io/topic/75458/compatibility-libraries-generated-by-msvc-and-mingw/3 @SGaist also wrote
Thus if any of your dependencies needs a particular version of VS, you have to stay with it.
@elsa Please do show some examples of the error messages.
-
@elsa
OK, at least that confirms the unresolveds are indeed from your libraries and not from, say, remaining references somewhere to MinGW functions. FWIW, those are "mangled" names which come from references to C++ functions.I think you should work through the points I suggested. In particular it's now unclear how come MinGW ever came into it/worked, since the third-party link you provided talked only about MSVC....
-
@JonB said in Link external library with MSCV compiler:
- Make sure however you configure your project to generate linker lines it's using the right linker and command-line options for whatever the correct files for it are. When you changed over from MinGW to MSVC you must have had to re-configure the makes from scratch I imagine, telling it which compiler/linker you're using, I imagine. I don't know, but those link library lines you show still look a bit gcc rather than msvc/link to me, but I could be mistaken.
how does MSCV linking look like? and by "reconfigure" you mean choosing the new kit/compiler and running qmake or is there something else?
-
@elsa
I'm not sure about the MSVC command-line. I was thinking it would useLINK
and have something like/LIB
and/or mention ofblas_win32_MT.LIB
, I'm niggled by the suspicion it's still trying to link with MinGW libraries, but I'm not sure. You could look at/show the actual linker line that's being executed?Yes, you needed to pick new compiler/linker kit and re-run
qmake
, or similar. It's very important that you cleaned everything out --- perferably restarted in a clean folder --- as you don't want any artefacts left over from old compiler/configuration. If it were me, at this point I'd be tempted to set up a brand new project in a new directory which just makes a couple of calls to those libraries and get it all working with MSVC from scratch.P.S.
blas_win32_MT
,lapack_win32_MT
: Apart from the fact that you need to check you're compiling & linking your code with/MT
, those must be 32-bit libraries. You are compiling your code for 32-bit too, right? -
@JonB said in Link external library with MSCV compiler:
@elsa
I'm not sure about the MSVC command-line. I was thinking it would useLINK
and have something like/LIB
and/or mention ofblas_win32_MT.LIB
, I'm niggled by the suspicion it's still trying to link with MinGW libraries, but I'm not sure. You could look at/show the actual linker line that's being executed?I thought this is just the line from the .pro file that I linked in the question. Is linking also defined somewhere else?
P.S.
blas_win32_MT
,lapack_win32_MT
: Apart from the fact that you need to check you're compiling & linking your code with/MT
, those must be 32-bit libraries. You are compiling your code for 32-bit too, right?Okay maybe this is the problem!
BIG UPDATE: The above mentioned errors get produced using the 64bit compiler, which -now that you say it- maybe explains why it doesn't work..
The weird thing is, however, when running the 32 bit compiler I get the following error:error: LNK1112: module machine type 'x86' conflicts with target machine type 'x64'
so I am confused now. Is 32bit or 64bit correct?
-
I thought this is just the line from the .pro file that I linked in the question. Is linking also defined somewhere else?
All you have shown is a
LIBS += ...
line in a.pro
file. When you compile (link) it must also show the actual command-line it has constructed and is executing using these, presumably in whatever "compiler output window" it has.error: LNK1112: module machine type 'x86' conflicts with target machine type 'x64'
so I am confused now. Is 32bit or 64bit correct?
x86
means 32-bit,x64
means 64-bit. Assuming from the names that those libraries you have are compiled 32-bit, you must compile everything else 32-bit (or get/compile 64-bit version of the libraries). The fact that you have a messagetarget machine type 'x64'
must indicate that somewhere you have told Qt Creator (the.pro
file?) that your target is 64-bit, and that does not look good.... -
All you have shown is a LIBS += ... line in a .pro file. When you compile (link) it must also show the actual command-line it has constructed and is executing using these, presumably in whatever "compiler output window" it has.
link /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST:embed /OUT:debug\DecaRangeRTLS.exe @C:\Users\FRHMELSA\AppData\Local\Temp\DecaRangeRTLS.exe.10468.50531.jom
x86
means 32-bit,x64
means 64-bit. Assuming from the names that those libraries you have are compiled 32-bit, you must compile everything else 32-bit (or get/compile 64-bit version of the libraries). The fact that you have a messagetarget machine type 'x64'
must indicate that somewhere you have told Qt Creator (the.pro
file?) that your target is 64-bit, and that does not look good....yes I have reached that assumption as well, but then how do I change the target machine type? :/
-
@elsa
I don't know in Qt Creator, but it can hardly be difficult, presumably you specify it at some point when you set up your project. Google for it.Unless the error is from one of your libraries already being compiled 64-bit. Check whether those libraries with
win32
in them are indeed 32-bit, not 64-bit.Come on, you can do this, I can't answer!
-
@elsa said in Link external library with MSCV compiler:
but then how do I change the target machine type?
Use Qt for that target machine type