Recent

Author Topic: [SOLVED] Linux binaries too big  (Read 15174 times)

tk

  • Sr. Member
  • ****
  • Posts: 361
[SOLVED] Linux binaries too big
« on: January 14, 2017, 02:04:01 pm »
Hi, of course I know about http://wiki.lazarus.freepascal.org/Lazarus_Faq#Why_are_the_generated_binaries_so_big.3F etc. but I still wonder why generated binary of the same lpi project (my case is shared library) is roughly 3 times bigger for Linux target than for Windows target.

i386-linux/libmylib.so 6686916 bytes
i386-win32/mylib.dll 2157056 bytes

When I inspect the *.so ELF:
- 3151152 bytes are taken by PROGBITS/.text section
- 1517624 bytes by PROGBITS/.data section
- 1352880 bytes by REL/.rel.dyn section
- 337740 bytes by PROGBITS/.rodata section
- 207160 bytes by PROGBITS/fpc.resources section
- 113460 bytes by NOBITS/.bss section
another section sizes are small (below 65536 bytes).

When I inspect the *.dll PE:
- 1463808 bytes are taken by .text section
- 370176 bytes by .rdata section
- 159232 bytes by .rsrc section
- 105984 bytes by .reloc section
again another section sizes are small (below 65536 bytes).

I don't have problem with it but I am just interested why these sizes are so different.
« Last Edit: January 17, 2017, 09:05:13 am by tk »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Linux binaries too big
« Reply #1 on: January 14, 2017, 02:48:12 pm »
Some possibilities in decreasing order
  • Smartlinking is default on on Windows, did you enable it on *nix?
  • Debug info?
  • Both files contain the relevant parts of the RTL, but since the Windows api is richer, the RTL is thinner
  • position independent code overhead

Considering the considerable size difference I'd say it is one of the first two.

 Note that the first (smartlinking) goes for all used components (FPC rtl+packages+lcl+whatever you compiled yourself), not just your project.

