Unnecessary linked libraries in linker - c++

I have a project which I can exclude some of libraries from linker and still builds ?
Is it any better to exclude them in terms of the performance and memory of final product ?

A good c++ linker would not include any calls from any libs that are not used in the code (the so-called ¨dead-code stripping¨).
So, I would say it depends what kind of C++ linker you are using to emit the final release. Maybe you should refer to your linker documentation to get information on dead-code stripping. If it is not doing that, then it would definitely help reducing the final memory footprint of the program.
Cheers, and hope that info helps !

Excluding some unused libraries from the final executable might make startup a bit faster and save a tiny amount of memory - chances are only the header and library startup code will actually end up being loaded, and these can be paged out after startup.
However, don't do it manually. If you were told to add the library there's probably a reason for it - perhaps some function call you're not using yet requires it, and later on if you use that function call you may have forgotten about it.
Most linkers have an option to exclude unused libraries automatically, so you may want to just enable that option to have it take care of things for you.
Note: In some rare cases, the library's startup code might have some important effect, in which case you should not exclude it. This is something that is best determined by checking the library's documentation; things like this should (hopefully!) be clearly documented.

It should not make any difference.
Any linker of any worth will not include anything from libraries that are not (directly or indirectly) referenced by the application, even if those libraries are specified on the command line.
The only reasons to include (a part of) a library are:
- The application uses a function or global object from the library
- A part of a library that was included to resolve some references has a reference to a function or global object of this library.
A linker does not just blindly put all the things you provide together in an application, but it makes a distinction between object files (for the application) and libraries.
The linker first collects all the object files and resolves as many references that are made between the files.
After that, the linker goes through the specified libraries and takes from each library those parts that are needed to resolve the (known) unresolved references. This may create new unresolved references due to dependencies between the libraries. Most linkers will make only a single pass over the libraries, but some may perform multiple passes to resolve all the references.
Parts of libraries that are not needed to resolve a reference are not included in the executable.

Yes, it's always better to exclude the unneccessary libraries.

Related

Sharing C++ static libraries between multiple solutions causes unnecessary rebuild

I have two solutions that both include and reference the same static library. And I'm including the library using the "Add reference..." feature, as opposed to specifying additional an linker input. It seems as though when I build one of the solutions, it causes the other solution to think it needs to rebuild the shared library, which then causes it to re-link the second solution. Thus, if I go back and forth between the two solutions building (without making any code changes) the solutions perform the link every time.
It doesn't appear that the shared static library is actually being re-compiled, but VS is performing the librarian step for it. I'm guessing this librarian step is happening because the .lastbuildstate file (which contains a path to the solution that last build the project) is determined to be outdated.
Anybody ever experienced this problem before? Is there a better way to go about this?
If the library is really shared and independent from both solutions, I'd suggest moving it to a separate solution... I understand that's not really what you intended, but it seems logical by the nature of dependencies itself.
Another consideration in favor of this is that the library may be later used for other projects. Hence, it'd be totally better to move it to a separate location (separate solution, separate folder in VCS) and treat it as any third-party library (i.e. openssl, boost, etc), specifying the dependency as linker input.
All of the above is just my thoughts on how I'd do it and is not a representation of any "best practices".

Function doesn't get executed

I want to understand the following scenario as what exactly happens.
I have a shared library(A) which loads another shared library(B) by dynamic loading.
Library A exposes few methods(F1) as well.
The main program loads the library, A and then library A loads library B at later point.
Now When library B tries to uses function F1 from the library A, it fails to load its symbol, and compile stops execution silently without giving any warning/error or core. Even though I can see these symbols exported from the library A(using nm command).
I am not very sure what exactly happening. I observed this on Linux.64.
The same scenario on windows work.
My psychic debugging powers tell me that because you tagged this as C++ you're compiling C++ code. I also guess that you used slightly different options to compile libraries A and B, causing their name decoration and/or ABI to be incompatible, and thus the method(s) can't be found.
Have you considered just letting the linker apply all the shared objects to your application rather than using dlopen? Then you'd know straight away that there was a problem because the linker couldn't match the symbols.
Alternately perhaps Linux just doesn't like your circular library references: can you refactor your libraries to eliminate the circular dependency?

Why can CImg achieve this kind of effect?

