I have a AVR GCC toolchain compiled to work on aarch64-linux-gnu devices (ARM64) and it produced twice larger file (around 35Kb) than almost identical command-line on desktop (mac silicon, around 20Kb):

Android

13:41:48.329 8114  System.out               I  avr-g++ -no-canonical-prefixes -std=gnu++11 -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fpermissive -fno-threadsafe-statics -mmcu=atmega328p -DF_CPU=16000000L -MMD -flto -Wno-error=narrowing -DARDUINO=10607 -DARDUINO_ARCH_AVR -DARDUINO_AVR_UNO -v -I/data/user/0/com.app/files/sdk/hardware/arduino/variants/standard -I/data/user/0/com.app/files/sdk/hardware/arduino/cores/arduino /data/user/0/com.app/files/sdk/hardware/arduino/cores/arduino/HardwareSerial.cpp -o /data/user/0/com.app/files/coreBuild/HardwareSerial.cpp.o 

Desktop

/Users/developer/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/Users/developer/Library/Arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino -I/Users/developer/Library/Arduino15/packages/arduino/hardware/avr/1.8.6/variants/standard /Users/developer/Library/Arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.cpp -o /Users/developer/Library/Caches/arduino/sketches/7DB601531F17D390EF34F3CA8F8B77C9/core/HardwareSerial.cpp.o

I've passed "-v" flag and i can see the binaries are configured with different flags.

Android:

13:41:48.334 8114  System.err               W  Configured with: /home/developer/tools/ct-ng_1.24.0-f7b1ece/build/.build/HOST-aarch64-linux-gnu/avr/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=aarch64-host_unknown-linux-gnu --target=avr --prefix=/home/developer/x-tools/HOST-aarch64-linux-gnu/avr --with-local-prefix=/home/developer/x-tools/HOST-aarch64-linux-gnu/avr/avr --with-headers=/home/developer/x-tools/HOST-aarch64-linux-gnu/avr/avr/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG 1.24.0-rc3.1-f7b1ece' --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --with-gmp=/home/developer/tools/ct-ng_1.24.0-f7b1ece/build/.build/HOST-aarch64-linux-gnu/avr/buildtools/complibs-host --with-mpfr=/home/developer/tools/ct-ng_1.24.0-f7b1ece/build/.build/HOST-aarch64-linux-gnu/avr/buildtools/complibs-host --with-mpc=/home/developer/tools/ct-ng_1.24.0-f7b1ece/build/.build/HOST-aarch64-linux-gnu/avr/buildtools/complibs-host --disable-lto --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++ -lm' --enable-target-optspace --disable-nls --enable-multiarch --enable-languages=c,c++ --enable-plugins --enable-lto
...
13:41:48.336 8114  System.err               W  GNU C++11 (crosstool-NG 1.24.0-rc3.1-f7b1ece) version 7.3.0 (avr)
13:41:48.336 8114  System.err               W   compiled by GNU C version 7.5.0, GMP version 5.0.2, MPFR version 3.1.0, MPC version 0.9, isl version none

Desktop:

Configured with: ../gcc/configure --enable-fixed-point --enable-languages=c,c++ --prefix=/Users/jenkins/jenkins/workspace/avr-gcc-staging/label/mac-mini/objdir --disable-nls --disable-libssp --disable-libada --disable-shared --with-avrlibc=yes --with-dwarf2 --disable-doc --target=avr
Thread model: single
...
GNU C++11 (GCC) version 7.3.0 (avr)
    compiled by GNU C version 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38), GMP version 5.0.2, MPFR version 3.1.0, MPC version 0.9, isl version none

What argument makes an impact on final .o file size to make it twice larger? Is it possible to avoid rebuilding toolchain and pass some runtime (cmd) arguments to avoid using what something that inflates the file?

6 Replies 6

Why the hell are you using Newlib (--with-newlib) and not AVR-LibC?

To see the difference, you can

  • Disassemble the code with avr-objdump and see what's different.
  • Analyze the objects with tools like avr-nm, avr-readelf, etc.
  • Build a map file with -Wl,-Map,my.map. This will generate a map file, simple text. It shows what modules are used for what reason, sizes, location etc.

And the size of an object also depends on the used debug info, e.g. -g0 vs. -g2 vs. -g3. Not a big deal since debug info is noload.

Also it may be helpful to show what options are different. It's hard to compare these extra long lines by hand, in particular because the options are in different places / are rearranged.

Apart from that, you can avoid many headaches wrt the host libs like GMP, MPFR, MPC etc by having them built in one go with GCC. It will download the required source versions and configure / build them locally. All you have to do is to run ./contrib/download-prerequisites from GCC top source with a web connection.

--disable-lto ... --enable-lto also looks strange.

I've also found the difference from the very beginning:

flag 0x11 on android and flag 0x10 on desktop version of the file and the sections list is different.

I'm very confused by using "newlib" instead of avr-libc, that's very surprising. I can't believe it's actually used and the sketch is actually working (at least LED is blinking).

Android

objdump -x ./HardwareSerial.cpp.o.android 

./HardwareSerial.cpp.o.android:     file format elf32-avr
./HardwareSerial.cpp.o.android
architecture: avr:5, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .group        00000008  00000000  00000000  00000034  2**2
                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD
  1 .text         00000000  00000000  00000000  0000003c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .data         00000000  00000000  00000000  0000003c  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .bss          00000000  00000000  00000000  0000003c  2**0
                  ALLOC
  4 .stab         00000e64  00000000  00000000  0000003c  2**2
                  CONTENTS, RELOC, READONLY, DEBUGGING
  5 .stabstr      00005004  00000000  00000000  00000ea0  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .gnu.lto_.profile.c4d17fbb731c47e6 00000014  00000000  00000000  00005ea4  2**0
...

Desktop:

objdump -x ./HardwareSerial.cpp.o.desktop

./HardwareSerial.cpp.o.desktop:     file format elf32-avr
./HardwareSerial.cpp.o.desktop
architecture: avr:5, flags 0x00000010:
HAS_SYMS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000000  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000034  2**0
                  ALLOC
  3 .gnu.lto_.profile.4bb1434b0876c6b6 00000014  00000000  00000000  00000034  2**0
                  CONTENTS, READONLY, EXCLUDE
...

LTO section is added in both cases so i guess it partly answers `--disable-lto and --enable-lto` note.

...moreover, the Arduino tools may have applied some patches. Did you apply them to the sources before building the tools for the new host?

Yup, i did. However it's still unexpected to see such a big difference.

Also seems to be a difference in the linkonce stuff, which indicates you are using a different Binutils version.

Also notice that in Canadian cross config like in your build, configure may have trouble figuring out the exact host tool properties since it cannot run programs on the host since host ≠ build. Tools avaiable on build may serve as a proxy. What you can also try is to configure with --with-gnu-as --with-gnu-ld so GCC configure knows you are using the GNU Binutils.

Also only one configure uses --with-dwarf2 which may explain the differences. Maybe the difference goes away when compiling with -gdwarf-2 etc.

-dwarf-2 did not help (checked out objdump output), but having -flto -ffunctions-sections -fdata-sections during the linking (not compilation to object file) helped!

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.