-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
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 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)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/ (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.
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:
/usr/bin/ld: Removing unused section ...
--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.
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 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.
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.
First: the compiler itself does not matter but the RTL and FCL and the FPC packages should...be build with -Cg -Xc -XX -CX and maybe -Xs
Second: Why would you need Forms and Interfaces in a shared library? That is bad practice: It will pull in ALL code, since a shared library will never be able to distinguish what you need.
A simple shared library is a few KB on Linux. Add classes for some Pzazz and it is still under 1 MB. (867 KB on ARM-LINUX.Note it still pulls in ALL of classes)Unfortunately I do not have simple libraries. Compare library size for a library that takes min. 200kB on Windows. What takes it on your Linux then?
The template for a shared library looks plainly stupid for Linux, but also in general.The default library template in Lazarus of course comes without any LCL dependency.
Unfortunately I do not have simple libraries. Compare library size for a library that takes min. 200kB on Windows. What takes it on your Linux then?
Depends: between 253 K and 800K.
Make a proof.I interpreted it differently - I tested one simple and one complex shared lib - but this should be around 250k on arm-linux. On Windows and 32bit intel linux it is much smaller:
library simple;
{$CALLING C}
uses initc; // this is actually needed for an so to make it callable from other languages.
function AddMe(const a,b:integer):integer;
begin
AddMe := a+b;
end;
exports AddMe;
begin
end.
I interpreted it differently
That means the sizes should converge to a similar size with larger dynlibs. And that is what I see.