Since sdcc
have some limitations, like compiling one file at a time, I've tried hard to write a Makefile to perfect the automation of MCS-51 development, which have some requirements:
- Source file (.c) expect main.c are stored in
ProjectFolder/Sources/
, whilemain.c
are stored at the root of project folder. - Headers are stored in
ProjectFolder/Includes/
. - Outputs through compiling, linking and locating should be stored at
ProjectFolder/Builds/
- Makefile should be smart enough to find all source files, instead of type their file name by hand.
- Makefile should be smart enough to if there are some files in
Sources/
, or there's onlymain.c
in the project.
The file structure can be depicted like:
Project Folder
|
|- Sources
| |
| |(some source files, but OPTIONAL)
|
|- Includes
| |
| |(some headers, but OPTIONAL)
|
|- Builds
| |
| |(some .rel .o .hex files. OUTPUT here)
|
|- main.c
|
|- Makefile
Here's my solution but still have a problem. It cannot be used for project only have one file main.c
which means no source file in Sources/
.
INCLUDES = Includes/
SOURCES = Sources/
BUILDS = Builds/
CC = sdcc
CFLAGS = -o $(BUILDS)
LOADER = stcgal
LOADER_FLAGS = -P stc89
$(BUILDS)main.ihx: main.c $(BUILDS)main.rel
# Link
@$(CC) main.c $(shell find $(BUILDS) -name "*.rel" -not -name "main.rel" -maxdepth 1) $(CFLAGS)
@echo Link & Locate Succeeded
$(BUILDS)main.rel: $(SOURCES) $(BUILDS)
# Compile
@for f in $(shell ls $(SOURCES)*.c) ; do \
$(CC) -c $${f} $(CFLAGS) ; \
done
@echo Compile Succeeded
$(SOURCES):
@mkdir $(SOURCES)
$(BUILDS):
@mkdir $(BUILDS)
clean:
# Remove all files in build folder
@rm $(BUILDS)*
@echo Build Folder Cleaned
load: $(BUILDS)main.ihx
# Load data to MCU via USB port
@$(LOADER) $(LOADER_FLAGS) -p $(shell ls /dev/tty.usbserial*) $(BUILDS)main.ihx