cmake_minimum_required(VERSION 3.16) project(vibechat VERSION 0.1.0 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_C_STANDARD 99) find_package(OpenSSL REQUIRED) find_package(Qt6 COMPONENTS Widgets Network Test QUIET) if(NOT Qt6_FOUND) find_package(Qt5 COMPONENTS Widgets Network Test REQUIRED) set(QT_LIBS Qt5::Widgets Qt5::Network) set(QT_CORE Qt5::Core) set(QT_TEST_LIB Qt5::Test) set(QT_PACKAGE Qt5) else() set(QT_LIBS Qt6::Widgets Qt6::Network) set(QT_CORE Qt6::Core) set(QT_TEST_LIB Qt6::Test) set(QT_PACKAGE Qt6) endif() # Каталоги в ресурсах: перевод работает и в переносимой сборке без файлов рядом с exe. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/chatgui_qt_package.txt" "${QT_PACKAGE}\n") get_target_property(QT_QMAKE ${QT_PACKAGE}::qmake IMPORTED_LOCATION) execute_process(COMMAND "${QT_QMAKE}" -query QT_HOST_BINS OUTPUT_VARIABLE QT_BINARY_DIR OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE QT_BINARY_RESULT) if(NOT QT_BINARY_RESULT EQUAL 0) message(FATAL_ERROR "Cannot query Qt host tools directory") endif() find_program(QT_GUI_LRELEASE NAMES lrelease HINTS "${QT_BINARY_DIR}" NO_DEFAULT_PATH) if(NOT QT_GUI_LRELEASE) message(FATAL_ERROR "Qt lrelease is required to build GUI translations (install Qt Linguist tools)") endif() execute_process(COMMAND "${QT_QMAKE}" -query QT_INSTALL_TRANSLATIONS OUTPUT_VARIABLE QT_TRANSLATIONS_DIR OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE QT_TRANSLATIONS_RESULT) if(NOT QT_TRANSLATIONS_RESULT EQUAL 0) message(FATAL_ERROR "Cannot query Qt translations directory") endif() set(QT_RUSSIAN_CATALOG "${QT_TRANSLATIONS_DIR}/qtbase_ru.qm") if(NOT EXISTS "${QT_RUSSIAN_CATALOG}") message(FATAL_ERROR "Qt Russian translations missing: ${QT_RUSSIAN_CATALOG}") endif() file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/translations") set(GUI_QM_FILES) foreach(LANGUAGE en ru) set(QM_FILE "${CMAKE_CURRENT_BINARY_DIR}/translations/chatgui_${LANGUAGE}.qm") add_custom_command(OUTPUT "${QM_FILE}" COMMAND "${QT_GUI_LRELEASE}" -nounfinished "${CMAKE_CURRENT_SOURCE_DIR}/translations/chatgui_${LANGUAGE}.ts" -qm "${QM_FILE}" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/translations/chatgui_${LANGUAGE}.ts" VERBATIM) list(APPEND GUI_QM_FILES "${QM_FILE}") endforeach() add_custom_target(chatgui_translations DEPENDS ${GUI_QM_FILES}) configure_file(translations/translations.qrc.in "${CMAKE_CURRENT_BINARY_DIR}/translations.qrc" @ONLY) find_package(rlottie REQUIRED HINTS "${CMAKE_CURRENT_SOURCE_DIR}/rlottie_build") message(STATUS "rlottie package: ${rlottie_DIR}") find_package(ZLIB REQUIRED) find_package(OpenSSL REQUIRED) set(ZXING_READERS ON CACHE BOOL "") set(ZXING_WRITERS "OLD" CACHE STRING "") set(ZXING_ENABLE_QRCODE ON CACHE BOOL "") set(ZXING_ENABLE_AZTEC OFF CACHE BOOL "") set(ZXING_ENABLE_DATAMATRIX OFF CACHE BOOL "") set(ZXING_ENABLE_MAXICODE OFF CACHE BOOL "") set(ZXING_ENABLE_PDF417 OFF CACHE BOOL "") set(ZXING_ENABLE_1D OFF CACHE BOOL "") set(ZXING_C_API OFF CACHE BOOL "") set(ZXING_EXAMPLES OFF CACHE BOOL "") set(ZXING_EXAMPLES_QT OFF CACHE BOOL "") set(ZXING_BLACKBOX_TESTS OFF CACHE BOOL "") set(ZXING_UNIT_TESTS OFF CACHE BOOL "") set(BUILD_SHARED_LIBS OFF CACHE BOOL "") add_subdirectory(zxing-cpp) set_target_properties(ZXing PROPERTIES AUTOMOC OFF) # FFmpeg - custom built shared libraries set(FFMPEG_INSTALL_DIR "${CMAKE_SOURCE_DIR}/ffmpeg/ffmpeg_build/install") set(ENV{PKG_CONFIG_PATH} "${FFMPEG_INSTALL_DIR}/lib/pkgconfig") find_package(PkgConfig QUIET) if(PkgConfig_FOUND) pkg_check_modules(FFMPEG_PC libavcodec libavformat libavutil libswscale libswresample IMPORTED_TARGET) if(FFMPEG_PC_FOUND) set(FFMPEG_FOUND TRUE) set(FFMPEG_TARGET PkgConfig::FFMPEG_PC) set(FFMPEG_INCLUDE_DIRS "${FFMPEG_PC_INCLUDE_DIRS}") endif() endif() if(NOT FFMPEG_FOUND) message(STATUS "pkg-config search failed, trying direct library search") find_path(FFMPEG_INCLUDE_DIR libavcodec/avcodec.h PATHS "${FFMPEG_INSTALL_DIR}/include" NO_DEFAULT_PATH) find_library(AVCODEC_LIBRARY avcodec PATHS "${FFMPEG_INSTALL_DIR}/lib" NO_DEFAULT_PATH) find_library(AVFORMAT_LIBRARY avformat PATHS "${FFMPEG_INSTALL_DIR}/lib" NO_DEFAULT_PATH) find_library(AVUTIL_LIBRARY avutil PATHS "${FFMPEG_INSTALL_DIR}/lib" NO_DEFAULT_PATH) find_library(SWSCALE_LIBRARY swscale PATHS "${FFMPEG_INSTALL_DIR}/lib" NO_DEFAULT_PATH) find_library(SWRESAMPLE_LIBRARY swresample PATHS "${FFMPEG_INSTALL_DIR}/lib" NO_DEFAULT_PATH) if(FFMPEG_INCLUDE_DIR AND AVCODEC_LIBRARY AND AVFORMAT_LIBRARY AND AVUTIL_LIBRARY) set(FFMPEG_FOUND TRUE) set(FFMPEG_INCLUDE_DIRS "${FFMPEG_INCLUDE_DIR}") set(FFMPEG_LIBRARIES "${AVCODEC_LIBRARY}" "${AVFORMAT_LIBRARY}" "${AVUTIL_LIBRARY}" "${SWSCALE_LIBRARY}" "${SWRESAMPLE_LIBRARY}") message(STATUS "FFmpeg found via direct search") endif() endif() if(NOT FFMPEG_FOUND) message(WARNING "FFmpeg not found at ${FFMPEG_INSTALL_DIR}. Video transcoding disabled. Run ./ffmpeg/build_ffmpeg.sh to enable.") set(FFMPEG_TARGET "") set(FFMPEG_LIBRARIES "") set(FFMPEG_INCLUDE_DIRS "") endif() if(UNIX AND NOT APPLE AND FFMPEG_FOUND) set(CMAKE_BUILD_RPATH "${FFMPEG_INSTALL_DIR}/lib") set(CMAKE_INSTALL_RPATH "${FFMPEG_INSTALL_DIR}/lib") endif() # uTun core library (C, built from ../src/ and ../lib/) add_subdirectory(libutun) add_library(chatgui_notifications STATIC src/message_notification.cpp src/user_activity_monitor.cpp) target_link_libraries(chatgui_notifications PUBLIC ${QT_PACKAGE}::Widgets PRIVATE utun) if(WIN32) target_link_libraries(chatgui_notifications PRIVATE user32) elseif(APPLE) target_link_libraries(chatgui_notifications PRIVATE "-framework ApplicationServices") endif() # Голосовой стек звонка (SoundTouch + voice_jitter + call_audio + call_tones), # C++ внутри, C-интерфейс наружу (call_audio.h). set(LIB_DIR "${CMAKE_SOURCE_DIR}/../../lib") set(CALL_DIR "${CMAKE_SOURCE_DIR}/../../src/call") include(${CALL_DIR}/voice_sources.cmake) utun_setup_voice("${LIB_DIR}" "${CALL_DIR}") add_library(utun_voice STATIC ${UTUN_VOICE_SOURCES}) target_include_directories(utun_voice PUBLIC ${UTUN_VOICE_INCLUDE_DIRS}) set_source_files_properties(${CALL_DIR}/call_audio.c ${CALL_DIR}/call_tones.c PROPERTIES LANGUAGE C) set_source_files_properties(${CMAKE_SOURCE_DIR}/../../src/radio/radio_audio.c PROPERTIES LANGUAGE C) set_target_properties(utun_voice PROPERTIES POSITION_INDEPENDENT_CODE ON) add_executable(vibechat src/main.cpp src/mainwindow.cpp src/channellist.cpp src/creategroupdialog.cpp src/channeldelegate.cpp src/channelsettingsdialog.cpp src/chatview.cpp src/messagedelegate.cpp src/message_links.cpp src/messagelist.cpp src/messagefeedback.cpp src/accountlist.cpp src/accountdelegate.cpp src/flagpainter.cpp src/memberpropsdialog.cpp src/renamedialog.cpp src/memberlistmodel.cpp src/emoji.cpp src/emojipanel.cpp src/emojitabbar.cpp src/inputbar.cpp src/lottieicon.cpp src/animtimer.cpp src/qrcode_utils.cpp src/invite_link.cpp src/invitedialog.cpp src/dminvitedialog.cpp src/inviteby.cpp src/joindialog.cpp src/settingsdialog.cpp src/networksettingspage.cpp src/databasesettingspage.cpp src/statuspage.cpp src/nodespage.cpp src/soundsettingspage.cpp src/sound_manager.cpp src/voice_audio_io.cpp src/audio_device.cpp src/audiorecorder.cpp src/voicemessageencoder.cpp src/voiceplayback.cpp src/media_blocks.cpp src/videoplayer_engine.cpp src/videoplayer_window.cpp src/imageviewer_window.cpp src/member_files/browser.cpp src/avatars/avatarcache.cpp src/avatars/avatarcrop.cpp src/avatars/avatargallery.cpp src/avatars/avatarmanager.cpp src/avatars/groupavatarmanager.cpp src/audiodevicesettingspage.cpp src/storagesettingspage.cpp src/connmonitorwindow.cpp src/callwindow.cpp src/call_audio_engine.cpp src/radio_audio_engine.cpp src/radiopanel.cpp src/ptt_hotkey_manager.cpp src/radiosettingspage.cpp transport/utun_node.cpp transport/node_config.cpp transport/config_updater.cpp transport/gui_bridge_impl.cpp transport/miniaudio_impl.c transport/audio_diagnostics.cpp db/db_manager.cpp ../../lib/sqlite3.c resources/chatgui.qrc "${CMAKE_CURRENT_BINARY_DIR}/translations.qrc" ) add_dependencies(vibechat chatgui_translations) target_include_directories(vibechat PRIVATE ${CMAKE_SOURCE_DIR}/../../lib ${CMAKE_SOURCE_DIR}/../../src ${CMAKE_SOURCE_DIR}/db ${CMAKE_SOURCE_DIR}/../../lib/libopus/include ${FFMPEG_INCLUDE_DIRS}) target_compile_definitions(vibechat PRIVATE SQLITE_THREADSAFE=1 USE_SQLITE VIBECHAT_VERSION="${PROJECT_VERSION}") # Лицензии лежат рядом с бинарником при сборке и устанавливаются с приложением. set(UTUN_LICENSE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../LICENSE" "${CMAKE_CURRENT_SOURCE_DIR}/../../LICENSING" "${CMAKE_CURRENT_SOURCE_DIR}/../../THIRD_PARTY_NOTICES") add_custom_target(vibechat_licenses ALL COMMAND ${CMAKE_COMMAND} -E make_directory "$/licenses" COMMAND ${CMAKE_COMMAND} -E copy_if_different ${UTUN_LICENSE_FILES} "$/licenses" COMMENT "Copying uTun license documents") install(FILES ${UTUN_LICENSE_FILES} DESTINATION share/licenses/utun) if(FFMPEG_FOUND) target_compile_definitions(vibechat PRIVATE HAVE_FFMPEG) endif() set_source_files_properties(../../lib/sqlite3.c transport/miniaudio_impl.c PROPERTIES LANGUAGE C) # Глобальное состояние клавиатуры для PTT: Windows user32 / Linux X11. if(CMAKE_SYSTEM_NAME STREQUAL "Linux") find_package(X11 REQUIRED) if(Qt6_FOUND) find_package(Qt6 COMPONENTS DBus REQUIRED) set(QT_DBUS Qt6::DBus) else() find_package(Qt5 COMPONENTS DBus REQUIRED) set(QT_DBUS Qt5::DBus) endif() target_sources(vibechat PRIVATE src/ptt_portal.cpp) target_compile_definitions(vibechat PRIVATE UTUN_PTT_PORTAL) target_link_libraries(vibechat PRIVATE ${QT_DBUS}) target_include_directories(vibechat PRIVATE ${X11_INCLUDE_DIR}) target_compile_definitions(chatgui_notifications PRIVATE UTUN_ACTIVITY_DBUS) target_link_libraries(chatgui_notifications PRIVATE ${QT_DBUS}) if(Qt6_FOUND) find_package(KF6IdleTime QUIET) set(ACTIVITY_KIDLETIME_TARGET KF6::IdleTime) else() find_package(KF5IdleTime QUIET) set(ACTIVITY_KIDLETIME_TARGET KF5::IdleTime) endif() if(TARGET ${ACTIVITY_KIDLETIME_TARGET}) target_compile_definitions(chatgui_notifications PRIVATE UTUN_ACTIVITY_KIDLETIME) target_link_libraries(chatgui_notifications PRIVATE ${ACTIVITY_KIDLETIME_TARGET}) else() message(STATUS "KIdleTime not found: Wayland activity uses GNOME IdleMonitor or ChatGUI input") endif() elseif(UNIX AND NOT APPLE) find_package(X11 QUIET) endif() if(TARGET X11::X11) target_link_libraries(chatgui_notifications PRIVATE X11::X11) endif() if(TARGET X11::Xss) target_compile_definitions(chatgui_notifications PRIVATE UTUN_ACTIVITY_X11) target_link_libraries(chatgui_notifications PRIVATE X11::Xss) elseif(UNIX AND NOT APPLE) message(STATUS "X11 screen saver library not found: X11 activity uses ChatGUI input") endif() target_link_libraries(vibechat PRIVATE chatgui_notifications) if(WIN32) target_link_libraries(vibechat PRIVATE ${QT_LIBS} rlottie::rlottie ZLIB::ZLIB OpenSSL::Crypto ZXing::ZXing utun utun_voice pthread user32 ${FFMPEG_TARGET} ${FFMPEG_LIBRARIES}) else() target_link_libraries(vibechat PRIVATE ${QT_LIBS} rlottie::rlottie ZLIB::ZLIB OpenSSL::Crypto ZXing::ZXing utun utun_voice pthread dl ${X11_LIBRARIES} ${FFMPEG_TARGET} ${FFMPEG_LIBRARIES}) endif() # ============================================================================ # Tests # ============================================================================ add_executable(test_member_sync ../../lib/sqlite3.c ../../tests/test_member_sync.c ) target_include_directories(test_member_sync PRIVATE transport ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/../../lib ${CMAKE_SOURCE_DIR}/../../src zxing-cpp/core/src ../../tests ) target_compile_definitions(test_member_sync PRIVATE USE_SQLITE SQLITE_THREADSAFE=1) set_source_files_properties(../../lib/sqlite3.c ../../tests/test_member_sync.c PROPERTIES LANGUAGE C) if(WIN32) target_link_libraries(test_member_sync PRIVATE OpenSSL::Crypto pthread) else() target_link_libraries(test_member_sync PRIVATE OpenSSL::Crypto pthread dl) endif() # ============================================================================ # Tests # ============================================================================ enable_testing() add_executable(test_message_notification tests/test_message_notification.cpp) target_link_libraries(test_message_notification PRIVATE chatgui_notifications ${QT_TEST_LIB} pthread ${CMAKE_DL_LIBS}) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") find_program(NOTIFICATION_DBUS_RUN_SESSION NAMES dbus-run-session) if(NOT NOTIFICATION_DBUS_RUN_SESSION) message(FATAL_ERROR "dbus-run-session is required for the isolated notification test") endif() target_compile_definitions(test_message_notification PRIVATE UTUN_TEST_ACTIVITY_DBUS) target_link_libraries(test_message_notification PRIVATE ${QT_DBUS}) add_test(NAME test_message_notification COMMAND ${NOTIFICATION_DBUS_RUN_SESSION} -- $) else() add_test(NAME test_message_notification COMMAND test_message_notification) endif() set_tests_properties(test_message_notification PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60) add_executable(test_message_events tests/test_message_events.cpp transport/gui_bridge_impl.cpp) target_link_libraries(test_message_events PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun utun_voice pthread ${CMAKE_DL_LIBS}) add_test(NAME test_message_events COMMAND test_message_events) set_tests_properties(test_message_events PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 15) # Ручной запуск с DISPLAY: проверяет применение desktop hints оконным менеджером, не меняя настройки рабочих столов. if(TARGET X11::X11) add_executable(test_message_notification_x11 tests/test_message_notification_x11.cpp) target_link_libraries(test_message_notification_x11 PRIVATE chatgui_notifications ${QT_TEST_LIB} X11::X11 pthread ${CMAKE_DL_LIBS}) endif() add_executable(test_file_drop tests/test_file_drop.cpp src/inputbar.cpp src/audiorecorder.cpp src/audio_device.cpp src/sound_manager.cpp src/voicemessageencoder.cpp src/emojipanel.cpp src/emojitabbar.cpp src/emoji.cpp src/animtimer.cpp src/lottieicon.cpp src/voice_audio_io.cpp transport/miniaudio_impl.c transport/audio_diagnostics.cpp) target_include_directories(test_file_drop PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_file_drop PRIVATE ${QT_LIBS} ${QT_TEST_LIB} rlottie::rlottie ZLIB::ZLIB utun_voice utun pthread ${CMAKE_DL_LIBS}) add_test(NAME test_file_drop COMMAND test_file_drop) set_tests_properties(test_file_drop PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30) add_executable(test_channel_replies tests/test_channel_replies.cpp db/db_manager.cpp) target_include_directories(test_channel_replies PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_channel_replies PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun utun_voice pthread ${CMAKE_DL_LIBS}) add_test(NAME test_channel_replies COMMAND test_channel_replies) set_tests_properties(test_channel_replies PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30) add_executable(test_member_files_browser tests/test_member_files_browser.cpp src/member_files/browser.cpp db/db_manager.cpp) target_link_libraries(test_member_files_browser PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun pthread) add_test(NAME test_member_files_browser COMMAND test_member_files_browser) set_tests_properties(test_member_files_browser PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30) add_executable(test_avatars tests/test_avatars.cpp src/avatars/avatarcache.cpp src/avatars/avatarmanager.cpp src/avatars/avatarcrop.cpp src/avatars/avatargallery.cpp src/imageviewer_window.cpp db/db_manager.cpp) target_link_libraries(test_avatars PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun pthread) add_test(NAME test_avatars COMMAND test_avatars) set_tests_properties(test_avatars PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 60) add_executable(test_group_avatars tests/test_group_avatars.cpp src/avatars/groupavatarmanager.cpp src/channelsettingsdialog.cpp db/db_manager.cpp) target_link_libraries(test_group_avatars PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun pthread) add_test(NAME test_group_avatars COMMAND test_group_avatars) set_tests_properties(test_group_avatars PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30) add_executable(test_gui_language tests/test_gui_language.cpp src/networksettingspage.cpp transport/node_config.cpp transport/config_updater.cpp "${CMAKE_CURRENT_BINARY_DIR}/translations.qrc") add_dependencies(test_gui_language chatgui_translations) target_compile_definitions(test_gui_language PRIVATE GUI_TS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/translations") target_link_libraries(test_gui_language PRIVATE ${QT_LIBS} ${QT_TEST_LIB} OpenSSL::Crypto utun pthread) add_test(NAME test_gui_language COMMAND test_gui_language) set_tests_properties(test_gui_language PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30) add_executable(test_emoji_playback tests/test_emoji_playback.cpp src/animtimer.cpp src/lottieicon.cpp src/emojipanel.cpp src/emojitabbar.cpp src/emoji.cpp src/chatview.cpp) target_link_libraries(test_emoji_playback PRIVATE ${QT_LIBS} ${QT_TEST_LIB} rlottie::rlottie ZLIB::ZLIB utun) add_test(NAME test_emoji_playback COMMAND test_emoji_playback) set_tests_properties(test_emoji_playback PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30) add_executable(test_invite_links tests/test_invite_links.cpp src/message_links.cpp src/messagedelegate.cpp src/chatview.cpp src/accountdelegate.cpp src/flagpainter.cpp src/animtimer.cpp src/lottieicon.cpp src/emoji.cpp src/voiceplayback.cpp src/sound_manager.cpp src/voice_audio_io.cpp src/audio_device.cpp transport/miniaudio_impl.c transport/audio_diagnostics.cpp) target_include_directories(test_invite_links PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_invite_links PRIVATE ${QT_LIBS} ${QT_TEST_LIB} rlottie::rlottie ZLIB::ZLIB utun_voice utun pthread ${CMAKE_DL_LIBS}) add_test(NAME test_invite_links COMMAND test_invite_links) set_tests_properties(test_invite_links PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30) add_executable(test_config_updater tests/test_config_updater.cpp transport/config_updater.cpp ) target_include_directories(test_config_updater PRIVATE ${CMAKE_SOURCE_DIR}) target_link_libraries(test_config_updater PRIVATE ${QT_CORE} pthread) add_test(NAME test_config_updater COMMAND test_config_updater) # тест адаптивного джиттер-буфера голоса (кодированные кадры + SoundTouch time-stretch) add_executable(test_radio_jitter tests/test_radio_jitter.cpp ) target_include_directories(test_radio_jitter PRIVATE ${CMAKE_SOURCE_DIR}/../../src) target_link_libraries(test_radio_jitter PRIVATE utun_voice pthread) add_test(NAME test_radio_jitter COMMAND test_radio_jitter) add_executable(test_call_jitter tests/test_call_jitter.cpp) target_include_directories(test_call_jitter PRIVATE ${CMAKE_SOURCE_DIR}/../../src) target_link_libraries(test_call_jitter PRIVATE utun_voice utun pthread) add_test(NAME test_call_jitter COMMAND test_call_jitter) # тест аудио-движка рации (per-source jitter + микшер + soft-clip) add_executable(test_radio_audio tests/test_radio_audio.cpp ) target_include_directories(test_radio_audio PRIVATE ${CMAKE_SOURCE_DIR}/../../src ${CMAKE_SOURCE_DIR}/../../lib ${CMAKE_SOURCE_DIR}/../../lib/libopus/include) target_link_libraries(test_radio_audio PRIVATE utun_voice utun pthread) add_test(NAME test_radio_audio COMMAND test_radio_audio) add_executable(test_radio_member_mute tests/test_radio_member_mute.cpp) target_include_directories(test_radio_member_mute PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_radio_member_mute PRIVATE ${QT_CORE} utun_voice utun pthread) add_test(NAME test_radio_member_mute COMMAND test_radio_member_mute) set(RADIO_MEMBER_TEST_SOURCES src/memberlistmodel.cpp src/avatars/avatarcache.cpp src/avatars/avatarmanager.cpp src/avatars/avatarcrop.cpp src/avatars/avatargallery.cpp src/imageviewer_window.cpp db/db_manager.cpp) add_executable(test_radio_mute_bridge tests/test_radio_mute_bridge.cpp transport/utun_node.cpp transport/gui_bridge_impl.cpp src/accountdelegate.cpp src/flagpainter.cpp ${RADIO_MEMBER_TEST_SOURCES}) target_include_directories(test_radio_mute_bridge PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_radio_mute_bridge PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun_voice utun pthread) add_test(NAME test_radio_mute_bridge COMMAND test_radio_mute_bridge) set_tests_properties(test_radio_mute_bridge PROPERTIES TIMEOUT 15 ENVIRONMENT "QT_QPA_PLATFORM=offscreen") set_tests_properties(test_radio_member_mute PROPERTIES TIMEOUT 20) if(UNIX AND NOT APPLE) target_compile_definitions(test_radio_member_mute PRIVATE UTUN_TEST_WRAP_VAD) target_link_options(test_radio_member_mute PRIVATE "-Wl,--wrap=silero_vad_create_default" "-Wl,--wrap=silero_vad_destroy" "-Wl,--wrap=silero_vad_reset" "-Wl,--wrap=silero_vad_process") endif() add_executable(test_audio_event_queue tests/test_audio_event_queue.cpp) target_link_libraries(test_audio_event_queue PRIVATE pthread) add_test(NAME test_audio_event_queue COMMAND test_audio_event_queue) add_executable(test_voice_audio_io tests/test_voice_audio_io.cpp src/voice_audio_io.cpp) target_include_directories(test_voice_audio_io PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_voice_audio_io PRIVATE utun pthread) add_test(NAME test_voice_audio_io COMMAND test_voice_audio_io) set_tests_properties(test_audio_event_queue test_voice_audio_io PROPERTIES TIMEOUT 15) if(UNIX AND NOT APPLE) add_executable(test_audio_timing tests/test_audio_timing.c transport/audio_diagnostics.cpp) target_link_libraries(test_audio_timing PRIVATE utun pthread dl m) target_compile_options(test_audio_timing PRIVATE -UNDEBUG) add_test(NAME test_audio_timing COMMAND test_audio_timing) add_executable(test_voice_tx tests/test_voice_tx.cpp) target_include_directories(test_voice_tx PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_voice_tx PRIVATE utun_voice utun pthread) target_link_options(test_voice_tx PRIVATE "-Wl,--wrap=radio_talk_begin" "-Wl,--wrap=radio_talk_end" "-Wl,--wrap=radio_talk_send" "-Wl,--wrap=call_send_media" "-Wl,--wrap=chat_setting_get_int" "-Wl,--wrap=silero_vad_create_default" "-Wl,--wrap=silero_vad_destroy" "-Wl,--wrap=silero_vad_reset" "-Wl,--wrap=silero_vad_process" "-Wl,--wrap=get_time_tb") add_test(NAME test_voice_tx COMMAND test_voice_tx) endif() # smoke-тест видео-декодера (FFmpeg). Ручной запуск: test_video_engine add_executable(test_video_engine tests/test_video_engine.cpp src/videoplayer_engine.cpp src/sound_manager.cpp src/voice_audio_io.cpp src/audio_device.cpp transport/miniaudio_impl.c transport/audio_diagnostics.cpp ) target_include_directories(test_video_engine PRIVATE ${CMAKE_SOURCE_DIR}/../../lib ${CMAKE_SOURCE_DIR}/../../src ${CMAKE_SOURCE_DIR}/db ${CMAKE_SOURCE_DIR}/../../lib/libopus/include ${FFMPEG_INCLUDE_DIRS}) target_compile_definitions(test_video_engine PRIVATE USE_SQLITE SQLITE_THREADSAFE=1) if(FFMPEG_FOUND) target_compile_definitions(test_video_engine PRIVATE HAVE_FFMPEG) endif() set_source_files_properties(transport/miniaudio_impl.c PROPERTIES LANGUAGE C) if(WIN32) target_link_libraries(test_video_engine PRIVATE ${QT_LIBS} ${QT_CORE} utun_voice utun pthread ${FFMPEG_TARGET} ${FFMPEG_LIBRARIES}) else() target_link_libraries(test_video_engine PRIVATE ${QT_LIBS} ${QT_CORE} utun_voice utun pthread dl ${FFMPEG_TARGET} ${FFMPEG_LIBRARIES}) endif() add_executable(test_ptt_key_chord tests/test_ptt_key_chord.cpp) target_link_libraries(test_ptt_key_chord PRIVATE ${QT_CORE}) add_test(NAME test_ptt_key_chord COMMAND test_ptt_key_chord) add_executable(test_voice_file tests/test_voice_file.cpp src/voiceplayback.cpp src/sound_manager.cpp src/voice_audio_io.cpp src/audio_device.cpp transport/miniaudio_impl.c transport/audio_diagnostics.cpp) target_include_directories(test_voice_file PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_voice_file PRIVATE ${QT_LIBS} utun_voice utun pthread ${CMAKE_DL_LIBS}) add_test(NAME test_voice_file COMMAND test_voice_file) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_executable(test_audio_recovery tests/test_audio_recovery.cpp src/audio_device.cpp src/sound_manager.cpp src/voice_audio_io.cpp src/audiorecorder.cpp src/call_audio_engine.cpp src/radio_audio_engine.cpp transport/miniaudio_impl.c transport/audio_diagnostics.cpp transport/config_updater.cpp) target_include_directories(test_audio_recovery PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_audio_recovery PRIVATE ${QT_LIBS} utun_voice utun pthread dl) target_link_options(test_audio_recovery PRIVATE "-Wl,--wrap=ma_context_init" "-Wl,--wrap=ma_context_uninit" "-Wl,--wrap=ma_device_init" "-Wl,--wrap=ma_device_start" "-Wl,--wrap=ma_device_uninit" "-Wl,--wrap=audio_context_failed") add_test(NAME test_audio_recovery COMMAND test_audio_recovery) set_tests_properties(test_audio_recovery PROPERTIES TIMEOUT 15) add_executable(test_radio_panel tests/test_radio_panel.cpp src/radiopanel.cpp src/radio_audio_engine.cpp src/radiosettingspage.cpp src/ptt_hotkey_manager.cpp src/sound_manager.cpp src/voice_audio_io.cpp src/audio_device.cpp transport/miniaudio_impl.c transport/audio_diagnostics.cpp transport/config_updater.cpp ${RADIO_MEMBER_TEST_SOURCES}) target_include_directories(test_radio_panel PRIVATE ${UTUN_INCLUDE_DIRS}) target_link_libraries(test_radio_panel PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun_voice utun pthread dl ${X11_LIBRARIES}) target_link_options(test_radio_panel PRIVATE "-Wl,--wrap=ma_context_init" "-Wl,--wrap=ma_device_start" "-Wl,--wrap=radio_talk_begin" "-Wl,--wrap=radio_talk_end" "-Wl,--wrap=radio_talk_send" "-Wl,--wrap=silero_vad_create_default" "-Wl,--wrap=silero_vad_destroy" "-Wl,--wrap=silero_vad_reset" "-Wl,--wrap=silero_vad_process") add_test(NAME test_radio_panel COMMAND test_radio_panel) set_tests_properties(test_radio_panel PROPERTIES TIMEOUT 25 ENVIRONMENT "QT_QPA_PLATFORM=offscreen") add_executable(test_ptt_portal tests/test_ptt_portal.cpp src/ptt_portal.cpp) target_link_libraries(test_ptt_portal PRIVATE ${QT_DBUS} ${QT_TEST_LIB} utun pthread) find_program(DBUS_RUN_SESSION dbus-run-session) if(NOT DBUS_RUN_SESSION) message(FATAL_ERROR "dbus-run-session is required for the isolated PTT portal test") endif() add_test(NAME test_ptt_portal COMMAND ${DBUS_RUN_SESSION} -- $) add_executable(test_linux_audio tests/test_linux_audio.c transport/audio_diagnostics.cpp) target_link_libraries(test_linux_audio PRIVATE utun pthread dl m) # assert выполняет вызовы стенда, поэтому не отключаем его в Release. target_compile_options(test_linux_audio PRIVATE -UNDEBUG) add_test(NAME test_linux_audio COMMAND test_linux_audio) add_executable(test_audio_diagnostics tests/test_audio_diagnostics.cpp) target_link_libraries(test_audio_diagnostics PRIVATE utun pthread) target_compile_options(test_audio_diagnostics PRIVATE -UNDEBUG) add_test(NAME test_audio_diagnostics COMMAND test_audio_diagnostics) endif()