title: AVR linker error, "relocation truncated to fit"
body: <p>I'm trying to compile some code for an ATmega328 micro, and I want use the libraries and the core of Arduino. I'm using <a href="http://en.wikipedia.org/wiki/CMake" rel="noreferrer">CMake</a>. I have gotten to compile the core library and all objects of my code and the libraries of Arduino. But when it's linking, they show me the following error.</p>
  
  <blockquote>
    <p>..."relocation truncated to fit: R_AVR_13_PCREL against
    symbol"..."avr5/libgcc.a"...</p>
  </blockquote>
  
  <p>I have <a href="http://www.google.es/search?q=relocation%20truncated%20to%20fit&amp;ie=utf-8&amp;oe=utf-8&amp;aq=t&amp;rls=org.mozilla%3aes-ES%3aofficial&amp;client=firefox-a#pq=avr-gcc%20relocation%20truncated%20to%20fit&amp;hl=es&amp;cp=16&amp;gs_id=38&amp;xhr=t&amp;q=avr-gcc%20libgcc.a%20relocation%20truncated%20to%20fit&amp;pf=p&amp;sclient=psy-ab&amp;safe=off&amp;client=firefox-a&amp;hs=tCV&amp;rls=org.mozilla%3aes-ES%3aofficial&amp;source=hp&amp;pbx=1&amp;oq=avr-gcc%20libgcc.a%20relocation%20truncated%20to%20fit&amp;aq=f&amp;aqi=&amp;aql=&amp;gs_sm=&amp;gs_upl=&amp;bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&amp;fp=1326fd29ce0ae023&amp;biw=1680&amp;bih=867" rel="noreferrer">found through Google</a> that this is a common error, but no solution has worked for me. The only thing I can't do is put "-lm" and "-lc" flags at the end of the linker sentence, because I don't know how I can do it with CMake.</p>
  
  <p><strong>EDIT</strong>: I have tried compile it with makefile too but I have gotten the same result, even putting "-lm" and "-lc" flags at the end of the linker sentence.</p>
  
  <p>I put my Makefile and CMake files here:</p>
  
  <hr>
  
  <p><strong>CMakeList.txt</strong> The main CMake file</p>
  
  <pre><code>cmake_minimum_required(VERSION 2.6)
  Project(IMU)
  
  set(ARDUINO_PROCESSOR atmega328p)
  set(ARDUINO_PROCESSOR_FREQ 1600000L)
  
  include(./arduino.cmake)
  
  add_library(ardlib
          libraries/EEPROM/EEPROM.cpp
          libraries/Wire/utility/twi.c
          libraries/Wire/Wire.cpp
          libraries/HMC58X3/HMC58X3
          )
  
  LINK_DIRECTORIES(${IMU_SRC_DIR}/libarduinocore
          ${IMU_SRC_DIR}/libraries/EEPROM
          ${IMU_SRC_DIR}/libraries/Wire
          ${IMU_SRC_DIR}/libraries/HMC58X3
          )
  
  link_libraries(arduinocore ardlib)
  
  include_directories(
          libarduinocore
          libraries/EEPROM
          libraries/Wire
          libraries/Wire/utility
          libraries/HMC58X3
          )
  
  set(C_SRCS
          ADXL345.cpp
          ApplicationRoutines.cpp
          DCM.cpp
          HMC5883L.cpp
          ITG3200.cpp
          matrix.cpp
          output.cpp
          timing.cpp
          vector.cpp
          )
  
  set(C_HDRS
          ADXL345.h
          ApplicationRoutines.h
          DCM.h
          HMC5883L.h
          ITG3200.h
          matrix.h
          output.h
          timing.h
          vector.h
          declarations.h
          )
  
  add_executable(IMU.elf main.cpp ${C_SRCS} ${C_HDRS})
  
  add_subdirectory(libarduinocore)
  </code></pre>
  
  <p><strong>arduino.cmake</strong>. That is imported by CMakeList.txt:</p>
  
  <pre><code>set(ARDUINO_PROCESSOR atmega328p)
  set(ARDUINO_PROCESSOR_FREQ 16000000L)
  
  # This module defines macros intended for use by cross-compiling toolchain files when
  # CMake is not able to automatically detect the compiler identification.
  include (CMakeForceCompiler)
  
  # Set this for cross compiling.  Otherwise it is set to CMAKE_HOST_SYSTEM_NAME,
  # which is the system we are developing on.
  set (CMAKE_SYSTEM_NAME Generic)
  
  # It sets CMAKE_&lt;lang&gt;_COMPILER to the given compiler and the cmake internal variable
  # CMAKE_&lt;lang&gt;_COMPILER_ID to the given compiler-id. It also bypasses the check for
  # working compiler and basic compiler information tests.
  SET(CMAKE_C_COMPILER avr-gcc)
  SET(CMAKE_CXX_COMPILER avr-g++)
  cmake_force_cxx_compiler (avr-g++ CrossAVR)
  cmake_force_c_compiler (avr-gcc CrossAVR)
  
  # Appparently we want to use the gnuc99 standard.
  #set (CSTANDARD "-std=gnu99")
  
  # Generate .stabs debugging symbols for assembler source lines. This enables avr-gdb to
  # trace through assembler source files.
  #set (CDEBUG "-gstabs")
  
  # Warn for functions declared or defined without specified argument types.
  set (CWARN "-Wall -Wstrict-prototypes")
  
  # -funsigned-char - Make any unqualfied char type an unsigned char. Without this option,
  #   they default to a signed char.
  # -funsigned-bitfields - Make any unqualified bitfield type unsigned. By default,
  #    they are signed.
  # -fpack-struct - Pack all structure members together without holes.
  # -fshort-enums - Allocate to an enum type only as many bytes as it needs for the declared
  #   range of possible values. Specifically, the enum type will be equivalent to the
  #   smallest integer type which has enough room.
  set (CTUNING_FLAGS "-ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums")
  
  # Optimize for size.   The special option -Os is meant to turn on all -O2 optimizations
  # that are not expected to increase code size.
  set (COPT "-Os")
  
  SET(CINCS "-I${ArduinoCode_SOURCE_DIR}/libarduinocore")
  
  # Finally the compilation flags are now configured.
  set(CMAKE_CXX_FLAGS "-lc -lm -mmcu=${ARDUINO_PROCESSOR} -DF_CPU=${ARDUINO_PROCESSOR_FREQ} ${CTUNING_FLAGS} ${CWARN} ${CSTANDARD} ${CDEBUG} ${COPT} ${CINCS} -lc")
  set(CMAKE_C_FLAGS "-lc -lm ${CMAKE_CXX_FLAGS} ${CTUNING_FLAGS} ${CWARN} ${CSTANDARD} ${CDEBUG} ${CINCS} -lc")
  
  # On gentoo, -rdynamic is passed to the compiler. The avr compiler does not recognize this
  # option.  Also, we are not building shared libraries.
  set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections")
  set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS ""
  </code></pre>
  
  <p><strong>Arduino core CMake file</strong>. This is a CMakeList.txt file put into <code>libarduinocore</code> directory.</p>
  
  <pre><code>include(../arduino.cmake)
  
  
  add_library (arduinocore
          HardwareSerial.cpp
          pins_arduino.c
          Print.cpp
          Tone.cpp
          WInterrupts.c
          wiring_analog.c
          wiring.c
          wiring_digital.c
          wiring_pulse.c
          wiring_shift.c
          WMath.cpp
          WString.cpp
          )
  </code></pre>
  
  <p><strong>Makefile</strong></p>
  
  <pre><code>TARGET = IMU
  PORT = /dev/ttyACM0
  BAUD = 57600
  PROGRAMMER = arduino
  MCU = atmega328p
  F_CPU = 8000000L
  
  CXX_SRCS = ADXL345.cpp \
             ApplicationRoutines.cpp \
             DCM.cpp \
             HMC5883L.cpp \
             ITG3200.cpp \
             matrix.cpp \
             output.cpp \
             timing.cpp \
             vector.cpp
  
  CXX_OBJ = $(CXX_SRCS:.cpp=.o)
  
  CXX_HDRS = ADXL345.h \
             ApplicationRoutines.h \
             DCM.h \
             declarations.h \
             HMC5883L.h \
             ITG3200.h \
             matrix.h \
             output.h \
             timing.h \
             vector.h
  
  CORE_DIR = libarduinocore
  
  CORE_CXX_SRCS = $(CORE_DIR)/HardwareSerial.cpp \
                  $(CORE_DIR)/Print.cpp \
                  $(CORE_DIR)/Tone.cpp \
                  $(CORE_DIR)/WMath.cpp \
                  $(CORE_DIR)/WString.cpp
  
  CORE_CXX_OBJ = $(CORE_CXX_SRCS:.cpp=.o)                                                                                                                                                                        
  
  CORE_CC_SRCS = $(CORE_DIR)/pins_arduino.c \                                                                                                                                                                    
                 $(CORE_DIR)/WInterrupts.c \                                                                                                                                                                     
                 $(CORE_DIR)/wiring_analog.c \                                                                                                                                                                   
                 $(CORE_DIR)/wiring.c \                                                                                                                                                                          
                 $(CORE_DIR)/wiring_digital.c \                                                                                                                                                                  
                 $(CORE_DIR)/wiring_pulse.c \                                                                                                                                                                    
                 $(CORE_DIR)/wiring_shift.c                                                                                                                                                                      
  
  CORE_CC_OBJ = $(CORE_CC_SRCS:.c=.o)                                                                                                                                                                            
  
  CORE_HDRS = $(CORE_DIR)/binary.h \                                                                                                                                                                             
              $(CORE_DIR)/HardwareSerial.h \                                                                                                                                                                     
              $(CORE_DIR)/pins_arduino.h \                                                                                                                                                                       
              $(CORE_DIR)/Print.h \                                                                                                                                                                              
              $(CORE_DIR)/Stream.h \                                                                                                                                                                             
              $(CORE_DIR)/WCharacter.h \                                                                                                                                                                         
              $(CORE_DIR)/WConstants.h \                                                                                                                                                                         
              $(CORE_DIR)/wiring.h \                                                                                                                                                                             
              $(CORE_DIR)/wiring_private.h \                                                                                                                                                                     
              $(CORE_DIR)/WProgram.h \                                                                                                                                                                           
              $(CORE_DIR)/WString.h
  
  ARD_LIB_DIR = libraries
  
  ARD_LIB_CXX_SRCS = $(ARD_LIB_DIR)/EEPROM/EEPROM.cpp \
                     $(ARD_LIB_DIR)/Wire/Wire.cpp \
                     $(ARD_LIB_DIR)/HMC58X3/HMC58X3.cpp
  ARD_LIB_CC_SRCS = $(ARD_LIB_DIR)/Wire/utility/twi.c
  
  ARD_LIB_CXX_OBJ = $(ARD_LIB_CXX_SRCS:.cpp=.o)
  ARD_LIB_CC_OBJ = $(ARD_LIB_CC_SRCS:.c=.o)
  
  CC = avr-gcc
  CXX = avr-g++
  OBJCOPY = avr-objcopy
  OBJDUMP = avr-objdump
  AR  = avr-ar
  SIZE = avr-size
  NM = avr-nm
  AVRDUDE = avrdude
  
  ARD_LIB_INC = -I$(ARD_LIB_DIR) -I$(ARD_LIB_DIR)/EEPROM -I$(ARD_LIB_DIR)/Wire -I$(ARD_LIB_DIR)/HMC58X3 -I$(ARD_LIB_DIR)/Wire/utility
  
  FLAGS_WARN = -Wall -Wstrict-prototypes
  FLAGS_TUNING = -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
  FLAGS_OPT = -Os
  
  ALL_INC = -I. $(ARD_LIB_INC) -I$(CORE_DIR)
  OBJS = $(CXX_OBJ) $(CORE_CXX_OBJ) $(CORE_CC_OBJ) $(ARD_LIB_CC_OBJ) $(ARD_LIB_CXX_OBJ)
  ALL_OBJS := $(addprefix build/, $(notdir $(OBJS)))
  ALL_CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) $(ALL_INC) $(FLAGS_WARN) $(FLAGS_TUNNIG) $(FLAGS_OPT)
  ALL_CXXFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) $(ALL_INC) -Wall $(FLAGS_TUNNIG) $(FLAGS_OPT)
  #ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
  
  all : $(TARGET).hex
          avr-objcopy -O ihex -R .eeprom $(TARGET).out $(TARGET).hex
  
  $(TARGET).out : $(OBJS)
          $(CXX) $(ALL_CXXFLAGS) main.cpp $(ALL_OBJS) -o $(TARGET).out -lc -lm
  
  upload : $(TARGET).hex
          avrdude -c$(PROGRAMMER) -p$(MCU) -P$(PORT) -U flash:w:$(TARGET).hex
  
  serialmon :
          picocom -b$(BAUD) $(PORT)
  
  .SUFFIXES: .hex .cpp .o .c
  
  # Compile: create object files from C++ source files.
  .cpp.o:
          $(CXX) -c $(ALL_CXXFLAGS) $&lt; -o $(addprefix build/, $(notdir $@)) -lc -lm
  
  # Compile: create object files from C source files.
  .c.o:
          $(CC) -c $(ALL_CFLAGS) $&lt; -o $(addprefix build/, $(notdir $@)) -lc -lm
  
  
  # Compile: create assembler files from C source files.
  .c.s:
          $(CC) -S $(ALL_CFLAGS) $&lt; -o build/$@ -lc -lm
  </code></pre>