impress_voice_input/CMakeLists.txt
impressionyang 5e0651453c fix: 修复跨平台快捷键设置和录制功能
- HotkeyRecorder 补全 installEventFilter,修复设置页按键捕获失效
- 快捷键默认值从 CapsLock 改为 Ctrl+Alt+C
- CapsLockVoiceHotkey 支持 Ctrl+Alt+X 等组合键解析
- VoiceInputService 配置变更增加日志输出
- 主窗口集成录音指示器和快捷键状态显示
- CMakeLists.txt 更新新增源文件和头文件

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-15 16:43:44 +08:00

295 lines
9.4 KiB
CMake
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

cmake_minimum_required(VERSION 3.20)
project(impress_voice_input
VERSION 0.1.0
LANGUAGES CXX
DESCRIPTION "基于 ONNX 的实时语音转文本输入法"
)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# 默认使用 Release 带调试信息
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "RelWithDebInfo" "MinSizeRel")
endif()
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# ============================================================================
# 依赖查找
# ============================================================================
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Qt 6
find_package(Qt6 REQUIRED COMPONENTS Core Widgets Concurrent Network)
# Windows 不需要 D-BusLinux/macOS 按需加载
if(WIN32)
find_package(Qt6 REQUIRED COMPONENTS Gui)
else()
find_package(Qt6 REQUIRED COMPONENTS DBus)
endif()
qt_standard_project_setup()
# ONNX Runtime
include(dependencies)
# ============================================================================
# 源文件
# ============================================================================
set(SOURCES
src/main.cpp
# App
src/app/application.cpp
src/app/config_manager.cpp
# Core (平台无关)
src/core/stt_engine.cpp
src/core/sense_voice_engine.cpp
src/core/ort_minimal.cpp
src/core/sense_voice_features.cpp
src/core/sense_voice_tokenizer.cpp
src/core/mel_spectrogram.cpp
src/core/whisper_tokenizer.cpp
src/core/audio_processor.cpp
src/core/vad.cpp
src/core/voice_input_service.cpp
# Audio
src/audio/audio_capture.cpp
src/audio/audio_decoder.cpp
src/audio/audio_ring_buffer.cpp
src/audio/streaming_audio_writer.cpp
# UI
src/ui/main_window.cpp
src/ui/stt_test_page.cpp
src/ui/file_transcribe_page.cpp
src/ui/settings_page.cpp
src/ui/widgets/audio_waveform.cpp
src/ui/widgets/text_output.cpp
src/ui/widgets/progress_panel.cpp
src/ui/widgets/hotkey_recorder.cpp
src/ui/widgets/recording_indicator.cpp
# Utils
src/utils/logger.cpp
src/utils/timer.cpp
src/utils/string_utils.cpp
)
set(HEADERS
src/app/application.h
src/app/config_manager.h
src/core/stt_engine.h
src/core/sense_voice_engine.h
src/core/sense_voice_features.h
src/core/sense_voice_tokenizer.h
src/core/sense_voice_cmvn.h
src/core/mel_spectrogram.h
src/core/whisper_tokenizer.h
src/core/audio_processor.h
src/core/vad.h
src/core/voice_input_service.h
src/audio/audio_capture.h
src/audio/audio_decoder.h
src/audio/audio_ring_buffer.h
src/audio/streaming_audio_writer.h
src/ui/main_window.h
src/ui/stt_test_page.h
src/ui/file_transcribe_page.h
src/ui/settings_page.h
src/ui/widgets/audio_waveform.h
src/ui/widgets/text_output.h
src/ui/widgets/progress_panel.h
src/ui/widgets/hotkey_recorder.h
src/ui/widgets/recording_indicator.h
src/utils/logger.h
src/utils/timer.h
src/utils/string_utils.h
)
# ============================================================================
# 平台特定源文件
# ============================================================================
if(WIN32)
# Windows 实现RegisterHotKey + SendInput
list(APPEND SOURCES src/core/win_hotkey.cpp src/core/win_text_injector.cpp)
list(APPEND HEADERS src/core/win_hotkey.h src/core/win_text_injector.h)
add_compile_definitions(PLATFORM_WINDOWS)
elseif(APPLE)
# macOS 实现待完善Carbon EventManager / CGEvent
list(APPEND SOURCES src/core/mac_hotkey.cpp src/core/mac_text_injector.cpp)
list(APPEND HEADERS src/core/mac_hotkey.h src/core/mac_text_injector.h)
add_compile_definitions(PLATFORM_MACOS)
else()
# Linux 实现X11 XGrabKey / evdev / libei / D-Bus Portal
list(APPEND SOURCES
src/core/caps_lock_voice_hotkey.cpp
src/core/caps_lock_backend.cpp
src/core/caps_lock_xcb.cpp
src/core/caps_lock_evdev.cpp
src/core/wayland_text_injector.cpp
)
list(APPEND HEADERS
src/core/caps_lock_voice_hotkey.h
src/core/caps_lock_backend.h
src/core/caps_lock_xcb.h
src/core/caps_lock_evdev.h
src/core/wayland_text_injector.h
)
add_compile_definitions(PLATFORM_LINUX)
endif()
# Windows 使用 WIN32 标志隐藏启动控制台,并嵌入应用图标
if(WIN32)
add_executable(${PROJECT_NAME} WIN32 ${SOURCES} ${HEADERS}
src/ui/resources/styles/styles.qrc
src/ui/resources/icons/icon.rc
)
else()
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}
src/ui/resources/styles/styles.qrc
)
endif()
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/third_party
${ONNXRUNTIME_INCLUDE_DIRS}
${PORTAUDIO_INCLUDE_DIRS}
${DR_LIBS_INCLUDE_DIR}
${NLOHMANN_JSON_INCLUDE_DIR}
)
target_link_libraries(${PROJECT_NAME} PRIVATE
Qt6::Core
Qt6::Widgets
Qt6::Concurrent
Qt6::Network
$<$<BOOL:${WIN32}>:Qt6::Gui>
$<$<NOT:$<BOOL:${WIN32}>>:Qt6::DBus>
${ONNXRUNTIME_LIBRARIES}
${PORTAUDIO_LIBRARIES}
$<$<NOT:$<BOOL:${WIN32}>>:pthread>
)
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -Wpedantic>
$<$<CXX_COMPILER_ID:MSVC>:/W4>
)
# ============================================================================
# Linux: libei 全局快捷键GNOME 47+
# ============================================================================
if(NOT WIN32 AND NOT APPLE)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(LIBEI QUIET libei-1.0)
endif()
if(LIBEI_FOUND)
find_library(LIBEI_LIB_PATH
NAMES ei
PATHS /usr/lib64 /usr/lib /usr/local/lib
)
if(LIBEI_LIB_PATH)
message(STATUS "找到 libei: ${LIBEI_LIB_PATH} (${LIBEI_VERSION})")
target_include_directories(${PROJECT_NAME} PRIVATE ${LIBEI_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBEI_LIB_PATH})
add_compile_definitions(HAVE_LIBEI)
endif()
endif()
endif()
# ============================================================================
# Linux: X11 全局快捷键XCB XGrabKey
# ============================================================================
if(NOT WIN32 AND NOT APPLE)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(XCB QUIET xcb)
pkg_check_modules(X11 QUIET x11)
endif()
if(XCB_FOUND AND X11_FOUND)
message(STATUS "找到 XCB: ${XCB_LIBDIR}")
message(STATUS "找到 X11: ${X11_LIBDIR}")
target_include_directories(${PROJECT_NAME} PRIVATE ${XCB_INCLUDE_DIRS} ${X11_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${XCB_LIBRARIES} ${X11_LIBRARIES})
add_compile_definitions(HAVE_XCB)
else()
message(STATUS "XCB/X11 未找到X11 全局快捷键不可用")
endif()
endif()
# ============================================================================
# Windows DLL 复制(交叉编译时自动拷贝到输出目录)
# ============================================================================
if(WIN32)
if(ONNXRUNTIME_DLL)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${ONNXRUNTIME_DLL}"
$<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMENT "拷贝 onnxruntime.dll 到输出目录"
)
endif()
if(ONNXRUNTIME_PROVIDERS_DLL)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${ONNXRUNTIME_PROVIDERS_DLL}"
$<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMENT "拷贝 onnxruntime_providers_shared.dll 到输出目录"
)
endif()
if(PORTAUDIO_DLL)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PORTAUDIO_DLL}"
$<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMENT "拷贝 libportaudio.dll 到输出目录"
)
endif()
endif()
# ============================================================================
# 安装
# ============================================================================
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
BUNDLE DESTINATION .
)
# GNOME Shell 扩展
if(NOT WIN32 AND NOT APPLE)
set(GNOME_EXT_UUID "io.impress.voice-input-hotkey@impress")
set(GNOME_EXT_SRC "${CMAKE_CURRENT_SOURCE_DIR}/gnome-extension/${GNOME_EXT_UUID}")
set(GNOME_EXT_DST "${CMAKE_INSTALL_PREFIX}/share/gnome-shell/extensions/${GNOME_EXT_UUID}")
install(FILES "${GNOME_EXT_SRC}/extension.js"
"${GNOME_EXT_SRC}/metadata.json"
DESTINATION share/gnome-shell/extensions/${GNOME_EXT_UUID})
endif()
# ============================================================================
# 测试
# ============================================================================
option(BUILD_TESTS "构建单元测试" OFF)
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()