Linker and libraries

Started by czerny, March 10, 2013, 03:02:03 PM

Previous topic - Next topic

czerny

Hi,

I want to know, if the linker is linking libs as a whole or only thouse functions (obj-files) needed.

I made a simple test ppw.

I have 3 libraries:

liba.lib: One function Add() in one source file a.c.
libb.lib: One function Mul() in one source file b.c.
liba.lib: Two functions Add() and Mul() in one source file c.c.

and two executables:

libtst1.exe: Which uses only Add() and links against libc.lib
libtst2.exe: Which uses only Add() and links against liba.lib

Problem: The 2 executales have both the same size. I had expected size(libtst2) < size(libtst1).

czerny

CommonTater

#1
Quote from: czerny on March 10, 2013, 03:02:03 PM
Hi,

I want to know, if the linker is linking libs as a whole or only thouse functions (obj-files) needed.

I made a simple test ppw.

I have 3 libraries:

liba.lib: One function Add() in one source file a.c.
libb.lib: One function Mul() in one source file b.c.
liba.lib: Two functions Add() and Mul() in one source file c.c.

and two executables:

libtst1.exe: Which uses only Add() and links against libc.lib
libtst2.exe: Which uses only Add() and links against liba.lib

Problem: The 2 executales have both the same size. I had expected size(libtst2) < size(libtst1).

czerny

If your libs are comparitively small the exe's block sizing may land you up with the same file size.  On big libraries, you will see the difference.

In any case Pelle's linker is not a "smart linker"... that is it doesn't pick functions out of objects the way some do.  It works at the object level.  That is the minimum it can link is one object. 

This means that if you are building a library with (lets say) 150 functions, you really need them to be in 150 separate source files, so they compile into 150 separate objects. That way the linker appears smart, picking only the needed objects (thus functions) to add to the executable.

If you took that 150 function library and compiled them all from one source page you'd have only one object and every program that uses the library would have all 150 functions linked in, even if you're only calling 1 or 2 of them.

TimoVJL

#2
Use linker option to create map-file and examine that.
May the source be with you

czerny

Quote from: CommonTater on March 10, 2013, 03:11:42 PM
If your libs are comparitively small the exe's block sizing may land you up with the same file size.  On big libraries, you will see the difference.
This might be the case. Thank you!

czerny

Quote from: timovjl on March 10, 2013, 03:20:52 PM
Use linker option to create map-file and examine that.
Thank you timovjl, that is a good example.

czerny

CommonTater

Quote from: czerny on March 11, 2013, 08:06:54 AM
Quote from: CommonTater on March 10, 2013, 03:11:42 PM
If your libs are comparitively small the exe's block sizing may land you up with the same file size.  On big libraries, you will see the difference.
This might be the case. Thank you!

On my own system I have a large library, basically an accumulation of frequently used functions.  There are several hundred functions in it.  Trust me I know how much difference using separate sources for each function makes...


TimoVJL

Microsoft C have compiler option -Gy to separate functions to different sections in same object file.
-Gy (Enable Function-Level Linking)
http://msdn.microsoft.com/en-us/library/xsa71f43(v=vs.90).aspx
PellesC is missing that feature.
May the source be with you

CommonTater

Quote from: timovjl on March 11, 2013, 04:10:12 PM
Microsoft C have compiler option -Gy to separate functions to different sections in same object file.
-Gy (Enable Function-Level Linking)
http://msdn.microsoft.com/en-us/library/xsa71f43(v=vs.90).aspx
PellesC is missing that feature.

Yep ... handy feature...

I guess Czerny can't hear me ....

Vortex

Hi CommonTater,

QuoteIn any case Pelle's linker is not a "smart linker"... that is it doesn't pick functions out of objects the way some do.  It works at the object level.  That is the minimum it can link is one object.

This is the granularity problem. Each procedure should go to separate modules. MS Link operates same as Polink. It extracts all the procedures from an object file.
Code it... That's all...

TimoVJL

#9
Quote from: Vortex on March 11, 2013, 07:23:05 PM
This is the granularity problem. Each procedure should go to separate modules. MS Link operates same as Polink. It extracts all the procedures from an object file.
Is it so ? I think polink picks just functions from same sections only (.text .data)?
That msvc -Gy option isn't perfect, it puts all data to same .data section.
May the source be with you

CommonTater

#10
Quote from: timovjl on March 11, 2013, 08:06:59 PM
Quote from: Vortex on March 11, 2013, 07:23:05 PM
This is the granularity problem. Each procedure should go to separate modules. MS Link operates same as Polink. It extracts all the procedures from an object file.
Is it so ? I think polink picks just functions from same sections only (.text .data)?
That msvc -Gy option isn't perfect, it puts all data to same .data section.

Actually Timo ... that is why my libraries are organized as they are... each function in it's own "module" (source page). 

If you write a library with func1() func2() func3() func4() all on the same source page, POCC will put them into a single .obj file and POLIB includes them in the .lib as one piece. Later when POLINK goes to the library, to get func1() for your current project, it will link the entire object, also linking in the other three, which will become dormant code (i.e. Bloat) in the resulting executable. 

On the other hand, if you create 4 separate source pages --thus having POCC create 4 separate objects-- the linker will pick only the needed function and not include the others.

So, although we are saying it in different ways, Vortex and I do appear to agree...


czerny

Quote from: CommonTater on March 11, 2013, 07:12:47 PM
Yep ... handy feature...

I guess Czerny can't hear me ....
I hear every word, Tater! Always!

japheth

Quote from: Vortex on March 11, 2013, 07:23:05 PM
This is the granularity problem. Each procedure should go to separate modules. MS Link operates same as Polink. It extracts all the procedures from an object file.
This is not the full truth. Both MS link and Polink know how to handle COMDAT sections ( COMDATs are described in the MS COFF docs ). Actually, the MSVC "function level linking" feature ( and also the "string pooling" thing ) are implemented by making use of such sections. In short: with COMDATs, it's possible that the linker uses certain sections of a module only - the rest won't become part of the final binary.

CommonTater

Quote from: japheth on March 12, 2013, 04:14:38 AM
Quote from: Vortex on March 11, 2013, 07:23:05 PM
This is the granularity problem. Each procedure should go to separate modules. MS Link operates same as Polink. It extracts all the procedures from an object file.
This is not the full truth. Both MS link and Polink know how to handle COMDAT sections ( COMDATs are described in the MS COFF docs ). Actually, the MSVC "function level linking" feature ( and also the "string pooling" thing ) are implemented by making use of such sections. In short: with COMDATs, it's possible that the linker uses certain sections of a module only - the rest won't become part of the final binary.

Trust me... POLINK is not simply a rename of LINK from MSVC++.  They are two very different animals.

If you don't want to be linking a whole mess of dead code into your programs, you will divide your code into separate source modules before compiling. 

japheth

Quote from: CommonTater on March 12, 2013, 04:24:24 AM
Trust me... POLINK is not simply a rename of LINK from MSVC++.  They are two very different animals.
I have to admit that my faith is "limited" - due to certain experiences.

Quote
If you don't want to be linking a whole mess of dead code into your programs, you will divide your code into separate source modules before compiling.

Well, the claim in my previous post wasn't based on guesses but on results of experiments with both MS link and Polink.