Cmake, .lib, dll and avoiding multiple .lib copies inside binary - c++

All in all, what I want is to avoid duplicate .lib files in several .dlls since the generated .dlls will be used together in a .exe file and this makes global state duplicated in the .lib file duplicated.
Concrete Problem:
I have a project with 3 libraries and one .exe:
libDependentA.dll
libDependentB.dll
libIndependent.lib -- static library
The dependencies are as follow:
libDependentA.dll -- depends on -> libIndependent.lib
libDependentB.dll -- depends on -> libIndependent.lib
I have an .exe. Depends on both libDependentA.dll and libDependentB.dll
This makes two copies of my .lib into the .exe, which is what is causing problems.
Solutions?
Preferred solution. Don't know if possible, when googling no info.
Make a .dll out of the libIndependent.lib. How can I do this? I couldn't make a dll out of .lib files in cmake through add_libary(newdllfromlib SHARED). It has no source files dependencies and I tried to target_link_libraries into
newdllfromlib. Is there an easy way without using empty source files or other tricks?
Make libDependentB.dll depend only in libDependentA.dll and remove libIndependent.lib from libDependentB.dll. How can I do that in cmake? The problem here seems to be that cmake transitively propagates to all the other places libIndependent.lib, including the .exe, if it appears in target_link_libraries(libDependentA.... If I add LINK_PRIVATE, then, I cannot set up the configuration I want in cmake, because I must link libIndependent.lib again into the libDependentB.dll. Anyway to do it?

Duplication of symbols in .dlls from linked static libraries is what static libraries are supposed to do. If the static library libIndependent is 3rd party code, then the developers of libIndependent probably have some reason why they chosen the static library and not a dynamic library.
If you use symbols from libIndependent in both libDependentA and libDependentB and you do not have source code of libIndependent, the short answer is that you cannot do it directly. Static libraries are usually build with different set of flags/defines than shared libraries (most obvious is exporting the symbols dllexport / dllimport as you noted). You can export some libIndependent symbols from libDependentA by def file. But usually only symbols that are used in dll are present in the library (libDependentA) and you can run into various other problems.
However you can create a shared library wrapper libIndependentWrapper.dll, where you create a wrapper function for every function from libIndependent you need. The wrapper functions would have new header with dllexport / dllimport.

Related

Is it possible to link lib dynamically like a DLL?

This is interview question.
Is it possible to link lib dynamically like a DLL ?
For example, for DLL, we use LoadLibrary and call exported functions.
Is it possible to use lib file in same manner?
No. .lib library are statically linked, and that is the purpose they're created for, to resolve the name symbols at link-time by Linker, and link-time occurs before runtime. They're often referred to as "static libraries" (that is why I added this tag in your question!). That is the brief story of lib.
However, you can create a DLL wrapper, if you really want to link at runtime.
No. Create a DLL instead or, if you do not have the source, wrap the functionality in the .lib with own DLL interface.
No. It's not possible. A DLL is module with a PE32 header with all information to load it into a process. A LIB is only a archive of OBJ files.
And despite others say it's easy to wrap a DLL around it, this can be quite difficult. The reason is, that a .LIB not only resolves some dependencies but can also have unresolved externals.
As long as these unresolved externals require only the compiler's runtime library wrapping in a DLL might work. You can check this when you create a DLL project, probably with a minimal C++ source, and try to compile. Than you see, if further externals must be resolved with other libraries.
One important problem may arise with memory management. When yo link statically with a .LIB you will use all the same definitions. If your library comes with own implementation, let's say of malloc-stlye functions, this will not be linked to your application as long as you add all these symbols to the EXPORT list. Finding the list of public symbols that should be included in the EXPORT table may be a pain.
Yes - not directly, but with a very small amount of work.
Create a new .DLL project, link the .lib, define which functions you want to export in a .DEF file then compile.

Static library with dependencies

e.exe is linked against my custom static library, c.lib, which uses Win32 API defined in w.dll. w.dll is located in C:\Windows\System32 and its import library is w.lib, located in Windows SDK directory. Shell w.lib be listed as Additional Dependency in c.lib or e.exe project? (e.exe builds successfully in both cases.) What is the best practice and why? I guess e.exe should not know about w.lib.
c.lib is intended to be shared among a group of developers only (not to be shipped to customers).
TEST: I used VS2008 and dumpbin utility to test both cases and here are results:
Case 1: w.lib added as Additional Dependency in c.lib project.
dumpbin /archivemembers c.lib output lists both offsets in w.dll and .obj files from c.lib project as Archive members.
Case 2: w.lib not added as Additional Dependency in c.lib but in e.exe project:
This time, dumpbin output contains only .obj files of c.lib and the size of c.lib is smaller than in Case 1
(c.lib was added as Additional Dependency in w.exe project in both cases.)
NOTE: I used w.lib and w.dll here as fictional, generic names for Windows libraries but they could be e.g. Userenv.lib and Userenv.dll or Version.lib and Version.dll...
I think you're misunderstanding what creating an archive and an import archive does.
Creating an archive, as you've rightly surmised in comments, creates a unified file containing compiled .objs. Now, this can contain any code you like, including but not limited to dynamic calls to libraries. An import library is a library that contains an obj that exclusively makes such calls, the idea being that by importing it, your exe can find the appropriate symbols (they must be in the executable you create).
The process of creating c.lib from w.lib simply extracts w.lib's objects and appends them to the collection of objects in c.lib. In effect, c.lib becomes an import library + code.
Do I think you should do this? Not really - it might lead to confusion as to what e.exe depends on; I think you should explicitly make this visible rather than trying to hide it. That said, that's a recommendation only, not a rule.
Libraries are not linked, so any project that uses a .lib also needs its dependencies.
Basically the .lib are "copied" to your exe during linking.
If you want to avoid your users to explicity link againts w.lib, transforms c.lib in a dll, dlls are linked and you do not need their dependencies during build.

No additional dependencies required for a LIB but are required for a DLL

I have a framework (in C++) which is dependent on a few third party libraries. When I compile a static version of the library framework, no additional dependencies are needed, that is, the lib files of the third part libraries are not needed. When I compile the same framework as a DLL, additional dependencies are now needed otherwise I get linking errors. I can guess as to why this is happening but would like a concrete answer/explanation to understand what is happening.
EDIT: Just to clarify, I am developing a framework which can be compiled as a lib and as a dll and then used in a(n) (executable) project. When compiling the framework as a lib and using functions from a third party library, I don't need additional dependencies. However, a project that now uses the lib file (which is the framework) must include the 3rd party lib files. When I compile the framework as a dll it gives me linking errors unless I specify the 3rd part libraries the framework is technically dependent on. For example: I have a few classes that call functionality from within Ogre3D. These classes are compiled as a lib file. I don't need to link against OgreMain.lib when compiling a lib of the classes. On the other hand, when I am compiling a dll version of the same classes, I now need to link against OgreMain.lib
When you have a static library (a .lib file), which is just a collection of one or more object files (.obj), the linker just adds that code to yours in one executable. You can tell the linker to do this via a command line switch, an IDE configuration setting, or perhaps even a #pragma (specifics depend on your environment and compiler).
When you link in a DLL, you need to give the linker some code to call when you invoke one of the DLLs functions. Usually, this is done with a file of the same name as the .dll, save that it is a .lib. The code in that .lib is linked into your program the same way as described above, but when you call it, it loads the DLL (if not already loaded) and then invokes the proper function.
There are other ways to handle DLL linking (for instance, .def files or #using statements in .NET), but this seems to be what you're talking about.
Responding to your question clarification:
The issue is that a .lib is not a final product. It is just an aggregation of object code to be used later when a linker connects all your functions calls to function addresses.
A DLL, on the other hand, is a final product, and so the linker requires all functions and variables be connected to actual addresses.
I'm speaking a bit imprecisely, but you get the idea.
A static library can include other static libraries, providing a single lib to link
A DLL can include static libraries, providing a single DLL to link.
A DLL or static library with dependencies on other DLLs has no way to combine them so your executable must explicitly link to those other DLLs.
When you link to a LIB it adds all the symbols/functions you actually use to your executable. The ones you don't use won't get added. When you link to a dll - all the code from the external library gets loaded. If this additional code (code you don't use) depends on more external libraries you need to provide these as well.
One example: You want to use a ip class from a network library. The ip class does not depend on other libraries. Other functions in the network library depend on other external libraries. If you link the network library as a LIB you just link the ip class -> you don't need the other libraries since the other code wont get linked. When you use the DLL all code in the dll need to be instanciated -> so you will need to provide the other external libraries.
Building a DLL is more like building an application than a library. The difference between building an application and a DLL is knowledge of what might be called. In an application all symbols that are not used can be discarded in the build, but in a DLL you cannot strip symbols that are not used - that would be all of them...
You would find the same link problems in your static libraries if you where able to call all the symbols that the DLL links.

Why dll can't be used in c++?

It's pointed out by this answer:
Failed to link mysql5.1.39\bin\libmySQL.dll
But I don't understand why,.dll is essentially the same as .lib except for there is only one copy of it used by different processes.
Does it have anything to do with the IDE?I'm using visual c++ 2008 express
UPDATE
Anyone know a free tool to convert .dll into .lib in windows?
You are wrong on two counts. Firstly, DLLs and LIBs (static libraries) are very different beasts. The LIB you are talking about (I think) is the export library, which is simply a list of names in the DLL. This library is typically produced when the DLL is compiled and is shipped with the DLL if the DLL is intended to be linked to by other developers.
To use a DLL with a modern IDE (I don't use VS) you typically include the matching .LIB (export library) in the project. At run-time you must make sure the DLL is available to your program - the simplest way to do this is to put the DLL in the same directory as the executable.
And secondly, DLLs can be used with C++.
DLL are specific windows executables which load on runtime. Their equivalent in Linux is the *.so .
If you want to understand what's the difference between a DLL and a static lib see here.
Main reason has probably something to do with dll-file being an output of the linker (link.exe). This command line utility doesnt know how to read dlls, only how to write them.
Actually sometimes .lib-files contain more than a list of functions. For example libpng.lib works as a standalone file, without any dll file.
In order to use a DLL in C/C++ you need to link with what is called an import lib. This is a small .lib that contains the names/ordinals the DLL exports in a format that the linker understands. Once this has been linked in, the resulting binary will be able to use the DLL. If you do not have the appropriate import lib, your C/C++ compiler should come with a tool to generate one from the DLL.
You can use the following analogy to understand the difference between a dll and a lib file.
the dll is like the source .cpp file while the lib is the header .h file.
While this is not exactly true, the DLL holds the executable code while the LIB file tells the linker how to glue the code together.
It is also possible (in some cases) to generate the lib from the dll. Basically, all you need to know to call a function is the function entry point in the dll, the number of parameters and the size of each parameters. Sending relevant information is then your own problem.

Visual Studio: What exactly are lib files (used for)?

I'm learning C++ and came across those *.lib files that are obviously used by the linker. I had to set some additional dependencies for OpenGL.
What exactly are library files in this context used for?
What are their contents?
How are they generated?
Is there anything else worth knowing about them?
Or are they just nothing more than relocateable object code similiar to *.obj files?
In simple terms, yes - .lib files are just a collection of .obj files.
There is a slight complication on Windows that you can have two classes of lib files.
Static lib files essentially contain a collection of .obj and are linked with your program to provide all the functions inside the .lib. They are mainly a convenience to save you having as many files to deal with.
There are also stub .lib which provide just the definitions of functions which are contained in a .dll file.
The .lib file is used at compile time to tell the compiler what to expect from the function, but the code is loaded at run time from the dll.
.lib files are "libraries" and contain "collections" of compiled code so-to-speak. So it is a way to provide software components, without giving away the internal source-code for example. They can be generated as "output" of a "build" just like executables are.
The specific contents depend on your platform / development environment, but they will contain symbols for the linker to "hook up" function-calls provided by e.g. the header-file of the library.
Some libraries are "dynamic" (.DLL's on Windows), which means the "hooking" of function-calls is setup when the executable using the library is loaded, allowing the library implementation to be changed without rebuilding the executable.
One last thing. You say you're learning C++, and a common confusing point is, that "symbols" generated by C++ compilers are "mangled" (in order to allow e.g. function overloading), and this "mangling" is not standardized across different compilers, so libraries often resort to C for the "API" of the library (just like OpenGL), even though the library may be implemented in C++ internally.
I hope shed some light on .lib-files. Happy OpenGL coding :-)
What exactly are library files in this
context used for?
They are compiled and linked code just like your executable. They're called static libraries that other programs can link to at compile time. In the case of OpenGL, you link to their libraries to build an executable that can run OpenGL code. Dynamic libraries (DLLs) are another type of library that executables link against, except at runtime.
What are their contents?
Static libs contain linked object code just like an exe. The *.obj files are the object code that the compiler generates for the linker.
How are they generated?
When the compiler creates the object files, it passes the work to the linker. You can create them in your development environment, just like executables.
Is there anything else worth knowing
about them?
Yeah, they're used everywhere, so it doesn't hurt to get used to them.