Files
live-caption/CMakeLists.txt
T
blumia a7a6f3e6b6 feat(gui): drive everything from settings, add tray and in-app download
The GUI no longer needs command line arguments: on first run it opens a
settings dialog that lists the registry, downloads models in-app (mirror
base, HTTP proxy, resume), and picks the active model. The caption window
gains a tray icon (show/hide, settings, quit); its close button hides to
the tray so the window can always be brought back, and the language pill
opens the settings. Appearance (font, opacity, line counts, position) is
persisted. CLI flags remain for automated testing and override settings.

GUI 不再依赖命令行参数:首次启动打开设置对话框,可在应用内下载模型
(下载源/代理/断点续传)、选择当前模型与识别语言;字幕窗增加托盘(显示
隐藏/设置/退出),关闭按钮改为隐藏到托盘以免关掉后无法再打开,语言标签
点击进设置;字号/透明度/行数/位置都会持久化。命令行参数保留作自动化测试。
2026-10-12 16:30:00 +08:00

161 lines
6.5 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.24)
project(live-caption LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_AUTOMOC ON)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
endif()
option(LC_BUILD_TESTS "构建单元测试" ON)
# ---------------------------------------------------------------------------
# llama.cpp / libmtmd 的搜索路径
#
# Debian/Deepin 把 llama 的 CMake config 放在非标准目录 cmake-private/,
# 而 pkg-config 的 llama.pc 又漏了 -lmtmd。所以这里把两个路径都塞进搜索前缀,
# 并单独用 find_library 找 mtmd。
# ---------------------------------------------------------------------------
foreach(_p
/usr/lib/x86_64-linux-gnu/llama
/usr/lib/x86_64-linux-gnu/llama/cmake-private
/usr/lib/x86_64-linux-gnu/llama/pkgconfig)
if(EXISTS "${_p}")
list(APPEND CMAKE_PREFIX_PATH "${_p}")
set(ENV{PKG_CONFIG_PATH} "${_p}:$ENV{PKG_CONFIG_PATH}")
endif()
endforeach()
find_package(Qt6 REQUIRED COMPONENTS Core Widgets Network)
find_package(PkgConfig REQUIRED)
find_package(Threads REQUIRED)
pkg_check_modules(SAMPLERATE REQUIRED IMPORTED_TARGET samplerate)
pkg_check_modules(PULSE REQUIRED IMPORTED_TARGET libpulse)
# --- llama:优先系统 pkg-config,其次 CMake config,最后 FetchContent 兜底 ---
pkg_check_modules(LLAMA QUIET IMPORTED_TARGET llama)
if(LLAMA_FOUND)
set(LC_LLAMA_TARGET PkgConfig::LLAMA)
message(STATUS "llama: 使用系统 pkg-config (${LLAMA_VERSION})")
else()
message(STATUS "llama: 系统未找到,改用 FetchContent 拉取固定版本")
include(FetchContent)
set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE ALWAYS) # 先 find_package,失败再拉源码
FetchContent_Declare(llama
GIT_REPOSITORY https://github.com/ggml-org/llama.cpp.git
GIT_TAG b9951
FIND_PACKAGE_ARGS NAMES llama CONFIG)
set(LLAMA_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(LLAMA_BUILD_SERVER OFF CACHE BOOL "" FORCE)
set(LLAMA_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(llama)
set(LC_LLAMA_TARGET llama)
endif()
# --- mtmd:llama.pc 里没有,单独找 ---
find_library(LC_MTMD_LIB NAMES mtmd HINTS /usr/lib/x86_64-linux-gnu/llama)
if(NOT LC_MTMD_LIB)
message(FATAL_ERROR "找不到 libmtmd(应随 libllama0 一起安装)")
endif()
message(STATUS "mtmd: ${LC_MTMD_LIB}")
# ---------------------------------------------------------------------------
# sherpa-onnx(X-ASR / zipformer / Nemotron 等流式 ONNX 模型)
#
# 注意:官方预编译库是用旧 C++ ABI 编译的,所以只能用它的 C API。
# 安装:把官方的 sherpa-onnx-vX.Y.Z-linux-x64-shared.tar.bz2 解到某个目录,
# 用 -DSHERPA_ONNX_ROOT=<dir> 指定(默认见下)。
# ---------------------------------------------------------------------------
set(SHERPA_ONNX_ROOT "$ENV{HOME}/.local/opt/sherpa-onnx" CACHE PATH "sherpa-onnx 安装目录")
set(LC_HAS_SHERPA OFF)
if(EXISTS "${SHERPA_ONNX_ROOT}/include/sherpa-onnx/c-api/c-api.h")
find_library(LC_SHERPA_C_API NAMES sherpa-onnx-c-api
HINTS "${SHERPA_ONNX_ROOT}/lib" REQUIRED)
find_library(LC_SHERPA_ORT NAMES onnxruntime
HINTS "${SHERPA_ONNX_ROOT}/lib" REQUIRED)
set(LC_HAS_SHERPA ON)
message(STATUS "sherpa-onnx: ${SHERPA_ONNX_ROOT}")
else()
message(WARNING "未找到 sherpa-onnx(${SHERPA_ONNX_ROOT}),流式 ONNX 后端将不可用")
endif()
# ---------------------------------------------------------------------------
# core:全部业务逻辑,刻意不依赖 Qt(方便测试与复用)
# ---------------------------------------------------------------------------
add_library(livecaption_core STATIC
src/core/transcript.cpp
src/core/audio.cpp
src/core/qwen3asr.cpp
src/core/streamingasr.cpp
src/core/livepipeline.cpp
)
if(LC_HAS_SHERPA)
target_sources(livecaption_core PRIVATE src/core/sherpaasr.cpp)
target_compile_definitions(livecaption_core PUBLIC LC_HAVE_SHERPA=1)
target_include_directories(livecaption_core PRIVATE "${SHERPA_ONNX_ROOT}/include")
target_link_libraries(livecaption_core PUBLIC ${LC_SHERPA_C_API} ${LC_SHERPA_ORT})
endif()
target_include_directories(livecaption_core PUBLIC src/core)
target_link_libraries(livecaption_core PUBLIC
Threads::Threads
PkgConfig::SAMPLERATE
PkgConfig::PULSE
${LC_LLAMA_TARGET}
${LC_MTMD_LIB}
)
# ---------------------------------------------------------------------------
# models:模型注册表与存储(Qt;注册表编译进二进制)
# ---------------------------------------------------------------------------
add_library(livecaption_models STATIC
src/models/modelstore.cpp
src/models/modeldownloader.cpp
)
target_include_directories(livecaption_models PUBLIC src/models)
target_link_libraries(livecaption_models PUBLIC Qt6::Core Qt6::Network)
qt_add_resources(livecaption_models "registry"
PREFIX "/"
BASE "${CMAKE_CURRENT_SOURCE_DIR}"
FILES data/models.json)
# ---------------------------------------------------------------------------
# ui:悬浮窗与 Qt 适配层
# ---------------------------------------------------------------------------
add_library(livecaption_ui STATIC
src/ui/captionwindow.cpp
src/ui/livetranscriber.cpp
src/ui/appsettings.cpp
src/ui/settingsdialog.cpp
)
target_include_directories(livecaption_ui PUBLIC src/ui)
target_link_libraries(livecaption_ui PUBLIC livecaption_core livecaption_models Qt6::Widgets)
# ---------------------------------------------------------------------------
# 可执行程序
# ---------------------------------------------------------------------------
# GUI:悬浮字幕窗
add_executable(live-caption apps/gui/main.cpp)
target_include_directories(live-caption PRIVATE apps/common)
target_link_libraries(live-caption PRIVATE livecaption_ui livecaption_models)
# CLI:文件 / 流式文件 / 命令行实时;不链接 Qt Widgets
add_executable(live-caption-cli apps/cli/main.cpp)
target_include_directories(live-caption-cli PRIVATE apps/common)
target_link_libraries(live-caption-cli PRIVATE livecaption_core livecaption_models)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
foreach(_t livecaption_core livecaption_ui livecaption_models live-caption live-caption-cli)
target_compile_options(${_t} PRIVATE -Wall -Wextra -Wno-unused-parameter)
endforeach()
endif()
# ---------------------------------------------------------------------------
if(LC_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()