usart sketch uploaded using makefile gives unusual behaviour This is a simple usart program in avr c which just transmits a character.

#include &lt;avr/io.h&gt;
#include &lt;util/delay.h&gt;
#define F_CPU 16000000UL
#define BAUD 9600 
#define BAUD_PRESCALLER ((F_CPU / (BAUD * 16UL)) - 1)
void send_val(unsigned char);
int main() {


UBRR0H = (uint8_t)(BAUD_PRESCALLER&gt;&gt;8);
UBRR0L = (uint8_t)(BAUD_PRESCALLER);
UCSR0B = (1&lt;&lt;TXEN0);
unsigned char x = 'B';
while(1) {

    send_val(x);
    _delay_ms(1000);
}

return 0;
}

void send_val(unsigned char v) {
while(!(UCSR0A &amp; (1&lt;&lt;UDRE0)));
UDR0 = v;

}


when I upload this code via the Arduino IDE, everything is fine and the code works as expected.The LED labeled "L" on the PCB is still.

but, when I upload the code using the following Makefile, the code uploads successfully but the outcome is unexpected. I see a weird character(see EDIT) and the LED "L" blinks a couple of times in that 1 sec delay.

CC=avr-gcc
OBJCOPY=avr-objcopy

CFLAGS=-Os -DF_CPU=16000000UL -mmcu=atmega328p
PORT=/dev/ttyACM0

led.hex: led.elf
    ${OBJCOPY} -O ihex -R .eeprom led.elf led.hex

led.elf: led.o
    ${CC} -o led.elf led.o

install: led.hex
    avrdude -F -V -c arduino -p ATMEGA328P -P ${PORT} -b 115200 -U flash:w:led.hex


I referred the Schematics and the led is connected to SCK but I don't understand why the makefile is causing it to trigger. 
that blinking of LED is what I think is causing the issue. Does the IDE have some other specific flags while uploading the code or am I committing some silly mistake?

EDIT: I wrote a small program to see the values in the device node /dev/ttyACM0. the ASCII value of the weired character(looks like a question mark) is actually 255.

another issue I noticed is that when I touch the solder beneath the pin 13 (only pin 13) the led L goes off!

As led L is connected to pin 13 I thought this is some hardware issue with my board but then I uploaded the blink led example code, touched the solder and everything is fine.

what could be the actual issue? this is getting mysterious.
The -mmcu=atmega328p compiler flag is needed not only for the compile
phase, but also for the link phase. Otherwise the linker will not know
which CRT (C run time) to link with your program, and it will link none.
The CRT is responsible for things like initializing the stack pointer,
clearing r1 (as required by the AVR calling convention) and calling
your main().

Edit: the following simplified Makefile should work if you have a
modern version of avrdude that understands ELF files:

CC     = avr-gcc
MCU    = atmega328p
CFLAGS = -Os -DF_CPU=16000000UL -mmcu=${MCU}
PORT   = /dev/ttyACM0

led.elf: led.c
    ${CC} ${CFLAGS} $&lt; -o $@

install: led.elf
    avrdude -c arduino -p ${MCU} -P ${PORT} -b 115200 -U $&lt;


Otherwise you can keep your rules for led.elf → led.hex → install.