lang/Makefile
2025-05-13 18:24:52 +02:00

244 lines
6.2 KiB
Makefile

# Basic configuration
TARGET := langc
AFLAGS = -felf64 -F dwarf -g
ifdef DEBUG
AFLAGS += -DDEBUG_BUILD
endif
# Directory structure
SRCDIR := src
OBJDIR := obj
LIBDIR := lib
# Core directories
COREDIR := $(SRCDIR)/core
MATHDIR := $(COREDIR)/math
VECDIR := $(COREDIR)/vector
STRDIR := $(COREDIR)/string
SBDIR := $(COREDIR)/string_builder
PRINTDIR := $(COREDIR)/print
MEMDIR := $(COREDIR)/mem
SYSCALLDIR := $(COREDIR)/syscall
FILEDIR := $(COREDIR)/file
# Parser directories
PARSEDIR := $(SRCDIR)/parse
EXPRDIR := $(PARSEDIR)/expression
TOKDIR := $(PARSEDIR)/token
# Lexer directories
LEXDIR := $(SRCDIR)/lexer
VARDIR := $(LEXDIR)/vars
# Other directories
GLOBALDIR := $(SRCDIR)/global
# Object file directories (mirroring source structure)
OBJCOREDIR := $(OBJDIR)/core
OBJMATHDIR := $(OBJCOREDIR)/math
OBJVECDIR := $(OBJCOREDIR)/vector
OBJSTRDIR := $(OBJCOREDIR)/string
OBJSBDIR := $(OBJCOREDIR)/string_builder
OBJPRINTDIR := $(OBJCOREDIR)/print
OBJMEMDIR := $(OBJCOREDIR)/mem
OBJSYSCALLDIR := $(OBJCOREDIR)/syscall
OBJFILEDIR := $(OBJCOREDIR)/file
OBJPARSEDIR := $(OBJDIR)/parse
OBJEXPRDIR := $(OBJPARSEDIR)/expression
OBJTOKDIR := $(OBJPARSEDIR)/token
OBJLEXDIR := $(OBJDIR)/lexer
OBJVARDIR := $(OBJLEXDIR)/vars
OBJGLOBALDIR := $(OBJDIR)/global
# All object directories in dependency order
OBJDIRS := $(OBJDIR) \
$(OBJCOREDIR) \
$(OBJMATHDIR) \
$(OBJVECDIR) \
$(OBJSTRDIR) \
$(OBJSBDIR) \
$(OBJPRINTDIR) \
$(OBJMEMDIR) \
$(OBJSYSCALLDIR) \
$(OBJFILEDIR) \
$(OBJPARSEDIR) \
$(OBJEXPRDIR) \
$(OBJTOKDIR) \
$(OBJLEXDIR) \
$(OBJVARDIR) \
$(OBJGLOBALDIR)
# Source file definitions by module
MATHSRC := $(addprefix $(MATHDIR)/, $(addsuffix .s, \
operators \
))
STRSRC := $(addprefix $(STRDIR)/, $(addsuffix .s, \
strlen split strcpy substr is_num strcmp is_alpha \
))
MEMSRC := $(addprefix $(MEMDIR)/, $(addsuffix .s, \
malloc memchr memcpy memset \
))
VECSRC := $(addprefix $(VECDIR)/, $(addsuffix .s, \
vec_create vec_push vec_get vec_pop \
))
PRINTSRC := $(addprefix $(PRINTDIR)/, $(addsuffix .s, \
print putnumber \
))
FILESRC := $(addprefix $(FILEDIR)/, $(addsuffix .s, \
read_file get_file_content \
))
SYSCALLSRC := $(addprefix $(SYSCALLDIR)/, $(addsuffix .s, \
exit file_ops syscall_err fork\
))
TOKSRC := $(addprefix $(TOKDIR)/, $(addsuffix .s, \
parse_tokens debug_token \
))
EXPRSRC := $(addprefix $(EXPRDIR)/, $(addsuffix .s, \
create_expressions debug_expression \
))
LEXSRC := $(addprefix $(LEXDIR)/, $(addsuffix .s, \
lexer lex_err lex_load lex_func program_prologue \
func_boiler_plate \
))
VARSRC := $(addprefix $(VARDIR)/, $(addsuffix .s, \
get_vars insert_var \
))
GLOBALSRC := $(addprefix $(GLOBALDIR)/, $(addsuffix .s, \
function_table regs \
))
SBSRC := $(addprefix $(SBDIR)/, $(addsuffix .s, \
string_builder\
))
# Collect all sources and objects
MAIN_SRC := $(SRCDIR)/start.s
ALL_SRC := $(MAIN_SRC) $(MATHSRC) $(STRSRC) $(SBSRC) $(PRINTSRC) $(FILESRC) $(VARSRC) $(SYSCALLSRC) $(MEMSRC) $(TOKSRC) $(EXPRSRC) $(LEXSRC) $(GLOBALSRC) $(VECSRC)
# Generate object file paths
ALL_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(ALL_SRC))
# Library settings
LIBNAME := $(LIBDIR)/core.a
LIB_OBJ := $(filter-out $(OBJDIR)/start.o, $(ALL_OBJ))
# Module-specific object files for staged compilation
MATH_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(MATHSRC))
STR_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(STRSRC))
MEM_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(MEMSRC))
VEC_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(VECSRC))
PRINT_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(PRINTSRC))
FILE_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(FILESRC))
SYSCALL_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(SYSCALLSRC))
TOK_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(TOKSRC))
EXPR_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(EXPRSRC))
LEX_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(LEXSRC))
VAR_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(VARSRC))
GLOBAL_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(GLOBALSRC))
SB_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(SBSRC))
MAIN_OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(MAIN_SRC))
# Main targets
all: prepare-build build-core build-parser build-lexer build-global build-main link-executable create-library
# Stage 1: Prepare build environment
prepare-build: create-directories
create-directories: | $(OBJDIRS) $(LIBDIR)
$(OBJDIRS):
mkdir -p $@
$(LIBDIR):
mkdir -p $@
# Stage 2: Build core modules
build-core: build-math build-string build-memory build-vector build-print build-file build-syscall build-string-builder
build-math: $(MATH_OBJ)
build-string: $(STR_OBJ)
build-memory: $(MEM_OBJ)
build-vector: $(VEC_OBJ)
build-print: $(PRINT_OBJ)
build-file: $(FILE_OBJ)
build-syscall: $(SYSCALL_OBJ)
build-string-builder: $(SB_OBJ)
# Stage 3: Build parser modules
build-parser: build-tokens build-expressions
build-tokens: $(TOK_OBJ)
build-expressions: $(EXPR_OBJ)
# Stage 4: Build lexer modules
build-lexer: build-lex-core build-lex-vars
build-lex-core: $(LEX_OBJ)
build-lex-vars: $(VAR_OBJ)
# Stage 5: Build global modules
build-global: $(GLOBAL_OBJ)
# Stage 6: Build main entry point
build-main: $(MAIN_OBJ)
# Stage 7: Link executable
link-executable: $(TARGET)
$(TARGET): $(ALL_OBJ)
ld -g -o $@ $(ALL_OBJ) -nostdlib -static
# Stage 8: Create library
create-library: $(LIBNAME)
$(LIBNAME): $(LIB_OBJ) | $(LIBDIR)
ar rcs $@ $(LIB_OBJ)
# Individual file compilation rule
$(OBJDIR)/%.o: $(SRCDIR)/%.s | $(OBJDIRS)
nasm $(AFLAGS) $< -o $@
# Utility targets
clean:
rm -rf $(OBJDIR)
clean-library:
rm -f $(LIBNAME)
clean-executable:
rm -f $(TARGET)
fclean: clean clean-library clean-executable
re: fclean all
# Debug target to show what would be built
show-config:
@echo "Target: $(TARGET)"
@echo "Flags: $(AFLAGS)"
@echo "Source files: $(words $(ALL_SRC)) files"
@echo "Object files: $(words $(ALL_OBJ)) files"
@echo "Object directories: $(OBJDIRS)"