A way to decrease executable sizes?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Filipe Martins

    A way to decrease executable sizes?

    Hello.

    I've read somewhere that the executable is smaller if we use a source file
    for each function!
    So, I tested this with gcc and it seams to confirm! What seams to happen is
    that if we call a function from a source-files that defines 3 others, the
    linkers includes the code of all the 4 functions, even if the on we call
    doesn't rely on the others!

    What do you people think about this?
    Is there any way to make the linker reject all the code that isn't needed?

    If there isn't any other answer to this, I may in the future create a small
    app that could be used in release mode to separate all the functions in
    their own files and compile all of it.


    Please state your opinions and theorys about this.

    PS: If someone wants it I can make the test project available.
  • Rolf Magnus

    #2
    Re: A way to decrease executable sizes?

    Filipe Martins wrote:
    [color=blue]
    > Hello.
    >
    > I've read somewhere that the executable is smaller if we use a source
    > file for each function![/color]

    This might be the case or it might not, depending on your
    compiler/linker.
    [color=blue]
    > So, I tested this with gcc and it seams to confirm! What seams to
    > happen is that if we call a function from a source-files that defines
    > 3 others, the linkers includes the code of all the 4 functions, even
    > if the on we call doesn't rely on the others![/color]

    Yes.
    [color=blue]
    > What do you people think about this?[/color]

    I think that it doesn't matter much. First, executable size doesn't
    really matter much on most platforms. Second, why would you write
    functions that are never used?
    [color=blue]
    > Is there any way to make the linker reject all the code that isn't
    > needed?[/color]

    That depends on the linker and/or compiler.

    Comment

    • osmium

      #3
      Re: A way to decrease executable sizes?

      Rolf Magnus writes:
      [color=blue][color=green]
      > > I've read somewhere that the executable is smaller if we use a source
      > > file for each function![/color]
      >
      > This might be the case or it might not, depending on your
      > compiler/linker.
      >[color=green]
      > > So, I tested this with gcc and it seams to confirm! What seams to
      > > happen is that if we call a function from a source-files that defines
      > > 3 others, the linkers includes the code of all the 4 functions, even
      > > if the on we call doesn't rely on the others![/color]
      >
      > Yes.
      >[color=green]
      > > What do you people think about this?[/color]
      >
      > I think that it doesn't matter much. First, executable size doesn't
      > really matter much on most platforms. Second, why would you write
      > functions that are never used?[/color]

      Is it a given that a program that calls sin() will also call tanh()? ISTM
      that is the kind of thing the OP is talking about.


      Comment

      • Leor Zolman

        #4
        Re: A way to decrease executable sizes?

        On 14 Apr 2004 17:25:44 -0700, filipe.martins@ free-spy.net (Filipe Martins)
        wrote:
        [color=blue]
        >Hello.
        >
        >I've read somewhere that the executable is smaller if we use a source file
        >for each function!
        >So, I tested this with gcc and it seams to confirm! What seams to happen is
        >that if we call a function from a source-files that defines 3 others, the
        >linkers includes the code of all the 4 functions, even if the on we call
        >doesn't rely on the others!
        >
        >What do you people think about this?
        >Is there any way to make the linker reject all the code that isn't needed?
        >
        >If there isn't any other answer to this, I may in the future create a small
        >app that could be used in release mode to separate all the functions in
        >their own files and compile all of it.
        >
        >
        >Please state your opinions and theorys about this.
        >
        >PS: If someone wants it I can make the test project available.[/color]

        First of all, this is borderline off-topic because it really isn't a
        language issue. But it is something that comes up and folks who create
        projects should be aware of the general approach that the tools take.

        My experience is not incredibly up-to-date with respect to the latest
        tools and/or project configurations being used, but here's how I see it:

        When you create a project that is composed of several primary source files,
        the usual scenario is that all the functions in all the source files are
        important parts of your program. If you use command line tools and give a
        command such as this:

        cl app.cpp more.cpp more2.cpp more3.cpp

        then the compiler/linker driver (in this case it would happen to be MSVC's)
        compiles all the cpp files into obj files, and then links them all into a
        single executable. IOW, it doesn't bother checking for dependencies;
        evidently, this is the same as the behavior you were seeing with gcc.

        To create object files composed of many general-purpose functions, you'd
        typically use some sort of library manager utility to create a special kind
        of object file: a "library" file. On Win32/etc., these would have the
        ".LIB" extension, on Unix they'd be .a files, etc. When these library files
        are provided on the command line:

        cl app.obj more.obj lib1.lib lbi2.lib

        then the extension clues in the linker that each and every function within
        the libraries is /not/ necessarily one we want, and it only selects those
        functions that are actually needed. IOW, functions are loaded based on
        dependencies. That's why only the functions you actually /use/ out of the
        Standard Library get loaded: they come from library files, not plain old
        object files.

        So to make a long story stay long, if you want the linker to pick and
        choose from an object file, make it a library rather than a plain old
        object file.

        Disclaimer: I'm sure there are all sorts of special cases, different
        extensions, etc., that would make some or most of what I've just said wrong
        in some context, but I hope the basic idea is apropos.
        -leor


        --
        Leor Zolman --- BD Software --- www.bdsoft.com
        On-Site Training in C/C++, Java, Perl and Unix
        C++ users: download BD Software's free STL Error Message Decryptor at:
        An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

        Comment

        • E. Robert Tisdale

          #5
          Re: A way to decrease executable sizes?

          Filipe Martins wrote:
          [color=blue]
          > I've read somewhere that the executable is smaller
          > if we use a source file for each function!
          > So, I tested this with gcc and it seams to confirm!
          > What seams to happen is that,
          > if we call a function from a source-files that defines 3 others,
          > the [link editor] includes the code of all the 4 functions,
          > even if the on we call doesn't rely on the others!
          >
          > What do you people think about this?
          > Is there any way to make the linker reject all the code
          > that isn't needed?
          >
          > If there isn't any other answer to this, I may, in the future,
          > create a small app that could be used in release mode
          > to separate all the functions in their own files[/color]

          You mean like csplit?
          [color=blue]
          > and compile all of it.
          >
          > Please state your opinions and theories about this.
          >
          > PS: If someone wants it I can make the test project available.[/color]

          Make sure that each file includes all of the headers that it needs.

          Once you have split the files up, you may notice that
          it takes longer, maybe a lot longer, to compile each time
          that you make changes to one of the header files.
          This is because each file will include the header file
          in each translation unit and must re-parse it every time.
          You can avoid this during program development
          by simply creating another source file
          which includes each of the separated source files.
          If the headers are idempotent,
          only the first one will be included and parsed by the compiler.

          Comment

          • Kevin Goodsell

            #6
            Re: [OT] A way to decrease executable sizes?

            Filipe Martins wrote:
            [color=blue]
            > Hello.
            >
            > I've read somewhere that the executable is smaller if we use a source file
            > for each function![/color]

            <snip>

            <off-topic>
            If you want to reduce executable size, you might be better off looking
            into some of the tools that are available for that purpose. There's a
            GNU tool called 'strip' that can remove information that's not required
            for execution. I'm not sure if this is based on a standard UNIX tool or not.

            UPX is a compressor for executables. I don't know much about it, but it
            seems to be able to compress several different executable formats.
            Execution speed is apparently impacted somewhat. The output is still an
            executable file, and can be run just like the original I believe.
            </off-topic>

            -Kevin
            --
            My email address is valid, but changes periodically.
            To contact me please use the address from a recent posting.

            Comment

            • Rolf Magnus

              #7
              Re: A way to decrease executable sizes?

              osmium wrote:
              [color=blue]
              > Rolf Magnus writes:
              >[color=green][color=darkred]
              >> > I've read somewhere that the executable is smaller if we use a
              >> > source file for each function![/color]
              >>
              >> This might be the case or it might not, depending on your
              >> compiler/linker.
              >>[color=darkred]
              >> > So, I tested this with gcc and it seams to confirm! What seams to
              >> > happen is that if we call a function from a source-files that
              >> > defines 3 others, the linkers includes the code of all the 4
              >> > functions, even if the on we call doesn't rely on the others![/color]
              >>
              >> Yes.
              >>[color=darkred]
              >> > What do you people think about this?[/color]
              >>
              >> I think that it doesn't matter much. First, executable size doesn't
              >> really matter much on most platforms. Second, why would you write
              >> functions that are never used?[/color]
              >
              > Is it a given that a program that calls sin() will also call tanh()?
              > ISTM that is the kind of thing the OP is talking about.[/color]

              To my knowledge, gcc (and that's what he was asking specifically about)
              has functions like sin and tanh now built into the compiler itself,
              since those are on many CPUs directly available on assembler level.
              Other non-builtin library functions are usually linked as shared
              library, where a concept of leaving out single functions doesn't make
              much sense.

              Comment

              • Karl Heinz Buchegger

                #8
                Re: A way to decrease executable sizes?

                Rolf Magnus wrote:[color=blue]
                >[color=green][color=darkred]
                >>> I think that it doesn't matter much. First, executable size doesn't
                >>> really matter much on most platforms. Second, why would you write
                >>> functions that are never used?[/color]
                >>
                >> Is it a given that a program that calls sin() will also call tanh()?
                >> ISTM that is the kind of thing the OP is talking about.[/color][/color]
                [color=blue]
                > To my knowledge, gcc (and that's what he was asking specifically about)
                > has functions like sin and tanh now built into the compiler itself,
                > since those are on many CPUs directly available on assembler level.
                > Other non-builtin library functions are usually linked as shared
                > library, where a concept of leaving out single functions doesn't make
                > much sense.[/color]

                But the principle is still the same. Every one of us programmers has some
                sort of common code which is just linked into the executable and does not
                reside in some library. I just use those source files and don't care much
                about functions in that source which are not needed in this specific project.

                --
                Karl Heinz Buchegger
                kbuchegg@gascad .at

                Comment

                • Gary Labowitz

                  #9
                  Re: A way to decrease executable sizes?

                  "Leor Zolman" <leor@bdsoft.co m> wrote in message
                  news:garr70h6i6 3ai0827pn6o1s88 3glp4ssrm@4ax.c om...[color=blue]
                  > On 14 Apr 2004 17:25:44 -0700, filipe.martins@ free-spy.net (Filipe[/color]
                  Martins)[color=blue]
                  > wrote:
                  >[color=green]
                  > >Hello.
                  > >
                  > >I've read somewhere that the executable is smaller if we use a[/color][/color]
                  source file[color=blue][color=green]
                  > >for each function!
                  > >So, I tested this with gcc and it seams to confirm! What seams to[/color][/color]
                  happen is[color=blue][color=green]
                  > >that if we call a function from a source-files that defines 3[/color][/color]
                  others, the[color=blue][color=green]
                  > >linkers includes the code of all the 4 functions, even if the on we[/color][/color]
                  call[color=blue][color=green]
                  > >doesn't rely on the others![/color][/color]
                  <<snip>>[color=blue]
                  > To create object files composed of many general-purpose functions,[/color]
                  you'd[color=blue]
                  > typically use some sort of library manager utility to create a[/color]
                  special kind[color=blue]
                  > of object file: a "library" file. On Win32/etc., these would have[/color]
                  the[color=blue]
                  > ".LIB" extension, on Unix they'd be .a files, etc. When these[/color]
                  library files[color=blue]
                  > are provided on the command line:
                  >
                  > cl app.obj more.obj lib1.lib lbi2.lib
                  >
                  > then the extension clues in the linker that each and every function[/color]
                  within[color=blue]
                  > the libraries is /not/ necessarily one we want, and it only selects[/color]
                  those[color=blue]
                  > functions that are actually needed. IOW, functions are loaded based[/color]
                  on[color=blue]
                  > dependencies. That's why only the functions you actually /use/ out[/color]
                  of the[color=blue]
                  > Standard Library get loaded: they come from library files, not plain[/color]
                  old[color=blue]
                  > object files.
                  >
                  > So to make a long story stay long, if you want the linker to pick[/color]
                  and[color=blue]
                  > choose from an object file, make it a library rather than a plain[/color]
                  old[color=blue]
                  > object file.[/color]

                  I'd like to think that linkers did what you said, Leor, but I am still
                  under the impression that when a linker searches a library (such as
                  lib1.lib) it looks at the header and finds the name of a function it
                  is trying to resolve and then includes the entire library. Can it, in
                  fact, only pull out the function and place it in the exe? I don't
                  remember us doing that in the OS/360 linker, and the fact that
                  compiling the functions separately results in smaller exe would seem
                  to confirm that the entire module is included otherwise.
                  Of course, this could (and probably is) different with each linker,
                  making the whole conversation a troll.
                  Can one of the current developers here confirm that some linker
                  somewhere does in fact selectively pull function code from libraries
                  when linking?
                  I'll try some tests with g++ and report back.
                  --
                  Gary


                  Comment

                  • Leor Zolman

                    #10
                    Re: A way to decrease executable sizes?

                    On Thu, 15 Apr 2004 08:42:22 -0400, "Gary Labowitz" <glabowitz@comc ast.net>
                    wrote:

                    [color=blue]
                    >
                    >I'd like to think that linkers did what you said, Leor, but I am still
                    >under the impression that when a linker searches a library (such as
                    >lib1.lib) it looks at the header and finds the name of a function it
                    >is trying to resolve and then includes the entire library. Can it, in
                    >fact, only pull out the function and place it in the exe? I don't
                    >remember us doing that in the OS/360 linker, and the fact that
                    >compiling the functions separately results in smaller exe would seem
                    >to confirm that the entire module is included otherwise.
                    >Of course, this could (and probably is) different with each linker,
                    >making the whole conversation a troll.
                    >Can one of the current developers here confirm that some linker
                    >somewhere does in fact selectively pull function code from libraries
                    >when linking?
                    >I'll try some tests with g++ and report back.[/color]

                    Yeah, I wasn't sure exactly how to go about testing this. I'm pretty sure
                    that at some point in the past I've verified this behavior, but I haven't
                    really delved into it in ages.

                    I figured I'd have a better chance at getting accurate size measurements
                    under Unix, but unfortunately I have no C/C++ development tools in my
                    Cygwin installation.

                    So I resorted to good ole' MSVC to see what I could come up with. The
                    executable size doesn't mean squat with MSVC, because it always seem to
                    round up for some reason, but I figured there ought to be an option to
                    print out a symbol table I could search for the usual suspects. I created
                    the following program, which I compiled once with the log10 call in there
                    and once without:

                    //
                    // does using one fn out of a lib drag in all the others?
                    //

                    #include <iostream>
                    #include <cmath>
                    using namespace std;

                    int main()
                    {
                    double d = sqrt(5.0);
                    cout << "chi = (" << d << " + 1 ) / 2" << endl;

                    // Compared with and without the following line:
                    // d = log10(d);

                    cout << "log10(d) = " << d << endl;

                    return 0;
                    }

                    In the resulting map file for compiling as shown, there was exactly one
                    occurrence of the pattern "log10" in the generated map file (MSVC 7.1, /Fm
                    option), shown with surrounding context (3 lines total, I've wrapped them
                    manually and put a space between):

                    0002:00002278 ??_C@_04COOMCNP B@sinh?$AA@
                    00414278 LIBC:fpexcept.o bj

                    0002:00002280 ??_C@_05HGHHAHA P@log10?$AA@
                    00414280 LIBC:fpexcept.o bj

                    0002:00002288 ??_C@_03MGHMBJC F@log?$AA@
                    00414288 LIBC:fpexcept.o bj


                    This looks to be some sort of master symbol dispatch table, but I'd guess
                    it does not represent address of actual code. But I don't know for sure.

                    In the /other/ map file (with the log10 call uncommented), I still get the
                    same entries as above (different addresses), PLUS:

                    0001:00005610 _log10 00406610 f LIBC:log10.obj
                    0001:00005650 __CIlog10 00406650 f LIBC:log10.obj
                    0001:0000568b __CIlog10_defau lt 0040668b f LIBC:log10.obj
                    0001:0000569f __log10_default 0040669f LIBC:log10.obj

                    0001:00008a50 __CIlog10_penti um4 00409a50 f
                    LIBC:log10_pent ium4.obj
                    0001:00008a68 __log10_pentium 4 00409a68
                    LIBC:log10_pent ium4.obj

                    0001:0000564f _$$$00002 0040664f f LIBC:log10.obj


                    So my guess would be that all those additional lines represent stuff that
                    got dragged into the executable for version #2 that was not in version #1.

                    Or I may be totally in dreamland. I don't know.
                    -leor

                    --
                    Leor Zolman --- BD Software --- www.bdsoft.com
                    On-Site Training in C/C++, Java, Perl and Unix
                    C++ users: download BD Software's free STL Error Message Decryptor at:
                    An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

                    Comment

                    • Peter van Merkerk

                      #11
                      Re: A way to decrease executable sizes?

                      Gary Labowitz wrote:[color=blue]
                      > "Leor Zolman" <leor@bdsoft.co m> wrote in message
                      > news:garr70h6i6 3ai0827pn6o1s88 3glp4ssrm@4ax.c om...[color=green]
                      >> On 14 Apr 2004 17:25:44 -0700, filipe.martins@ free-spy.net (Filipe
                      >> Martins) wrote:
                      >>[color=darkred]
                      >>> Hello.
                      >>>
                      >>> I've read somewhere that the executable is smaller if we use a
                      >>> source file for each function!
                      >>> So, I tested this with gcc and it seams to confirm! What seams to
                      >>> happen is that if we call a function from a source-files that
                      >>> defines 3 others, the linkers includes the code of all the 4
                      >>> functions, even if the on we call doesn't rely on the others![/color][/color]
                      > <<snip>>[color=green]
                      >> To create object files composed of many general-purpose functions,
                      >> you'd typically use some sort of library manager utility to create a
                      >> special kind of object file: a "library" file. On Win32/etc., these
                      >> would have the ".LIB" extension, on Unix they'd be .a files, etc.
                      >> When these library files are provided on the command line:
                      >>
                      >> cl app.obj more.obj lib1.lib lbi2.lib
                      >>
                      >> then the extension clues in the linker that each and every function
                      >> within the libraries is /not/ necessarily one we want, and it only
                      >> selects those functions that are actually needed. IOW, functions are
                      >> loaded based on dependencies. That's why only the functions you
                      >> actually /use/ out of the Standard Library get loaded: they come
                      >> from library files, not plain old object files.
                      >>
                      >> So to make a long story stay long, if you want the linker to pick and
                      >> choose from an object file, make it a library rather than a plain old
                      >> object file.[/color]
                      >
                      > I'd like to think that linkers did what you said, Leor, but I am still
                      > under the impression that when a linker searches a library (such as
                      > lib1.lib) it looks at the header and finds the name of a function it
                      > is trying to resolve and then includes the entire library. Can it, in
                      > fact, only pull out the function and place it in the exe?[/color]

                      With MSVC you can enable the "function level linking" (/Gy) option so only
                      referenced functions are put in the executable. The last time I checked
                      with G++ it always included the whole .obj. In that case it would help to
                      put every function in a separate compilation unit. IOW the answer to the
                      original question: it depends on the tools you use.

                      --
                      Peter van Merkerk
                      peter.van.merke rk(at)dse.nl



                      Comment

                      • Leor Zolman

                        #12
                        Re: A way to decrease executable sizes?

                        On Thu, 15 Apr 2004 15:28:48 +0200, "Peter van Merkerk"
                        <merkerk@deadsp am.com> wrote:
                        [color=blue]
                        >
                        >With MSVC you can enable the "function level linking" (/Gy) option so only
                        >referenced functions are put in the executable. The last time I checked
                        >with G++ it always included the whole .obj. In that case it would help to
                        >put every function in a separate compilation unit. IOW the answer to the
                        >original question: it depends on the tools you use.[/color]

                        Absolutely true, "tools and options" even, and I neglected to restate that
                        in my original response. What I was trying to say (and I still tend to
                        stray off the major point of a thread sometimes while getting distracted by
                        specific details...) was that there may be platform-specific solutions to
                        the problem of unwanted code being dragged into an executable that do not
                        necessarily involve separating all the independent pieces into separate
                        TU's. Based on my experience, creating a "library" would be one possible
                        path to explore. In the case of MSVC, Peter's /Gy would definitely be
                        another...
                        -leor


                        --
                        Leor Zolman --- BD Software --- www.bdsoft.com
                        On-Site Training in C/C++, Java, Perl and Unix
                        C++ users: download BD Software's free STL Error Message Decryptor at:
                        An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

                        Comment

                        • Thomas Matthews

                          #13
                          Re: A way to decrease executable sizes?

                          Filipe Martins wrote:
                          [color=blue]
                          > Hello.
                          >
                          > I've read somewhere that the executable is smaller if we use a source file
                          > for each function!
                          > So, I tested this with gcc and it seams to confirm! What seams to happen is
                          > that if we call a function from a source-files that defines 3 others, the
                          > linkers includes the code of all the 4 functions, even if the on we call
                          > doesn't rely on the others!
                          >
                          > What do you people think about this?
                          > Is there any way to make the linker reject all the code that isn't needed?[/color]

                          Good luck. I've been in the embedded systems arena for over 20 years
                          and have been wanting a linker that will remove unused functions.
                          It seems easier (and cheaper) to make a linker that removes at the
                          file level rather than the function level.

                          [color=blue]
                          > If there isn't any other answer to this, I may in the future create a small
                          > app that could be used in release mode to separate all the functions in
                          > their own files and compile all of it.[/color]

                          As others have stated, place your modules into a library and use the
                          library.

                          [color=blue]
                          >
                          > Please state your opinions and theorys about this.
                          >
                          > PS: If someone wants it I can make the test project available.[/color]

                          In today's programming world, executable size is seldom a high concern.
                          Although in many embedded systems with small memory footprints,
                          executable size is a concern, but not the highest.

                          On my current project, the following are the priorites, due to the
                          fact that the executable will be masked into a Read Only Memory
                          device and changes after the mask will be very expensive (and
                          time consuming):
                          1. Correctness: Is it behaving as designed or required?
                          2. Robustness: Are all conditions considered?
                          Will it run into a deadlock or unknown state?
                          3. Code Size: Will it fit into the allocated space?
                          4. Speed: Will the events be serviced in the required
                          time?
                          5. Schedule: Will the executable be delivered on time.

                          {Although my associates would like to raise the priority of
                          the schedule.}

                          Some tricks to shrink your code:
                          1. Remove dead code, Functions, requirements and other stuff.
                          2. Consolidate code and data. If it is used more than once
                          share it.
                          3. Refrain from using system libraries functions. These
                          functions often have hidden dependencies and callout
                          more functions. For example, write a "hello world"
                          program using puts, printf and fwrite. Note the
                          size differences in the executable. The printf function
                          may include a floating point library even though your
                          program does not use floating point.

                          By the way, before you optimize for space, record how much
                          time you spend optimizing. Then subtract this time from
                          your schedule to find out how early you could have finished
                          your project.


                          --
                          Thomas Matthews

                          C++ newsgroup welcome message:

                          C++ Faq: http://www.parashift.com/c++-faq-lite
                          C Faq: http://www.eskimo.com/~scs/c-faq/top.html
                          alt.comp.lang.l earn.c-c++ faq:

                          Other sites:
                          http://www.josuttis.com -- C++ STL Library book

                          Comment

                          • osmium

                            #14
                            Re: A way to decrease executable sizes?

                            Gary Labowitz writes:
                            [color=blue][color=green][color=darkred]
                            > > >I've read somewhere that the executable is smaller if we use a[/color][/color]
                            > source file[color=green][color=darkred]
                            > > >for each function!
                            > > >So, I tested this with gcc and it seams to confirm! What seams to[/color][/color]
                            > happen is[color=green][color=darkred]
                            > > >that if we call a function from a source-files that defines 3[/color][/color]
                            > others, the[color=green][color=darkred]
                            > > >linkers includes the code of all the 4 functions, even if the on we[/color][/color]
                            > call[color=green][color=darkred]
                            > > >doesn't rely on the others![/color][/color]
                            > <<snip>>[color=green]
                            > > To create object files composed of many general-purpose functions,[/color]
                            > you'd[color=green]
                            > > typically use some sort of library manager utility to create a[/color]
                            > special kind[color=green]
                            > > of object file: a "library" file. On Win32/etc., these would have[/color]
                            > the[color=green]
                            > > ".LIB" extension, on Unix they'd be .a files, etc. When these[/color]
                            > library files[color=green]
                            > > are provided on the command line:
                            > >
                            > > cl app.obj more.obj lib1.lib lbi2.lib
                            > >
                            > > then the extension clues in the linker that each and every function[/color]
                            > within[color=green]
                            > > the libraries is /not/ necessarily one we want, and it only selects[/color]
                            > those[color=green]
                            > > functions that are actually needed. IOW, functions are loaded based[/color]
                            > on[color=green]
                            > > dependencies. That's why only the functions you actually /use/ out[/color]
                            > of the[color=green]
                            > > Standard Library get loaded: they come from library files, not plain[/color]
                            > old[color=green]
                            > > object files.
                            > >
                            > > So to make a long story stay long, if you want the linker to pick[/color]
                            > and[color=green]
                            > > choose from an object file, make it a library rather than a plain[/color]
                            > old[color=green]
                            > > object file.[/color]
                            >
                            > I'd like to think that linkers did what you said, Leor, but I am still
                            > under the impression that when a linker searches a library (such as
                            > lib1.lib) it looks at the header and finds the name of a function it
                            > is trying to resolve and then includes the entire library. Can it, in
                            > fact, only pull out the function and place it in the exe? I don't
                            > remember us doing that in the OS/360 linker, and the fact that
                            > compiling the functions separately results in smaller exe would seem
                            > to confirm that the entire module is included otherwise.
                            > Of course, this could (and probably is) different with each linker,
                            > making the whole conversation a troll.
                            > Can one of the current developers here confirm that some linker
                            > somewhere does in fact selectively pull function code from libraries
                            > when linking?
                            > I'll try some tests with g++ and report back.[/color]

                            You probably remember this conversation from last December. After a lot of
                            to and fro it turned out that Microsoft, with their advanced linker was able
                            to cram this code:

                            fabs(1.23);

                            into only 24,576 bytes!

                            And there was a long harangue about how complicated that code really was and
                            so on .....

                            ISTM that the exponent of smart linkers was trusting Microsoft's glib
                            promises rather than their end results.


                            241%40ID-179017.news.uni-berlin.de


                            Comment

                            • Gary Labowitz

                              #15
                              Re: A way to decrease executable sizes?

                              "Peter van Merkerk" <merkerk@deadsp am.com> wrote in message
                              news:c5m2mj$3a6 e7$1@ID-133164.news.uni-berlin.de...[color=blue]
                              > Gary Labowitz wrote:[color=green]
                              > > "Leor Zolman" <leor@bdsoft.co m> wrote in message
                              > > news:garr70h6i6 3ai0827pn6o1s88 3glp4ssrm@4ax.c om...[color=darkred]
                              > >> On 14 Apr 2004 17:25:44 -0700, filipe.martins@ free-spy.net[/color][/color][/color]
                              (Filipe[color=blue][color=green][color=darkred]
                              > >> Martins) wrote:
                              > >>
                              > >>> Hello.
                              > >>>
                              > >>> I've read somewhere that the executable is smaller if we use a
                              > >>> source file for each function!
                              > >>> So, I tested this with gcc and it seams to confirm! What seams[/color][/color][/color]
                              to[color=blue][color=green][color=darkred]
                              > >>> happen is that if we call a function from a source-files that
                              > >>> defines 3 others, the linkers includes the code of all the 4
                              > >>> functions, even if the on we call doesn't rely on the others![/color]
                              > > <<snip>>[color=darkred]
                              > >> To create object files composed of many general-purpose[/color][/color][/color]
                              functions,[color=blue][color=green][color=darkred]
                              > >> you'd typically use some sort of library manager utility to[/color][/color][/color]
                              create a[color=blue][color=green][color=darkred]
                              > >> special kind of object file: a "library" file. On Win32/etc.,[/color][/color][/color]
                              these[color=blue][color=green][color=darkred]
                              > >> would have the ".LIB" extension, on Unix they'd be .a files, etc.
                              > >> When these library files are provided on the command line:
                              > >>
                              > >> cl app.obj more.obj lib1.lib lbi2.lib
                              > >>
                              > >> then the extension clues in the linker that each and every[/color][/color][/color]
                              function[color=blue][color=green][color=darkred]
                              > >> within the libraries is /not/ necessarily one we want, and it[/color][/color][/color]
                              only[color=blue][color=green][color=darkred]
                              > >> selects those functions that are actually needed. IOW, functions[/color][/color][/color]
                              are[color=blue][color=green][color=darkred]
                              > >> loaded based on dependencies. That's why only the functions you
                              > >> actually /use/ out of the Standard Library get loaded: they come
                              > >> from library files, not plain old object files.
                              > >>
                              > >> So to make a long story stay long, if you want the linker to pick[/color][/color][/color]
                              and[color=blue][color=green][color=darkred]
                              > >> choose from an object file, make it a library rather than a plain[/color][/color][/color]
                              old[color=blue][color=green][color=darkred]
                              > >> object file.[/color]
                              > >
                              > > I'd like to think that linkers did what you said, Leor, but I am[/color][/color]
                              still[color=blue][color=green]
                              > > under the impression that when a linker searches a library (such[/color][/color]
                              as[color=blue][color=green]
                              > > lib1.lib) it looks at the header and finds the name of a function[/color][/color]
                              it[color=blue][color=green]
                              > > is trying to resolve and then includes the entire library. Can it,[/color][/color]
                              in[color=blue][color=green]
                              > > fact, only pull out the function and place it in the exe?[/color]
                              >
                              > With MSVC you can enable the "function level linking" (/Gy) option[/color]
                              so only[color=blue]
                              > referenced functions are put in the executable. The last time I[/color]
                              checked[color=blue]
                              > with G++ it always included the whole .obj. In that case it would[/color]
                              help to[color=blue]
                              > put every function in a separate compilation unit. IOW the answer to[/color]
                              the[color=blue]
                              > original question: it depends on the tools you use.[/color]
                              I never heard of the /Gy in MSVC, but then I don't use MSVC very often
                              (too many bugs!).
                              I did try g++ with two functions, each with a large footprint and
                              linked them separately and then together and got the following
                              results:

                              Calling module using functions separate functions together
                              both funcs 872kb 872kb
                              on func 482kb 872kb

                              It would appear that when the two functions are in one .o they are
                              both linked in regardless of whether one or both functions are called
                              by the base module. With them separate (in two .o's) it allows for
                              only including what you need.
                              It's a lot of bother, really, and I suspect that it doesn't matter
                              nowadays.
                              --
                              Gary


                              Comment

                              Working...