diff --git a/Marlin/Makefile b/Marlin/Makefile
index 930a200719e765080cd03c3bab5f8a144e16f6a9..9eed5cdf3a0ca4d0cc386521cc9f3040f064579c 100644
--- a/Marlin/Makefile
+++ b/Marlin/Makefile
@@ -227,6 +227,22 @@ OPT = s
 
 DEFINES ?=
 
+# Program settings
+CC = $(AVR_TOOLS_PATH)avr-gcc
+CXX = $(AVR_TOOLS_PATH)avr-g++
+OBJCOPY = $(AVR_TOOLS_PATH)avr-objcopy
+OBJDUMP = $(AVR_TOOLS_PATH)avr-objdump
+AR  = $(AVR_TOOLS_PATH)avr-ar
+SIZE = $(AVR_TOOLS_PATH)avr-size
+NM = $(AVR_TOOLS_PATH)avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Tool for testing compiler flags
+cc-option=$(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`" \
+    ; then echo "$(2)"; else echo "$(3)"; fi ;)
+
 # Place -D or -U options here
 CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)}
 CXXDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)}
@@ -251,10 +267,12 @@ CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
 endif
 #CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
 
-CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING)
-CXXFLAGS =         $(CDEFS) $(CINCS) -O$(OPT) -Wall    $(CEXTRA) $(CTUNING)
+CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING) \
+    $(call cc-option,$(CC),-flto -fwhole-program,)
+CXXFLAGS :=         $(CDEFS) $(CINCS) -O$(OPT) -Wall    $(CEXTRA) $(CTUNING) \
+    $(call cc-option,$(CC),-flto -fwhole-program,)
 #ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
-LDFLAGS = -lm
+LDFLAGS = -lm -Wl,--relax
 
 
 # Programming support using avrdude. Settings and variables.
@@ -264,18 +282,6 @@ AVRDUDE_FLAGS = -D -C $(ARDUINO_INSTALL_DIR)/hardware/tools/avrdude.conf \
 	-p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
 	-b $(UPLOAD_RATE)
 
-# Program settings
-CC = $(AVR_TOOLS_PATH)avr-gcc
-CXX = $(AVR_TOOLS_PATH)avr-g++
-OBJCOPY = $(AVR_TOOLS_PATH)avr-objcopy
-OBJDUMP = $(AVR_TOOLS_PATH)avr-objdump
-AR  = $(AVR_TOOLS_PATH)avr-ar
-SIZE = $(AVR_TOOLS_PATH)avr-size
-NM = $(AVR_TOOLS_PATH)avr-nm
-AVRDUDE = avrdude
-REMOVE = rm -f
-MV = mv -f
-
 # Define all object files.
 OBJ = ${patsubst %.c, $(BUILD_DIR)/%.o, ${SRC}}
 OBJ += ${patsubst %.cpp, $(BUILD_DIR)/%.o, ${CXXSRC}}
@@ -372,9 +378,13 @@ extcoff: $(TARGET).elf
 	$(NM) -n $< > $@
 
 	# Link: create ELF output file from library.
-$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
+$(BUILD_DIR)/$(TARGET).elf: $(BUILD_DIR)/$(TARGET).o
+	$(Pecho) "  CXX   $@"
+	$P $(CC) $(ALL_CXXFLAGS) -Wl,--gc-sections -o $@ -L. $^ $(LDFLAGS)
+
+$(BUILD_DIR)/$(TARGET).o: $(OBJ) Configuration.h
 	$(Pecho) "  CXX   $@"
-	$P $(CC) $(ALL_CXXFLAGS) -Wl,--gc-sections -o $@ -L. $(OBJ) $(LDFLAGS)
+	$P $(CC) $(ALL_CXXFLAGS) -nostdlib -Wl,-r -o $@ $(OBJ)
 
 $(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE)
 	$(Pecho) "  CC    $<"