# ============================================================================== # H2 CORE PLATFORM v6.0 -- LVGL SHARED LIBRARY BUILD # ============================================================================== # Architecture (Phase 6 decision): # LVGL v8.3.11 + lv_drivers v8.3.0 are built ONCE as liblvgl.so (~200KB). # All 12 module binaries and the master broker link DYNAMICALLY against it. # Before: 13 copies x ~200KB = ~2.6MB of duplicated graphics code. # After: 1 shared lib (~200KB) + 13 tiny modules (~4KB each) = ~252KB total. # # Rationale: # LVGL provides a battle-tested widget factory (labels, lists, keyboards, # dropdowns, sliders, charts, rollers, text areas). Direct framebuffer # would require hand-rolling every UI primitive. For future expansion, # adding module N+1 costs ~4KB (just the module logic) instead of ~200KB. # The shared library approach eliminates bloat while preserving the full # LVGL API surface for future use. # # Toolchain: mipsel-linux-musl-gcc (MIPS32r2 little-endian, musl libc) # Target: Ingenic T31 / HiFiWalker H2 (320x240 LCD, rotary encoder input) # ============================================================================== CC = mipsel-linux-musl-gcc STRIP = mipsel-linux-musl-strip # --- compiler flags --- CFLAGS_BASE = -march=mips32r2 -mhard-float -O2 \ -Wall -Wextra -Werror -Wno-unused-parameter \ -fstack-protector-strong -D_FORTIFY_SOURCE=2 \ -DLV_CONF_INCLUDE_SIMPLE -I. -I./lvgl -I./lv_drivers # Module CFLAGS: position-independent code not needed for the final # executables, but we need -fPIC for any code that calls LVGL functions # exported from the shared library. On musl/ELF, executables linking # against a .so do NOT need -fPIC themselves — only the .so does. CFLAGS_MOD = $(CFLAGS_BASE) -L. -llvgl -Wl,-rpath,/usr/lib # Shared library CFLAGS: must be position-independent CFLAGS_SO = $(CFLAGS_BASE) -fPIC -shared LIBS = -lm -lpthread # --- paths --- TARGET = overlay/usr/bin/h2_test MAPPER_BIN = overlay/usr/bin/emulator_input_mapper MOD_DIR = overlay/apps LIB_DIR = overlay/usr/lib # --- platform binaries (no LVGL dependency) --- CFLAGS_PLAT = -march=mips32r2 -mhard-float -O2 \ -Wall -Wextra -Werror -Wno-unused-parameter \ -fstack-protector-strong -D_FORTIFY_SOURCE=2 # --- LVGL sources (built into the shared library) --- LVGL_SRC = $(wildcard lvgl/src/core/*.c lvgl/src/draw/*.c lvgl/src/misc/*.c) \ lv_drivers/display/fbdev.c \ lv_drivers/indev/evdev.c LVGL_OBJ = $(LVGL_SRC:.c=.lo) # --- module map: source file -> output binary --- MODULES = \ vault:vault.c \ nettap:scalpel.c \ deploy:deploy.c \ studio:studio.c \ probe:probe.c \ vterm:vterm.c \ radar:noise_radar.c \ ducky:ducky.c \ extract:extract.c \ noise:noise.c \ reset:reset.c \ emulator:emulator.c # expand to flat lists for make MOD_NAMES = $(foreach m,$(MODULES),$(word 1,$(subst :, ,$m))) MOD_SOURCES = $(foreach m,$(MODULES),$(word 2,$(subst :, ,$m))) MOD_BINS = $(foreach n,$(MOD_NAMES),$(MOD_DIR)/$(n).mod) # ============================================================================== .PHONY: all submodules clean help all: submodules $(LIB_DIR)/liblvgl.so $(TARGET) $(MAPPER_BIN) $(MOD_BINS) @echo "======================================================================" @echo "[OK] H2 Core Platform v6.0 built." @echo " Shared lib: $(LIB_DIR)/liblvgl.so" @echo " Launcher: $(TARGET)" @echo " Mapper: $(MAPPER_BIN)" @echo " Modules: $(MOD_BINS)" @echo "======================================================================" # --- fetch LVGL + lv_drivers if not present --- submodules: @if [ ! -d "lvgl/src" ]; then \ echo "[*] Cloning LVGL v8.3.11 + lv_drivers v8.3.0..."; \ git clone --depth 1 -b v8.3.11 https://github.com/lvgl/lvgl.git; \ git clone --depth 1 -b v8.3.0 https://github.com/lvgl/lv_drivers.git; \ fi @if [ ! -f "lv_conf.h" ]; then \ echo "[*] Installing lv_conf.h..."; \ cp lv_conf.h.dist lv_conf.h; \ fi @if [ ! -f "lv_drv_conf.h" ]; then \ cp lv_drivers/lv_drv_conf_template.h lv_drv_conf.h; \ sed -i 's/#if 0/#if 1/' lv_drv_conf.h; \ sed -i 's/USE_FBDEV 0/USE_FBDEV 1/' lv_drv_conf.h; \ sed -i 's/USE_EVDEV 0/USE_EVDEV 1/' lv_drv_conf.h; \ fi # --- shared library: liblvgl.so --- $(LIB_DIR)/liblvgl.so: $(LVGL_OBJ) @mkdir -p $(LIB_DIR) $(CC) -shared -Wl,-soname,liblvgl.so -o $@ $^ $(LIBS) $(STRIP) --strip-unneeded $@ # compile LVGL sources as .lo (library objects, position-independent) %.lo: %.c $(CC) $(CFLAGS_SO) -c $< -o $@ # --- master launcher --- $(TARGET): main.c $(LIB_DIR)/liblvgl.so $(CC) $(CFLAGS_MOD) main.c -o $@ $(LIBS) $(STRIP) $@ # --- emulator input mapper (no LVGL, standalone daemon) --- $(MAPPER_BIN): emulator_input_mapper.c @mkdir -p $(dir $@) $(CC) $(CFLAGS_PLAT) emulator_input_mapper.c -o $@ $(STRIP) --strip-unneeded $@ # --- module binaries (pattern rule from the MODULES map) --- # Each module links dynamically against liblvgl.so define MODULE_RULE $(MOD_DIR)/$(word 1,$(subst :, ,$1)).mod: $(word 2,$(subst :, ,$1)) $(LIB_DIR)/liblvgl.so $$(CC) $$(CFLAGS_MOD) $(word 2,$(subst :, ,$1)) -o $$@ $$(LIBS) $$(STRIP) $$@ endef $(foreach m,$(MODULES),$(eval $(call MODULE_RULE,$(m)))) # --- cleanup --- clean: rm -f $(LVGL_OBJ) rm -f $(LIB_DIR)/liblvgl.so rm -f $(TARGET) rm -f $(MAPPER_BIN) rm -f $(MOD_BINS) help: @echo "H2 Core Platform v6.0 -- LVGL Shared Library Build" @echo "" @echo "Targets:" @echo " all Build everything (default)" @echo " submodules Clone LVGL + lv_drivers if missing" @echo " clean Remove all build artifacts" @echo "" @echo "Architecture:" @echo " liblvgl.so Shared LVGL library -> overlay/usr/lib/" @echo " h2_test Master launcher -> overlay/usr/bin/" @echo " emulator_* Input mapper daemon -> overlay/usr/bin/" @echo " *.mod Module binaries -> overlay/apps/" @echo "" @echo "Key flags: -Werror -fstack-protector-strong -D_FORTIFY_SOURCE=2" @echo " -Wl,-rpath,/usr/lib (modules find liblvgl.so at runtime)"