From cd3670d2a44ffd4912f7abbbf57b4c9b0b62a481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 16:05:52 +0100 Subject: [PATCH 01/19] Add GitHub Actions build and release pipeline --- .github/workflows/build-release.yml | 233 ++++++++++++++++++++++++++++ .gitignore | 3 + CMakeLists.txt | 60 ++++--- 3 files changed, 276 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/build-release.yml diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 000000000..751e98644 --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,233 @@ +name: Build and Release + +on: + push: + branches: + - master + - ubuntu25.10-wayland + tags: + - "v*" + pull_request: + branches: + - master + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Linux + os: ubuntu-24.04 + artifact_name: dsview-linux-x86_64 + archive_name: linux-x86_64 + - name: Windows + os: windows-2022 + artifact_name: dsview-windows-x86_64 + archive_name: windows-x86_64 + - name: macOS + os: macos-13 + artifact_name: dsview-macos-x86_64 + archive_name: macos-x86_64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Compute build metadata + id: meta + shell: bash + run: | + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then + version="${GITHUB_REF_NAME}" + else + version="sha-${GITHUB_SHA::7}" + fi + echo "version=${version}" >> "${GITHUB_OUTPUT}" + + - name: Install Linux dependencies + if: runner.os == 'Linux' + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y \ + cmake ninja-build pkg-config \ + qt6-base-dev qt6-tools-dev qt6-wayland \ + libglib2.0-dev libfftw3-dev libusb-1.0-0-dev \ + libboost-dev zlib1g-dev python3-dev + + - name: Set up MSYS2 + if: runner.os == 'Windows' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: >- + base-devel + git + zip + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-cmake + mingw-w64-x86_64-ninja + mingw-w64-x86_64-pkgconf + mingw-w64-x86_64-python + mingw-w64-x86_64-zlib + mingw-w64-x86_64-glib2 + mingw-w64-x86_64-libusb + mingw-w64-x86_64-fftw + mingw-w64-x86_64-boost + mingw-w64-x86_64-qt6-base + + - name: Install macOS dependencies + if: runner.os == 'macOS' + shell: bash + run: | + brew update + brew install cmake ninja pkg-config qt@6 glib libusb fftw boost python@3.12 + + - name: Configure Linux + if: runner.os == 'Linux' + shell: bash + run: cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON + + - name: Configure Windows + if: runner.os == 'Windows' + shell: msys2 {0} + run: cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON + + - name: Configure macOS + if: runner.os == 'macOS' + shell: bash + run: | + export PATH="$(brew --prefix qt@6)/bin:$PATH" + cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON -DCMAKE_PREFIX_PATH="$(brew --prefix qt@6)" + + - name: Build Linux + if: runner.os == 'Linux' + shell: bash + run: cmake --build build --parallel + + - name: Build Windows + if: runner.os == 'Windows' + shell: msys2 {0} + run: cmake --build build --parallel + + - name: Build macOS + if: runner.os == 'macOS' + shell: bash + run: cmake --build build --parallel + + - name: Smoke check Linux + if: runner.os == 'Linux' + shell: bash + run: ./build.dir/DSView -v + + - name: Smoke check Windows + if: runner.os == 'Windows' + shell: msys2 {0} + run: ./build.dir/DSView.exe -v + + - name: Smoke check macOS + if: runner.os == 'macOS' + shell: bash + run: ./build.dir/DSView.app/Contents/MacOS/DSView -v + + - name: Package Linux + if: runner.os == 'Linux' + shell: bash + run: | + set -euo pipefail + version="${{ steps.meta.outputs.version }}" + stage="${RUNNER_TEMP}/stage" + package_root="${RUNNER_TEMP}/DSView-${version}-${{ matrix.archive_name }}" + mkdir -p "${stage}" "${package_root}" dist + cmake --install build --prefix "${stage}/usr" + tar -C "${stage}" -czf "dist/DSView-${version}-${{ matrix.archive_name }}.tar.gz" usr + + - name: Package Windows + if: runner.os == 'Windows' + shell: msys2 {0} + run: | + set -euo pipefail + version="${{ steps.meta.outputs.version }}" + stage="${RUNNER_TEMP}/stage" + package_root="${RUNNER_TEMP}/DSView-${version}-${{ matrix.archive_name }}" + mkdir -p "${stage}" "${package_root}" dist + cmake --install build --prefix "${stage}" + cp -R "${stage}/bin/." "${package_root}/" + cp -R "${stage}/share/DSView/." "${package_root}/" + mkdir -p "${package_root}/decoders" + cp -R "${stage}/share/libsigrokdecode4DSL/decoders/." "${package_root}/decoders/" + + deployqt="$(command -v windeployqt6.exe || command -v windeployqt.exe || command -v windeployqt6 || command -v windeployqt)" + "${deployqt}" --release --compiler-runtime "${package_root}/DSView.exe" + + for dep in $(ldd "${package_root}/DSView.exe" | awk '/=> \\/mingw64\\// {print $3}'); do + cp -n "${dep}" "${package_root}/" + done + + 7z a "dist/DSView-${version}-${{ matrix.archive_name }}.zip" "${package_root}" >/dev/null + + - name: Package macOS + if: runner.os == 'macOS' + shell: bash + run: | + set -euo pipefail + version="${{ steps.meta.outputs.version }}" + stage="${RUNNER_TEMP}/stage" + app_path="${stage}/DSView.app" + mkdir -p "${stage}" dist + export PATH="$(brew --prefix qt@6)/bin:$PATH" + + cmake --install build --prefix "${stage}" + mkdir -p "${app_path}/Contents/share" + cp -R "${stage}/share/DSView" "${app_path}/Contents/share/DSView" + cp -R "${stage}/share/libsigrokdecode4DSL" "${app_path}/Contents/share/libsigrokdecode4DSL" + + macdeployqt "${app_path}" -dmg + ditto -c -k --sequesterRsrc --keepParent "${app_path}" "dist/DSView-${version}-${{ matrix.archive_name }}.zip" + mv "${stage}/DSView.dmg" "dist/DSView-${version}-${{ matrix.archive_name }}.dmg" + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact_name }} + path: dist/* + if-no-files-found: error + retention-days: 14 + + release: + name: Publish GitHub release + if: github.ref_type == 'tag' + runs-on: ubuntu-24.04 + needs: + - build + + steps: + - name: Download packaged artifacts + uses: actions/download-artifact@v4 + with: + path: release-artifacts + + - name: Create or update release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + tag="${GITHUB_REF_NAME}" + if ! gh release view "${tag}" >/dev/null 2>&1; then + gh release create "${tag}" --title "${tag}" --generate-notes + fi + mapfile -d '' files < <(find release-artifacts -type f -print0) + gh release upload "${tag}" "${files[@]}" --clobber diff --git a/.gitignore b/.gitignore index 81fa4defb..749da0210 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,9 @@ moc_*.cpp_parameters DSView-prj build* +!.github/ +!.github/workflows/ +!.github/workflows/build-release.yml share .vscode qtpro diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e5eed435..2600eaaab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -571,6 +571,13 @@ elseif(Qt5Core_FOUND) qt5_add_resources(DSView_RESOURCES_RCC ${DSView_RESOURCES}) endif() +if(APPLE) + set(DSVIEW_APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/DSView.icns) + set_source_files_properties(${DSVIEW_APP_ICON_MACOSX} + PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + list(APPEND DSView_SOURCES ${DSVIEW_APP_ICON_MACOSX}) +endif() + add_definitions(${QT_DEFINITIONS}) add_definitions(-Wall -Wextra -Wno-return-type -Wno-ignored-qualifiers) @@ -633,15 +640,32 @@ else() list(APPEND DSVIEW_LINK_LIBS ${PKGDEPS_LIBRARIES}) endif() -add_executable(${PROJECT_NAME} - ${common_SOURCES} - ${DSView_SOURCES} - ${DSView_HEADERS_MOC} - ${DSView_FORMS_HEADERS} - ${DSView_RESOURCES_RCC} - ${libsigrok4DSL_SOURCES} - ${libsigrokdecode4DSL_SOURCES} -) +if(APPLE) + add_executable(${PROJECT_NAME} MACOSX_BUNDLE + ${common_SOURCES} + ${DSView_SOURCES} + ${DSView_HEADERS_MOC} + ${DSView_FORMS_HEADERS} + ${DSView_RESOURCES_RCC} + ${libsigrok4DSL_SOURCES} + ${libsigrokdecode4DSL_SOURCES} + ) + set_target_properties(${PROJECT_NAME} PROPERTIES + MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME} + MACOSX_BUNDLE_GUI_IDENTIFIER com.dreamsourcelab.dsview + MACOSX_BUNDLE_ICON_FILE DSView.icns + ) +else() + add_executable(${PROJECT_NAME} + ${common_SOURCES} + ${DSView_SOURCES} + ${DSView_HEADERS_MOC} + ${DSView_FORMS_HEADERS} + ${DSView_RESOURCES_RCC} + ${libsigrok4DSL_SOURCES} + ${libsigrokdecode4DSL_SOURCES} + ) +endif() target_link_libraries(${PROJECT_NAME} ${DSVIEW_LINK_LIBS}) @@ -663,7 +687,11 @@ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build.dir") #------------------------------------------------------------------------------- # Install the executable. -install(TARGETS ${PROJECT_NAME} DESTINATION bin) +if(APPLE) + install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION .) +else() + install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) +endif() install(DIRECTORY DSView/res DESTINATION share/DSView) install(DIRECTORY DSView/demo DESTINATION share/DSView) install(FILES DSView/icons/logo.svg DESTINATION share/DSView RENAME logo.svg) @@ -671,15 +699,8 @@ install(FILES DSView/icons/logo.svg DESTINATION share/icons/hicolor/scalable/app install(FILES DSView/icons/logo.svg DESTINATION share/pixmaps RENAME dsview.svg) if(CMAKE_SYSTEM_NAME MATCHES "Linux") - install(FILES DSView/DSView.desktop DESTINATION /usr/share/applications RENAME dsview.desktop) - - if(IS_DIRECTORY /usr/lib/udev/rules.d) - install(FILES DSView/DreamSourceLab.rules DESTINATION /usr/lib/udev/rules.d RENAME 60-dreamsourcelab.rules) - elseif(IS_DIRECTORY /lib/udev/rules.d) - install(FILES DSView/DreamSourceLab.rules DESTINATION /lib/udev/rules.d RENAME 60-dreamsourcelab.rules) - elseif(IS_DIRECTORY /etc/udev/rules.d) - install(FILES DSView/DreamSourceLab.rules DESTINATION /etc/udev/rules.d RENAME 60-dreamsourcelab.rules) - endif() + install(FILES DSView/DSView.desktop DESTINATION share/applications RENAME dsview.desktop) + install(FILES DSView/DreamSourceLab.rules DESTINATION lib/udev/rules.d RENAME 60-dreamsourcelab.rules) endif() @@ -716,4 +737,3 @@ if(ENABLE_TESTS) enable_testing() add_test(test ${CMAKE_CURRENT_BINARY_DIR}/DSView/test/DSView-test) endif(ENABLE_TESTS) - From 2c67fb0f8eaaae1e8766930b6d88e4c258be2f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 16:10:46 +0100 Subject: [PATCH 02/19] Add Debian package output to Linux releases --- .github/workflows/build-release.yml | 4 ++-- CMakeLists.txt | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 751e98644..72d666cd7 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -149,10 +149,10 @@ jobs: set -euo pipefail version="${{ steps.meta.outputs.version }}" stage="${RUNNER_TEMP}/stage" - package_root="${RUNNER_TEMP}/DSView-${version}-${{ matrix.archive_name }}" - mkdir -p "${stage}" "${package_root}" dist + mkdir -p "${stage}" dist cmake --install build --prefix "${stage}/usr" tar -C "${stage}" -czf "dist/DSView-${version}-${{ matrix.archive_name }}.tar.gz" usr + cpack --config build/CPackConfig.cmake -G DEB -B dist - name: Package Windows if: runner.os == 'Windows' diff --git a/CMakeLists.txt b/CMakeLists.txt index 2600eaaab..55734b1f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -716,6 +716,10 @@ install(DIRECTORY lang DESTINATION share/DSView) #= Packaging (handled by CPack) #------------------------------------------------------------------------------- +set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME}) +set(CPACK_PACKAGE_VENDOR "DreamSourceLab") +set(CPACK_PACKAGE_CONTACT "DSView Packaging ") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/modelclixxo/DSView") set(CPACK_PACKAGE_VERSION_MAJOR ${DS_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${DS_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${DS_VERSION_MICRO}) @@ -726,6 +730,18 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO}") set(CPACK_SOURCE_GENERATOR "TGZ") +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + set(CPACK_GENERATOR "DEB;TGZ") + set(CPACK_PACKAGING_INSTALL_PREFIX "/usr") + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "DSView Packaging") + set(CPACK_DEBIAN_PACKAGE_SECTION "electronics") + set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION + "DSView is a GUI application for DreamSourceLab USB instruments including logic analyzers and oscilloscopes.") +endif() + include(CPack) #=============================================================================== From f609af1a144f47681d4cebb77f11ebee0b99ff51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 16:19:47 +0100 Subject: [PATCH 03/19] Align release versioning with git tags --- .github/workflows/build-release.yml | 73 +++++++++++++++++++++++------ CMakeLists.txt | 7 +++ 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 72d666cd7..b30311b2a 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -48,12 +48,50 @@ jobs: id: meta shell: bash run: | - if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then - version="${GITHUB_REF_NAME}" - else - version="sha-${GITHUB_SHA::7}" - fi - echo "version=${version}" >> "${GITHUB_OUTPUT}" + python3 <<'PY' >> "${GITHUB_OUTPUT}" + import os + import pathlib + import re + + cmake = pathlib.Path("CMakeLists.txt").read_text(encoding="utf-8") + + def pick(name: str) -> str: + match = re.search(rf"set\({name}\s+([0-9]+)\)", cmake) + if not match: + raise SystemExit(f"Unable to find {name} in CMakeLists.txt") + return match.group(1) + + project_version = ".".join( + [ + pick("DS_VERSION_MAJOR"), + pick("DS_VERSION_MINOR"), + pick("DS_VERSION_MICRO"), + ] + ) + + ref_type = os.environ.get("GITHUB_REF_TYPE", "") + ref_name = os.environ.get("GITHUB_REF_NAME", "") + short_sha = os.environ.get("GITHUB_SHA", "")[:7] + + if ref_type == "tag": + tag_version = ref_name[1:] if ref_name.startswith("v") else ref_name + if tag_version != project_version: + raise SystemExit( + f"Git tag {ref_name} does not match project version {project_version}" + ) + artifact_version = project_version + package_version = project_version + release_title = f"DSView {project_version}" + else: + artifact_version = f"{project_version}+git.{short_sha}" + package_version = f"{project_version}+git{short_sha}" + release_title = f"DSView {artifact_version}" + + print(f"project_version={project_version}") + print(f"artifact_version={artifact_version}") + print(f"package_version={package_version}") + print(f"release_title={release_title}") + PY - name: Install Linux dependencies if: runner.os == 'Linux' @@ -98,19 +136,19 @@ jobs: - name: Configure Linux if: runner.os == 'Linux' shell: bash - run: cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON + run: cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" - name: Configure Windows if: runner.os == 'Windows' shell: msys2 {0} - run: cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON + run: cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" - name: Configure macOS if: runner.os == 'macOS' shell: bash run: | export PATH="$(brew --prefix qt@6)/bin:$PATH" - cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON -DCMAKE_PREFIX_PATH="$(brew --prefix qt@6)" + cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" -DCMAKE_PREFIX_PATH="$(brew --prefix qt@6)" - name: Build Linux if: runner.os == 'Linux' @@ -147,19 +185,21 @@ jobs: shell: bash run: | set -euo pipefail - version="${{ steps.meta.outputs.version }}" + version="${{ steps.meta.outputs.artifact_version }}" stage="${RUNNER_TEMP}/stage" mkdir -p "${stage}" dist cmake --install build --prefix "${stage}/usr" tar -C "${stage}" -czf "dist/DSView-${version}-${{ matrix.archive_name }}.tar.gz" usr - cpack --config build/CPackConfig.cmake -G DEB -B dist + cpack --config build/CPackConfig.cmake -G DEB -B dist/cpack + deb_file="$(find dist/cpack -maxdepth 1 -type f -name '*.deb' | head -n 1)" + mv "${deb_file}" "dist/DSView-${version}-linux-amd64.deb" - name: Package Windows if: runner.os == 'Windows' shell: msys2 {0} run: | set -euo pipefail - version="${{ steps.meta.outputs.version }}" + version="${{ steps.meta.outputs.artifact_version }}" stage="${RUNNER_TEMP}/stage" package_root="${RUNNER_TEMP}/DSView-${version}-${{ matrix.archive_name }}" mkdir -p "${stage}" "${package_root}" dist @@ -183,7 +223,7 @@ jobs: shell: bash run: | set -euo pipefail - version="${{ steps.meta.outputs.version }}" + version="${{ steps.meta.outputs.artifact_version }}" stage="${RUNNER_TEMP}/stage" app_path="${stage}/DSView.app" mkdir -p "${stage}" dist @@ -201,7 +241,7 @@ jobs: - name: Upload build artifact uses: actions/upload-artifact@v4 with: - name: ${{ matrix.artifact_name }} + name: ${{ matrix.artifact_name }}-${{ steps.meta.outputs.artifact_version }} path: dist/* if-no-files-found: error retention-days: 14 @@ -226,8 +266,11 @@ jobs: run: | set -euo pipefail tag="${GITHUB_REF_NAME}" + title="DSView ${tag#v}" if ! gh release view "${tag}" >/dev/null 2>&1; then - gh release create "${tag}" --title "${tag}" --generate-notes + gh release create "${tag}" --title "${title}" --generate-notes + else + gh release edit "${tag}" --title "${title}" fi mapfile -d '' files < <(find release-artifacts -type f -print0) gh release upload "${tag}" "${files[@]}" --clobber diff --git a/CMakeLists.txt b/CMakeLists.txt index 55734b1f1..b63a02e8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -720,9 +720,15 @@ set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME}) set(CPACK_PACKAGE_VENDOR "DreamSourceLab") set(CPACK_PACKAGE_CONTACT "DSView Packaging ") set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/modelclixxo/DSView") +set(DSVIEW_PACKAGE_VERSION_OVERRIDE "" CACHE STRING "Override package version used for generated release packages") +set(DSVIEW_EFFECTIVE_PACKAGE_VERSION ${DS_VERSION_STRING}) +if(DSVIEW_PACKAGE_VERSION_OVERRIDE) + set(DSVIEW_EFFECTIVE_PACKAGE_VERSION ${DSVIEW_PACKAGE_VERSION_OVERRIDE}) +endif() set(CPACK_PACKAGE_VERSION_MAJOR ${DS_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${DS_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${DS_VERSION_MICRO}) +set(CPACK_PACKAGE_VERSION ${DSVIEW_EFFECTIVE_PACKAGE_VERSION}) set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/DSView/README) set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/DSView/COPYING) set(CPACK_SOURCE_IGNORE_FILES ${CMAKE_CURRENT_BINARY_DIR} ".gitignore" ".git") @@ -738,6 +744,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux") set(CPACK_DEBIAN_PACKAGE_SECTION "electronics") set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_PACKAGE_VERSION ${DSVIEW_EFFECTIVE_PACKAGE_VERSION}) set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "DSView is a GUI application for DreamSourceLab USB instruments including logic analyzers and oscilloscopes.") endif() From b45f440ea224cf2631f5813e55c8c4493ea5f810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 16:41:07 +0100 Subject: [PATCH 04/19] Harden GitHub Actions runner configuration --- .github/workflows/build-release.yml | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index b30311b2a..3372313dd 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -36,13 +36,13 @@ jobs: artifact_name: dsview-windows-x86_64 archive_name: windows-x86_64 - name: macOS - os: macos-13 - artifact_name: dsview-macos-x86_64 - archive_name: macos-x86_64 + os: macos-latest + artifact_name: dsview-macos + archive_name: macos steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Compute build metadata id: meta @@ -125,6 +125,7 @@ jobs: mingw-w64-x86_64-fftw mingw-w64-x86_64-boost mingw-w64-x86_64-qt6-base + mingw-w64-x86_64-qt6-tools - name: Install macOS dependencies if: runner.os == 'macOS' @@ -141,7 +142,18 @@ jobs: - name: Configure Windows if: runner.os == 'Windows' shell: msys2 {0} - run: cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" + run: | + set -euo pipefail + export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig" + export CMAKE_PREFIX_PATH="/mingw64" + export Python3_ROOT_DIR="/mingw64" + export Boost_ROOT="/mingw64" + cmake -S . -B build -G Ninja \ + -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ + -DPython3_ROOT_DIR="${Python3_ROOT_DIR}" \ + -DBoost_ROOT="${Boost_ROOT}" \ + -DDSVIEW_PREFER_QT6=ON \ + -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" - name: Configure macOS if: runner.os == 'macOS' @@ -200,6 +212,7 @@ jobs: run: | set -euo pipefail version="${{ steps.meta.outputs.artifact_version }}" + dist_dir="$(pwd)/dist" stage="${RUNNER_TEMP}/stage" package_root="${RUNNER_TEMP}/DSView-${version}-${{ matrix.archive_name }}" mkdir -p "${stage}" "${package_root}" dist @@ -216,7 +229,7 @@ jobs: cp -n "${dep}" "${package_root}/" done - 7z a "dist/DSView-${version}-${{ matrix.archive_name }}.zip" "${package_root}" >/dev/null + (cd "${RUNNER_TEMP}" && zip -r "${dist_dir}/DSView-${version}-${{ matrix.archive_name }}.zip" "$(basename "${package_root}")" >/dev/null) - name: Package macOS if: runner.os == 'macOS' @@ -239,7 +252,7 @@ jobs: mv "${stage}/DSView.dmg" "dist/DSView-${version}-${{ matrix.archive_name }}.dmg" - name: Upload build artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: ${{ matrix.artifact_name }}-${{ steps.meta.outputs.artifact_version }} path: dist/* @@ -255,7 +268,7 @@ jobs: steps: - name: Download packaged artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: path: release-artifacts From 565be8ef916748fb7c643d248fc6742d4cb49019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 16:45:41 +0100 Subject: [PATCH 05/19] Teach CMake find modules about MSYS2 paths --- CMake/FindFFTW.cmake | 6 +++++- CMake/Findlibusb-1.0.cmake | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CMake/FindFFTW.cmake b/CMake/FindFFTW.cmake index 82095c7e3..dc994fdcd 100755 --- a/CMake/FindFFTW.cmake +++ b/CMake/FindFFTW.cmake @@ -11,16 +11,20 @@ FIND_PATH(FFTW_INCLUDE_DIR NAMES fftw3.h PATHS + /mingw64/include + /clang64/include /usr/local/include /opt/local/include /usr/include ) -SET(FFTW_NAMES ${FFTW_NAMES} fftw3 fftw3f fftw3l fftw3-3) +SET(FFTW_NAMES ${FFTW_NAMES} fftw3 fftw3f fftw3l fftw3-3 libfftw3 libfftw3-3) FIND_LIBRARY(FFTW_LIBRARY NAMES ${FFTW_NAMES} PATHS + /mingw64/lib + /clang64/lib /usr/local/lib64 /opt/local/lib64 /usr/lib64 diff --git a/CMake/Findlibusb-1.0.cmake b/CMake/Findlibusb-1.0.cmake index 663f7d799..b583bc780 100755 --- a/CMake/Findlibusb-1.0.cmake +++ b/CMake/Findlibusb-1.0.cmake @@ -51,6 +51,8 @@ else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) NAMES libusb.h PATHS + /mingw64/include + /clang64/include /usr/local/include /opt/local/include /usr/include @@ -61,8 +63,10 @@ else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) find_library(LIBUSB_1_LIBRARY NAMES - usb-1.0 usb + usb-1.0 libusb-1.0 usb PATHS + /mingw64/lib + /clang64/lib /usr/local/lib64 /opt/local/lib64 /usr/lib64 From 7b6bd36e652835f208911d12ba114ecb4cc800a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 17:01:01 +0100 Subject: [PATCH 06/19] Improve Windows and macOS configure paths --- .github/workflows/build-release.yml | 16 +++++++++++++--- CMake/FindFFTW.cmake | 4 ++++ CMake/Findlibusb-1.0.cmake | 4 ++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 3372313dd..dc955b106 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -144,12 +144,15 @@ jobs: shell: msys2 {0} run: | set -euo pipefail + export PATH="/mingw64/bin:${PATH}" export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig" + export PKG_CONFIG_EXECUTABLE="/mingw64/bin/pkg-config" export CMAKE_PREFIX_PATH="/mingw64" export Python3_ROOT_DIR="/mingw64" export Boost_ROOT="/mingw64" - cmake -S . -B build -G Ninja \ + /mingw64/bin/cmake -S . -B build -G Ninja \ -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ + -DPKG_CONFIG_EXECUTABLE="${PKG_CONFIG_EXECUTABLE}" \ -DPython3_ROOT_DIR="${Python3_ROOT_DIR}" \ -DBoost_ROOT="${Boost_ROOT}" \ -DDSVIEW_PREFER_QT6=ON \ @@ -159,8 +162,15 @@ jobs: if: runner.os == 'macOS' shell: bash run: | - export PATH="$(brew --prefix qt@6)/bin:$PATH" - cmake -S . -B build -G Ninja -DDSVIEW_PREFER_QT6=ON -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" -DCMAKE_PREFIX_PATH="$(brew --prefix qt@6)" + brew_prefix="$(brew --prefix)" + qt_prefix="$(brew --prefix qt@6)" + export PATH="${qt_prefix}/bin:${brew_prefix}/bin:$PATH" + export PKG_CONFIG_PATH="${brew_prefix}/lib/pkgconfig:${qt_prefix}/lib/pkgconfig" + cmake -S . -B build -G Ninja \ + -DDSVIEW_PREFER_QT6=ON \ + -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" \ + -DCMAKE_PREFIX_PATH="${qt_prefix};${brew_prefix}" \ + -DPKG_CONFIG_EXECUTABLE="${brew_prefix}/bin/pkg-config" - name: Build Linux if: runner.os == 'Linux' diff --git a/CMake/FindFFTW.cmake b/CMake/FindFFTW.cmake index dc994fdcd..04e0ba8d0 100755 --- a/CMake/FindFFTW.cmake +++ b/CMake/FindFFTW.cmake @@ -11,6 +11,8 @@ FIND_PATH(FFTW_INCLUDE_DIR NAMES fftw3.h PATHS + /opt/homebrew/include + /opt/homebrew/opt/fftw/include /mingw64/include /clang64/include /usr/local/include @@ -23,6 +25,8 @@ FIND_LIBRARY(FFTW_LIBRARY NAMES ${FFTW_NAMES} PATHS + /opt/homebrew/lib + /opt/homebrew/opt/fftw/lib /mingw64/lib /clang64/lib /usr/local/lib64 diff --git a/CMake/Findlibusb-1.0.cmake b/CMake/Findlibusb-1.0.cmake index b583bc780..8c957a8f7 100755 --- a/CMake/Findlibusb-1.0.cmake +++ b/CMake/Findlibusb-1.0.cmake @@ -51,6 +51,8 @@ else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) NAMES libusb.h PATHS + /opt/homebrew/include + /opt/homebrew/opt/libusb/include /mingw64/include /clang64/include /usr/local/include @@ -65,6 +67,8 @@ else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) NAMES usb-1.0 libusb-1.0 usb PATHS + /opt/homebrew/lib + /opt/homebrew/opt/libusb/lib /mingw64/lib /clang64/lib /usr/local/lib64 From 75ded245bb5d9f41708355d32f058d87bd2e2b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 17:05:56 +0100 Subject: [PATCH 07/19] Improve CI configure diagnostics --- .github/workflows/build-release.yml | 31 ++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index dc955b106..908962429 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -146,17 +146,30 @@ jobs: set -euo pipefail export PATH="/mingw64/bin:${PATH}" export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig" - export PKG_CONFIG_EXECUTABLE="/mingw64/bin/pkg-config" export CMAKE_PREFIX_PATH="/mingw64" export Python3_ROOT_DIR="/mingw64" export Boost_ROOT="/mingw64" - /mingw64/bin/cmake -S . -B build -G Ninja \ + cmake_bin="$(command -v cmake)" + pkg_config_bin="$(command -v pkg-config || command -v pkgconf)" + python_bin="$(command -v python3 || command -v python)" + echo "cmake=${cmake_bin}" + echo "pkg-config=${pkg_config_bin}" + echo "python=${python_bin}" + "${cmake_bin}" -S . -B build -G Ninja \ -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ - -DPKG_CONFIG_EXECUTABLE="${PKG_CONFIG_EXECUTABLE}" \ + -DPKG_CONFIG_EXECUTABLE="${pkg_config_bin}" \ + -DPython3_EXECUTABLE="${python_bin}" \ -DPython3_ROOT_DIR="${Python3_ROOT_DIR}" \ -DBoost_ROOT="${Boost_ROOT}" \ -DDSVIEW_PREFER_QT6=ON \ - -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" + -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" \ + 2>&1 | tee configure-windows.log + status=${PIPESTATUS[0]} + if [[ ${status} -ne 0 ]]; then + test -f build/CMakeFiles/CMakeError.log && cat build/CMakeFiles/CMakeError.log + test -f build/CMakeFiles/CMakeOutput.log && cat build/CMakeFiles/CMakeOutput.log + exit ${status} + fi - name: Configure macOS if: runner.os == 'macOS' @@ -166,11 +179,19 @@ jobs: qt_prefix="$(brew --prefix qt@6)" export PATH="${qt_prefix}/bin:${brew_prefix}/bin:$PATH" export PKG_CONFIG_PATH="${brew_prefix}/lib/pkgconfig:${qt_prefix}/lib/pkgconfig" + pkg_config_bin="$(command -v pkg-config)" cmake -S . -B build -G Ninja \ -DDSVIEW_PREFER_QT6=ON \ -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" \ -DCMAKE_PREFIX_PATH="${qt_prefix};${brew_prefix}" \ - -DPKG_CONFIG_EXECUTABLE="${brew_prefix}/bin/pkg-config" + -DPKG_CONFIG_EXECUTABLE="${pkg_config_bin}" \ + 2>&1 | tee configure-macos.log + status=${PIPESTATUS[0]} + if [[ ${status} -ne 0 ]]; then + test -f build/CMakeFiles/CMakeError.log && cat build/CMakeFiles/CMakeError.log + test -f build/CMakeFiles/CMakeOutput.log && cat build/CMakeFiles/CMakeOutput.log + exit ${status} + fi - name: Build Linux if: runner.os == 'Linux' From d137000658b59022fc9a51da64e0673e59270805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 17:12:33 +0100 Subject: [PATCH 08/19] Add Homebrew and MSYS2 CMake search paths --- CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b63a02e8d..e4b5661ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,18 @@ include(GNUInstallDirs) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake") #list(APPEND CMAKE_PREFIX_PATH "xxx.cmake find path") +if(WIN32 AND EXISTS "/mingw64") + list(APPEND CMAKE_PREFIX_PATH "/mingw64") + list(APPEND CMAKE_INCLUDE_PATH "/mingw64/include") + list(APPEND CMAKE_LIBRARY_PATH "/mingw64/lib") +endif() + +if(APPLE AND EXISTS "/opt/homebrew") + list(APPEND CMAKE_PREFIX_PATH "/opt/homebrew") + list(APPEND CMAKE_INCLUDE_PATH "/opt/homebrew/include") + list(APPEND CMAKE_LIBRARY_PATH "/opt/homebrew/lib") +endif() + find_package(PkgConfig) if(NOT PKG_CONFIG_FOUND) From 0b0380a5ad47d735d73e49ea5546009a130755ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 22:31:12 +0100 Subject: [PATCH 09/19] Add explicit Python and Boost hints to CI configure --- .github/workflows/build-release.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 908962429..326cc013b 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -152,15 +152,23 @@ jobs: cmake_bin="$(command -v cmake)" pkg_config_bin="$(command -v pkg-config || command -v pkgconf)" python_bin="$(command -v python3 || command -v python)" + python_include="$("${python_bin}" -c 'import sysconfig; print(sysconfig.get_path("include"))')" + python_library="$("${python_bin}" -c 'import pathlib, sysconfig; libdir = sysconfig.get_config_var("LIBDIR") or sysconfig.get_config_var("LIBPL") or ""; library = sysconfig.get_config_var("LDLIBRARY") or sysconfig.get_config_var("LIBRARY") or ""; print(pathlib.Path(libdir, library) if libdir and library else "")')" echo "cmake=${cmake_bin}" echo "pkg-config=${pkg_config_bin}" echo "python=${python_bin}" + echo "python-include=${python_include}" + echo "python-library=${python_library}" "${cmake_bin}" -S . -B build -G Ninja \ -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ -DPKG_CONFIG_EXECUTABLE="${pkg_config_bin}" \ -DPython3_EXECUTABLE="${python_bin}" \ -DPython3_ROOT_DIR="${Python3_ROOT_DIR}" \ + -DPython3_INCLUDE_DIR="${python_include}" \ + -DPython3_LIBRARY="${python_library}" \ -DBoost_ROOT="${Boost_ROOT}" \ + -DBOOST_INCLUDEDIR="/mingw64/include" \ + -DBOOST_LIBRARYDIR="/mingw64/lib" \ -DDSVIEW_PREFER_QT6=ON \ -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" \ 2>&1 | tee configure-windows.log @@ -177,14 +185,24 @@ jobs: run: | brew_prefix="$(brew --prefix)" qt_prefix="$(brew --prefix qt@6)" + boost_prefix="$(brew --prefix boost)" + python_prefix="$(brew --prefix python@3.12)" export PATH="${qt_prefix}/bin:${brew_prefix}/bin:$PATH" export PKG_CONFIG_PATH="${brew_prefix}/lib/pkgconfig:${qt_prefix}/lib/pkgconfig" pkg_config_bin="$(command -v pkg-config)" + python_bin="${python_prefix}/bin/python3" + python_include="$("${python_bin}" -c 'import sysconfig; print(sysconfig.get_path("include"))')" + python_library="$("${python_bin}" -c 'import pathlib, sysconfig; libdir = sysconfig.get_config_var("LIBDIR") or sysconfig.get_config_var("LIBPL") or ""; library = sysconfig.get_config_var("LDLIBRARY") or sysconfig.get_config_var("LIBRARY") or ""; print(pathlib.Path(libdir, library) if libdir and library else "")')" cmake -S . -B build -G Ninja \ -DDSVIEW_PREFER_QT6=ON \ -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" \ -DCMAKE_PREFIX_PATH="${qt_prefix};${brew_prefix}" \ -DPKG_CONFIG_EXECUTABLE="${pkg_config_bin}" \ + -DPython3_EXECUTABLE="${python_bin}" \ + -DPython3_ROOT_DIR="${python_prefix}" \ + -DPython3_INCLUDE_DIR="${python_include}" \ + -DPython3_LIBRARY="${python_library}" \ + -DBoost_ROOT="${boost_prefix}" \ 2>&1 | tee configure-macos.log status=${PIPESTATUS[0]} if [[ ${status} -ne 0 ]]; then From f1d70f995311add292ca53994eb0f4723f7f6b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Thu, 26 Mar 2026 22:39:24 +0100 Subject: [PATCH 10/19] Harden macOS CI search paths and diagnostics --- .github/workflows/build-release.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 326cc013b..786dce330 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -185,10 +185,13 @@ jobs: run: | brew_prefix="$(brew --prefix)" qt_prefix="$(brew --prefix qt@6)" + glib_prefix="$(brew --prefix glib)" + libusb_prefix="$(brew --prefix libusb)" + fftw_prefix="$(brew --prefix fftw)" boost_prefix="$(brew --prefix boost)" python_prefix="$(brew --prefix python@3.12)" export PATH="${qt_prefix}/bin:${brew_prefix}/bin:$PATH" - export PKG_CONFIG_PATH="${brew_prefix}/lib/pkgconfig:${qt_prefix}/lib/pkgconfig" + export PKG_CONFIG_PATH="${glib_prefix}/lib/pkgconfig:${libusb_prefix}/lib/pkgconfig:${fftw_prefix}/lib/pkgconfig:${boost_prefix}/lib/pkgconfig:${python_prefix}/lib/pkgconfig:${brew_prefix}/lib/pkgconfig:${qt_prefix}/lib/pkgconfig" pkg_config_bin="$(command -v pkg-config)" python_bin="${python_prefix}/bin/python3" python_include="$("${python_bin}" -c 'import sysconfig; print(sysconfig.get_path("include"))')" @@ -196,7 +199,7 @@ jobs: cmake -S . -B build -G Ninja \ -DDSVIEW_PREFER_QT6=ON \ -DDSVIEW_PACKAGE_VERSION_OVERRIDE="${{ steps.meta.outputs.package_version }}" \ - -DCMAKE_PREFIX_PATH="${qt_prefix};${brew_prefix}" \ + -DCMAKE_PREFIX_PATH="${qt_prefix};${glib_prefix};${libusb_prefix};${fftw_prefix};${boost_prefix};${python_prefix};${brew_prefix}" \ -DPKG_CONFIG_EXECUTABLE="${pkg_config_bin}" \ -DPython3_EXECUTABLE="${python_bin}" \ -DPython3_ROOT_DIR="${python_prefix}" \ @@ -211,6 +214,18 @@ jobs: exit ${status} fi + - name: Upload configure diagnostics + if: failure() + uses: actions/upload-artifact@v5 + with: + name: configure-diagnostics-${{ matrix.artifact_name }}-${{ steps.meta.outputs.artifact_version }} + path: | + configure-*.log + build/CMakeFiles/CMakeError.log + build/CMakeFiles/CMakeOutput.log + if-no-files-found: ignore + retention-days: 14 + - name: Build Linux if: runner.os == 'Linux' shell: bash From 0abea66e506edea0ff2421cfb29885bd46703629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 08:14:59 +0100 Subject: [PATCH 11/19] Raise CMake minimum version for modern runners --- CMakeLists.txt | 2 +- DSView/test/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e4b5661ac..c2dbcdd0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ ## along with this program. If not, see . ## -cmake_minimum_required(VERSION 2.8.6) +cmake_minimum_required(VERSION 3.16) project(DSView) diff --git a/DSView/test/CMakeLists.txt b/DSView/test/CMakeLists.txt index ccb95df71..0dd84591a 100644 --- a/DSView/test/CMakeLists.txt +++ b/DSView/test/CMakeLists.txt @@ -19,7 +19,7 @@ ## along with this program. If not, see . ## -cmake_minimum_required(VERSION 2.8.6) +cmake_minimum_required(VERSION 3.16) include(FindPkgConfig) include(GNUInstallDirs) From 2c34e62cf5d09db43c0b112eefb6c0f714ce7146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 08:23:44 +0100 Subject: [PATCH 12/19] Improve macOS Python detection and build diagnostics --- .github/workflows/build-release.yml | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 786dce330..409412212 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -132,7 +132,7 @@ jobs: shell: bash run: | brew update - brew install cmake ninja pkg-config qt@6 glib libusb fftw boost python@3.12 + brew install cmake ninja pkg-config qt@6 glib libusb fftw boost python - name: Configure Linux if: runner.os == 'Linux' @@ -189,11 +189,11 @@ jobs: libusb_prefix="$(brew --prefix libusb)" fftw_prefix="$(brew --prefix fftw)" boost_prefix="$(brew --prefix boost)" - python_prefix="$(brew --prefix python@3.12)" export PATH="${qt_prefix}/bin:${brew_prefix}/bin:$PATH" + pkg_config_bin="$(command -v pkg-config || command -v pkgconf)" + python_bin="$(command -v python3 || command -v python)" + python_prefix="$(cd "$(dirname "${python_bin}")/.." && pwd)" export PKG_CONFIG_PATH="${glib_prefix}/lib/pkgconfig:${libusb_prefix}/lib/pkgconfig:${fftw_prefix}/lib/pkgconfig:${boost_prefix}/lib/pkgconfig:${python_prefix}/lib/pkgconfig:${brew_prefix}/lib/pkgconfig:${qt_prefix}/lib/pkgconfig" - pkg_config_bin="$(command -v pkg-config)" - python_bin="${python_prefix}/bin/python3" python_include="$("${python_bin}" -c 'import sysconfig; print(sysconfig.get_path("include"))')" python_library="$("${python_bin}" -c 'import pathlib, sysconfig; libdir = sysconfig.get_config_var("LIBDIR") or sysconfig.get_config_var("LIBPL") or ""; library = sysconfig.get_config_var("LDLIBRARY") or sysconfig.get_config_var("LIBRARY") or ""; print(pathlib.Path(libdir, library) if libdir and library else "")')" cmake -S . -B build -G Ninja \ @@ -214,13 +214,14 @@ jobs: exit ${status} fi - - name: Upload configure diagnostics + - name: Upload failure diagnostics if: failure() uses: actions/upload-artifact@v5 with: - name: configure-diagnostics-${{ matrix.artifact_name }}-${{ steps.meta.outputs.artifact_version }} + name: failure-diagnostics-${{ matrix.artifact_name }}-${{ steps.meta.outputs.artifact_version }} path: | configure-*.log + build-*.log build/CMakeFiles/CMakeError.log build/CMakeFiles/CMakeOutput.log if-no-files-found: ignore @@ -234,12 +235,22 @@ jobs: - name: Build Windows if: runner.os == 'Windows' shell: msys2 {0} - run: cmake --build build --parallel + run: | + cmake --build build --parallel 2>&1 | tee build-windows.log + status=${PIPESTATUS[0]} + if [[ ${status} -ne 0 ]]; then + exit ${status} + fi - name: Build macOS if: runner.os == 'macOS' shell: bash - run: cmake --build build --parallel + run: | + cmake --build build --parallel 2>&1 | tee build-macos.log + status=${PIPESTATUS[0]} + if [[ ${status} -ne 0 ]]; then + exit ${status} + fi - name: Smoke check Linux if: runner.os == 'Linux' From 96b3523dd934815cc516473dff6e7b6779cbdfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 08:30:17 +0100 Subject: [PATCH 13/19] Upload failure diagnostics after build steps --- .github/workflows/build-release.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 409412212..f128e1e8a 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -214,19 +214,6 @@ jobs: exit ${status} fi - - name: Upload failure diagnostics - if: failure() - uses: actions/upload-artifact@v5 - with: - name: failure-diagnostics-${{ matrix.artifact_name }}-${{ steps.meta.outputs.artifact_version }} - path: | - configure-*.log - build-*.log - build/CMakeFiles/CMakeError.log - build/CMakeFiles/CMakeOutput.log - if-no-files-found: ignore - retention-days: 14 - - name: Build Linux if: runner.os == 'Linux' shell: bash @@ -252,6 +239,19 @@ jobs: exit ${status} fi + - name: Upload failure diagnostics + if: failure() + uses: actions/upload-artifact@v5 + with: + name: failure-diagnostics-${{ matrix.artifact_name }}-${{ steps.meta.outputs.artifact_version }} + path: | + configure-*.log + build-*.log + build/CMakeFiles/CMakeError.log + build/CMakeFiles/CMakeOutput.log + if-no-files-found: ignore + retention-days: 14 + - name: Smoke check Linux if: runner.os == 'Linux' shell: bash From 104aaf192aae949c7888095100ca6d35c043eebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 08:37:28 +0100 Subject: [PATCH 14/19] Fix Windows Qt6 taskbar and libusb include paths --- CMake/Findlibusb-1.0.cmake | 5 ++--- DSView/pv/mainframe.cpp | 30 +++++++++++++++++------------- DSView/pv/mainframe.h | 22 +++++++++++----------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/CMake/Findlibusb-1.0.cmake b/CMake/Findlibusb-1.0.cmake index 8c957a8f7..782259794 100755 --- a/CMake/Findlibusb-1.0.cmake +++ b/CMake/Findlibusb-1.0.cmake @@ -49,7 +49,8 @@ if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) find_path(LIBUSB_1_INCLUDE_DIR NAMES - libusb.h + libusb-1.0/libusb.h + libusb.h PATHS /opt/homebrew/include /opt/homebrew/opt/libusb/include @@ -59,8 +60,6 @@ else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) /opt/local/include /usr/include - PATH_SUFFIXES - libusb-1.0 ) find_library(LIBUSB_1_LIBRARY diff --git a/DSView/pv/mainframe.cpp b/DSView/pv/mainframe.cpp index 540e047de..a2663192f 100644 --- a/DSView/pv/mainframe.cpp +++ b/DSView/pv/mainframe.cpp @@ -110,11 +110,15 @@ MainFrame::MainFrame() bool isWin32 = false; -#ifdef _WIN32 +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) setWindowFlags(Qt::FramelessWindowHint); _is_win32_parent_window = true; _taskBtn = NULL; isWin32 = true; +#elif defined(_WIN32) + setWindowFlags(Qt::FramelessWindowHint); + _is_win32_parent_window = true; + isWin32 = true; #else const bool wayland = ui::is_wayland_platform(); _use_native_window_frame = ui::use_native_window_frame(); @@ -212,10 +216,10 @@ MainFrame::MainFrame() _layout->addLayout(vbox, 0, 0); } -#ifdef _WIN32 - _taskBtn = new QWinTaskbarButton(this); - connect(_mainWindow, SIGNAL(prgRate(int)), this, SLOT(setTaskbarProgress(int))); -#endif +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + _taskBtn = new QWinTaskbarButton(this); + connect(_mainWindow, SIGNAL(prgRate(int)), this, SLOT(setTaskbarProgress(int))); +#endif connect(&_timer, SIGNAL(timeout()), this, SLOT(unfreezing())); @@ -1092,10 +1096,10 @@ void MainFrame::ReadSettings() _initWndInfo.k = k; } -#ifdef _WIN32 -void MainFrame::showEvent(QShowEvent *event) -{ - // Taskbar Progress Effert for Win7 and Above +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +void MainFrame::showEvent(QShowEvent *event) +{ + // Taskbar Progress Effert for Win7 and Above if (_taskBtn && _taskBtn->window() == NULL) { _taskBtn->setWindow(windowHandle()); _taskPrg = _taskBtn->progress(); @@ -1106,10 +1110,10 @@ void MainFrame::showEvent(QShowEvent *event) void MainFrame::setTaskbarProgress(int progress) { -#ifdef _WIN32 - if (progress > 0) { - _taskPrg->setVisible(true); - _taskPrg->setValue(progress); +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + if (progress > 0) { + _taskPrg->setVisible(true); + _taskPrg->setValue(progress); } else { _taskPrg->setVisible(false); } diff --git a/DSView/pv/mainframe.h b/DSView/pv/mainframe.h index da5795ff4..8a85e1b4c 100644 --- a/DSView/pv/mainframe.h +++ b/DSView/pv/mainframe.h @@ -30,10 +30,10 @@ #include #include -#ifdef _WIN32 -#include -#include -#endif +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include +#include +#endif #include "toolbars/titlebar.h" @@ -108,9 +108,9 @@ class MainFrame : void resizeEvent(QResizeEvent *event); void closeEvent(QCloseEvent *event); bool eventFilter(QObject *object, QEvent *event) override; -#ifdef _WIN32 - void showEvent(QShowEvent *event); -#endif +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + void showEvent(QShowEvent *event); +#endif void changeEvent(QEvent *event) override; @@ -170,10 +170,10 @@ public slots: QTimer _timer; bool _freezing; // Taskbar Progress Effert for Win7 and Above -#ifdef _WIN32 - QWinTaskbarButton *_taskBtn; - QWinTaskbarProgress *_taskPrg; -#endif +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QWinTaskbarButton *_taskBtn; + QWinTaskbarProgress *_taskPrg; +#endif bool _is_win32_parent_window; bool _use_native_window_frame; From 56bc44a606109af2659c3ad7cee93712b368a63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 08:46:02 +0100 Subject: [PATCH 15/19] Update Windows screenshot path for Qt6 --- DSView/pv/mainwindow.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 0d03870e9..82f200f38 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -538,12 +538,12 @@ namespace pv (void)x; (void)y; -#ifdef _WIN32 - #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - QPixmap pixmap = QGuiApplication::primaryScreen()->grabWindow(QApplication::desktop->winId(), x, y, w, h); - #else - QPixmap pixmap = QPixmap::grabWidget(parentWidget()); - #endif +#ifdef _WIN32 + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QPixmap pixmap = QGuiApplication::primaryScreen()->grabWindow(0, x, y, w, h); + #else + QPixmap pixmap = QPixmap::grabWidget(parentWidget()); + #endif #elif __APPLE__ x += MainFrame::Margin; y += MainFrame::Margin; From e880b937c52e40459101f9045813e706e7ad3547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 08:54:13 +0100 Subject: [PATCH 16/19] Fix Qt6 QTextCodec usage on Windows --- DSView/pv/storesession.cpp | 4 ---- DSView/pv/utility/encoding.cpp | 8 ++------ DSView/pv/utility/path.cpp | 13 ++----------- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index 24887a9b7..3d282e1f9 100644 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -49,10 +49,6 @@ #include #include -#ifdef _WIN32 -#include -#endif - #include #include "config/appconfig.h" #include "dsvdef.h" diff --git a/DSView/pv/utility/encoding.cpp b/DSView/pv/utility/encoding.cpp index a891f8c6f..ed2ea78f1 100644 --- a/DSView/pv/utility/encoding.cpp +++ b/DSView/pv/utility/encoding.cpp @@ -28,16 +28,12 @@ #include #endif -#ifdef _WIN32 -#include -#endif - namespace pv{ namespace encoding{ void init() { -#ifdef _WIN32 +#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); #endif } @@ -52,4 +48,4 @@ namespace encoding{ #endif } } -} \ No newline at end of file +} diff --git a/DSView/pv/utility/path.cpp b/DSView/pv/utility/path.cpp index 7ca423224..d9846383b 100644 --- a/DSView/pv/utility/path.cpp +++ b/DSView/pv/utility/path.cpp @@ -21,8 +21,6 @@ #include "path.h" #ifdef _WIN32 -#include -#include "../log.h" #include #endif @@ -49,15 +47,8 @@ namespace path{ std::string str; #ifdef _WIN32 - QTextCodec *codec = QTextCodec::codecForName("System"); - if (codec != NULL){ - QByteArray str_tmp = codec->fromUnicode(path); - str = str_tmp.data(); - } - else{ - dsv_err("Error: can't get \"System\" page code"); - str = path.toUtf8().data(); - } + QByteArray str_tmp = path.toLocal8Bit(); + str = str_tmp.constData(); #else str = path.toUtf8().data(); #endif From 9cf2a912969f18f6c5fba783c87816a67377d694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 09:02:27 +0100 Subject: [PATCH 17/19] Build native Windows frame sources in CI --- CMakeLists.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c2dbcdd0f..2045c4cfe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -570,7 +570,15 @@ if(WIN32) set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILER} -O coff -I${CMAKE_CURRENT_SOURCE_DIR} ") enable_language(RC) # app icon - list(APPEND DSView_SOURCES applogo.rc) + list(APPEND DSView_SOURCES + applogo.rc + DSView/pv/winnativewidget.cpp + DSView/pv/winshadow.cpp + ) + list(APPEND DSView_HEADERS + DSView/pv/winnativewidget.h + DSView/pv/winshadow.h + ) endif() if(Qt6Core_FOUND) From 7d73f791823b1179c08ccdbc6405f0ec0f7426df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 09:09:18 +0100 Subject: [PATCH 18/19] Remove Qt5 desktop header from native widget --- DSView/pv/winnativewidget.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/DSView/pv/winnativewidget.cpp b/DSView/pv/winnativewidget.cpp index 7b8663015..2fe48e700 100644 --- a/DSView/pv/winnativewidget.cpp +++ b/DSView/pv/winnativewidget.cpp @@ -21,12 +21,11 @@ */ -#include "winnativewidget.h" -#include -#include -#include -#include -#include +#include "winnativewidget.h" +#include +#include +#include +#include #include #include #include From e6f1f4481b2c5389f9d86a3a8d6967dd136e6d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Sch=C3=B6b?= Date: Fri, 27 Mar 2026 09:15:12 +0100 Subject: [PATCH 19/19] Fix native widget key events on Qt6 --- DSView/pv/winnativewidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DSView/pv/winnativewidget.cpp b/DSView/pv/winnativewidget.cpp index 2fe48e700..b7c5d6ee3 100644 --- a/DSView/pv/winnativewidget.cpp +++ b/DSView/pv/winnativewidget.cpp @@ -177,13 +177,13 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam case WM_KEYDOWN: { //enable the hot key. - QKeyEvent keyEvent(QEvent::KeyPress, (int)wParam, 0); + QKeyEvent keyEvent(QEvent::KeyPress, (int)wParam, Qt::NoModifier); QApplication::sendEvent(self->_childWidget->GetBodyView(), &keyEvent); break; } case WM_KEYUP: { - QKeyEvent keyEvent(QEvent::KeyRelease, (int)wParam, 0); + QKeyEvent keyEvent(QEvent::KeyRelease, (int)wParam, Qt::NoModifier); QApplication::sendEvent(self->_childWidget->GetBodyView(), &keyEvent); break; }