From ad3524bd235150c09824a018081eb798c542335e Mon Sep 17 00:00:00 2001 From: ubuntu1804 Date: Tue, 11 Nov 2025 17:59:09 +0800 Subject: [PATCH] Generate version files and integrate into build Add CMake configure steps to produce version.h and version.sh from templates and include the build dir for the generated header. Add version.h.in and version.sh.in, include version.h in VulkanWidget and use APP_VK_VERSION for the Vulkan applicationVersion. Update make_deb.sh to source version.sh for the package version instead --- CMakeLists.txt | 19 ++++++++++ make_deb.sh | 21 ++++++++--- src/version.h.in | 15 ++++++++ src/vulkanwidget.cpp | 87 ++++++++++++++++++++++---------------------- version.sh | 16 ++++++++ version.sh.in | 16 ++++++++ 6 files changed, 126 insertions(+), 48 deletions(-) create mode 100644 src/version.h.in create mode 100644 version.sh create mode 100644 version.sh.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 07e955a..c344219 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,20 @@ else() message(STATUS "Vulkan support disabled") endif() +# Generate version header from template (for C++ code) +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/src/version.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/version.h" + @ONLY +) + +# Generate version shell script from template (for shell scripts) +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/version.sh.in" + "${CMAKE_CURRENT_SOURCE_DIR}/version.sh" + @ONLY +) + # Common source files set(SOURCES src/main.cpp @@ -187,6 +201,11 @@ add_executable(${PROJECT_NAME} ${HEADERS} ) +# Include build directory for generated version.h +target_include_directories(${PROJECT_NAME} PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} +) + # Link Qt5 libraries target_link_libraries(${PROJECT_NAME} Qt5::Core diff --git a/make_deb.sh b/make_deb.sh index d9703a2..6483112 100755 --- a/make_deb.sh +++ b/make_deb.sh @@ -12,13 +12,24 @@ NC='\033[0m' # No Color # 配置变量 APP_NAME="ScreenLockDetector" PACKAGE_NAME="ScreenLockDetector" -# 从 CMakeLists.txt 中提取版本号 -VERSION=$(grep -oP '(?<=project\(ScreenLockDetector VERSION )[0-9.]+' CMakeLists.txt) -if [ -z "$VERSION" ]; then - echo -e "${RED}错误: 无法从 CMakeLists.txt 中提取版本号${NC}" + +# 从自动生成的 version.sh 中读取版本号 +if [ ! -f "version.sh" ]; then + echo -e "${RED}错误: version.sh 文件不存在${NC}" + echo -e "${YELLOW}请先运行 ./build.sh 生成版本文件${NC}" exit 1 fi -echo -e "${GREEN}✓ 从 CMakeLists.txt 读取版本号: ${VERSION}${NC}" + +# Source version.sh to get APP_VERSION +source version.sh + +if [ -z "$APP_VERSION" ]; then + echo -e "${RED}错误: 无法从 version.sh 中读取版本号${NC}" + exit 1 +fi + +VERSION="$APP_VERSION" +echo -e "${GREEN}✓ 从 version.sh 读取版本号: ${VERSION}${NC}" ARCH="amd64" QT_DIR="$HOME/sdk/qt-5.15.2" LINUXDEPLOYQT="${LINUXDEPLOYQT:-$HOME/tools/sunvpack-py/bin/linuxdeployqt}" diff --git a/src/version.h.in b/src/version.h.in new file mode 100644 index 0000000..7eb4e3e --- /dev/null +++ b/src/version.h.in @@ -0,0 +1,15 @@ +#ifndef VERSION_H +#define VERSION_H + +// Auto-generated version information from CMakeLists.txt +// DO NOT EDIT THIS FILE MANUALLY - Edit CMakeLists.txt instead + +#define APP_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define APP_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define APP_VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define APP_VERSION_STRING "@PROJECT_VERSION@" + +// Vulkan version macros +#define APP_VK_VERSION VK_MAKE_VERSION(APP_VERSION_MAJOR, APP_VERSION_MINOR, APP_VERSION_PATCH) + +#endif // VERSION_H diff --git a/src/vulkanwidget.cpp b/src/vulkanwidget.cpp index aff8e66..bfa38f0 100644 --- a/src/vulkanwidget.cpp +++ b/src/vulkanwidget.cpp @@ -1,5 +1,6 @@ #include "vulkanwidget.h" #include "vulkanrenderer.h" +#include "version.h" #include #include #include @@ -68,7 +69,7 @@ VulkanWidget::VulkanWidget(QWidget *parent) // Create render timer m_renderTimer = new QTimer(this); connect(m_renderTimer, &QTimer::timeout, this, &VulkanWidget::onRenderTimer); - + // Initialize FPS calculation m_frameTimes.reserve(FPS_SAMPLE_COUNT); @@ -111,7 +112,7 @@ void VulkanWidget::setRenderingEnabled(bool enabled) if (m_renderingEnabled) { qDebug() << "Vulkan rendering ENABLED - Resuming animations"; - + // Check if device was lost (e.g., after wake from sleep) if (m_deviceLost) { qDebug() << "Device lost detected on resume, attempting recovery..."; @@ -121,7 +122,7 @@ void VulkanWidget::setRenderingEnabled(bool enabled) return; } } - + // 恢复渲染时,重新启动定时器(锁屏时已停止) if (!m_renderTimer->isActive()) { m_renderTimer->start(16); // ~60 FPS @@ -291,7 +292,7 @@ bool VulkanWidget::createInstance() VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "VulkanWidget"; - appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.applicationVersion = APP_VK_VERSION; // Auto-generated from CMakeLists.txt appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; @@ -344,7 +345,7 @@ bool VulkanWidget::createSurface() #elif defined(__linux__) VkXlibSurfaceCreateInfoKHR createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - + // Reuse existing X11 display or open a new one Display* x11Display = static_cast(m_x11Display); if (!x11Display) { @@ -358,7 +359,7 @@ bool VulkanWidget::createSurface() } else { qDebug() << "Reusing existing X11 display"; } - + createInfo.dpy = x11Display; createInfo.window = static_cast(window->winId()); @@ -772,7 +773,7 @@ void VulkanWidget::renderFrame() if (!m_initialized || m_isClosing) { return; } - + // Don't render if device is lost (recovery will be attempted on next enable) if (m_deviceLost) { return; @@ -785,14 +786,14 @@ void VulkanWidget::renderFrame() QDateTime currentTime = QDateTime::currentDateTime(); qint64 frameTimeUs = m_lastFrameTime.msecsTo(currentTime) * 1000; // Convert to microseconds m_lastFrameTime = currentTime; - + if (frameTimeUs > 0) { // Add frame time to circular buffer if (m_frameTimes.size() >= FPS_SAMPLE_COUNT) { m_frameTimes.erase(m_frameTimes.begin()); } m_frameTimes.push_back(frameTimeUs); - + // Calculate average FPS from recent frames if (!m_frameTimes.empty()) { qint64 totalTimeUs = 0; @@ -857,7 +858,7 @@ void VulkanWidget::renderFrame() result = vkQueueSubmit(m_queue, 1, &submitInfo, m_inFlightFences[m_currentFrame]); if (result != VK_SUCCESS) { qDebug() << "Failed to submit draw command buffer! Error code = " << result; - + // Handle device lost error (e.g., after wake from sleep/hibernation) if (result == VK_ERROR_DEVICE_LOST || result == -4) { qDebug() << "VK_ERROR_DEVICE_LOST detected! Attempting to recover device..."; @@ -957,7 +958,7 @@ void VulkanWidget::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t i // Calculate elapsed time in seconds QDateTime now = QDateTime::currentDateTime(); qint64 elapsedTime = m_startTime.secsTo(now); - + m_renderer->recordCommandBuffer(commandBuffer, imageIndex, imageView, m_frameCount, static_cast(elapsedTime), m_currentFps, @@ -1083,7 +1084,7 @@ void VulkanWidget::cleanupVulkan() if (m_surface != VK_NULL_HANDLE) { vkDestroySurfaceKHR(m_instance, m_surface, nullptr); } - + // Close X11 display if it was opened (Linux only) #ifdef __linux__ if (m_x11Display) { @@ -1228,13 +1229,13 @@ std::vector VulkanWidget::getRequiredDeviceExtensions() bool VulkanWidget::handleDeviceLost() { qDebug() << "=== Handling device lost error ==="; - + // Stop rendering timer to prevent more render attempts during recovery if (m_renderTimer && m_renderTimer->isActive()) { m_renderTimer->stop(); qDebug() << "Render timer stopped for device recovery"; } - + // Wait for any pending operations to complete (may fail, but try anyway) if (m_device != VK_NULL_HANDLE) { VkResult result = vkDeviceWaitIdle(m_device); @@ -1242,14 +1243,14 @@ bool VulkanWidget::handleDeviceLost() qDebug() << "vkDeviceWaitIdle failed (expected with device lost), continuing recovery..."; } } - + // Attempt to recreate the device and all resources bool success = recreateDevice(); - + if (success) { m_deviceLost = false; qDebug() << "Device recovery successful!"; - + // Restart rendering timer if rendering was enabled if (m_renderingEnabled && m_renderTimer && !m_renderTimer->isActive()) { m_renderTimer->start(16); // ~60 FPS @@ -1258,21 +1259,21 @@ bool VulkanWidget::handleDeviceLost() } else { qDebug() << "Device recovery failed!"; } - + return success; } bool VulkanWidget::recreateDevice() { qDebug() << "=== Recreating Vulkan device ==="; - + // Clean up renderer first if (m_renderer) { delete m_renderer; m_renderer = nullptr; qDebug() << "Renderer cleaned up"; } - + // Clean up sync objects if (m_device != VK_NULL_HANDLE) { for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { @@ -1288,16 +1289,16 @@ bool VulkanWidget::recreateDevice() } qDebug() << "Sync objects cleaned up"; } - + m_renderFinishedSemaphores.clear(); m_imageAvailableSemaphores.clear(); m_inFlightFences.clear(); - + // Clean up command objects if (m_device != VK_NULL_HANDLE && m_commandPool != VK_NULL_HANDLE) { if (!m_commandBuffers.empty()) { - vkFreeCommandBuffers(m_device, m_commandPool, - static_cast(m_commandBuffers.size()), + vkFreeCommandBuffers(m_device, m_commandPool, + static_cast(m_commandBuffers.size()), m_commandBuffers.data()); m_commandBuffers.clear(); } @@ -1305,10 +1306,10 @@ bool VulkanWidget::recreateDevice() m_commandPool = VK_NULL_HANDLE; qDebug() << "Command objects cleaned up"; } - + // Clean up swapchain cleanupSwapchain(); - + // Destroy logical device if (m_device != VK_NULL_HANDLE) { vkDestroyDevice(m_device, nullptr); @@ -1316,14 +1317,14 @@ bool VulkanWidget::recreateDevice() m_queue = VK_NULL_HANDLE; qDebug() << "Logical device destroyed"; } - + // Destroy surface if (m_surface != VK_NULL_HANDLE) { vkDestroySurfaceKHR(m_instance, m_surface, nullptr); m_surface = VK_NULL_HANDLE; qDebug() << "Surface destroyed"; } - + // Close and reset X11 display (Linux only) - will be reopened when creating new surface #ifdef __linux__ if (m_x11Display) { @@ -1332,21 +1333,21 @@ bool VulkanWidget::recreateDevice() qDebug() << "X11 display closed for recreation"; } #endif - + // Now recreate everything from surface onwards - + // Important: Add a small delay to let the GPU driver fully reset // This prevents VK_ERROR_SURFACE_LOST_KHR on some systems qDebug() << "Waiting for GPU driver to stabilize..."; QThread::msleep(200); // 200ms delay - + // Step 1: Recreate surface if (!createSurface()) { setError("Failed to recreate surface after device lost"); return false; } qDebug() << "Surface recreated"; - + // Verify the physical device still supports this surface VkBool32 surfaceSupported = VK_FALSE; vkGetPhysicalDeviceSurfaceSupportKHR(m_physicalDevice, m_queueFamilyIndex, m_surface, &surfaceSupported); @@ -1356,14 +1357,14 @@ bool VulkanWidget::recreateDevice() return false; } qDebug() << "Surface support verified"; - + // Step 2: Recreate logical device if (!createDevice()) { setError("Failed to recreate device after device lost"); return false; } qDebug() << "Logical device recreated"; - + // Step 3: Recreate swapchain // Query surface capabilities again to ensure they're current VkSurfaceCapabilitiesKHR surfaceCaps; @@ -1374,31 +1375,31 @@ bool VulkanWidget::recreateDevice() return false; } qDebug() << "Surface capabilities validated"; - + if (!createSwapchain()) { setError("Failed to recreate swapchain after device lost"); return false; } qDebug() << "Swapchain recreated"; - + // Step 4: Recreate command objects if (!createCommandObjects()) { setError("Failed to recreate command objects after device lost"); return false; } qDebug() << "Command objects recreated"; - + // Step 5: Recreate synchronization objects if (!createSyncObjects()) { setError("Failed to recreate sync objects after device lost"); return false; } qDebug() << "Sync objects recreated"; - + // Step 6: Recreate VulkanRenderer if (m_surfaceWidth >= 100 && m_surfaceHeight >= 100) { m_renderer = new VulkanRenderer(); - + // Get swapchain format VkSurfaceFormatKHR surfaceFormat; uint32_t formatCount = 0; @@ -1408,7 +1409,7 @@ bool VulkanWidget::recreateDevice() vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &formatCount, formats.data()); surfaceFormat = formats[0]; } - + // Initialize renderer if (!m_renderer->initialize(m_device, m_physicalDevice, m_queue, m_queueFamilyIndex, @@ -1419,13 +1420,13 @@ bool VulkanWidget::recreateDevice() m_renderer = nullptr; return false; } - + qDebug() << "VulkanRenderer recreated successfully!"; } - + // Reset frame counter m_currentFrame = 0; - + qDebug() << "=== Device recreation complete ==="; return true; } diff --git a/version.sh b/version.sh new file mode 100644 index 0000000..91fb0a8 --- /dev/null +++ b/version.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Auto-generated version information from CMakeLists.txt +# DO NOT EDIT THIS FILE MANUALLY - Edit CMakeLists.txt instead +# This file is sourced by shell scripts to get version information + +APP_VERSION_MAJOR=1 +APP_VERSION_MINOR=3 +APP_VERSION_PATCH=0 +APP_VERSION="1.3.0" + +# Export for use in other scripts +export APP_VERSION_MAJOR +export APP_VERSION_MINOR +export APP_VERSION_PATCH +export APP_VERSION diff --git a/version.sh.in b/version.sh.in new file mode 100644 index 0000000..c93c748 --- /dev/null +++ b/version.sh.in @@ -0,0 +1,16 @@ +#!/bin/bash + +# Auto-generated version information from CMakeLists.txt +# DO NOT EDIT THIS FILE MANUALLY - Edit CMakeLists.txt instead +# This file is sourced by shell scripts to get version information + +APP_VERSION_MAJOR=@PROJECT_VERSION_MAJOR@ +APP_VERSION_MINOR=@PROJECT_VERSION_MINOR@ +APP_VERSION_PATCH=@PROJECT_VERSION_PATCH@ +APP_VERSION="@PROJECT_VERSION@" + +# Export for use in other scripts +export APP_VERSION_MAJOR +export APP_VERSION_MINOR +export APP_VERSION_PATCH +export APP_VERSION