Description
I am working on a project with an Arduino MEGA2560 using IDE 1.8.12 and keep running up against a bug that I have determined is in the linker. The bug occurs randomly as I modify the code. My research, see below, indicates that it is related to relative jumps and calls. The most promising solution I have found is the reorder two libraries via a custom make file. I have not found a good way to do this on a Windows platform. There is a Linux make file solution it seems, however, I do not have a linux box and can't get Hyper-V on Windows 10 to share the USB port to reach the Atmega 2560.
Here is a post thread from the forum: https://forum.arduino.cc/index.php?topic=671220.0
I have attached a version of my code that causes the bug to occur.
PH Meter 20200430A.zip
When compiled the following error message occurs:
C:\Users\steve\AppData\Local\Temp\cceoUYLk.ltrans0.ltrans.o: In function `main':
:(.text.startup+0x2624): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Mega or Mega 2560.
Here is an article I found on a workaround to the library link order issue. It may be related and provide some illumination.
https://www.stix.id.au/wiki/AVR_relocation_truncations_workaround
From this article by Paul Ripke (aka “stix”) [email protected]:
...libm uses RCALL and RJMP which use a space and execution time efficient instruction format. However, it is limited to a 13-bit signed PC-relative offset - ±4KiB. Normally these symbols should be resolved to the ones present in libm, however, in the above output, ld is resolving them to the duplicate symbols present in libgcc.
This is a known bug (libavr and gcc) that seems to not have received much love. A workaround is to force the library order passed to the linker, passing libm before libgcc. The avr-g++ command line becomes:
/usr/pkg/bin/avr-g++ -mmcu=atmega2560 -I. -DF_CPU=16000000 -DARDUINO=105 -I/home/stix/src/arduino-1.0.5/hardware/arduino/cores/arduino -I/home/stix/src/arduino-1.0.5/libraries/LiquidCrystal -I/home/stix/src/arduino-1.0.5/libraries/Wire -I/home/stix/src/arduino-1.0.5/libraries/utility/twi -I../libraries/DS1307RTC -I../libraries/OneWire -I../libraries/Time -I/home/stix/src/arduino-1.0.5/libraries/LiquidCrystal/utility/ -I/home/stix/src/arduino-1.0.5/libraries/Wire/utility/ -I/home/stix/src/arduino-1.0.5/libraries/utility/twi/utility/ -I../libraries/DS1307RTC/utility/ -I../libraries/OneWire/utility/ -I../libraries/Time/utility/ -I/home/stix/src/arduino-1.0.5/hardware/arduino/variants/mega -Os -mno-short-calls -o applet/thermo.elf applet/thermo.cpp -L. applet/core.a -nodefaultlibs -Wl,--gc-sections -lm -lgcc -lc -lgcc
That is, pass -nodefaultlibs to prevent libgcc and libc being automatically added, and append -lm -lgcc -lc -lgcc. The second -lgcc is required to resolve symbols in libgcc referenced by libc.