Generating a map file might also give some info.


Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Linux binaries too big
« Reply #2 on: January 14, 2017, 05:21:31 pm »
Smartlinking and debug info (which often improperly stripped) indeed. Properly smartlinked and stripped debug info should have similar size on platforms with identical bitness (even under different bitness, the difference shouldn't be 300%). Example from one of my projects:
https://bitbucket.org/leledumbo/erd-maker/downloads

tk

  • Sr. Member
  • ****
  • Posts: 361
Re: Linux binaries too big
« Reply #3 on: January 14, 2017, 06:38:47 pm »
I made further observations with fresh projects - see attachments. And it looks like the problem applies only for a shared library (DLL vs. SO), for normal executable there is no significant difference.

My executable project binaries now have ca. 2 MB in size both for Win and Linux and for shared library the DLL size is 1.7 MB and SO size is 5.4 MB.

I tried almost everything, played with -Cx,-XX,-Xs,-WR,another optimization levels,rebuild,clean up+rebuild...

Using now FPC r35280 from yesterday.

Could it be some issue with PIC? I don't have -fPIC enabled for the library but when I add it to the compiler options the SO size does not change. So is it possible that FPC generates PIC for Linux target implicitly?

This is my Linux compiler option string for the library:
Code: [Select]
-MObjFPC -Scghi -CX -O3 -Xs -XX -l -vewnhibq -Filib/i386-linux -Fu/home/osboxes/Documents/lazarus/lcl/units/i386-linux/gtk2 -Fu/home/osboxes/Documents/lazarus/lcl/units/i386-linux -Fu/home/osboxes/Documents/lazarus/components/lazutils/lib/i386-linux -Fu/home/osboxes/Documents/lazarus/packager/units/i386-linux -Fu. -FUlib/i386-linux -olibproject1.so -dLCL -dLCLgtk2

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Linux binaries too big
« Reply #4 on: January 14, 2017, 08:00:49 pm »
I made further observations with fresh projects - see attachments. And it looks like the problem applies only for a shared library (DLL vs. SO)

I can confirm this. My 64-bit dynamic libraries (.so) on Linux are always about 2x the size of 64-bit .dll on Windows or 64-bit .dylib on OS X.

With OS X, -XX passes -dead_strip to the linker. With Linux, -XX passes --gc-sections to the linker. The man notes for ld suggest that --gc-sections does not apply to dynamic libraries. No apparent restriction like that for Mac's -dead_strip though.

Add -k--print-gc-sections to FPC command line to see what gets stripped out with a normal executable when -XX is used (--gc-sections).


minesadorada

  • Sr. Member
  • ****
  • Posts: 452
  • Retired
Re: Linux binaries too big
« Reply #5 on: January 14, 2017, 08:43:55 pm »
I use UPX as an External Tool in Lazarus to shrink compiled files. You can associate it with a key (I use NumLock)
Its free and open source.

https://upx.github.io/
GPL Apps: Health MonitorRetro Ski Run
OnlinePackageManager Components: LazAutoUpdate, LongTimer, PoweredBy, ScrollText, PlaySound, CryptINI

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Linux binaries too big
« Reply #6 on: January 14, 2017, 10:58:27 pm »
I use UPX as an External Tool in Lazarus to shrink compiled files. You can associate it with a key (I use NumLock)
Its free and open source.

https://upx.github.io/

And say hello for dozen complaints from users who uses paranoid antivirus suites. IMHO, do not use executable packers. They can cause problems with antivirus programs.

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: Linux binaries too big
« Reply #7 on: January 15, 2017, 12:01:49 am »
Quote
And say hello for dozen complaints from users who uses paranoid antivirus suites. IMHO, do not use executable packers. They can cause problems with antivirus programs.

That's true. I needed to talk with various AV companies to say that my application was safe. There's a category specific for "UPX-Packed" kind of virus.

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: Linux binaries too big
« Reply #8 on: January 15, 2017, 02:41:37 am »
Yeah, never ever use UPX. As has been stated already in this thread, UPX-compressed executables are widely viewed as "infected" automatically by a number of AV suites. I'm pretty sure this is a direct result of the fact that UPX was extensively used by a variety of malware authors in the early to mid 2000s (Most of them from Russia for some reason, and much of the code in Delphi, believe it or not!) Also, UPX-compressed executables quite often have noticeably reduced startup times, and can also cause what's known as "disk thrashing" (depending on the nature of the application itself, of course.) If anyone out there is using it with the intention of "protecting" their FPC-built application: chill out. No one is going to decompile it. While it's true that there are quite a few applications able to do high-quality decompilation of Delphi code, the same cannot be said for FPC. I am not aware of any notable decompiler that even recognizes FPC-compiled code specifically at all. (IDA, for example, tends to think it's GCC code when the executable is linked with dwarf or stab debug symbols, and Visual C++ code when it's been stripped.)

minesadorada

  • Sr. Member
  • ****
  • Posts: 452
  • Retired
Re: Linux binaries too big
« Reply #9 on: January 15, 2017, 07:53:19 am »
I use UPX as an External Tool in Lazarus to shrink compiled files. You can associate it with a key (I use NumLock)
Its free and open source.

https://upx.github.io/

And say hello for dozen complaints from users who uses paranoid antivirus suites. IMHO, do not use executable packers. They can cause problems with antivirus programs.
So not a problem for Linux executables (which is the topic subject)
Your comments are sound for Windows executables.
« Last Edit: January 15, 2017, 02:45:46 pm by minesadorada »
GPL Apps: Health MonitorRetro Ski Run
OnlinePackageManager Components: LazAutoUpdate, LongTimer, PoweredBy, ScrollText, PlaySound, CryptINI

tk

  • Sr. Member
  • ****
  • Posts: 361
Re: Linux binaries too big
« Reply #10 on: January 15, 2017, 11:01:46 am »
I can confirm this. My 64-bit dynamic libraries (.so) on Linux are always about 2x the size of 64-bit .dll on Windows or 64-bit .dylib on OS X.
Yes, my dylib/OS X version of the shared library is about 2.9 MB, that is only slightly bigger than the Windows binary. Only Linux binaries are so big.

Add -k--print-gc-sections to FPC command line to see what gets stripped out with a normal executable when -XX is used (--gc-sections).
I can see lot of these messages for the executable but none for the shared lib:
Code: [Select]
/usr/bin/ld: Removing unused section ...
So it really seems that -XX has no effect for shared libraries on Linux.
Quote
--gc-sections decides which input sections are used by examining symbols and relocations. The section containing the entry symbol and all sections containing symbols undefined on the command-line will be kept, as will sections containing symbols referenced by dynamic objects. Note that when building shared libraries, the linker must assume that any visible symbol is referenced. Once this initial set of sections has been determined, the linker recursively marks as used any section referenced by their relocations. See --entry and --undefined.
So as far as I understand this it is clearly a linker issue, which cannot be influenced by the compiler and we must count with bigger sizes of shared libraries on Linux.

UPX:
I know about it but as I said, the bigger sizes are not a problem for me/us. I just wanted to know why the Linux shared library binaries are so big. Today's hard disks are very big and I/we always use installers/packagers to decrease the size of the binaries for distribution. So I don't see the need for upx anymore...

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Linux binaries too big
« Reply #11 on: January 15, 2017, 12:00:44 pm »
Note this very important quote from Marco:
Quote
Note that the first (smartlinking) goes for all used components (FPC rtl+packages+lcl+whatever you compiled yourself), not just your project.
You really need to build EVERYTHING including all Lazarus libraries with -CX -XX -Xs.
You will find that only in that case the executable size approaches that on Windows.
I always do that from the command-line and a specific configuration.

Also, try to optimize it with whole program optimization. (not straightforward to do, but not rocket science either)
« Last Edit: January 15, 2017, 12:08:18 pm by Thaddy »
Specialize a type, not a var.

tk

  • Sr. Member
  • ****
  • Posts: 361
Re: Linux binaries too big
« Reply #12 on: January 15, 2017, 12:34:04 pm »
You really need to build EVERYTHING including all Lazarus libraries with -CX -XX -Xs.
You will find that only in that case the executable size approaches that on Windows.
I always do that from the command-line and a specific configuration.

I am pretty sure I did this but one never knows, that's why I am asking here.
Can you confirm the binary size approaches that on Windows for a Linux build of the shared library I attached im my previous post or any of your shared libraries, on your Linux system?
If yes please specify exact instructions how to build them.

I repeat we are talking now only about shared libraries, not executable programs.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Linux binaries too big
« Reply #13 on: January 15, 2017, 02:04:09 pm »
So as far as I understand this it is clearly a linker issue, which cannot be influenced by the compiler and we must count with bigger sizes of shared libraries on Linux.

If it is true, it has not been verified yet. The problem is that it is not just an OS difference, but also the way how FPC was build ON that OS.

In that, Thaddy is right, the observations only count if it has been proven without a doubt that the whole system is built with smartlinking.



tk

  • Sr. Member
  • ****
  • Posts: 361
Re: Linux binaries too big
« Reply #14 on: January 15, 2017, 02:22:27 pm »
Wait, do I have to rebuild FPC itself with smartlinking? This I did not! But even if this would matter, then why is the size of EXE similar as on Win and the size of DLL so different? Note that, of course, I compiled both of the attached fresh projects with the same compiler.

Also note that I get the same results both for the compiler built on Linux and the Linux crosscompiler built on Windows. Both compilers were built in a "default" way (on Linux with make clean all and on Windows with fpcupdeluxe).

 

TinyPortal © 2005-2018