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-Bus,Linux/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 # 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/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 实现(D-Bus Portal + XTest) list(APPEND SOURCES src/core/caps_lock_voice_hotkey.cpp src/core/wayland_text_injector.cpp) list(APPEND HEADERS src/core/caps_lock_voice_hotkey.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 $<$:Qt6::Gui> $<$>:Qt6::DBus> ${ONNXRUNTIME_LIBRARIES} ${PORTAUDIO_LIBRARIES} $<$>:pthread> ) target_compile_options(${PROJECT_NAME} PRIVATE $<$:-Wall -Wextra -Wpedantic> $<$:/W4> ) # ============================================================================ # Windows DLL 复制(交叉编译时自动拷贝到输出目录) # ============================================================================ if(WIN32) if(ONNXRUNTIME_DLL) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ONNXRUNTIME_DLL}" $ 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}" $ 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}" $ COMMENT "拷贝 libportaudio.dll 到输出目录" ) endif() endif() # ============================================================================ # 安装 # ============================================================================ install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin BUNDLE DESTINATION . ) # ============================================================================ # 测试 # ============================================================================ option(BUILD_TESTS "构建单元测试" OFF) if(BUILD_TESTS) enable_testing() add_subdirectory(tests) endif()