From 15e20d87001099d629beff8b31ff6a9af497fce1 Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Thu, 9 Oct 2025 01:58:45 +0800 Subject: [PATCH 1/4] Refine build system for efficient configurations This addresses build system inefficiencies and compatibility issues: 1. Configuration change detection: Use cmp-based comparison to avoid unnecessary rebuilds when configuration hasn't actually changed. Previously, every make run would touch .config and trigger full rebuilds. 2. Directory creation optimization: Replace runtime mkdir -p $(shell dirname) calls with order-only prerequisites (|). Add mkdir -p $(dir $@) to compilation rules to ensure subdirectories exist for nested object files (build/dtc/libfdt/*.o, build/devices/*.o). 3. Configuration dependency tracking: Add $(CONFIG_FILE) as explicit prerequisite to all compilation rules. This ensures object files rebuild when feature flags change (e.g., ENABLE_JIT=1 -> 0). 4. Emscripten SDL2_mixer fix: Add -sSTRICT=0 to CFLAGS_emcc to disable STRICT mode. The emscripten-ports/SDL2_mixer repository was archived in Jan 2024 and has warnings in music_modplug.c that become fatal errors under STRICT mode's -Werror flag. 5. CI scan-build fix: Set LATEST_RELEASE=dummy environment variable in scan-build steps. This prevents network-dependent prebuilt file downloads while avoiding 32-bit compilation requirements (ENABLE_PREBUILT=0 triggers -m32 flag which requires 32-bit development libraries). 6. Build system hygiene: Remove duplicate .PHONY declarations, fix shell script indentation in riscv-arch-test.mk, and add .PHONY coverage for all target declarations. --- .github/workflows/main.yml | 6 +++++ Makefile | 53 +++++++++++++++++++++++++++++++++----- mk/external.mk | 8 +++--- mk/riscv-arch-test.mk | 8 +++--- mk/softfloat.mk | 6 +++-- mk/system.mk | 9 +++++-- mk/tests.mk | 20 +++++++++----- mk/tools.mk | 4 ++- mk/wasm.mk | 8 +++++- 9 files changed, 96 insertions(+), 26 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4cb3308b7..a752cfa7a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -283,6 +283,7 @@ jobs: - name: Architecture test env: CC: ${{ steps.install_cc.outputs.cc }} + LATEST_RELEASE: dummy run: | .ci/riscv-tests.sh if: ${{ always() }} @@ -492,6 +493,7 @@ jobs: - name: Architecture test env: CC: ${{ steps.install_cc.outputs.cc }} + LATEST_RELEASE: dummy run: | python3 -m venv venv . venv/bin/activate @@ -529,8 +531,12 @@ jobs: sudo apt-get install -q=2 clang-18 clang-tools-18 shell: bash - name: run scan-build without JIT + env: + LATEST_RELEASE: dummy run: make distclean && scan-build-18 -v -o ~/scan-build --status-bugs --use-cc=clang-18 --force-analyze-debug-code --show-description -analyzer-config stable-report-filename=true -enable-checker valist,nullability make ENABLE_EXT_F=0 ENABLE_SDL=0 ENABLE_JIT=0 - name: run scan-build with JIT + env: + LATEST_RELEASE: dummy run: | make ENABLE_JIT=1 distclean && scan-build-18 -v -o ~/scan-build --status-bugs --use-cc=clang-18 --force-analyze-debug-code --show-description -analyzer-config stable-report-filename=true -enable-checker valist,nullability make ENABLE_EXT_F=0 ENABLE_SDL=0 ENABLE_JIT=1 diff --git a/Makefile b/Makefile index e3eae877f..f1f581b39 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ include mk/common.mk include mk/toolchain.mk +# Verify GNU make version (3.80+ required for order-only prerequisites) +ifeq ($(filter 3.80 3.81 3.82 3.83 3.84 4.% 5.%,$(MAKE_VERSION)),) +$(error GNU make 3.80 or higher is required. Current version: $(MAKE_VERSION)) +endif + OUT ?= build BIN := $(OUT)/rv32emu @@ -46,6 +51,7 @@ endif # Device Tree(initrd, memory range) # src/io.c(memory init) # src/riscv.c(system emulation layout init) +# Note: These memory settings are for SYSTEM mode only (when ELF_LOADER=0) ifeq ($(call has, SYSTEM), 1) ifeq ($(call has, ELF_LOADER), 0) MiB = 1024*1024 @@ -66,6 +72,7 @@ CFLAGS_dt += -DMEM_START=0x$(MEM_START) \ -DINITRD_END=0x$(shell echo "obase=16; ibase=16; \ $(REAL_MEM_SIZE) - $(call compute_size, $(DTB_SIZE)) - 1" | bc) +# Memory size for SYSTEM mode (may be overridden by FULL4G if ENABLE_ELF_LOADER=1) CFLAGS += -DMEM_SIZE=0x$(REAL_MEM_SIZE) -DDTB_SIZE=0x$(REAL_DTB_SIZE) -DINITRD_SIZE=0x$(REAL_INITRD_SIZE) endif endif @@ -225,7 +232,22 @@ endif # Full access to a 4 GiB address space, necessitating more memory mapping # during emulator initialization. $(call set-feature, FULL4G) + +# Configuration validation and conflict detection +ifeq ($(call has, SDL), 1) +ifeq ($(call has, SYSTEM), 1) +ifeq ($(call has, ELF_LOADER), 0) +ifeq ($(call has, FULL4G), 0) + $(warning SDL requires FULL4G=1 but SYSTEM forces FULL4G=0. Set ENABLE_ELF_LOADER=1 or disable SDL/SYSTEM) +endif +endif +endif +endif + ifeq ($(call has, FULL4G), 1) +# Note: If both SYSTEM and FULL4G are enabled with ELF_LOADER=1, +# this MEM_SIZE definition will override the SYSTEM mode definition. +# This is intentional for ELF loader use cases. CFLAGS += -DMEM_SIZE=0xFFFFFFFFULL # 2^{32} - 1 endif @@ -278,6 +300,8 @@ ifeq ($(call has, JIT), 1) else $(error No llvm-config-18 installed. Check llvm-config-18 installation in advance, or use "ENABLE_T2C=0" to disable tier-2 LLVM compiler) endif + else + $(warning T2C (tier-2 compiler) is disabled. Using tier-1 JIT only.) endif ifneq ($(processor),$(filter $(processor),x86_64 aarch64 arm64)) $(error JIT mode only supports for x64 and arm64 target currently.) @@ -318,7 +342,7 @@ DTB_DEPS := $(BUILD_DTB) $(BUILD_DTB2C) endif endif -all: config $(DTB_DEPS) $(BIN) +all: config $(DTB_DEPS) $(BUILD_DTB) $(BUILD_DTB2C) $(BIN) OBJS := \ map.o \ @@ -353,19 +377,31 @@ ifeq ($(call has, GDBSTUB), 1) $(OBJS): $(GDBSTUB_LIB) endif -$(OUT)/%.o: src/%.c $(deps_emcc) - $(Q)mkdir -p $(shell dirname $@) +$(OUT)/%.o: src/%.c $(CONFIG_FILE) $(deps_emcc) | $(OUT) + $(Q)mkdir -p $(dir $@) $(VECHO) " CC\t$@\n" $(Q)$(CC) -o $@ $(CFLAGS) $(CFLAGS_emcc) -c -MMD -MF $@.d $< -$(BIN): $(OBJS) $(DEV_OBJS) +$(OUT): + $(Q)mkdir -p $@ + +$(BIN): $(OBJS) $(DEV_OBJS) | $(OUT) $(VECHO) " LD\t$@\n" $(Q)$(CC) -o $@ $(CFLAGS_emcc) $^ $(LDFLAGS) +$(CONFIG_FILE): FORCE + $(Q)mkdir -p $(OUT) + $(Q)echo "$(CFLAGS)" | xargs -n1 | sort | sed -n 's/^RV32_FEATURE/ENABLE/p' > $@.tmp + $(Q)if ! cmp -s $@ $@.tmp 2>/dev/null; then \ + mv $@.tmp $@; \ + $(PRINTF) "Configuration updated. Check $(OUT)/.config for configured items.\n"; \ + else \ + $(RM) $@.tmp; \ + fi + +.PHONY: FORCE config +FORCE: config: $(CONFIG_FILE) -$(CONFIG_FILE): - $(Q)echo "$(CFLAGS)" | xargs -n1 | sort | sed -n 's/^RV32_FEATURE/ENABLE/p' > $@ - $(VECHO) "Check the file $(OUT)/.config for configured items.\n" # Tools include mk/tools.mk @@ -460,4 +496,7 @@ distclean: clean $(Q)-$(RM) -r $(SOFTFLOAT_DUMMY_PLAT) $(OUT)/softfloat $(Q)$(call notice, [OK]) +.PHONY: all config tool check check-hello misalign misalign-in-blk-emu mmu-test +.PHONY: gdbstub-test doom quake clean distclean artifact + -include $(deps) diff --git a/mk/external.mk b/mk/external.mk index 16f9fa443..b4d7f68ec 100644 --- a/mk/external.mk +++ b/mk/external.mk @@ -4,10 +4,10 @@ COMPRESSED_IS_DIR := EXTRACTOR := VERIFIER := -# temporarily files to store correct SHA value and computed SHA value +# Temporary files to store correct SHA value and computed SHA value # respectively for verification of directory source -$(eval SHA_FILE1 := $(shell mktemp)) -$(eval SHA_FILE2 := $(shell mktemp)) +SHA_FILE1 := $(shell mktemp) +SHA_FILE2 := $(shell mktemp) # $(1): compressed source define prologue @@ -17,7 +17,7 @@ endef # $(1), $(2), $(3): files to be deleted define epilogue - $(eval _ := $(shell $(RM) $(1) $(2) $(3))) + $(RM) $(1) $(2) $(3) endef # $(1): compressed source URL diff --git a/mk/riscv-arch-test.mk b/mk/riscv-arch-test.mk index 5ca0941d4..941e50091 100644 --- a/mk/riscv-arch-test.mk +++ b/mk/riscv-arch-test.mk @@ -1,8 +1,8 @@ riscof-check: $(Q)if [ "$(shell pip show riscof 2>&1 | head -n 1 | cut -d' ' -f1)" = "WARNING:" ]; then \ - $(PRINTF) "Run 'pip3 install -r requirements.txt to install dependencies.\n"; \ - exit 1; \ - fi; + $(PRINTF) "Run 'pip3 install -r requirements.txt' to install dependencies.\n"; \ + exit 1; \ + fi ARCH_TEST_DIR ?= tests/riscv-arch-test ARCH_TEST_SUITE ?= $(ARCH_TEST_DIR)/riscv-test-suite @@ -27,3 +27,5 @@ endif --config=$(RISCV_TARGET)/config.ini \ --suite=$(ARCH_TEST_SUITE) \ --env=$(ARCH_TEST_DIR)/riscv-test-suite/env + +.PHONY: riscof-check arch-test diff --git a/mk/softfloat.mk b/mk/softfloat.mk index acc9a9e2f..cb82a5e0f 100644 --- a/mk/softfloat.mk +++ b/mk/softfloat.mk @@ -334,11 +334,13 @@ $(SOFTFLOAT_DUMMY_PLAT): $(Q)touch $@ $(SOFTFLOAT_FILES): $(SOFTFLOAT_SENTINEL) -$(OUT)/softfloat/%.o: $(SOFTFLOAT_DIR)/%.c $(SOFTFLOAT_SENTINEL) $(SOFTFLOAT_DUMMY_PLAT) - $(Q)mkdir -p $(shell dirname $@) +$(OUT)/softfloat/%.o: $(SOFTFLOAT_DIR)/%.c $(CONFIG_FILE) $(SOFTFLOAT_SENTINEL) $(SOFTFLOAT_DUMMY_PLAT) | $(OUT)/softfloat $(OUT)/softfloat/RISCV $(VECHO) " CC\t$@\n" $(Q)$(CC) -o $@ $(CFLAGS) $(CFLAGS_softfloat) -c -MMD -MF $@.d $< +$(OUT)/softfloat $(OUT)/softfloat/RISCV: + $(Q)mkdir -p $@ + SOFTFLOAT_LIB := $(OUT)/softfloat/softfloat.a $(SOFTFLOAT_LIB): $(SOFTFLOAT_OBJS) $(VECHO) " AR\t$@\n" diff --git a/mk/system.mk b/mk/system.mk index 14d73591e..6f63fb44a 100644 --- a/mk/system.mk +++ b/mk/system.mk @@ -29,10 +29,13 @@ $(BUILD_DTB2C): $(BIN_TO_C) $(BUILD_DTB) $(VECHO) " BIN2C\t$@\n" $(Q)$(BIN_TO_C) $(BUILD_DTB) > $@ -$(DEV_OUT)/%.o: $(DEV_SRC)/%.c $(deps_emcc) - $(Q)mkdir -p $(DEV_OUT) +$(DEV_OUT)/%.o: $(DEV_SRC)/%.c $(CONFIG_FILE) $(deps_emcc) | $(DEV_OUT) $(VECHO) " CC\t$@\n" $(Q)$(CC) -o $@ $(CFLAGS) $(CFLAGS_emcc) -c -MMD -MF $@.d $< + +$(DEV_OUT): + $(Q)mkdir -p $@ + DEV_OBJS := $(patsubst $(DEV_SRC)/%.c, $(DEV_OUT)/%.o, $(wildcard $(DEV_SRC)/*.c)) deps := $(DEV_OBJS:%.o=%.o.d) @@ -46,4 +49,6 @@ system_deps += artifact $(BUILD_DTB) $(BUILD_DTB2C) $(BIN) system: $(system_deps) $(system_action) +.PHONY: system + endif diff --git a/mk/tests.mk b/mk/tests.mk index 29816e3c3..cf89f82ab 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -85,11 +85,13 @@ $(CACHE_TEST_TARGET): $(CACHE_TEST_OBJS) $(VECHO) " CC\t$@\n" $(Q)$(CC) $^ -o $@ $(LDFLAGS) -$(CACHE_TEST_OUTDIR)/%.o: $(CACHE_TEST_SRCDIR)/%.c +$(CACHE_TEST_OUTDIR)/%.o: $(CACHE_TEST_SRCDIR)/%.c $(CONFIG_FILE) | $(CACHE_TEST_OUTDIR) $(CACHE_TEST_OUTDIR)/lfu $(VECHO) " CC\t$@\n" - $(Q)mkdir -p $(dir $@)/lfu $(Q)$(CC) -o $@ $(CFLAGS) -I./src -c -MMD -MF $@.d $< +$(CACHE_TEST_OUTDIR) $(CACHE_TEST_OUTDIR)/lfu: + $(Q)mkdir -p $@ + $(MAP_TEST_OUT): $(MAP_TEST_TARGET) $(Q)touch $@ @@ -97,11 +99,13 @@ $(MAP_TEST_TARGET): $(MAP_TEST_OBJS) $(VECHO) " CC\t$@\n" $(Q)$(CC) $^ -o $@ $(LDFLAGS) -$(MAP_TEST_OUTDIR)/%.o: $(MAP_TEST_SRCDIR)/%.c +$(MAP_TEST_OUTDIR)/%.o: $(MAP_TEST_SRCDIR)/%.c $(CONFIG_FILE) | $(MAP_TEST_OUTDIR) $(VECHO) " CC\t$@\n" - $(Q)mkdir -p $(dir $@) $(Q)$(CC) -o $@ $(CFLAGS) -I./src -c -MMD -MF $@.d $< +$(MAP_TEST_OUTDIR): + $(Q)mkdir -p $@ + $(PATH_TEST_OUT): $(PATH_TEST_TARGET) $(Q)touch $@ @@ -109,7 +113,11 @@ $(PATH_TEST_TARGET): $(PATH_TEST_OBJS) $(VECHO) " CC\t$@\n" $(Q)$(CC) $^ -o $@ $(LDFLAGS) -$(PATH_TEST_OUTDIR)/%.o: $(PATH_TEST_SRCDIR)/%.c +$(PATH_TEST_OUTDIR)/%.o: $(PATH_TEST_SRCDIR)/%.c $(CONFIG_FILE) | $(PATH_TEST_OUTDIR) $(VECHO) " CC\t$@\n" - $(Q)mkdir -p $(dir $@) $(Q)$(CC) -o $@ $(CFLAGS) -I./src -c -MMD -MF $@.d $< + +$(PATH_TEST_OUTDIR): + $(Q)mkdir -p $@ + +.PHONY: tests run-test-cache run-test-map run-test-path diff --git a/mk/tools.mk b/mk/tools.mk index 0d6a2157f..fbef691fa 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -23,7 +23,7 @@ HIST_OBJS := \ HIST_OBJS := $(addprefix $(OUT)/, $(HIST_OBJS)) deps += $(HIST_OBJS:%.o=%.o.d) -$(OUT)/%.o: tools/%.c +$(OUT)/%.o: tools/%.c | $(OUT) $(VECHO) " CC\t$@\n" $(Q)$(CC) -o $@ $(CFLAGS) -Wno-missing-field-initializers -Isrc -c -MMD -MF $@.d $< @@ -39,3 +39,5 @@ LINUX_IMAGE_SRC = $(BUILDROOT_DATA) $(LINUX_DATA) build-linux-image: $(LINUX_IMAGE_SRC) $(Q)./tools/build-linux-image.sh $(Q)$(PRINTF) "Build done.\n" + +.PHONY: build-linux-image diff --git a/mk/wasm.mk b/mk/wasm.mk index 21c0d2d60..78b818cd3 100644 --- a/mk/wasm.mk +++ b/mk/wasm.mk @@ -18,7 +18,10 @@ CFLAGS += -mtail-call # Build emscripten-port SDL ifeq ($(call has, SDL), 1) -CFLAGS_emcc += -sUSE_SDL=2 -sSDL2_MIXER_FORMATS=wav,mid -sUSE_SDL_MIXER=2 +# Disable STRICT mode to avoid -Werror in SDL2_mixer port compilation. +# The emscripten-ports/SDL2_mixer was archived in Jan 2024 and has warnings +# in music_modplug.c that become fatal errors under STRICT mode. +CFLAGS_emcc += -sSTRICT=0 -sUSE_SDL=2 -sSDL2_MIXER_FORMATS=wav,mid -sUSE_SDL_MIXER=2 OBJS_EXT += syscall_sdl.o LDFLAGS += -pthread endif @@ -159,4 +162,7 @@ start-web: $(start_web_deps) $(foreach T, $(STATIC_WEB_FILES), $(call cp-web-file, $(T))) $(Q)mv $(DEMO_DIR)/*.html $(DEMO_DIR)/index.html $(Q)python3 -m http.server --bind $(DEMO_IP) $(DEMO_PORT) --directory $(DEMO_DIR) + +.PHONY: check-demo-dir-exist start-web + endif From a2ff417bd32e686acb3e85790bc4ba631a6bcb4f Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Thu, 9 Oct 2025 11:35:59 +0800 Subject: [PATCH 2/4] Add SDL_MIXER feature flag for conditional audio mixing support Introduce ENABLE_SDL_MIXER feature flag to conditionally compile SDL2_mixer-dependent audio code. This allows SDL2 graphics support without the problematic SDL2_mixer library in emscripten builds. emscripten-ports/SDL2_mixer (archived in 2024) has unfixable compilation warnings in music_modplug.c. The port system enforces -sSTRICT -Werror which cannot be overridden. --- Makefile | 13 +++++++++++++ src/syscall_sdl.c | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/Makefile b/Makefile index f1f581b39..dbe9d4e63 100644 --- a/Makefile +++ b/Makefile @@ -199,6 +199,7 @@ ENABLE_FULL4G ?= 0 # Experimental SDL oriented system calls ENABLE_SDL ?= 1 +ENABLE_SDL_MIXER ?= 1 ifneq ("$(CC_IS_EMCC)", "1") # note that emcc generates port SDL headers/library, so it does not requires system SDL headers/library ifeq ($(call has, SDL), 1) ifeq (, $(shell which sdl2-config)) @@ -208,18 +209,30 @@ endif ifeq (1, $(shell pkg-config --exists SDL2_mixer; echo $$?)) $(warning No SDL2_mixer lib installed. Check SDL2_mixer installation in advance) override ENABLE_SDL := 0 +override ENABLE_SDL_MIXER := 0 endif endif +else +# Disable SDL_MIXER for emscripten builds to avoid SDL2_mixer port compilation issues +# The emscripten-ports/SDL2_mixer was archived in Jan 2024 with unfixable warnings +override ENABLE_SDL_MIXER := 0 +endif $(call set-feature, SDL) +$(call set-feature, SDL_MIXER) ifeq ($(call has, SDL), 1) OBJS_EXT += syscall_sdl.o +ifneq ("$(CC_IS_EMCC)", "1") $(OUT)/syscall_sdl.o: CFLAGS += $(shell sdl2-config --cflags) +endif # 4 GiB of memory is required to run video games. ENABLE_FULL4G := 1 +ifneq ("$(CC_IS_EMCC)", "1") LDFLAGS += $(shell sdl2-config --libs) -pthread +ifeq ($(call has, SDL_MIXER), 1) LDFLAGS += $(shell pkg-config --libs SDL2_mixer) endif endif +endif # If SYSTEM is enabled and ELF_LOADER is not, then skip FULL4G bacause guestOS # has dedicated memory mapping range. diff --git a/src/syscall_sdl.c b/src/syscall_sdl.c index ae95b37fb..32a339721 100644 --- a/src/syscall_sdl.c +++ b/src/syscall_sdl.c @@ -15,7 +15,9 @@ #include #include +#if RV32_HAS(SDL_MIXER) #include +#endif #include "riscv.h" #include "riscv_private.h" @@ -94,11 +96,13 @@ typedef struct sound { /* SDL-mixer-related and music-related variables */ static pthread_t music_thread; static uint8_t *music_midi_data; +#if RV32_HAS(SDL_MIXER) static Mix_Music *mid; /* SDL-mixer-related and sfx-related variables */ static pthread_t sfx_thread; static Mix_Chunk *sfx_chunk; +#endif static uint8_t *sfx_samples; static uint32_t nr_sfx_samples; static int chan; @@ -718,6 +722,7 @@ uint8_t *mus2midi(uint8_t *data, int *length) return midi_data; } +#if RV32_HAS(SDL_MIXER) static void *sfx_handler(void *arg) { sound_t *sfx = (sound_t *) arg; @@ -836,8 +841,10 @@ static void play_sfx(riscv_t *rv) .size = sfx_data_size, .volume = volume, }; +#if RV32_HAS(SDL_MIXER) pthread_create(&sfx_thread, NULL, sfx_handler, &sfx); sfx_thread_init = true; +#endif /* FIXME: In web browser runtime, web workers in thread pool do not reap * after sfx_handler return, thus we have to join them. sfx_handler does not * contain infinite loop,so do not worry to be stalled by it */ @@ -893,8 +900,10 @@ static void play_music(riscv_t *rv) .looping = looping, .volume = volume, }; +#if RV32_HAS(SDL_MIXER) pthread_create(&music_thread, NULL, music_handler, &music); music_thread_init = true; +#endif /* FIXME: In web browser runtime, web workers in thread pool do not reap * after music_handler return, thus we have to join them. music_handler does * not contain infinite loop,so do not worry to be stalled by it */ @@ -916,6 +925,7 @@ static void set_music_volume(riscv_t *rv) /* multiplied by 8 because volume's max is 15 */ Mix_VolumeMusic(volume * 8); } +#endif /* RV32_HAS(SDL_MIXER) */ static void init_audio(void) { @@ -933,6 +943,7 @@ static void init_audio(void) exit(EXIT_FAILURE); } +#if RV32_HAS(SDL_MIXER) /* Initialize SDL2 Mixer */ if (Mix_Init(MIX_INIT_MID) != MIX_INIT_MID) { rv_log_fatal("Mix_Init failed: %s", Mix_GetError()); @@ -943,6 +954,7 @@ static void init_audio(void) Mix_Quit(); exit(EXIT_FAILURE); } +#endif audio_init = true; } @@ -956,6 +968,7 @@ static void shutdown_audio() * on a valid pthread_t identifier. */ +#if RV32_HAS(SDL_MIXER) if (music_thread_init) { stop_music(); pthread_join(music_thread, NULL); @@ -974,6 +987,7 @@ static void shutdown_audio() Mix_CloseAudio(); Mix_Quit(); +#endif audio_init = sfx_thread_init = music_thread_init = false; } @@ -1020,16 +1034,24 @@ void syscall_control_audio(riscv_t *rv) switch (request) { case PLAY_MUSIC: +#if RV32_HAS(SDL_MIXER) play_music(rv); +#endif break; case PLAY_SFX: +#if RV32_HAS(SDL_MIXER) play_sfx(rv); +#endif break; case SET_MUSIC_VOLUME: +#if RV32_HAS(SDL_MIXER) set_music_volume(rv); +#endif break; case STOP_MUSIC: +#if RV32_HAS(SDL_MIXER) stop_music(); +#endif break; default: rv_log_error("Unknown sound control request: %d", request); From 1cc6d5718ec88c7f871759bb0978717b689aaa05 Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Thu, 9 Oct 2025 14:09:22 +0800 Subject: [PATCH 3/4] Fix CI regressions This addresses multiple CI failures related to Architecture tests and SDL_MIXER installation across different platforms. --- .github/workflows/main.yml | 19 ++++++++++++++++--- Makefile | 7 +------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a752cfa7a..e491a8429 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -283,8 +283,14 @@ jobs: - name: Architecture test env: CC: ${{ steps.install_cc.outputs.cc }} - LATEST_RELEASE: dummy run: | + . .ci/common.sh + export LATEST_RELEASE=$(download_with_headers "https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases" \ + "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + | grep '"tag_name"' \ + | grep "sail" \ + | head -n 1 \ + | sed -E 's/.*"tag_name": "([^"]+)".*/\1/') .ci/riscv-tests.sh if: ${{ always() }} @@ -342,7 +348,8 @@ jobs: - uses: actions/checkout@v4 - name: install-dependencies run: | - brew install make dtc expect sdl2 sdl2_mixer bc e2fsprogs p7zip llvm@18 dcfldd + brew install make dtc expect sdl2 bc e2fsprogs p7zip llvm@18 dcfldd + brew install sdl2_mixer || echo "Warning: sdl2_mixer installation failed, continuing without SDL_MIXER support" .ci/riscv-toolchain-install.sh echo "${{ github.workspace }}/toolchain/bin" >> $GITHUB_PATH echo "$(brew --prefix llvm@18)/bin" >> $GITHUB_PATH @@ -493,8 +500,14 @@ jobs: - name: Architecture test env: CC: ${{ steps.install_cc.outputs.cc }} - LATEST_RELEASE: dummy run: | + . .ci/common.sh + export LATEST_RELEASE=$(download_with_headers "https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases" \ + "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + | grep '"tag_name"' \ + | grep "sail" \ + | head -n 1 \ + | sed -E 's/.*"tag_name": "([^"]+)".*/\1/') python3 -m venv venv . venv/bin/activate .ci/riscv-tests.sh diff --git a/Makefile b/Makefile index dbe9d4e63..4481ed3ae 100644 --- a/Makefile +++ b/Makefile @@ -207,15 +207,10 @@ $(warning No sdl2-config in $$PATH. Check SDL2 installation in advance) override ENABLE_SDL := 0 endif ifeq (1, $(shell pkg-config --exists SDL2_mixer; echo $$?)) -$(warning No SDL2_mixer lib installed. Check SDL2_mixer installation in advance) -override ENABLE_SDL := 0 +$(warning No SDL2_mixer lib installed. SDL2_mixer support will be disabled) override ENABLE_SDL_MIXER := 0 endif endif -else -# Disable SDL_MIXER for emscripten builds to avoid SDL2_mixer port compilation issues -# The emscripten-ports/SDL2_mixer was archived in Jan 2024 with unfixable warnings -override ENABLE_SDL_MIXER := 0 endif $(call set-feature, SDL) $(call set-feature, SDL_MIXER) From 18f6db1e0267dc252e3038eba2cecd3a6dc1307b Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Mon, 27 Oct 2025 23:00:16 +0800 Subject: [PATCH 4/4] Fix SDL mixer guards and cleanup --- src/syscall_sdl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/syscall_sdl.c b/src/syscall_sdl.c index 32a339721..9930cf908 100644 --- a/src/syscall_sdl.c +++ b/src/syscall_sdl.c @@ -849,8 +849,10 @@ static void play_sfx(riscv_t *rv) * after sfx_handler return, thus we have to join them. sfx_handler does not * contain infinite loop,so do not worry to be stalled by it */ #ifdef __EMSCRIPTEN__ +#if RV32_HAS(SDL_MIXER) pthread_join(sfx_thread, NULL); #endif +#endif } static void play_music(riscv_t *rv) @@ -908,8 +910,10 @@ static void play_music(riscv_t *rv) * after music_handler return, thus we have to join them. music_handler does * not contain infinite loop,so do not worry to be stalled by it */ #ifdef __EMSCRIPTEN__ +#if RV32_HAS(SDL_MIXER) pthread_join(music_thread, NULL); #endif +#endif } static void stop_music() @@ -981,14 +985,17 @@ static void shutdown_audio() pthread_join(sfx_thread, NULL); Mix_HaltChannel(-1); Mix_FreeChunk(sfx_chunk); - free(sfx_samples); - sfx_samples = NULL; } Mix_CloseAudio(); Mix_Quit(); #endif + if (sfx_samples) { + free(sfx_samples); + sfx_samples = NULL; + } + audio_init = sfx_thread_init = music_thread_init = false; }