Für asm-Ausgabe guckst du
https://www.roboternetz.de/wissen/in...en_mit_avr-gcc

Ich finde make ist was für Leute, die ihre Schwiegermutter gemeuchelt haben Ich benutz es zwar auch, aber je universeller Makefiles sind, desto schwerer sind sie auch zu verstehen/anzupassen und erst recht zu debuggen.

Meine sind ganz simpel gehalten. Was ich da nich brauche hab ich rausgeworfen. Ursprünlich sind die aus den Beispielen, die WinAVR mitbringt.

Code:
PRG            = main
SRC            = time.c $(PRG).c timer1.c dcf.c fifo.c uart.c uput.c rc5.c
OBJ            = $(SRC:.c=.o)

MCU_TARGET     = atmega8
#MCU_TARGET     = at90s2313
OPTIMIZE       = -Os

RESET_SCRIPT   = /d/avr/bin/reset.sh
BURN_SCRIPT    = /d/avr/bin/burn-prog.sh
INCLUDES		   = 

DEFS           = -DF_CPU=10000000 	-DDCF_DEBUG  \
						-DUART_OUTFIFO
LIBS           =

# You should not have to change anything below here.

CC             = avr-gcc

.PHONY: all clean size burn lst hex eeprom depend reset

# Override is only needed by avr-lib build system.

CFLAGS        = -mmcu=$(MCU_TARGET) -Wall $(OPTIMIZE) -Winline -fno-keep-inline-functions $(DEFS) $(INCLUDES) -fno-common 
LDFLAGS       = -mmcu=$(MCU_TARGET) -Wl,-Map,$(PRG).map -Wl,-section-start=.eeprom=0x810001
ASMFLAGS      = -dp -save-temps -fverbose-asm
OBJCOPY        = avr-objcopy
OBJDUMP        = avr-objdump

all: depend $(PRG).elf lst hex eeprom

fsize:
	avr-nm --size-sort -S $(PRG).elf

depend:
	$(CC) -MM $(SRC) -mmcu=$(MCU_TARGET) $(DEFS) $(INCLUDES) > .depend
	
size: #$(PRG).elf $(OBJ)
	avr-size -x $(OBJ)
	avr-size -C --mcu=$(MCU_TARGET) $(PRG).elf |grep -E '^(Data)|(Pro)|(AVR)'

$(PRG).elf: $(OBJ)
	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

-include .depend

%.o: %.c Makefile
	$(CC) $(CFLAGS) $< -S $(ASMFLAGS)
	$(CC) $(CFLAGS) $< -c -o $@ 

clean:
	rm -rf *.o $(PRG).elf *.bak *.s *.i *.c.*
	rm -rf *.lst *.map
	rm -f .depend

lst:  $(PRG).lst

reset:
	sh $(RESET_SCRIPT) $(MCU_TARGET)
	
burn: 
	sh $(BURN_SCRIPT) $(PRG).hex $(MCU_TARGET)

%.lst: %.elf
	$(OBJDUMP) -h -S -j .data -j .eeprom -j .text $< > $@

# Rules for building the .text rom images

hex: $(PRG).hex

%.hex: %.elf
	$(OBJCOPY) -j .text -j .data -O ihex $< $@

# Rules for building the .eeprom rom images

eeprom:  $(PRG)_eeprom.hex

%_eeprom.hex: %.elf
	$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
Da es sich um 8-Bit-µC handelt sind die Projekte alle kleine und überschauber (im ggs zu Host-Projekten).

Von der Organsation würde man nicht das LCD Zeug unter das Projektverzeichnis legen, sondern besser auf gleiche Ebene. Auch würde man nicht aus dem Projekt Makefie heraus generieren, sondern LCD hätte ein eigenes Makefile, das aus dem PRJ Makefile angestossen wird.
Code:
cd ../xxx && make
Evtl ist besser, eine Lib zu erzeugen und im PRJ nur noch gegen diese Lib zu linken. Das schliesst aber bestimmte Optimierungen/Anpassungen aus. Das LCD Zeug ist ja keine Lib (auch keine Lib-Quelle), sondern ein Quellpaket.