mjspier
mjspier

Reputation: 6526

why my executable is bigger after linking

I have a small C program which I need to run on different chips. The executable should be smaller than 32kb. For this I have several toolchains with different compilers for arm, mips etc.

The program consists of several files which each is compiled to an object file and then linked together to an executable.

When I use the system gcc (x86) my executable is 15kb big. With the arm toolchain the executable is 65kb big. With another toolchain it is 47kb.

For example for arm all objects which are included in the executable are 14kb big together.

The objects are compiled with the following options:

-march=armv7-m -mtune=cortex-m3 -mthumb -msoft-float -Os

For linking the following options are used:

-s -specs=nosys.specs -march-armv7-m

The nosys.specs library is 274 bytes big.

Why is my executable still so much bigger (65kb) when my code is only 14kb and the library 274 bytes?

Update:

After suggestions from the answer I removed all malloc and printf commands from my code and removed the unused includes. Also I added the compile flags -ffunction-sections -fdata-sections and linking flag --gc-sections , but the executable is still too big.

For experimenting I created a dummy program:

int main()
{
    return 1;
}

When I compile the program with different compilers I get very different executable sizes:

8.3 KB : gcc -Os
22 KB  : r2-gcc -Os
40 KB  : arm-gcc --specs=nosys.specs -Os
1.1 KB : avr-gcc -Os

So why is my arm-gcc executable so much bigger? The avr-gcc executable does static linking as well, I guess.

Upvotes: 2

Views: 496

Answers (2)

lrouter
lrouter

Reputation: 379

The embedded software porting depends on target hardware and software platform. The hardware platforms are splitted into mcu, cpus which could run linux os. The software platform includes compiler toolchain and libraries.

It's meaningless to compare the program image size for mcu and x86 hardware platform. But it's worth to compare the program image size on the same type of CPU using different toolchains.

Upvotes: 0

user149341
user149341

Reputation:

Your x86 executable is probably being dynamically linked, so any standard library functions you use -- malloc, printf, string and math functions, etc -- are not included in the binary.

The ARM executable is being statically linked, so those functions must be included in your binary. This is why it's larger. To make it smaller, you may want to consider compiling with -ffunction-sections -fdata-sections, then linking with --gc-sections to discard any unused functions or data from your binary.

(The "nosys.specs library" is not a library. It's a configuration file. The real library files are elsewhere.)

Upvotes: 6

Related Questions