How to get a .lib file instead of a .dll? [SOLVED]
-
Hi,
dll and lib are not the same thing.
In the shared case the *.dll contains the shared code and is loaded at run time and the *.lib contains the binary interface to link to
In the static case the .lib contains the binary code to link to so no external loading at runtime
-
O now it made sense... But why Qt creator's "Add library..." Option only wants *.lib files? In Linux I simply select the *.so file and it imports it for me. If *.so is somewhat like *.dll, why can't Qt creator just add *.dll files?
It's not a big issue actually... Just curious. I know how to manually add it in the *.pro file.
-
It's because it's against the lib file that you link whether it provides the interface or the code doesn't matter.
@LIBS +=
-Lpath_to_where_you_lib_file_is
-lyour_lib_name_without_the_extension@ -
SGaist, I read up about it(http://www.daniweb.com/software-development/cpp/threads/391439/regarding-.lib-and-.dll-files) but I... don't understand your reply.
I know *.lib files are import libraries that are only available with MSVC2010... but it doesn't seem to be a difference whether that *.lib file existed or not, and that Qt Creator should let me select *.dll files in the "add library..." option and have a bunch of code automatically added to my *.pro file.
Is there a difference whether there's a *.lib file?
-
Yes there is, you don't link against dlls.
If you don't have the import libraries, you can't compile your code. On the other side, if you have the import lib but not the dlls, you'll be able to compile but not run your application.
Windows/Linux don't work the same for dynamic libraries handling. Even if both type of files are loaded at runtime, the rest is different.
I hope I haven't made myself unclearer :)
-
haha! I think I'm getting a clearer picture.
I think.
so I'm assuming this: If I compile the library with MinGW, I don't need the *.lib files and just *.dll files would work(actually MinGW doesn't even process out *.lib files). However if I use a MSCV2010 compiler I would need *.lib AND *.dll files!!
...right?
-
No! That's completely wrong.
.dll is the file that holds the actual executable code.
You can take any dll from your computer, load it into your program with LoadLibrary , get the memory address of the function inside it with GetProcAddress and call it.But! You wouldn't want to do this every little time you need to call a library function.
To help with this a library can be distributed with sort of a "glue code", that does all this for you and exposes nice interface. To make this possible this "glue code" is statically linked into your executable. Each compiler compiles code into it's own intermediate binary format before passing it to the linker. The "glue code" is distributed in that intermediate format.
MSVC uses .lib files for that.
MinGW(GCC) uses .a files (although it understands .lib files too!(in most cases)).When you add library to a project the only thing a linker needs is the "glue code" in the .lib or .a file that is statically linked into the produced executable. It doesn't need .dll at that point. Those are needed to run the final program but not to compile and link it. .dll files are already compiled and linked.
So, when you add a library through a wizard(I personally never use it) it's the same as manually entering a
LIBS +=
statement in your .pro file. This tells qmake to tell linker to look for that .lib when linking functions from the external library.Apart from that, Qt has a shortcut for it's own libraries, so when you see a
QT += core
in your .pro file it's like adding
LIBS += -LC:\PathToQt\lib\ -lcore
So, to summarize:
When you have an external library, these are your options:- if library ships code: just include and use as any other .h/.cpp
- if library ships only dlls(rarely): manually load at runtime with LoadLibrary/GetProcAddress (or the QLibrary class equivalent) and use. Nothing is needed at compile/link time, .dll is needed at runtime.
- if library ships with headers, .lib/.a and .dll (most common): include headers, link .lib/.a via wizard or by manually adding
LIBS +=
. Headers are needed at compile time, .lib/.a at link time and .dll is needed at runtime. - if library ships only headers and .lib/.a (somewhat common): include headers, link to .lib/.a. In this case .lib/.a holds the actual executable code, so it's a little different then the .lib/.dll combo. In this case nothing is needed at runtime.
Case 2 is called dynamic linking. Case 4 is called static linking. Case 3 is a mix of those. You can find a ton of info about advantages and shortcomings of those solutions on the web.
-
uh... I still don't get it. What you're saying(if I'm not mistaken) is that I need the *.a file when I compiled the library from MinGW or *.lib file if from MVCS2010. So yea, the library compiled out a mylibrary.dll and a libmylibrary.a as expected.
What I did was put the header files and the *.dll inside a folder and add the LIBS+= in my pro file. It compiles happily, though I have to put a copy of the .dll file next to my resulting executable. So libmylibrary.a is just doing nothing.
Here's smth strange: When I add on libmylibrary.a attempted to change -lmylibrary to -llibmylibrary to the name of my library the compiler tells me it couldn't find it.
I've been testing this for some time(clean and rebuilding) and results are the same.
So the conclusion was there is an option 5, in which it was provided just the dll and the header files. So like "hey, I don't need that *.a file! That's convenient!". Idk... the "link time" thing doesn't seem to be happening. Did I do something wrong? Then again, there was only 1 *.dll.
It would seem to me also, that a *.dll or a *.so is simply all the *.cpp files clumped up together so that all the implementation details are hidden, since I could replace the *.cpp files with a single *.dll. Hope I got that one right! >_<
-
Well... It depends on your compiler... MinGW has several"wiki":http://www.mingw.org/wiki/DLL pages on the subject that might help you understand how it works.
As for the -l you usually give the library name (the one you set in TARGET), the lib prefix is appended automagically.
Option 5 depends heavily on the "target audience" of your lib.
-
Are you actually pulling any symbols from that library? Like call a function? If not, then it doesn't matter if you link the .a or not.
Also, where do you keep the .a and .dll and how exacly are you adding them to your project? If you keep them in the same directory and do LIBS += -lmylibrary it will link the .a file, not the .dllI did a little research and it seems that there is indeed option 5 (in MinGW only) : "MinGW page":http://www.mingw.org/wiki/CreateImportLibraries , but it's not really a common scenario on Windows. Additionally, if I understand it correctly, it works only with MinGW generated .dlls.
.dll is not a bunch o .cpps.
.cpp is a text file with C++ source code.
.dll are more like .exe files( actually it's "the same format":http://en.wikipedia.org/wiki/Portable_Executable ), and they contain compiled and linked binary executable code from any language, be it delphi, C++, assembler or anything else. -
Here you have an example of a pro file which creates a static library (meant to use with mingw, VC requires some extra ifndef stuff in your classes).
Simply add your own files and output names for debug and release, then compile.@QT -= gui
CONFIG += staticlib
CONFIG(debug,debug|release) {
TARGET = MLpkgd
} else {
TARGET = MLpkg
DEFINES += QT_NO_DEBUG_OUTPUT
}CONFIG += debug_and_release
CONFIG += build_allTEMPLATE = lib
SOURCES +=
../../src/MLpkgLib/Package.cpp \HEADERS +=
../../src/MLpkgLib/Package.h @ -
Krzysztof: I'm calling static methods and instantiating objects via header files. I keep the *.dll(and toss the *.a file away. Yay option 5!!) in folder in which I set LIB+= and depend include path there. A piece of the *.pro file:
@
note that in unix(linux) systems library names are case sensitive
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/build-MyLibrary/ -lmylibrary
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/build-MyLibrary/ -lmylibrary
else:unix: LIBS += -L$$PWD/build-MyLibrary/ -lMyLibraryINCLUDEPATH += $$PWD/build-MyLibrary
DEPENDPATH += $$PWD/build-MyLibrary
@...and I finally understood *.lib and *.a and *.dll(an executable that doesn't run but helps other executables to run) and *.so... I know it's tough to explain things to a novice... so thanks everyone! Really appreciate your time! :D