diff --git a/.github/workflows/win-deploy.yml b/.github/workflows/win-deploy.yml index a68ed09..f6ba340 100644 --- a/.github/workflows/win-deploy.yml +++ b/.github/workflows/win-deploy.yml @@ -6,6 +6,9 @@ on: - main tags: - 'v[0-9]+.[0-9]+.[0-9]+*' + pull_request: + branches: + - main workflow_dispatch: permissions: @@ -23,15 +26,19 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Ensure submodules are updated + run: git submodule update --init --recursive + - name: Install Qt 6 (MinGW) uses: jurplel/install-qt-action@v4 with: version: '6.7.2' host: 'windows' target: 'desktop' - arch: 'win64_mingw' - tools: 'tools_mingw' - modules: 'qtserialport qtwebsockets' + arch: 'win64_mingw' + # Pull a modern MinGW toolchain with reliable support (GCC 13.1) + tools: 'tools_mingw1310' + modules: 'qtserialport qtwebsockets' - name: Configure CMake run: | @@ -73,7 +80,12 @@ jobs: -DCMAKE_PREFIX_PATH="$qtDirCmake" ` -DCMAKE_C_COMPILER="$gccCmake" ` -DCMAKE_CXX_COMPILER="$gppCmake" - + + - name: Pre-build bundled Protobuf (serial) + run: | + # Build the ExternalProject first to avoid racing it against proto generation + cmake --build build --config Release --target project_protobuf-install -- -j1 + - name: Build run: cmake --build build --config Release --parallel @@ -82,27 +94,54 @@ jobs: # Recover Qt dir $qtDir = $env:Qt6_DIR if (-not $qtDir) { $qtDir = $env:QT_ROOT_DIR } - - $exePath = "build/src/engine.exe" - - if (-Not (Test-Path $exePath)) { - $exePath = "build/src/engine/engine.exe" - if (-Not (Test-Path $exePath)) { - throw "Executable not found. Tried build/src/engine.exe and build/src/engine/engine.exe" - } + + # Prefer common locations, but fall back to a recursive search to avoid path + # mismatches between generators/configurations. + $exePath = @( + "build/src/engine.exe", + "build/src/engine/engine.exe" + ) | Where-Object { Test-Path $_ } | Select-Object -First 1 + + if (-not $exePath) { + $found = Get-ChildItem -Path "build" -Filter "engine.exe" -Recurse -File -ErrorAction SilentlyContinue | + Select-Object -First 1 + if ($found) { $exePath = $found.FullName } } - + + if (-not $exePath) { + throw "Executable not found under build/. Checked build/src/engine.exe and build/src/engine/engine.exe, and no engine.exe was discovered recursively." + } + + # Persist the resolved path for later steps (normalize slashes for downstream tooling) + "ENGINE_EXE=$($exePath -replace '\\','/')" | Out-File -FilePath $env:GITHUB_ENV -Append + & "$qtDir\bin\windeployqt.exe" $exePath --compiler-runtime --no-translations - name: Stage deployment bundle run: | $distDir = "dist/engine-windows" New-Item -ItemType Directory -Force -Path $distDir | Out-Null - - $exePath = "build/src/engine.exe" - if (-Not (Test-Path $exePath)) { $exePath = "build/src/engine/engine.exe" } + + $exePath = $env:ENGINE_EXE + if (-not $exePath) { + $exePath = @( + "build/src/engine.exe", + "build/src/engine/engine.exe" + ) | Where-Object { Test-Path $_ } | Select-Object -First 1 + } + + if (-not $exePath) { + $found = Get-ChildItem -Path "build" -Filter "engine.exe" -Recurse -File -ErrorAction SilentlyContinue | + Select-Object -First 1 + if ($found) { $exePath = $found.FullName } + } + + if (-not $exePath) { + throw "Executable not found under build/. Checked build/src/engine.exe and build/src/engine/engine.exe, and no engine.exe was discovered recursively." + } + $deployedFilesDir = (Split-Path $exePath) - + if (Test-Path "build/config.ini") { Copy-Item "build/config.ini" $distDir -ErrorAction Stop } @@ -113,14 +152,18 @@ jobs: - name: Compress artifact run: | - $zipName = "engine-${{ github.ref_name }}-windows-mingw-x64.zip" + $refName = "${{ github.ref_name }}" + # Replace path separators (e.g., feature/foo) to avoid treating the zip name as a directory path + $safeRef = $refName -replace "[\\/]+", "-" + $zipName = "engine-$safeRef-windows-mingw-x64.zip" Compress-Archive -Path dist/engine-windows/* -DestinationPath $zipName - + echo "ZIP_NAME=$zipName" | Out-File -FilePath $env:GITHUB_ENV -Append + - name: Upload artifact uses: actions/upload-artifact@v4 with: name: windows-release-artifact - path: engine-v*-windows-mingw-x64.zip + path: ${{ env.ZIP_NAME }} if-no-files-found: error release-github: @@ -138,7 +181,7 @@ jobs: - name: Create Release and Upload Assets uses: softprops/action-gh-release@v2 with: - files: engine-v*-windows-mingw-x64.zip + files: engine-${{ github.ref_name }}-windows-mingw-x64.zip draft: false generate_release_notes: true env: diff --git a/CMakeLists.txt b/CMakeLists.txt index 78af9b8..b445f80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ include(BuildProtobuf) # Compile protobuf include(CompileProtobuf) -set(PROTOBUF_ROOT "${CMAKE_BINARY_DIR}/project_protobuf-prefix") # <- more correct than using 'build/project_protobuf-prefix' +set(PROTOBUF_ROOT "${PROTOBUF_INSTALL_DIR}") set(Protobuf_PROTOC_EXECUTABLE "${PROTOBUF_ROOT}/bin/protoc") set(Protobuf_INCLUDE_DIR "${PROTOBUF_ROOT}/include") # Check if we are on Windows but NOT using MinGW (i.e., using Visual Studio) @@ -66,9 +66,9 @@ endif() set(PROTO_SRC_DIR "${CMAKE_SOURCE_DIR}/src/protobuf/protos") set(PROTO_GEN_DIR "${CMAKE_SOURCE_DIR}/src/protobuf") define_proto_generation_target(generate_protos ${PROTO_SRC_DIR} ${PROTO_GEN_DIR}) -add_dependencies(generate_protos project_protobuf) +add_dependencies(generate_protos project_protobuf project_protobuf-install) add_library(proto_files STATIC ${generate_protos_SRCS} ${generate_protos_HDRS}) -add_dependencies(proto_files generate_protos) +add_dependencies(proto_files generate_protos project_protobuf project_protobuf-install) target_include_directories(proto_files PUBLIC "${PROTO_GEN_DIR}" "${Protobuf_INCLUDE_DIR}" diff --git a/cmake/BuildProtobuf.cmake b/cmake/BuildProtobuf.cmake index 4da0396..35d6c73 100644 --- a/cmake/BuildProtobuf.cmake +++ b/cmake/BuildProtobuf.cmake @@ -1,7 +1,7 @@ include(ExternalProject) # Define expected output files -set(PROTOBUF_BUILT_FILE "${CMAKE_BINARY_DIR}/protobuf-install/bin/protoc${CMAKE_EXECUTABLE_SUFFIX}") +set(PROTOBUF_BUILT_FILE "${PROTOBUF_INSTALL_DIR}/bin/protoc${CMAKE_EXECUTABLE_SUFFIX}") set(PROTOBUF_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}") set(PROTOC_SUBPATH "bin/protoc${CMAKE_EXECUTABLE_SUFFIX}") @@ -16,6 +16,7 @@ if(NOT EXISTS "${PROTOBUF_BUILT_FILE}") DOWNLOAD_NO_PROGRESS true # PATCH_COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/protobuf.CMakeLists.txt CMakeLists.txt DOWNLOAD_DIR "${DEPENDENCY_DOWNLOADS}" + INSTALL_DIR "${PROTOBUF_INSTALL_DIR}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE} @@ -26,6 +27,9 @@ if(NOT EXISTS "${PROTOBUF_BUILT_FILE}") -DCMAKE_BUILD_TYPE:STRING=Release "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} -std=gnu++11 -w" -Dprotobuf_BUILD_TESTS:BOOL=OFF + # Disable Zlib to avoid optional dependency failures on the Windows CI runner + -Dprotobuf_WITH_ZLIB:BOOL=OFF + -DCMAKE_DISABLE_FIND_PACKAGE_ZLIB:BOOL=ON STEP_TARGETS install ) @@ -65,9 +69,9 @@ else() set(PROTOBUF_FOUND true) set(PROTOBUF_VERSION "3.6.1") - set(PROTOBUF_INCLUDE_DIR "${CMAKE_BINARY_DIR}/protobuf-install/include") + set(PROTOBUF_INCLUDE_DIR "${PROTOBUF_INSTALL_DIR}/include") set(PROTOBUF_INCLUDE_DIRS "${PROTOBUF_INCLUDE_DIR}") - set(PROTOBUF_LIBRARY "${CMAKE_BINARY_DIR}/protobuf-install/${PROTOBUF_SUBPATH}") + set(PROTOBUF_LIBRARY "${PROTOBUF_INSTALL_DIR}/${PROTOBUF_SUBPATH}") set(PROTOBUF_LIBRARIES "${PROTOBUF_LIBRARY}") set(PROTOBUF_PROTOC_EXECUTABLE "${PROTOBUF_BUILT_FILE}") set(Protobuf_PROTOC_EXECUTABLE "${PROTOBUF_BUILT_FILE}") diff --git a/src/luainterface/luabindings.cpp b/src/luainterface/luabindings.cpp index 2caa62f..4a2cfc5 100644 --- a/src/luainterface/luabindings.cpp +++ b/src/luainterface/luabindings.cpp @@ -1,4 +1,4 @@ -#include "LuaBindings.hpp" +#include "luabindings.hpp" #include // ---- Include your project headers here ---- diff --git a/src/protobuf/CMakeLists.txt b/src/protobuf/CMakeLists.txt index 0fc263a..ddc19e4 100644 --- a/src/protobuf/CMakeLists.txt +++ b/src/protobuf/CMakeLists.txt @@ -22,4 +22,7 @@ target_include_directories(protobuf PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # Link Protobuf to the library #find_package(Protobuf REQUIRED) -target_link_libraries(protobuf PUBLIC protobuf::libprotobuf) \ No newline at end of file +target_link_libraries(protobuf PUBLIC protobuf::libprotobuf) + +# Ensure the external Protobuf build/install completes before this target +add_dependencies(protobuf project_protobuf project_protobuf-install)