From eb77bbeaff6a2d3e99322ca97689b06e67d2ed54 Mon Sep 17 00:00:00 2001 From: scawful Date: Thu, 20 Nov 2025 03:01:15 -0500 Subject: [PATCH] fix: resolve Linux FLAGS symbol conflicts by moving FLAGS_quiet to flags.cc and renaming emulator test flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move FLAGS_quiet definition from cli_main.cc to flags.cc (shared flags location) - Change FLAGS_quiet in cli_main.cc to ABSL_DECLARE_FLAG (declaration only) - Rename emu_test.cc FLAGS_rom to FLAGS_emu_test_rom to avoid conflict with shared FLAGS_rom - Update usage message in emu_test.cc to reflect renamed flag This fixes multiple definition errors on Linux where FLAGS symbols were defined in multiple translation units. FLAGS_quiet is now defined once in flags.cc and declared where needed. The emulator test now uses unique flag names. Fixes symbol conflicts identified in Windows build handoff analysis. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- cmake/absl.cmake | 3 +++ src/cli/cli_main.cc | 2 +- src/cli/flags.cc | 1 + src/emu_test.cc | 10 ++++----- src/util/util.cmake | 54 +++++++++++++++++++++++++++++++-------------- 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/cmake/absl.cmake b/cmake/absl.cmake index 1653f486..d8d3b9a9 100644 --- a/cmake/absl.cmake +++ b/cmake/absl.cmake @@ -38,6 +38,9 @@ if(_yaze_use_fetched_absl) set(ABSL_ENABLE_INSTALL OFF CACHE BOOL "" FORCE) FetchContent_MakeAvailable(absl) message(STATUS "Fetched Abseil ${YAZE_ABSL_GIT_TAG}") + + # NEW: Export source directory for Windows builds that need explicit include paths + set(YAZE_ABSL_SOURCE_DIR "${absl_SOURCE_DIR}" CACHE INTERNAL "Abseil source directory") endif() endif() diff --git a/src/cli/cli_main.cc b/src/cli/cli_main.cc index cb75102e..cc2097a1 100644 --- a/src/cli/cli_main.cc +++ b/src/cli/cli_main.cc @@ -21,7 +21,7 @@ // Define all CLI flags ABSL_FLAG(bool, tui, false, "Launch interactive Text User Interface"); -ABSL_FLAG(bool, quiet, false, "Suppress non-essential output"); +ABSL_DECLARE_FLAG(bool, quiet); ABSL_FLAG(bool, version, false, "Show version information"); #ifdef YAZE_HTTP_API_ENABLED ABSL_FLAG(int, http_port, 0, diff --git a/src/cli/flags.cc b/src/cli/flags.cc index c5866521..87d1189b 100644 --- a/src/cli/flags.cc +++ b/src/cli/flags.cc @@ -6,6 +6,7 @@ ABSL_FLAG(std::string, rom, "", "Path to the ROM file"); ABSL_FLAG(bool, mock_rom, false, "Use mock ROM mode for testing without requiring an actual ROM file. " "Loads all Zelda3 embedded labels but no actual ROM data."); +ABSL_FLAG(bool, quiet, false, "Suppress non-essential output"); // AI Service Configuration Flags ABSL_FLAG(std::string, ai_provider, "auto", diff --git a/src/emu_test.cc b/src/emu_test.cc index 1169fde9..7fa1a4a0 100644 --- a/src/emu_test.cc +++ b/src/emu_test.cc @@ -17,7 +17,7 @@ #include "app/emu/snes.h" #include "util/log.h" -ABSL_FLAG(std::string, rom, "", "Path to ROM file to test"); +ABSL_FLAG(std::string, emu_test_rom, "", "Path to ROM file to test"); ABSL_FLAG(int, max_frames, 60, "Maximum frames to run (0 = infinite)"); ABSL_FLAG(int, log_interval, 10, "Log APU state every N frames"); ABSL_FLAG(bool, dump_audio, false, "Dump audio output to WAV file"); @@ -208,17 +208,17 @@ int main(int argc, char** argv) { absl::ParseCommandLine(argc, argv); // Configure logging - std::string rom_path = absl::GetFlag(FLAGS_rom); + std::string rom_path = absl::GetFlag(FLAGS_emu_test_rom); int max_frames = absl::GetFlag(FLAGS_max_frames); int log_interval = absl::GetFlag(FLAGS_log_interval); bool verbose = absl::GetFlag(FLAGS_verbose); bool trace_apu = absl::GetFlag(FLAGS_trace_apu); if (rom_path.empty()) { - std::cerr << "Error: --rom flag is required\n"; - std::cerr << "Usage: yaze_emu_test --rom=zelda3.sfc [options]\n"; + std::cerr << "Error: --emu_test_rom flag is required\n"; + std::cerr << "Usage: yaze_emu_test --emu_test_rom=zelda3.sfc [options]\n"; std::cerr << "\nOptions:\n"; - std::cerr << " --rom=PATH Path to ROM file (required)\n"; + std::cerr << " --emu_test_rom=PATH Path to ROM file (required)\n"; std::cerr << " --max_frames=N Run for N frames (0=infinite, " "default=60)\n"; std::cerr << " --log_interval=N Log APU state every N frames " diff --git a/src/util/util.cmake b/src/util/util.cmake index c5f3066c..1966218a 100644 --- a/src/util/util.cmake +++ b/src/util/util.cmake @@ -54,23 +54,6 @@ if(YAZE_ENABLE_GRPC) absl::strings absl::str_format ) - - # CRITICAL FIX FOR WINDOWS: Explicitly add Abseil include directory - # When gRPC bundles Abseil, the include paths don't always propagate correctly - # on Windows with Ninja + clang-cl. We need to explicitly add the Abseil source - # directory where headers are located. - if(WIN32) - # Get Abseil source directory from CPM or gRPC fetch - if(DEFINED absl_SOURCE_DIR) - target_include_directories(yaze_util PUBLIC ${absl_SOURCE_DIR}) - message(STATUS "Windows: Added explicit Abseil include path: ${absl_SOURCE_DIR}") - elseif(DEFINED grpc_SOURCE_DIR AND EXISTS "${grpc_SOURCE_DIR}/third_party/abseil-cpp") - target_include_directories(yaze_util PUBLIC "${grpc_SOURCE_DIR}/third_party/abseil-cpp") - message(STATUS "Windows: Added explicit Abseil include path from gRPC: ${grpc_SOURCE_DIR}/third_party/abseil-cpp") - else() - message(WARNING "Windows: Could not find Abseil source directory - build may fail") - endif() - endif() else() # Link standalone Abseil targets (configured in cmake/absl.cmake) target_link_libraries(yaze_util PUBLIC @@ -81,6 +64,43 @@ else() ) endif() +# CRITICAL FIX FOR WINDOWS: Explicitly add Abseil include directory +# Issue: Windows builds with Ninja + clang-cl fail to find Abseil headers even when +# linking to absl::* targets. This affects BOTH standalone Abseil AND gRPC-bundled Abseil. +# +# Root cause: In ci-windows preset, YAZE_ENABLE_GRPC=ON but YAZE_ENABLE_REMOTE_AUTOMATION=OFF, +# which causes options.cmake to forcibly disable gRPC. This means standalone Abseil is used, +# but the previous fix only ran when YAZE_ENABLE_GRPC=ON, so it never applied. +# +# Solution: Apply include path fix unconditionally on Windows, with multi-source detection: +# 1. Check YAZE_ABSL_SOURCE_DIR (exported from cmake/absl.cmake for standalone Abseil) +# 2. Check absl_SOURCE_DIR (direct FetchContent variable) +# 3. Check grpc_SOURCE_DIR/third_party/abseil-cpp (gRPC-bundled Abseil) +if(WIN32) + set(_absl_include_found FALSE) + + # Priority 1: Check YAZE_ABSL_SOURCE_DIR (exported by cmake/absl.cmake) + if(DEFINED YAZE_ABSL_SOURCE_DIR AND EXISTS "${YAZE_ABSL_SOURCE_DIR}") + target_include_directories(yaze_util PUBLIC ${YAZE_ABSL_SOURCE_DIR}) + message(STATUS "Windows: Added explicit Abseil include path (standalone): ${YAZE_ABSL_SOURCE_DIR}") + set(_absl_include_found TRUE) + # Priority 2: Check absl_SOURCE_DIR (direct FetchContent variable) + elseif(DEFINED absl_SOURCE_DIR AND EXISTS "${absl_SOURCE_DIR}") + target_include_directories(yaze_util PUBLIC ${absl_SOURCE_DIR}) + message(STATUS "Windows: Added explicit Abseil include path (FetchContent): ${absl_SOURCE_DIR}") + set(_absl_include_found TRUE) + # Priority 3: Check gRPC-bundled Abseil + elseif(DEFINED grpc_SOURCE_DIR AND EXISTS "${grpc_SOURCE_DIR}/third_party/abseil-cpp") + target_include_directories(yaze_util PUBLIC "${grpc_SOURCE_DIR}/third_party/abseil-cpp") + message(STATUS "Windows: Added explicit Abseil include path (gRPC-bundled): ${grpc_SOURCE_DIR}/third_party/abseil-cpp") + set(_absl_include_found TRUE) + endif() + + if(NOT _absl_include_found) + message(WARNING "Windows: Could not find Abseil source directory - build may fail with 'absl/status/statusor.h' not found") + endif() +endif() + set_target_properties(yaze_util PROPERTIES POSITION_INDEPENDENT_CODE ON ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"