Auto linking dependencies of a static lib - c++

I have a static lib A, which also uses static libs B, C and D.
I then have applications X and Y which both use A, but not B, C or D.
Is there some way to make it so X and Y will automatically see that A used B, C and D and link them, so that I don't need to keep track for the entire dependency tree so I can explicitly pass every static lib (quite a lot with things like Windows, Boost, etc)?

Static libraries do not link with other static libraries. Only when building the executable (or shared library/DLL) is linkage performed, and the way to keep track of this is (of course) to use make.

I think, conceptually, you might be able to merge libs together to achieve what you want - they are after simply collections of symbols ready made for the linker. Having said that, I've never seen a tool to do it. The binary format of a lib is a compiler matter, so it would have to be a mingw or gcc specific tool.
In terms of knowing which version of Boost lib A uses, there isn't really much for it but to find the documentation for A.

The easy way is to always offer the particular libraries A, B, C, and D to be linked. For a true library, the linker only retrieves the modules needed.
The key problem with A having some implicit linkage to other libraries is that they aren't necessarily uniquely identifiable. For example, should it use version 2.0 or 3.1? The one in /usr/share/lib or the one in /usr/lib/X11/xdm/share/lib? Etc.

Related

Is there something like maven-shade-plugin in C or C++ when linking?

I know when building Java programs, we can use maven-shade-plugin to resolve dependency confliction.
For example, if B depends on library A(version 1) and C depends on library A(version 2), both B and C can't build with the given version of library A, like the following
Though there doesn't exists one version A that satisfy both B and C, we can pacakge diffenrent versions of A into one executive. For example, we can rename library A of version 1 to A_v1, so if A.x exists in library A, it can be referred as A_v1.x. We can do the same to library A of version 2 by renaming it to A_v2.
Then, I find C/C++'s compile/link building procedure has similar aspects because it will also define and search symbols, so I am wondering if there are some ways to enable multiple version of one library be linked into one executive, by renaming tokens.
I will take the C library as an example. The function printf can be firstly renamed into version_2_12_0_printf or version_2_13_0_printf before linking, and the linker can somehow find location of the correct version of printf and link.

Library linking in C++, dependence between three libraries

This might be a weird / beginners question for someone. However I have the following situation.
In my code, I am creating three libraries, lets say A,B and C. In library B i am linking library A, so something like target_link_libraries(... A).
My C library is linking against B. So I have:
B -> A
C -> B.
Should it then be possible, that I use methods, enums whatever defined in library A also in C? Although C is not linking A explicitly? I was using an enum defined in library A in C, A::someClass::someEnum and it compiled and showed correct value entries.
Should it then be possible, that I use methods, enums whatever defined in library A also in C?
Does your C library uses these methods/enums/etc. via including a header from the library A or from the library B?
If C directly includes the header from the library A, then it should be linked with the library A explicitly:
# A is a private linkage of B.
target_link_libraries(B PRIVATE A)
# C needs to be linked with A
target_link_libraries(C B A)
If C includes the header from the library B, which in turn includes the header from the library A, then A library should be a part of the B interface:
# B links with A and this linkage is an interface of B
target_link_libraries(B PUBLIC A)
# C may link with B only
target_link_libraries(C B)
These approaches assume "modern" (target-oriented) CMake to be used. But using these approaches one would get most scalable solution.
Remember that linkage dependency and compilation dependency are not the same thing.
It's quite possible that the sources of library C use definitions from headers associated with library A... irrespective of whether C depends on A when linking.
Now, in CMake, we use target_link_libraries() not only for linking. This CMake command makes sure that the library's headers are available to the dependent target, for compilation, and that its libraries are available for linking.
It's also possible for library C to require library A for linking - to have the definitions of, say, functions or variables from library A. Libraries can theoretically have circular link dependencies (which means that you need to either link against the entire circle, or no part of it).

On Chained static library, Do i have to add all libraries chained?