The compilation is done on the fly :
only CImg functionalities really used
by your program are compiled and
appear in the compiled executable
program. This leads to very compact
code, without any unused stuffs.
Any one knows the principle?
CImg is a header-only library, and they use templates liberally, which is what they're referring to.
If they used a precompiled library of some kind (.dll/.lib/.a/.so) the library file would have to contain the entire CImg library, regardless of which bits of it you actually use.
In the case of a statically linked library (.lib or .a), the linker can then strip out unused symbols, but that may depend on optimization settings.
When the entire library is included in one or two headers, it is only actually compiled when you #include it, and so it is part of the same compilation process as the rest of your program, and the compiler can easily determine which parts of the library are used, and which ones aren't.
And because the CImg API uses templates, no code is generated for functions that are never called.
They are overselling it a bit though, because as the other answers point out, unused symbols will usually be stripped out anyway.
Sounds like fairly standard behaviour to me - a C++ linker will usually throw away any unused library references rather than including uncallable code. Similarly, an optimized build will not include uncallable code.
This sounds like MSVC's Eliminate Unreferenced Data (/OPT:REF) linker command, GCC should have something similar too this too

Why does the C++ linker require the library files during a build, even though I am dynamically linking?

I have a C++ executable and I'm dynamically linking against several libraries (Boost, Xerces-c and custom libs).
I understand why I would require the .lib/.a files if I choose to statically link against these libraries (relevant SO question here). However, why do I need to provide the corresponding .lib/.so library files when linking my executable if I'm dynamically linking against these external libraries?
The compiler isn't aware of dynamic linking, it just knows that a function exists via its prototype. The linker needs the lib files to resolve the symbol. The lib for a DLL contains additional information like what DLL the functions live in and how they are exported (by name, by ordinal, etc.) The lib files for DLL's contain much less information than lib files that contain the full object code - libcmmt.lib on my system is 19.2 MB, but msvcrt.lib is "only" 2.6 MB.
Note that this compile/link model is nearly 40 years old at this point, and predates dynamic linking on most platforms. If it were designed today, dynamic linking would be a first class citizen (for instance, in .NET, each assembly has rich metadata describing exactly what it exports, so you don't need separate headers and libs.)
Raymond Chen wrote a couple blog entries about this specific to Windows. Start with The classical model for linking and then follow-up with Why do we have import libraries anyway?.
To summarize, history has defined the compiler as the component that knows about detailed type information, whereas the linker only knows about symbol names. So the linker ends up creating the .DLL without type information, and therefore programs that want to link with it need some sort of metadata to tell it about how the functions are exported and what parameter types they take and return.
The reason .DLLs don't have all the information you need to link with them directly is is historic, and not a technical limitation.
For one thing, the linker inserts the versions of the libraries that exist at link time so that you have some chance of your program working if library versions are updated. Multiple versions of shared libraries can exist on a system.
The linker has the job of validating that all your undefined symbols are accounted for, either with static content or dynamic content.
By default, then, it insists on all your symbols being present.
However, that's just the default. See -z, and --allow-shlib-undefined, and friends.
Perhaps this dynamic linking is done via import libraries (function has __declspec(dllimport) before definition).
If this is the way than compilator expects that there's __imp_symbol function declared and this function is responsible for forwarding call to the right library dynamically loaded.
Those functions are generated during linkage of symbols with __declspec(dllimport) keyword
Here is a very SIMPLIFIED description that may help. Static linking puts all of the code needed to run your program into the executable so everything is found. Dynamic linking means some of the required code does not get put into the executable and will be found at runtime. Where do I find it? Is function x() there? How do I make a call to function x()? That is what the library tells the linker when you are dynamically linking.

Can I ask VC++ linker to ignore unresolved externals?

I'm trying to build a very complex open-source project with VC++. The project consists of dozens of libraries and one executable depending on those libraries.
For some reasons VC++ linker doesn't want to see about 40 functions implemented in one of those libraries and reports "unresolved external reference" on each, so I can't link. I don't want to waste time resolving the problem - those functions are likely never called.
I'd like to just ask the linker to link what it sees and insert some reasonable error handling (like reporting an error and terminating the program) instead of missing functions. How can I do that?
You can use the /FORCE:UNRESOLVED linker option.
The documentation for that contains the rather understated warning:
A file created with this option may
not run as expected.
In pratice, there'll be no error handling - just a crash.
If the functions are truly never called, then create actual libraries (.lib files) for the libraries. Then the linker will only extract from the libraries what's needed.
The linker's job is to resolve all references, so I don't think you're going to get it to insert error handling code.
P.S. The first thing I'd check is to see if C functions got compiled as C++, leading to the missing symbols.
If they're never called, remove the references from your project. If they are called, then fix the damn problem. There's no real other option here.
There are some notable exceptions, but most OpenSource projects are not designed to be built under VisualStudio.
Generally for a Windows port you are better off using either cygwin or the mingw system. My advice is usually for mingw, unless the program uses a lot of Unix OSey calls like pipes and signals.