The validation added in #1084 rejected anything but digits and dots, which is narrower than semver: a prerelease suffix after a hyphen is part of the spec, and the native about page's ParseVersion already strips such a suffix for the update check while displaying it verbatim. Allow exactly one hyphen segment of [0-9A-Za-z.-] after the numeric body, so dev builds can embed 0.7.1-dev.20261019.<hash> and the about page shows the full string. version.txt itself stays bare MAJOR.MINOR.PATCH and every release passes unchanged. lcompile-release.ps1 feeds the same override locally, so its ValidatePattern loosens in step.
671 lines
28 KiB
CMake
671 lines
28 KiB
CMake
cmake_minimum_required(VERSION 3.25.0)
|
||
if(POLICY CMP0141)
|
||
cmake_policy(SET CMP0141 NEW)
|
||
endif()
|
||
|
||
set(PROJECT_NAME "MetasequoiaImeServer")
|
||
|
||
cmake_policy(SET CMP0167 NEW)
|
||
project(${PROJECT_NAME} VERSION 1.0)
|
||
|
||
# Release binaries need usable symbols for crash diagnosis. Keep the PDB beside each executable so
|
||
# the release job can validate and publish it without changing the binary's install layout.
|
||
#
|
||
# The debug info is embedded in each object (/Z7) rather than written to a compile-time PDB (/Zi).
|
||
# The two produce the same final .pdb once the linker's /DEBUG runs over them, but sccache -- the CI
|
||
# compiler cache -- can only cache an MSVC compile whose debug info lives in the object. With /Zi it
|
||
# treats every translation unit as uncacheable and the cache sits at a 0% hit rate. /Z7 keeps the
|
||
# beside-the-executable PDB the release job expects while letting that cache actually work.
|
||
if(MSVC)
|
||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "Embedded")
|
||
add_compile_options("$<$<CONFIG:Release>:/Z7>")
|
||
add_link_options("$<$<CONFIG:Release>:/DEBUG>")
|
||
endif()
|
||
|
||
include(CTest)
|
||
|
||
# The engine is a first-party component of this repository, vendored in-tree at engine/ next to
|
||
# server/, ui/ and windows/. The remaining third-party sources are still submodules under vendor/.
|
||
set(MSIME_REPO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||
set(MSIME_ENGINE_DIR "${MSIME_REPO_ROOT}/engine")
|
||
set(MSIME_VENDOR_DIR "${MSIME_REPO_ROOT}/vendor")
|
||
|
||
# 内置皮肤的出厂清单(skins/default/<id>/skin.toml)编进程序:数据目录里那一份缺失或写坏时,
|
||
# 外观仍按出厂清单画。清单是唯一的来源,这里只把它们原样嵌成字符串;改了清单会触发重新配置。
|
||
set(MSIME_FACTORY_SKIN_IDS fluent wechat wechat_scroll graphite willow_green autumn_osmanthus microsoft canvas)
|
||
set(MSIME_GENERATED_DIR "${CMAKE_BINARY_DIR}/generated")
|
||
set(MSIME_VERSION_FILE "${MSIME_REPO_ROOT}/version.txt")
|
||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${MSIME_VERSION_FILE}")
|
||
set(MSIME_PRODUCT_VERSION_OVERRIDE "" CACHE STRING "Product version to embed in the settings page")
|
||
if(MSIME_PRODUCT_VERSION_OVERRIDE)
|
||
set(MSIME_PRODUCT_VERSION "${MSIME_PRODUCT_VERSION_OVERRIDE}")
|
||
else()
|
||
file(STRINGS "${MSIME_VERSION_FILE}" MSIME_PRODUCT_VERSION LIMIT_COUNT 1)
|
||
endif()
|
||
string(STRIP "${MSIME_PRODUCT_VERSION}" MSIME_PRODUCT_VERSION)
|
||
# 版本主体必须是数字段;允许一个可选的连字符后缀(semver 预发布段),dev-build 用它携带
|
||
# 日期与 commit(0.7.1-dev.20261019.<hash>),设置窗口关于页原样显示。关于页的 ParseVersion
|
||
# 会剥掉后缀做更新检查的数字比较,所以后缀不影响版本判定。
|
||
if(NOT MSIME_PRODUCT_VERSION MATCHES "^[0-9]+(\\.[0-9]+)*(-[0-9A-Za-z.-]+)?$")
|
||
message(FATAL_ERROR "Invalid product version in ${MSIME_VERSION_FILE}: '${MSIME_PRODUCT_VERSION}'")
|
||
endif()
|
||
configure_file(
|
||
"${CMAKE_CURRENT_SOURCE_DIR}/src/msime_version.h.in"
|
||
"${MSIME_GENERATED_DIR}/msime_version.h"
|
||
@ONLY
|
||
)
|
||
set(_msime_factory_skins "")
|
||
foreach(_skin_id IN LISTS MSIME_FACTORY_SKIN_IDS)
|
||
set(_skin_manifest "${MSIME_REPO_ROOT}/skins/default/${_skin_id}/skin.toml")
|
||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${_skin_manifest}")
|
||
file(READ "${_skin_manifest}" _skin_text)
|
||
string(APPEND _msime_factory_skins "{\"${_skin_id}\", R\"msimeskin(${_skin_text})msimeskin\"},\n")
|
||
endforeach()
|
||
# 只在内容变了时才写,免得每次配置都让皮肤目录的编译单元重编。
|
||
set(_msime_factory_skins_file "${MSIME_GENERATED_DIR}/builtin_skin_manifests.inc")
|
||
set(_msime_factory_skins_old "")
|
||
if(EXISTS "${_msime_factory_skins_file}")
|
||
file(READ "${_msime_factory_skins_file}" _msime_factory_skins_old)
|
||
endif()
|
||
if(NOT _msime_factory_skins_old STREQUAL _msime_factory_skins)
|
||
file(WRITE "${_msime_factory_skins_file}" "${_msime_factory_skins}")
|
||
endif()
|
||
include_directories("${MSIME_GENERATED_DIR}")
|
||
|
||
# Boost
|
||
# An explicit -DBoost_ROOT wins, then BOOST_ROOT from the environment, and only then the scoop
|
||
# layout under the current user's profile. The fallback used to name one developer's home directory,
|
||
# which meant anyone else without BOOST_ROOT set got a configure failure pointing at a path that
|
||
# does not exist on their machine.
|
||
if(NOT DEFINED Boost_ROOT)
|
||
if(DEFINED ENV{BOOST_ROOT})
|
||
set(Boost_ROOT "$ENV{BOOST_ROOT}")
|
||
elseif(DEFINED ENV{USERPROFILE} AND EXISTS "$ENV{USERPROFILE}/scoop/apps/boost/current")
|
||
set(Boost_ROOT "$ENV{USERPROFILE}/scoop/apps/boost/current")
|
||
endif()
|
||
endif()
|
||
set (Boost_USE_STATIC_LIBS ON)
|
||
find_package(Boost REQUIRED COMPONENTS locale json)
|
||
include_directories(${Boost_INCLUDE_DIRS})
|
||
|
||
# fmt, spdlog and sqlite3
|
||
find_package(fmt CONFIG REQUIRED)
|
||
find_package(spdlog CONFIG REQUIRED)
|
||
find_package(unofficial-sqlite3 CONFIG REQUIRED)
|
||
find_package(nlohmann_json CONFIG REQUIRED)
|
||
find_package(CURL CONFIG REQUIRED)
|
||
find_package(ZLIB REQUIRED)
|
||
|
||
# The engine ships its own CMake target. Consume that instead of listing its
|
||
# translation units here, so that adding a file to the engine no longer requires
|
||
# a matching edit in this file. EXCLUDE_FROM_ALL keeps the engine's own test
|
||
# executables out of the default build.
|
||
#
|
||
# Which is also why BUILD_TESTING has to be off across that add_subdirectory: the engine registers
|
||
# its own add_test() entries behind that flag, and EXCLUDE_FROM_ALL then never builds the
|
||
# executables they point at, so ctest reports an "Unable to find executable" failure per entry. The
|
||
# engine's own suite runs in the separate Engine job of ci.yml (scripts/ci/test-engine.ps1), which
|
||
# builds the engine standalone. Restored immediately afterwards so this repository's own tests/
|
||
# still register.
|
||
set(_metasequoia_saved_build_testing "${BUILD_TESTING}")
|
||
set(BUILD_TESTING OFF)
|
||
set(METASEQUOIA_IME_BUILD_VOICE ON CACHE BOOL "" FORCE)
|
||
set(MSIME_VOICE_CAPTURE ON CACHE BOOL "" FORCE)
|
||
add_subdirectory("${MSIME_ENGINE_DIR}" "${CMAKE_BINARY_DIR}/engine" EXCLUDE_FROM_ALL)
|
||
set(BUILD_TESTING "${_metasequoia_saved_build_testing}")
|
||
unset(_metasequoia_saved_build_testing)
|
||
|
||
# Build the OpenCC submodule as a static dependency of the server.
|
||
add_subdirectory("${MSIME_VENDOR_DIR}/opencc" "${CMAKE_BINARY_DIR}/opencc" EXCLUDE_FROM_ALL)
|
||
|
||
# OpenCC's Windows dictionary helper copies the library into the tools output
|
||
# directory before MSBuild has necessarily created that directory.
|
||
add_custom_target(opencc_tools_output_dir
|
||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||
"${CMAKE_BINARY_DIR}/opencc/src/tools/$<CONFIG>"
|
||
)
|
||
add_dependencies(copy_libopencc_to_dir_of_opencc_dict opencc_tools_output_dir)
|
||
|
||
# cpp-pinyin: settings uses it to annotate pure-Chinese phrase imports.
|
||
set(_cpp_pinyin_saved_shared_libs "${BUILD_SHARED_LIBS}")
|
||
set(BUILD_SHARED_LIBS OFF)
|
||
set(CPP_PINYIN_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||
set(CPP_PINYIN_INSTALL OFF CACHE BOOL "" FORCE)
|
||
add_subdirectory("${MSIME_VENDOR_DIR}/cpp-pinyin" "${CMAKE_BINARY_DIR}/cpp-pinyin" EXCLUDE_FROM_ALL)
|
||
set(BUILD_SHARED_LIBS "${_cpp_pinyin_saved_shared_libs}")
|
||
unset(_cpp_pinyin_saved_shared_libs)
|
||
|
||
set(CMAKE_CXX_STANDARD 17)
|
||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||
|
||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||
|
||
add_definitions(
|
||
/D_UNICODE=1
|
||
/DUNICODE=1
|
||
/DFANY_DEBUG=1
|
||
)
|
||
|
||
# HandwritingPanel still uses the legacy <experimental/coroutine>; on newer
|
||
# MSVC STL the deprecation is a hard error, so silence it explicitly.
|
||
add_definitions(/D_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS)
|
||
|
||
# add_definitions(
|
||
# /DFANY_DEBUG=1
|
||
# /DFANY_IPC_DEBUG=1
|
||
# )
|
||
|
||
# For utf8cpp, make it use C++11 and later
|
||
add_compile_options(/Zc:__cplusplus /FS /utf-8)
|
||
|
||
include_directories("./")
|
||
include_directories("./src/")
|
||
# The repository root is on the include path so engine headers are reached as "engine/...", which
|
||
# names the component the same way the source tree does.
|
||
include_directories("${MSIME_REPO_ROOT}")
|
||
include_directories("${MSIME_VENDOR_DIR}")
|
||
include_directories("${MSIME_ENGINE_DIR}/utfcpp/source/")
|
||
|
||
set(MY_EXECUTABLE_NAME "MetasequoiaImeServer")
|
||
set(WATCHDOG_EXECUTABLE_NAME "MetasequoiaImeWatchdog")
|
||
set(DICTIONARY_REPLAY_EXECUTABLE_NAME "MetasequoiaImeDictionaryReplay")
|
||
|
||
add_executable(${WATCHDOG_EXECUTABLE_NAME} WIN32
|
||
"./src/watchdog/main.cpp"
|
||
"./src/watchdog/watchdog_protocol.h"
|
||
"./src/utils/single_instance.h"
|
||
"./src/resource/resource.h"
|
||
"./src/resource/resource.rc"
|
||
)
|
||
target_compile_definitions(${WATCHDOG_EXECUTABLE_NAME} PRIVATE
|
||
NOMINMAX=1
|
||
WIN32_LEAN_AND_MEAN=1
|
||
)
|
||
target_link_libraries(${WATCHDOG_EXECUTABLE_NAME} PRIVATE shell32 ole32)
|
||
if(MSVC)
|
||
target_compile_options(${WATCHDOG_EXECUTABLE_NAME} PRIVATE /W4 /permissive-)
|
||
endif()
|
||
|
||
set(SRC_FILES
|
||
"./src/ai/ai_assistant.cpp"
|
||
"./src/ai/ai_assistant.h"
|
||
"./src/ai/ai_assistant_cache.cpp"
|
||
"./src/ai/ai_assistant_cache.h"
|
||
"./src/ai/ai_assistant_cache_key.cpp"
|
||
"./src/ai/ai_assistant_cache_key.h"
|
||
"./src/ai/ai_assistant_request.cpp"
|
||
"./src/ai/ai_assistant_request.h"
|
||
"./src/ai/ai_provider_store.cpp"
|
||
"./src/ai/ai_provider_store.h"
|
||
"./src/config/ai_provider.h"
|
||
"./src/ai/chat_completions.cpp"
|
||
"./src/ai/jev_client.cpp"
|
||
"./src/ai/chat_completions.h"
|
||
"./src/ai/chat_request_params.h"
|
||
"./src/clipboard/clipboard_history.cpp"
|
||
"./src/clipboard/clipboard_history.h"
|
||
"./src/cloud/ai_translation.cpp"
|
||
"./src/cloud/ai_translation.h"
|
||
"./src/cloud/cloud_ime.cpp"
|
||
"./src/cloud/cloud_ime.h"
|
||
"./src/cloud/cloud_translation.cpp"
|
||
"./src/cloud/cloud_translation.h"
|
||
"./src/cloud/custom_translation.cpp"
|
||
"./src/cloud/custom_translation.h"
|
||
"./src/cloud/niutrans_translation.cpp"
|
||
"./src/cloud/niutrans_translation.h"
|
||
"./src/cloud/tencent_tmt.cpp"
|
||
"./src/cloud/tencent_tmt.h"
|
||
"./src/cloud/translation_gloss.cpp"
|
||
"./src/cloud/translation_gloss.h"
|
||
"./src/config/credential_protection.cpp"
|
||
"./src/config/credential_protection.h"
|
||
"./src/config/ime_config.cpp"
|
||
"./src/config/ime_config_credentials.cpp"
|
||
"./src/config/ime_config.h"
|
||
"./src/config/ime_config_appearance.cpp"
|
||
"./src/config/ime_config_fonts.cpp"
|
||
"./src/config/ime_config_general.cpp"
|
||
"./src/config/ime_config_input.cpp"
|
||
"./src/config/ime_config_internal.h"
|
||
"./src/config/ime_config_keys.cpp"
|
||
"./src/config/ime_config_services.cpp"
|
||
"./src/config/ime_config_shuangpin.cpp"
|
||
"./src/config/ime_config_template.cpp"
|
||
"./src/config/ime_config_theme.cpp"
|
||
"./src/config/ime_config_toml.cpp"
|
||
"./src/config/ime_config_toolbar.cpp"
|
||
"./src/config/ime_config_write.cpp"
|
||
"./src/conversion/chinese_converter.cpp"
|
||
"./src/conversion/chinese_converter.h"
|
||
"./src/defines/defines.h"
|
||
"./src/english/english_ime.cpp"
|
||
"./src/english/english_ime.h"
|
||
"./src/global/globals.h"
|
||
"./src/ipc/candidate_translation_policy.h"
|
||
"./src/ipc/event_listener.cpp"
|
||
"./src/ipc/event_listener.h"
|
||
"./src/ipc/event_listener_async_candidates.cpp"
|
||
"./src/ipc/event_listener_candidates.cpp"
|
||
"./src/ipc/event_listener_internal.h"
|
||
"./src/ipc/event_listener_keys.cpp"
|
||
"./src/ipc/event_listener_pipes.cpp"
|
||
"./src/ipc/event_listener_selection.cpp"
|
||
"./src/ipc/event_listener_worker.cpp"
|
||
"./src/ipc/ipc.cpp"
|
||
"./src/ipc/ipc.h"
|
||
"./src/ipc/voice_composition_pipe.h"
|
||
"./src/ipc/voice_control_dispatch.cpp"
|
||
"./src/ipc/voice_control_dispatch.h"
|
||
"./src/mixed/date_time_candidates.h"
|
||
"./src/mixed/mixed_candidates.cpp"
|
||
"./src/mixed/mixed_candidates.h"
|
||
"./src/log/fanylog.cpp"
|
||
"./src/log/fanylog.h"
|
||
"./src/log/candidate_diag_log.cpp"
|
||
"./src/log/candidate_diag_log.h"
|
||
"./src/log/ftb_diag_log.h"
|
||
"./src/resource/resource.h"
|
||
"./src/resource/resource.rc"
|
||
"./src/settings/settings_launcher.cpp"
|
||
"./src/settings/settings_launcher.h"
|
||
"./src/settings/api_credential_test.cpp"
|
||
"./src/settings/api_credential_test.h"
|
||
"./src/settings/api_credential_test_request.h"
|
||
"./src/settings/collocation_model.cpp"
|
||
"./src/settings/collocation_model.h"
|
||
"./src/skin/candidate_skin_catalog.cpp"
|
||
"./src/skin/candidate_skin_catalog.h"
|
||
"./src/session/engine_input_session.cpp"
|
||
"./src/session/engine_input_session.h"
|
||
"./src/session/input_session.h"
|
||
"./src/session/session_factory.cpp"
|
||
"./src/session/session_factory.h"
|
||
"./src/statistics/stats_aggregate.cpp"
|
||
"./src/statistics/stats_aggregate.h"
|
||
"./src/statistics/stats_candidate_capture.cpp"
|
||
"./src/statistics/stats_candidate_capture.h"
|
||
"./src/statistics/stats_frames.cpp"
|
||
"./src/statistics/stats_frames.h"
|
||
"./src/statistics/stats_pipe.cpp"
|
||
"./src/statistics/stats_pipe.h"
|
||
"./src/statistics/stats_store.cpp"
|
||
"./src/statistics/stats_store.h"
|
||
"./src/statistics/stats_types.h"
|
||
"./src/utils/candidate_size_estimator.cpp"
|
||
"./src/utils/candidate_size_estimator.h"
|
||
"./src/utils/common_utils.cpp"
|
||
"./src/utils/common_utils.h"
|
||
"./src/utils/hanzi_pinyin.cpp"
|
||
"./src/utils/hanzi_pinyin.h"
|
||
"./src/utils/ime_paths.cpp"
|
||
"./src/utils/ime_utils.cpp"
|
||
"./src/utils/ime_utils.h"
|
||
"./src/utils/network_proxy.cpp"
|
||
"./src/utils/network_proxy.h"
|
||
"./src/utils/serial_task_runner.cpp"
|
||
"./src/utils/serial_task_runner.h"
|
||
"./src/utils/shuangpin_preedit_display.cpp"
|
||
"./src/utils/shuangpin_preedit_display.h"
|
||
"./src/utils/window_utils.cpp"
|
||
"./src/utils/window_utils.h"
|
||
"./src/window/candidate_presenter.cpp"
|
||
"./src/window/candidate_presenter.h"
|
||
"./src/window/candidate_skin_layers.cpp"
|
||
"./src/window/candidate_skin_layers.h"
|
||
"./src/window/candidate_skin_overlay.cpp"
|
||
"./src/window/candidate_skin_overlay.h"
|
||
"./src/window/candidate_skin_palette.cpp"
|
||
"./src/window/candidate_skin_palette.h"
|
||
"./src/window/candidate_skin_scene.cpp"
|
||
"./src/window/candidate_skin_scene.h"
|
||
"./src/window/candidate_skin_tokens.cpp"
|
||
"./src/window/candidate_skin_tokens.h"
|
||
"./src/window/tray_menu_presenter.cpp"
|
||
"./src/window/tray_menu_presenter.h"
|
||
"./src/window/floating_toolbar_presenter.cpp"
|
||
"./src/window/floating_toolbar_presenter.h"
|
||
"./src/window/floating_toolbar_skin.cpp"
|
||
"./src/window/floating_toolbar_skin.h"
|
||
"./src/window/caret_state_indicator.cpp"
|
||
"./src/window/caret_state_indicator.h"
|
||
"./src/window/ime_windows.cpp"
|
||
"./src/window/ime_windows.h"
|
||
"./src/window/ime_windows_candidate.cpp"
|
||
"./src/window/ime_windows_internal.h"
|
||
"./src/window/ime_windows_menu.cpp"
|
||
"./src/window/ime_windows_toolbar.cpp"
|
||
"./src/window/small_windows.cpp"
|
||
"./src/window/small_windows.h"
|
||
"./src/window/window_hook.cpp"
|
||
"./src/window/window_hook.h"
|
||
"./src/voice-input/voice_input_service.cpp"
|
||
"./src/voice-input/voice_input_service.h"
|
||
"./src/voice-input/system_audio_muter.cpp"
|
||
"./src/voice-input/system_audio_muter.h"
|
||
"./src/voice-input/doubao_asr_client.cpp"
|
||
"./src/voice-input/doubao_asr_client.h"
|
||
"./src/voice-input/voice_batch_protocol.cpp"
|
||
"./src/voice-input/voice_providers.cpp"
|
||
"./src/voice-input/voice_providers.h"
|
||
"./src/voice-input/wave_overlay.cpp"
|
||
"./src/voice-input/wave_overlay.h"
|
||
"./src/voice-input/cue_player.cpp"
|
||
"./src/voice-input/cue_player.h"
|
||
"./src/voice-input/mvi_utils.h"
|
||
"./src/voice-input/voice_input_overlay_utils.cpp"
|
||
"./src/main.cpp"
|
||
)
|
||
|
||
add_executable(${MY_EXECUTABLE_NAME} WIN32
|
||
${SRC_FILES}
|
||
)
|
||
|
||
# Tomlplusplus and other header-only libraries
|
||
target_include_directories(${PROJECT_NAME}
|
||
PRIVATE
|
||
"${CMAKE_BINARY_DIR}/vcpkg_installed/x64-windows/include"
|
||
"${CMAKE_SOURCE_DIR}/src/voice-input"
|
||
"${MSIME_ENGINE_DIR}/voice/third_party/miniaudio"
|
||
)
|
||
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE MetasequoiaIme::Engine MetasequoiaIme::Voice MetasequoiaIme::VoiceCapture)
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE unofficial::sqlite3::sqlite3 fmt::fmt spdlog::spdlog Boost::locale Boost::json nlohmann_json::nlohmann_json)
|
||
# U 模式候选的注音(utils/hanzi_pinyin)与设置页的导入注音共用 cpp-pinyin。
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE cpp-pinyin::cpp-pinyin)
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE OpenCC::OpenCC)
|
||
add_dependencies(${PROJECT_NAME} Dictionaries)
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE winhttp)
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE CURL::libcurl)
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB)
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE d2d1 dwrite dwmapi shell32 shcore ole32 bcrypt)
|
||
|
||
# The helper executables below already build at /W4. The server itself -- the process that owns
|
||
# every network call and the skin loader -- was still at the default /W3.
|
||
if(MSVC)
|
||
target_compile_options(${MY_EXECUTABLE_NAME} PRIVATE /W4)
|
||
endif()
|
||
|
||
add_executable(${DICTIONARY_REPLAY_EXECUTABLE_NAME}
|
||
"./src/user-dictionary-replay/main.cpp"
|
||
"./src/resource/resource.h"
|
||
"./src/resource/resource.rc"
|
||
)
|
||
target_link_libraries(${DICTIONARY_REPLAY_EXECUTABLE_NAME} PRIVATE
|
||
MetasequoiaIme::Engine
|
||
unofficial::sqlite3::sqlite3
|
||
)
|
||
target_compile_definitions(${DICTIONARY_REPLAY_EXECUTABLE_NAME} PRIVATE NOMINMAX=1)
|
||
add_dependencies(${PROJECT_NAME} ${DICTIONARY_REPLAY_EXECUTABLE_NAME})
|
||
|
||
# msimeui stays a separately built GUI framework component at ../ui. The product-owned emoji panel
|
||
# lives under src/emoji-panel so it can evolve separately from the framework's example applications.
|
||
# msimeui's standalone layout tests belong to its own CI job. Its EXCLUDE_FROM_ALL
|
||
# targets are not built here, so registering those tests would break Server CTest.
|
||
set(_metasequoia_saved_build_testing "${BUILD_TESTING}")
|
||
set(BUILD_TESTING OFF)
|
||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../ui" "${CMAKE_BINARY_DIR}/msimeui" EXCLUDE_FROM_ALL)
|
||
set(BUILD_TESTING "${_metasequoia_saved_build_testing}")
|
||
unset(_metasequoia_saved_build_testing)
|
||
set(EMOJI_EXECUTABLE_NAME "MetasequoiaImeEmojiPanel")
|
||
add_executable(${EMOJI_EXECUTABLE_NAME} WIN32
|
||
"./src/emoji-panel/EmojiPanel.cpp"
|
||
"./src/emoji-panel/EmojiPanel.h"
|
||
"./src/emoji-panel/emoji_panel_icons.cpp"
|
||
"./src/emoji-panel/emoji_panel_icons.h"
|
||
"./src/emoji-panel/emoji_panel_splash.cpp"
|
||
"./src/emoji-panel/emoji_panel_splash.h"
|
||
"./src/emoji-panel/svg_path_geometry.cpp"
|
||
"./src/emoji-panel/svg_path_geometry.h"
|
||
"./src/emoji-panel/main.cpp"
|
||
"./src/emoji-panel/emoji_panel.rc"
|
||
"./src/emoji-panel/resource.h"
|
||
"./src/clipboard/clipboard_history.cpp"
|
||
"./src/clipboard/clipboard_history.h"
|
||
"./src/utils/ime_paths.cpp"
|
||
"./src/utils/surface_theme_config.cpp"
|
||
"./src/utils/surface_theme_config.h"
|
||
)
|
||
add_dependencies(${MY_EXECUTABLE_NAME} ${WATCHDOG_EXECUTABLE_NAME})
|
||
target_compile_definitions(${PROJECT_NAME} PRIVATE NOMINMAX=1)
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE msimeui d3d11 dxgi dcomp)
|
||
target_link_libraries(${EMOJI_EXECUTABLE_NAME} PRIVATE msimeui unofficial::sqlite3::sqlite3 shell32 advapi32 ole32)
|
||
target_compile_definitions(${EMOJI_EXECUTABLE_NAME} PRIVATE
|
||
NOMINMAX=1
|
||
WIN32_LEAN_AND_MEAN=1
|
||
)
|
||
if(MSVC)
|
||
target_compile_options(${EMOJI_EXECUTABLE_NAME} PRIVATE /W4 /permissive-)
|
||
endif()
|
||
add_dependencies(${PROJECT_NAME} ${EMOJI_EXECUTABLE_NAME})
|
||
add_custom_command(TARGET ${EMOJI_EXECUTABLE_NAME} POST_BUILD
|
||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||
"${CMAKE_BINARY_DIR}/vcpkg_installed/x64-windows/$<$<CONFIG:Debug>:debug/>bin/sqlite3.dll"
|
||
$<TARGET_FILE_DIR:${EMOJI_EXECUTABLE_NAME}>
|
||
)
|
||
|
||
set(KEYBOARD_EXECUTABLE_NAME "MetasequoiaImeKeyboardPanel")
|
||
add_executable(${KEYBOARD_EXECUTABLE_NAME} WIN32
|
||
"./src/keyboard-panel/KeyboardPanel.cpp"
|
||
"./src/keyboard-panel/KeyboardPanel.h"
|
||
"./src/keyboard-panel/main.cpp"
|
||
"./src/keyboard-panel/keyboard_panel.rc"
|
||
"./src/keyboard-panel/resource.h"
|
||
"./src/utils/ime_paths.cpp"
|
||
"./src/utils/surface_theme_config.cpp"
|
||
"./src/utils/surface_theme_config.h"
|
||
)
|
||
target_link_libraries(${KEYBOARD_EXECUTABLE_NAME} PRIVATE msimeui shell32 advapi32 ole32)
|
||
target_compile_definitions(${KEYBOARD_EXECUTABLE_NAME} PRIVATE
|
||
NOMINMAX=1
|
||
WIN32_LEAN_AND_MEAN=1
|
||
)
|
||
if(MSVC)
|
||
target_compile_options(${KEYBOARD_EXECUTABLE_NAME} PRIVATE /W4 /permissive-)
|
||
endif()
|
||
add_dependencies(${PROJECT_NAME} ${KEYBOARD_EXECUTABLE_NAME})
|
||
|
||
set(HANDWRITING_EXECUTABLE_NAME "MetasequoiaImeHandwritingPanel")
|
||
add_executable(${HANDWRITING_EXECUTABLE_NAME} WIN32
|
||
"./src/handwriting-panel/HandwritingPanel.cpp"
|
||
"./src/handwriting-panel/HandwritingPanel.h"
|
||
"./src/handwriting-panel/main.cpp"
|
||
"./src/handwriting-panel/handwriting_panel.rc"
|
||
"./src/handwriting-panel/resource.h"
|
||
"./src/utils/ime_paths.cpp"
|
||
"./src/utils/surface_theme_config.cpp"
|
||
"./src/utils/surface_theme_config.h"
|
||
)
|
||
target_link_libraries(${HANDWRITING_EXECUTABLE_NAME} PRIVATE msimeui windowsapp.lib shell32 advapi32 ole32)
|
||
target_compile_definitions(${HANDWRITING_EXECUTABLE_NAME} PRIVATE
|
||
NOMINMAX=1
|
||
WIN32_LEAN_AND_MEAN=1
|
||
)
|
||
if(MSVC)
|
||
target_compile_options(${HANDWRITING_EXECUTABLE_NAME} PRIVATE /W4 /permissive-)
|
||
endif()
|
||
add_dependencies(${PROJECT_NAME} ${HANDWRITING_EXECUTABLE_NAME})
|
||
|
||
set(SETTINGS_EXECUTABLE_NAME "MetasequoiaImeSettings")
|
||
add_executable(${SETTINGS_EXECUTABLE_NAME} WIN32
|
||
"./src/settings/settings_app.cpp"
|
||
"./src/ai/chat_request_params.h"
|
||
"./src/settings/api_credential_test.cpp"
|
||
"./src/settings/api_credential_test.h"
|
||
"./src/ai/ai_provider_store.cpp"
|
||
"./src/ai/ai_provider_store.h"
|
||
"./src/config/ai_provider.h"
|
||
"./src/settings/api_credential_test_request.h"
|
||
"./src/settings/collocation_model.cpp"
|
||
"./src/settings/collocation_model.h"
|
||
"./src/settings/neural_model.cpp"
|
||
"./src/settings/neural_model.h"
|
||
"./src/settings/default_input_method.cpp"
|
||
"./src/settings/default_input_method.h"
|
||
"./src/settings/game_compat_name.cpp"
|
||
"./src/settings/game_compat_name.h"
|
||
"./src/settings/settings_launcher.cpp"
|
||
"./src/settings/settings_launcher.h"
|
||
"./src/settings/native/native_settings_bindings.cpp"
|
||
"./src/settings/native/native_settings_controls.cpp"
|
||
"./src/settings/native/native_settings_controls.h"
|
||
"./src/settings/native/native_settings_model.cpp"
|
||
"./src/settings/native/native_settings_model.h"
|
||
"./src/settings/native/native_settings_pages.h"
|
||
"./src/settings/native/native_settings_theme.cpp"
|
||
"./src/settings/native/native_settings_theme.h"
|
||
"./src/settings/native/native_settings_window.cpp"
|
||
"./src/settings/native/native_settings_window.h"
|
||
"./src/settings/native/native_page_appearance.cpp"
|
||
"./src/settings/native/native_page_input.cpp"
|
||
"./src/settings/native/native_page_helpcode.cpp"
|
||
"./src/settings/native/native_page_shortcut.cpp"
|
||
"./src/settings/native/native_page_dictionary.cpp"
|
||
"./src/settings/native/native_page_dictionary_panel.cpp"
|
||
"./src/settings/native/native_page_dictionary_panel.h"
|
||
"./src/settings/native/native_page_skin.cpp"
|
||
"./src/settings/native/native_page_skin_common.cpp"
|
||
"./src/settings/native/native_page_skin_common.h"
|
||
"./src/settings/native/native_page_skin_widgets.cpp"
|
||
"./src/settings/native/native_page_voice.cpp"
|
||
"./src/settings/native/native_page_voice_fields.cpp"
|
||
"./src/settings/native/native_page_voice_fields.h"
|
||
"./src/settings/native/native_page_screenkb.cpp"
|
||
"./src/settings/native/native_page_handwriting.cpp"
|
||
"./src/settings/native/native_page_tools.cpp"
|
||
"./src/settings/native/native_page_ai.cpp"
|
||
"./src/settings/native/native_page_floating_toolbar.cpp"
|
||
"./src/settings/native/native_page_stats.cpp"
|
||
"./src/settings/native/native_page_help.cpp"
|
||
"./src/settings/native/native_page_help_widgets.cpp"
|
||
"./src/settings/native/native_page_help_widgets.h"
|
||
"./src/settings/native/native_page_about.cpp"
|
||
"./src/settings/native/native_page_feedback.cpp"
|
||
"./src/skin/candidate_skin_catalog.cpp"
|
||
"./src/skin/candidate_skin_catalog.h"
|
||
"./src/window/candidate_skin_layers.cpp"
|
||
"./src/window/candidate_skin_layers.h"
|
||
# 皮肤预览与候选窗共用同一套场景与皮肤解析,画出来的才一模一样。
|
||
"./src/window/candidate_skin_overlay.cpp"
|
||
"./src/window/candidate_skin_overlay.h"
|
||
"./src/window/candidate_skin_palette.cpp"
|
||
"./src/window/candidate_skin_palette.h"
|
||
"./src/window/candidate_skin_scene.cpp"
|
||
"./src/window/candidate_skin_scene.h"
|
||
"./src/window/candidate_skin_tokens.cpp"
|
||
"./src/window/candidate_skin_tokens.h"
|
||
"./src/window/floating_toolbar_skin.cpp"
|
||
"./src/window/floating_toolbar_skin.h"
|
||
"./src/settings/dictionary_manager.cpp"
|
||
"./src/settings/dictionary_manager.h"
|
||
"./src/settings/dictionary_validation.cpp"
|
||
"./src/settings/dictionary_validation.h"
|
||
"./src/statistics/stats_overview.cpp"
|
||
"./src/statistics/stats_overview.h"
|
||
"./src/statistics/stats_store.cpp"
|
||
"./src/statistics/stats_store.h"
|
||
"./src/config/credential_protection.cpp"
|
||
"./src/config/credential_protection.h"
|
||
"./src/config/ime_config.cpp"
|
||
"./src/config/ime_config_credentials.cpp"
|
||
"./src/config/ime_config.h"
|
||
"./src/config/ime_config_appearance.cpp"
|
||
"./src/config/ime_config_fonts.cpp"
|
||
"./src/config/ime_config_general.cpp"
|
||
"./src/config/ime_config_input.cpp"
|
||
"./src/config/ime_config_internal.h"
|
||
"./src/config/ime_config_keys.cpp"
|
||
"./src/config/ime_config_services.cpp"
|
||
"./src/config/ime_config_shuangpin.cpp"
|
||
"./src/config/ime_config_template.cpp"
|
||
"./src/config/ime_config_theme.cpp"
|
||
"./src/config/ime_config_toml.cpp"
|
||
"./src/config/ime_config_toolbar.cpp"
|
||
"./src/config/ime_config_write.cpp"
|
||
"./src/ai/chat_completions.cpp"
|
||
"./src/ai/jev_client.cpp"
|
||
"./src/ai/chat_completions.h"
|
||
"./src/cloud/ai_translation.cpp"
|
||
"./src/cloud/ai_translation.h"
|
||
"./src/cloud/custom_translation.cpp"
|
||
"./src/cloud/custom_translation.h"
|
||
"./src/cloud/niutrans_translation.cpp"
|
||
"./src/cloud/niutrans_translation.h"
|
||
"./src/cloud/tencent_tmt.cpp"
|
||
"./src/cloud/tencent_tmt.h"
|
||
"./src/cloud/translation_gloss.cpp"
|
||
"./src/cloud/translation_gloss.h"
|
||
"./src/voice-input/doubao_asr_client.cpp"
|
||
"./src/voice-input/doubao_asr_client.h"
|
||
"./src/voice-input/voice_providers.cpp"
|
||
"./src/voice-input/voice_providers.h"
|
||
"./src/clipboard/clipboard_history.cpp"
|
||
"./src/clipboard/clipboard_history.h"
|
||
"./src/utils/common_utils.cpp"
|
||
"./src/utils/common_utils.h"
|
||
"./src/utils/hanzi_pinyin.cpp"
|
||
"./src/utils/hanzi_pinyin.h"
|
||
"./src/utils/ime_paths.cpp"
|
||
"./src/utils/network_proxy.cpp"
|
||
"./src/utils/network_proxy.h"
|
||
"./src/resource/resource.rc"
|
||
)
|
||
target_include_directories(${SETTINGS_EXECUTABLE_NAME}
|
||
PRIVATE
|
||
"${CMAKE_BINARY_DIR}/vcpkg_installed/x64-windows/include"
|
||
)
|
||
target_link_libraries(${SETTINGS_EXECUTABLE_NAME} PRIVATE
|
||
msimeui
|
||
MetasequoiaIme::Engine
|
||
fmt::fmt
|
||
Boost::locale
|
||
Boost::json
|
||
nlohmann_json::nlohmann_json
|
||
unofficial::sqlite3::sqlite3
|
||
spdlog::spdlog
|
||
cpp-pinyin::cpp-pinyin
|
||
CURL::libcurl
|
||
ZLIB::ZLIB
|
||
bcrypt
|
||
winhttp
|
||
dwmapi
|
||
dcomp
|
||
d2d1
|
||
dwrite
|
||
shell32
|
||
)
|
||
if(MSVC)
|
||
target_compile_options(${SETTINGS_EXECUTABLE_NAME} PRIVATE /W4)
|
||
endif()
|
||
# The server launches the settings executable from the same output directory.
|
||
# Building the server target alone must therefore also produce Settings.
|
||
add_dependencies(${PROJECT_NAME} ${SETTINGS_EXECUTABLE_NAME})
|
||
add_custom_command(TARGET ${SETTINGS_EXECUTABLE_NAME} POST_BUILD
|
||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||
"${MSIME_VENDOR_DIR}/cpp-pinyin/res/dict"
|
||
"$<TARGET_FILE_DIR:${SETTINGS_EXECUTABLE_NAME}>/dict"
|
||
)
|
||
|
||
# Runtime assets next to the executable
|
||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||
$<TARGET_FILE_DIR:${PROJECT_NAME}>/assets/audios
|
||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||
${CMAKE_SOURCE_DIR}/assets/audios/start.mp3
|
||
${CMAKE_SOURCE_DIR}/assets/audios/end.mp3
|
||
$<TARGET_FILE_DIR:${PROJECT_NAME}>/assets/audios
|
||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||
$<TARGET_FILE_DIR:${PROJECT_NAME}>/assets/opencc
|
||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||
${MSIME_VENDOR_DIR}/opencc/data/config/s2t.json
|
||
${CMAKE_BINARY_DIR}/opencc/data/CJK_Compatibility_Ideographs.ocd2
|
||
${CMAKE_BINARY_DIR}/opencc/data/STCharacters.ocd2
|
||
${CMAKE_BINARY_DIR}/opencc/data/STPhrases.ocd2
|
||
${CMAKE_BINARY_DIR}/opencc/data/STPhrases_GeneratedFromRegionalPhrases.ocd2
|
||
$<TARGET_FILE_DIR:${PROJECT_NAME}>/assets/opencc
|
||
)
|
||
|
||
if(BUILD_TESTING)
|
||
add_subdirectory(tests)
|
||
endif()
|