Al vincular estáticamente, ¿el vinculador incluye toda la biblioteca?

For example, if I static link to freeglut, does the compiler include everything from freeglut or only the parts that I use? Of course, this implies that the linker (or compiler?) do some kind of dependency analysis to figure out what it can safely exclude.

If so, is there a way to see what have been included or excluded in Visual Studio?

preguntado el 10 de marzo de 12 a las 14:03

4 Respuestas

It's partly a Quality of Implementation issue, but there is a real gotcha.

Namely, by the standard the linker has to add in all unidades de compilación that are referenced. But say that in the library, you have a compilation unit with nothing but a static variable whose initialization registers something with a something registry, e.g. message handling, factory, whatever, or perhaps its constructor and destructor output, respectively, "before main" and "after main". If nothing in that compilation unit is referenced, then the linker is within its rights to just skip it, remove it.

So, to ensure that such static variables are not optimized away, with a standard-conforming toolchain it is necessary and sufficient to reference something in that compilation unit.

Re seeing in Visual Studio what has been included, as far as I know there's no way except asking for verbose output from the linker, like, linker option /verbose:ref.

However, with that option you get realmente salida detallada.

An alternative is to ask the linker for a map file, like, linker option /map:blah.

Also this output is very verbose, though.

respondido 10 mar '12, 14:03

This reflects my test results. I've build a simple library with two functions in the same C++ file. When I link against this library, both functions are included, even if I only use one of them. If I split those functions into two C++ file (which results in two obj file), only the function I use in my application gets included. - Subb

@PavanManjunath: in the Holy Standard it's called a unidad de traducción. Effectively it's what you have after preprocessing of some implementation file (e.g. cpp file). The whole thing is described in the "phases of translation" somewhere at the start of the standard. - Saludos y hth. - Alf

It's not only a quality of implementation issue for the linker, but also for the particular library you're using. Most libraries these days are written by people who have no understanding of linkers or the purpose of translation units, and who make it so basically using any one feature of the library pulls in nearly the whole library. Try static linking a "hello, world" program that uses printf o incluso solo puts with glibc (it'll be >500k), or worse yet, a C++ "hello world" program using iostream from libstdc++ (it'll be >900k). I suspect freeglut is awful in this regard... - R .. GitHub DEJA DE AYUDAR A ICE

Yes, the linker will include just the translation units that your code references.

If you generate a map file for your executable then you can see exactly what it contains.

respondido 10 mar '12, 18:03

Linker include only symbols, which are needed.

Probably, the question about inspecting *.lib files, answers the second part (dumpbin works for *.exe files too).

contestado el 23 de mayo de 17 a las 13:05

<code>dumpbin/code> doesn't seem to find ordinary symbols even in exe with debug info. - Saludos y hth. - Alf

I think you can write a sample lib to get the answer. In a C++ lib, 1 write a class to print all the subclass name. 2 and several class derived from it.

In a real main program, just use one of the sub-classes.

And then print all the name.

Then you will find the answer, I think.

respondido 10 mar '12, 14:03

Please provide answers, not riddles. This is a Q&A platform. - Nick Russler

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.