I made static library A, the library is using another static library B.
And in order to use library A in code C, i added library A and header A but B.
Because i have known that static library is combined in compile time, so library B is already contained within A.
But When i compile code C, it seem to require that i add library B also showing undefined reference error.
And when i add library B also, the error disappear.
Why ?
You'll need to add both A and B.
When static lib A uses static lib B, B is absolutely NOT combined in A. That is impossible since when generating static libraries there is no link step.
This is the difference between shared and static libraries on Linux.
If your library is written well, you may not need to add B headers in code C, but when linking, (executable or shared library or even DLL in windows) you'll need all used static libraries.

Calling C/C++ functions in dynamic and static libraries in D

I'm having trouble wrapping my head around how to interface with C/C++ libraries, both static (.lib/.a) and dynamic (.dll/.so), in D. From what I understand, it's possible to tell the DMD compiler to link with .lib files, and that you can convert .dll files to .lib with the implib tool that Digital Mars provides. In addition, I've come across this page, which implies being able to call functions in .dlls by converting C header files to D interface files. Are both of these methods equivalent? Would these same methods work for Unix library files? Also, how would one reference functions, enums, etc from these libraries, and how would one tell their D compiler to link with these libs (I'm using VisualD, specifically)? If anyone could provide some examples of referencing .lib, .dll, .a, and .so files from D code, I'd be most grateful.
Note you are dealing with three phases for generating an executable. During compilation you are creating object files (.lib/.a are just archives of object files). Once these files are created you use a Linker to put all the pieces together. When dealing with dynamic libraries (.dll, .so) there is the extra step of loading the library when the program starts/during run-time.
During compilation the compiler only needs to be aware of what you are using, it doesn't care if it is implemented. This is where the D interface files come in and are kind of equivalent to Header Files in this respect. Enumerations are declared in the D interface file and must also be defined because they only exist at compile time. Functions and variables can just be declared with no body.
int myFunction(char* str);
The guide for converting a header file to D is in the page you referenced. These files can then be passed to the compiler or exist in the Include Path.
When the linker runs is when you'll need the .lib/.a file. These files can be passed to the compiler which will forward them to the Linker or you can use pragma(lib, "my.lib"); in your program. In both cases the linker must be able to finding at link time (compilation).
In Linux I don't believe there is a difference for linking dynamic and static. In Windows you don't even need the D interface file. Instead you must obtain the function through system calls. I'm really not that familiar with this area, but I suggest Loading Plugins (DLLs) on-the-fly
Update: I can't help much with VisualD, but there is D for .NET Programmers.
There samples in D distribution of how to do this.
You need to define thunk module like this:
module harmonia.native.win32;
version(build) { pragma(nolink); }
export int DialogBoxParamA(HINSTANCE hInstance, LPCSTR lpTemplateName,
HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam);
and include import libs of DLLs where functions like DialogBoxParamA are defined.

Do static libraries, which depend on other slibs need the actual 'code' from them to work?

Sorry about the vague question title, I just want to ascertain some things.
Static libraries don't link with other static libraries, right?
So when I write a slib: A, that uses functionality of another: B, all I have to provide are the headers of B to A, and only those, even if A actually uses functionality from B?
Yes?
As long as exe: X, which uses A,has B.lib specified as linker input?
So that at link time, the linker takes A.lib, which basically only knows that a function of B was called somewhere inside its code, and somehow fills that information from B.lib, making A.lib 'whole', before X gets linked with the now working parts of it?
The motivation behind these questions is to get rid of some linker warnings 4006 and discarded double definitions, and I think that should do the trick, if this is actually a valid way of doing it.
Yes, you have got it pretty much right. Executables (and DLLs) which depend on static libraries cannot be created without those dependencies being resolved, but static libraries that contain dependencies on other static libraries do not require those dependencies to be resolved at static library creation time. In fact, the process of creating a static library does not involve the linker at all.
Can't really add the Neils answer except to say that a static library is really just a whole bunch of object (.o) files collected into a single indexed file. So what works for a .o file will work for a static library.