diff --git a/CMakeLists.txt b/CMakeLists.txt index d256919e..997f35f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,45 +1,24 @@ -cmake_minimum_required(VERSION 3.14) -project(advanced-scene-switcher) +cmake_minimum_required(VERSION 3.21) -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE RELWITHDEBINFO) +project(advanced-scene-switcher VERSION 1.0.0) +set(LIB_NAME "${PROJECT_NAME}-lib") +add_library(${PROJECT_NAME} MODULE) +add_library(${LIB_NAME} SHARED) + +set(PLUGIN_AUTHOR "WarmUpTill") +set(MACOS_BUNDLEID "com.warmuptill.${PROJECT_NAME}") +set(LINUX_MAINTAINER_EMAIL "noone@nothing.com") + +message(STATUS "CMAKE_PROJECT_NAME is ${CMAKE_PROJECT_NAME}") +if(${CMAKE_PROJECT_NAME} STREQUAL "obs-studio") + if(NOT DEFINED BUILD_OUT_OF_TREE) + message(STATUS "${PROJECT_NAME} configured for in-tree build") + endif() +else() + set(BUILD_OUT_OF_TREE ON) + message(STATUS "${PROJECT_NAME} configured for out-of-tree build") endif() -# Compiler settings -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED YES) -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) - -if(CMAKE_COMPILER_IS_GNUCC - OR CMAKE_COMPILER_IS_GNUCXX - OR CMAKE_COMPILER_IS_CLANG) - set(CMAKE_CXX_FLAGS - "-Wall -Wextra -Wvla -Wno-unused-function -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS} -fno-strict-aliasing" - ) - set(CMAKE_C_FLAGS - "-Wall -Wextra -Wvla -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-braces -Wno-missing-field-initializers ${CMAKE_C_FLAGS} -std=gnu99 -fno-strict-aliasing" - ) - - option(USE_LIBC++ "Use libc++ instead of libstdc++" ${APPLE}) - if(USE_LIBC++) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - endif() -elseif(MSVC) - if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") - endif() - - # Disable pointless constant condition warnings - set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} /wd4127 /wd4201 /wd4456 /wd4457 /wd4458 /wd4459 /wd4595" - ) - add_definitions(-DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS - -D_CRT_NONSTDC_NO_WARNINGS) -endif() - -# Generate version info list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") include(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA1) @@ -47,80 +26,300 @@ git_describe(GIT_TAG) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp" @ONLY) -# Windows installer -if(WIN32) - get_filename_component(ISS_PLUGIN_FILES_DIR - "${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE) - file(TO_NATIVE_PATH "${ISS_PLUGIN_FILES_DIR}" ISS_PLUGIN_FILES_DIR) - get_filename_component(ISS_MSVC_REDIST_HELPER_DIR "${CMAKE_BINARY_DIR}\\.." - ABSOLUTE) - file(TO_NATIVE_PATH "${ISS_MSVC_REDIST_HELPER_DIR}" - ISS_MSVC_REDIST_HELPER_DIR) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CI/windows/setup.iss.in" - "${CMAKE_CURRENT_BINARY_DIR}/CI/windows/setup.iss" @ONLY) -endif() +target_sources(${PROJECT_NAME} PRIVATE src/advanced-scene-switcher-module.c) + +target_sources( + ${LIB_NAME} + PRIVATE src/headers/advanced-scene-switcher.hpp + src/headers/switcher-data-structs.hpp + src/headers/scene-group.hpp + src/headers/scene-trigger.hpp + src/headers/switch-audio.hpp + src/headers/switch-executable.hpp + src/headers/switch-file.hpp + src/headers/switch-idle.hpp + src/headers/switch-media.hpp + src/headers/switch-network.hpp + src/headers/switch-pause.hpp + src/headers/switch-random.hpp + src/headers/switch-screen-region.hpp + src/headers/switch-time.hpp + src/headers/switch-transitions.hpp + src/headers/switch-window.hpp + src/headers/switch-sequence.hpp + src/headers/switch-video.hpp + src/headers/switch-generic.hpp + src/headers/macro-action.hpp + src/headers/macro-action-edit.hpp + src/headers/macro-action-audio.hpp + src/headers/macro-action-file.hpp + src/headers/macro-action-filter.hpp + src/headers/macro-action-hotkey.hpp + src/headers/macro-action-macro.hpp + src/headers/macro-action-media.hpp + src/headers/macro-action-plugin-state.hpp + src/headers/macro-action-profile.hpp + src/headers/macro-action-random.hpp + src/headers/macro-action-recording.hpp + src/headers/macro-action-replay-buffer.hpp + src/headers/macro-action-run.hpp + src/headers/macro-action-scene-collection.hpp + src/headers/macro-action-scene-order.hpp + src/headers/macro-action-scene-switch.hpp + src/headers/macro-action-scene-transform.hpp + src/headers/macro-action-scene-visibility.hpp + src/headers/macro-action-screenshot.hpp + src/headers/macro-action-sequence.hpp + src/headers/macro-action-source.hpp + src/headers/macro-action-streaming.hpp + src/headers/macro-action-studio-mode.hpp + src/headers/macro-action-systray.hpp + src/headers/macro-action-timer.hpp + src/headers/macro-action-transition.hpp + src/headers/macro-action-virtual-cam.hpp + src/headers/macro-action-wait.hpp + src/headers/macro-condition.hpp + src/headers/macro-condition-edit.hpp + src/headers/macro-condition-audio.hpp + src/headers/macro-condition-cursor.hpp + src/headers/macro-condition-date.hpp + src/headers/macro-condition-file.hpp + src/headers/macro-condition-filter.hpp + src/headers/macro-condition-hotkey.hpp + src/headers/macro-condition-idle.hpp + src/headers/macro-condition-macro.hpp + src/headers/macro-condition-media.hpp + src/headers/macro-condition-obs-stats.hpp + src/headers/macro-condition-plugin-state.hpp + src/headers/macro-condition-process.hpp + src/headers/macro-condition-profile.hpp + src/headers/macro-condition-recording.hpp + src/headers/macro-condition-replay-buffer.hpp + src/headers/macro-condition-scene-order.hpp + src/headers/macro-condition-scene-transform.hpp + src/headers/macro-condition-scene-visibility.hpp + src/headers/macro-condition-scene.hpp + src/headers/macro-condition-source.hpp + src/headers/macro-condition-streaming.hpp + src/headers/macro-condition-studio-mode.hpp + src/headers/macro-condition-timer.hpp + src/headers/macro-condition-transition.hpp + src/headers/macro-condition-virtual-cam.hpp + src/headers/macro-condition-window.hpp + src/headers/macro.hpp + src/headers/macro-ref.hpp + src/headers/macro-list-entry-widget.hpp + src/headers/macro-properties.hpp + src/headers/macro-segment.hpp + src/headers/macro-segment-list.hpp + src/headers/macro-selection.hpp + src/headers/curl-helper.hpp + src/headers/hotkey.hpp + src/headers/scene-item-selection.hpp + src/headers/scene-selection.hpp + src/headers/screenshot-helper.hpp + src/headers/transition-selection.hpp + src/headers/name-dialog.hpp + src/headers/duration-control.hpp + src/headers/file-selection.hpp + src/headers/section.hpp + src/headers/status-control.hpp + src/headers/platform-funcs.hpp + src/headers/resizing-text-edit.hpp + src/headers/utility.hpp + src/headers/volume-control.hpp + src/headers/version.h + src/advanced-scene-switcher.cpp + src/switcher-data-structs.cpp + src/scene-group.cpp + src/scene-trigger.cpp + src/switch-transitions.cpp + src/switch-screen-region.cpp + src/switch-priority.cpp + src/switch-executable.cpp + src/switch-idle.cpp + src/switch-sequence.cpp + src/switch-file.cpp + src/switch-window.cpp + src/switch-media.cpp + src/switch-network.cpp + src/file-selection.cpp + src/hotkey.cpp + src/general.cpp + src/switch-pause.cpp + src/switch-random.cpp + src/switch-time.cpp + src/switch-audio.cpp + src/switch-video.cpp + src/switch-generic.cpp + src/macro-action.cpp + src/macro-action-edit.cpp + src/macro-action-audio.cpp + src/macro-action-file.cpp + src/macro-action-filter.cpp + src/macro-action-hotkey.cpp + src/macro-action-macro.cpp + src/macro-action-media.cpp + src/macro-action-plugin-state.cpp + src/macro-action-profile.cpp + src/macro-action-random.cpp + src/macro-action-recording.cpp + src/macro-action-replay-buffer.cpp + src/macro-action-run.cpp + src/macro-action-scene-collection.cpp + src/macro-action-scene-order.cpp + src/macro-action-scene-switch.cpp + src/macro-action-scene-transform.cpp + src/macro-action-scene-visibility.cpp + src/macro-action-screenshot.cpp + src/macro-action-sequence.cpp + src/macro-action-source.cpp + src/macro-action-streaming.cpp + src/macro-action-studio-mode.cpp + src/macro-action-systray.cpp + src/macro-action-timer.cpp + src/macro-action-transition.cpp + src/macro-action-virtual-cam.cpp + src/macro-action-wait.cpp + src/macro-condition.cpp + src/macro-condition-edit.cpp + src/macro-condition-audio.cpp + src/macro-condition-cursor.cpp + src/macro-condition-date.cpp + src/macro-condition-file.cpp + src/macro-condition-filter.cpp + src/macro-condition-hotkey.cpp + src/macro-condition-idle.cpp + src/macro-condition-macro.cpp + src/macro-condition-media.cpp + src/macro-condition-obs-stats.cpp + src/macro-condition-plugin-state.cpp + src/macro-condition-process.cpp + src/macro-condition-profile.cpp + src/macro-condition-recording.cpp + src/macro-condition-replay-buffer.cpp + src/macro-condition-scene-order.cpp + src/macro-condition-scene-transform.cpp + src/macro-condition-scene-visibility.cpp + src/macro-condition-scene.cpp + src/macro-condition-source.cpp + src/macro-condition-streaming.cpp + src/macro-condition-studio-mode.cpp + src/macro-condition-timer.cpp + src/macro-condition-transition.cpp + src/macro-condition-virtual-cam.cpp + src/macro-condition-window.cpp + src/macro.cpp + src/macro-ref.cpp + src/macro-list-entry-widget.cpp + src/macro-properties.cpp + src/macro-segment.cpp + src/macro-segment-list.cpp + src/macro-selection.cpp + src/macro-tab.cpp + src/curl-helper.cpp + src/scene-item-selection.cpp + src/scene-selection.cpp + src/screenshot-helper.cpp + src/transition-selection.cpp + src/name-dialog.cpp + src/resizing-text-edit.cpp + src/duration-control.cpp + src/status-control.cpp + src/section.cpp + src/utility.cpp + src/volume-control.cpp + src/version.cpp) -# Out of tree specific settings if(BUILD_OUT_OF_TREE) - set(CMAKE_PREFIX_PATH "${QTDIR}") - set(CMAKE_INCLUDE_CURRENT_DIR ON) - find_package(Qt5Core REQUIRED) - find_package(Qt5Widgets REQUIRED) - find_package(LibObs) - find_package(LibObs-frontend-api) - if(LibObs_FOUND) - set(LIBOBS_LIB ${LIBOBS_LIBRARIES}) - set(LIBOBS_INCLUDE_DIR ${LIBOBS_INCLUDE_DIRS}) - endif() - if(LibObs-frontend-api_FOUND) - set(LIBOBS_FRONTEND_API_LIB ${LIBOBS-FRONTEND-API_LIBRARIES}) - set(LIBOBS_FRONTEND_INCLUDE_DIR ${LIBOBS-FRONTEND-API_INCLUDE_DIR}) - endif() - - if(NOT LIBOBS_LIB) - message(FATAL_ERROR "obs library not found - please set LIBOBS_LIB") - endif() - if(NOT LIBOBS_FRONTEND_API_LIB) - message( - FATAL_ERROR - "libobs frontend-api library not found - please set LIBOBS_FRONTEND_API_LIB" - ) - endif() - if(NOT LIBOBS_INCLUDE_DIR) - message( - FATAL_ERROR "obs.hpp header not found - please set LIBOBS_INCLUDE_DIR") - endif() - if(NOT LIBOBS_FRONTEND_INCLUDE_DIR) - message( - FATAL_ERROR - " obs-frontend-api.h not found - please set LIBOBS_FRONTEND_INCLUDE_DIR" - ) - endif() - - include_directories("${LIBOBS_INCLUDE_DIR}" "${LIBOBS_FRONTEND_INCLUDE_DIR}" - ${Qt5Core_INCLUDES} ${Qt5Widgets_INCLUDES}) - - find_package(CURL REQUIRED) - include_directories("${CURL_INCLUDE_DIRS}") + find_package(libobs REQUIRED) + find_package(obs-frontend-api REQUIRED) + include(cmake/ObsPluginHelpers.cmake) + target_link_libraries(${LIB_NAME} PUBLIC OBS::libobs OBS::obs-frontend-api) + target_link_libraries(${PROJECT_NAME} PUBLIC ${LIB_NAME}) else() - find_package(Libcurl REQUIRED) - include_directories("${LIBCURL_INCLUDE_DIRS}") - add_definitions(-DVCAM_SUPPORTED) - add_definitions(-DREPLAYBUFFER_SUPPORTED) - add_definitions(-DVISIBILITY_TRANSITIONS_SUPPORTED) + target_link_libraries(${LIB_NAME} PUBLIC OBS::libobs OBS::frontend-api) + target_link_libraries(${PROJECT_NAME} PUBLIC ${LIB_NAME}) endif() -# Platform specific settings -if(APPLE) - set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") - find_library(COCOA Cocoa) - if(BUILD_OUT_OF_TREE) - find_package(Qt5MacExtras REQUIRED) +find_qt(COMPONENTS Widgets Core) +target_link_libraries(${LIB_NAME} PUBLIC Qt::Core Qt::Widgets) + +include(cmake/AdvSSHelpers.cmake) + +# --- Platform-independent build settings --- + +target_include_directories( + ${LIB_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src" + "${CMAKE_CURRENT_BINARY_DIR}/forms") + +set_target_properties( + ${LIB_NAME} + PROPERTIES AUTOMOC ON + AUTOUIC ON + AUTORCC ON + AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/forms") + +target_compile_features(${LIB_NAME} PUBLIC cxx_std_17) + +add_definitions(-DASIO_STANDALONE) +target_include_directories( + ${LIB_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include" + "${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp") + +# --- End of section --- + +# --- Windows-specific build settings and tasks --- +if(OS_WINDOWS) + configure_file(cmake/bundle/windows/installer-Windows.iss.in + ${CMAKE_CURRENT_BINARY_DIR}/installer-Windows.generated.iss) + + if(MSVC) + target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267) endif() - include_directories(${COCOA}) -endif() + target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp) + add_definitions(-D_WEBSOCKETPP_CPP11_STL_) + set_property(TARGET ${LIB_NAME} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS true) + # --- End of section --- + + # -- macOS specific build settings and tasks -- +elseif(OS_MACOS) + configure_file(cmake/bundle/macos/installer-macos.pkgproj.in + ${CMAKE_CURRENT_BINARY_DIR}/installer-macos.generated.pkgproj) + + set(MACOSX_PLUGIN_GUI_IDENTIFIER "${MACOS_BUNDLEID}") + set(MACOSX_PLUGIN_BUNDLE_VERSION "${PROJECT_VERSION}") + set(MACOSX_PLUGIN_SHORT_VERSION_STRING "1") + + target_compile_options( + ${LIB_NAME} PRIVATE -Wall -Wextra -Werror-implicit-function-declaration + -stdlib=libc++ -fvisibility=default) + + set_target_properties(${LIB_NAME} PROPERTIES PREFIX "" SUFFIX ".so") + + find_library(COCOA Cocoa) + target_include_directories(${LIB_NAME} PRIVATE ${COCOA}) + target_sources(${LIB_NAME} PRIVATE src/osx/advanced-scene-switcher-osx.mm) + set_source_files_properties(advanced-scene-switcher-osx.mm + PROPERTIES COMPILE_FLAGS "-fobjc-arc") + set("${PROJECT_NAME}_PLATFORM_LIBS" ${COCOA}) + find_package(CURL) + find_package(Libcurl) + if(CURL_FOUND) + target_include_directories(${LIB_NAME} PRIVATE "${CURL_INCLUDE_DIRS}") + elseif(Libcurl_FOUND) + target_include_directories(${LIB_NAME} PRIVATE "${LIBCURL_INCLUDE_DIRS}") + else() + message(FATAL_ERROR "Couldn't find CURL or Libcurl - abort") + endif() + # --- End of section --- + + # --- Linux-specific build settings and tasks --- +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra) + + set_target_properties(${LIB_NAME} PROPERTIES PREFIX "") -if(UNIX AND NOT APPLE) find_package(X11 REQUIRED COMPONENTS Xtst Xss) find_path(PROCPS_INCLUDE_DIR NAMES proc/procps.h) if(NOT PROCPS_INCLUDE_DIR) @@ -132,321 +331,53 @@ if(UNIX AND NOT APPLE) if(NOT PROCPS_LIBRARY) message(FATAL_ERROR "procps lib not found - please set PROCPS_LIBRARY") endif() - link_libraries(${X11_LIBRARIES} ${procps_LIBRARIES}) - include_directories("${X11_INCLUDE_DIR}" "${X11_Xtst_INCLUDE_PATH}" - "${X11_Xss_INCLUDE_PATH}" "${PROCPS_INCLUDE_DIR}") -endif() - -if(WIN32) - set(advanced-scene-switcher_PLATFORM_SOURCES - src/win/advanced-scene-switcher-win.cpp) -elseif(APPLE) - set(advanced-scene-switcher_PLATFORM_SOURCES - src/osx/advanced-scene-switcher-osx.mm) - set_source_files_properties(advanced-scene-switcher-osx.mm - PROPERTIES COMPILE_FLAGS "-fobjc-arc") - set(advanced-scene-switcher_PLATFORM_LIBS ${COCOA}) -else() - set(advanced-scene-switcher_PLATFORM_SOURCES - src/linux/advanced-scene-switcher-nix.cpp) - set(advanced-scene-switcher_PLATFORM_LIBS Xss ${PROCPS_LIBRARY}) -endif() - -# asio and websocketpp -add_definitions(-DASIO_STANDALONE) -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include" - "${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp") -if(WIN32) - add_definitions(-D_WEBSOCKETPP_CPP11_STL_) -endif() - -# Setup QT tools -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/forms") -set(advanced-scene-switcher_UI ${advanced-scene-switcher_UI} - forms/advanced-scene-switcher.ui) -qt5_wrap_ui(advanced-scene-switcher_UI_HEADERS ${advanced-scene-switcher_UI} - ${advanced-scene-switcher_PLATFORM_UI}) - -# The plugin sources -set(advanced-scene-switcher_HEADERS - ${advanced-scene-switcher_HEADERS} - src/headers/advanced-scene-switcher.hpp - src/headers/switcher-data-structs.hpp - src/headers/scene-group.hpp - src/headers/scene-trigger.hpp - src/headers/switch-audio.hpp - src/headers/switch-executable.hpp - src/headers/switch-file.hpp - src/headers/switch-idle.hpp - src/headers/switch-media.hpp - src/headers/switch-network.hpp - src/headers/switch-pause.hpp - src/headers/switch-random.hpp - src/headers/switch-screen-region.hpp - src/headers/switch-time.hpp - src/headers/switch-transitions.hpp - src/headers/switch-window.hpp - src/headers/switch-sequence.hpp - src/headers/switch-video.hpp - src/headers/switch-generic.hpp - src/headers/macro-action.hpp - src/headers/macro-action-edit.hpp - src/headers/macro-action-audio.hpp - src/headers/macro-action-file.hpp - src/headers/macro-action-filter.hpp - src/headers/macro-action-hotkey.hpp - src/headers/macro-action-macro.hpp - src/headers/macro-action-media.hpp - src/headers/macro-action-plugin-state.hpp - src/headers/macro-action-profile.hpp - src/headers/macro-action-random.hpp - src/headers/macro-action-recording.hpp - src/headers/macro-action-replay-buffer.hpp - src/headers/macro-action-run.hpp - src/headers/macro-action-scene-collection.hpp - src/headers/macro-action-scene-order.hpp - src/headers/macro-action-scene-switch.hpp - src/headers/macro-action-scene-transform.hpp - src/headers/macro-action-scene-visibility.hpp - src/headers/macro-action-screenshot.hpp - src/headers/macro-action-sequence.hpp - src/headers/macro-action-source.hpp - src/headers/macro-action-streaming.hpp - src/headers/macro-action-studio-mode.hpp - src/headers/macro-action-systray.hpp - src/headers/macro-action-timer.hpp - src/headers/macro-action-transition.hpp - src/headers/macro-action-virtual-cam.hpp - src/headers/macro-action-wait.hpp - src/headers/macro-condition.hpp - src/headers/macro-condition-edit.hpp - src/headers/macro-condition-audio.hpp - src/headers/macro-condition-cursor.hpp - src/headers/macro-condition-date.hpp - src/headers/macro-condition-file.hpp - src/headers/macro-condition-filter.hpp - src/headers/macro-condition-hotkey.hpp - src/headers/macro-condition-idle.hpp - src/headers/macro-condition-macro.hpp - src/headers/macro-condition-media.hpp - src/headers/macro-condition-obs-stats.hpp - src/headers/macro-condition-plugin-state.hpp - src/headers/macro-condition-process.hpp - src/headers/macro-condition-profile.hpp - src/headers/macro-condition-recording.hpp - src/headers/macro-condition-replay-buffer.hpp - src/headers/macro-condition-scene-order.hpp - src/headers/macro-condition-scene-transform.hpp - src/headers/macro-condition-scene-visibility.hpp - src/headers/macro-condition-scene.hpp - src/headers/macro-condition-source.hpp - src/headers/macro-condition-streaming.hpp - src/headers/macro-condition-studio-mode.hpp - src/headers/macro-condition-timer.hpp - src/headers/macro-condition-transition.hpp - src/headers/macro-condition-virtual-cam.hpp - src/headers/macro-condition-window.hpp - src/headers/macro.hpp - src/headers/macro-ref.hpp - src/headers/macro-list-entry-widget.hpp - src/headers/macro-properties.hpp - src/headers/macro-segment.hpp - src/headers/macro-segment-list.hpp - src/headers/macro-selection.hpp - src/headers/curl-helper.hpp - src/headers/hotkey.hpp - src/headers/scene-item-selection.hpp - src/headers/scene-selection.hpp - src/headers/screenshot-helper.hpp - src/headers/transition-selection.hpp - src/headers/name-dialog.hpp - src/headers/duration-control.hpp - src/headers/file-selection.hpp - src/headers/section.hpp - src/headers/status-control.hpp - src/headers/platform-funcs.hpp - src/headers/resizing-text-edit.hpp - src/headers/utility.hpp - src/headers/volume-control.hpp - src/headers/version.h) - -set(advanced-scene-switcher_SOURCES - ${advanced-scene-switcher_SOURCES} - src/advanced-scene-switcher.cpp - src/advanced-scene-switcher-module.c - src/switcher-data-structs.cpp - src/scene-group.cpp - src/scene-trigger.cpp - src/switch-transitions.cpp - src/switch-screen-region.cpp - src/switch-priority.cpp - src/switch-executable.cpp - src/switch-idle.cpp - src/switch-sequence.cpp - src/switch-file.cpp - src/switch-window.cpp - src/switch-media.cpp - src/switch-network.cpp - src/file-selection.cpp - src/hotkey.cpp - src/general.cpp - src/switch-pause.cpp - src/switch-random.cpp - src/switch-time.cpp - src/switch-audio.cpp - src/switch-video.cpp - src/switch-generic.cpp - src/macro-action.cpp - src/macro-action-edit.cpp - src/macro-action-audio.cpp - src/macro-action-file.cpp - src/macro-action-filter.cpp - src/macro-action-hotkey.cpp - src/macro-action-macro.cpp - src/macro-action-media.cpp - src/macro-action-plugin-state.cpp - src/macro-action-profile.cpp - src/macro-action-random.cpp - src/macro-action-recording.cpp - src/macro-action-replay-buffer.cpp - src/macro-action-run.cpp - src/macro-action-scene-collection.cpp - src/macro-action-scene-order.cpp - src/macro-action-scene-switch.cpp - src/macro-action-scene-transform.cpp - src/macro-action-scene-visibility.cpp - src/macro-action-screenshot.cpp - src/macro-action-sequence.cpp - src/macro-action-source.cpp - src/macro-action-streaming.cpp - src/macro-action-studio-mode.cpp - src/macro-action-systray.cpp - src/macro-action-timer.cpp - src/macro-action-transition.cpp - src/macro-action-virtual-cam.cpp - src/macro-action-wait.cpp - src/macro-condition.cpp - src/macro-condition-edit.cpp - src/macro-condition-audio.cpp - src/macro-condition-cursor.cpp - src/macro-condition-date.cpp - src/macro-condition-file.cpp - src/macro-condition-filter.cpp - src/macro-condition-hotkey.cpp - src/macro-condition-idle.cpp - src/macro-condition-macro.cpp - src/macro-condition-media.cpp - src/macro-condition-obs-stats.cpp - src/macro-condition-plugin-state.cpp - src/macro-condition-process.cpp - src/macro-condition-profile.cpp - src/macro-condition-recording.cpp - src/macro-condition-replay-buffer.cpp - src/macro-condition-scene-order.cpp - src/macro-condition-scene-transform.cpp - src/macro-condition-scene-visibility.cpp - src/macro-condition-scene.cpp - src/macro-condition-source.cpp - src/macro-condition-streaming.cpp - src/macro-condition-studio-mode.cpp - src/macro-condition-timer.cpp - src/macro-condition-transition.cpp - src/macro-condition-virtual-cam.cpp - src/macro-condition-window.cpp - src/macro.cpp - src/macro-ref.cpp - src/macro-list-entry-widget.cpp - src/macro-properties.cpp - src/macro-segment.cpp - src/macro-segment-list.cpp - src/macro-selection.cpp - src/macro-tab.cpp - src/curl-helper.cpp - src/scene-item-selection.cpp - src/scene-selection.cpp - src/screenshot-helper.cpp - src/transition-selection.cpp - src/name-dialog.cpp - src/resizing-text-edit.cpp - src/duration-control.cpp - src/status-control.cpp - src/section.cpp - src/utility.cpp - src/volume-control.cpp - src/version.cpp) - -# Backwards compatability checks with older OBS versions -if(DEFINED LibObs_VERSION_MAJOR) - if(LibObs_VERSION_MAJOR GREATER_EQUAL 27) - add_definitions(-DVCAM_SUPPORTED) - add_definitions(-DVISIBILITY_TRANSITIONS_SUPPORTED) + target_link_libraries(${LIB_NAME} PRIVATE ${X11_LIBRARIES} + ${procps_LIBRARIES}) + target_include_directories( + ${LIB_NAME} PRIVATE "${X11_INCLUDE_DIR}" "${X11_Xtst_INCLUDE_PATH}" + "${X11_Xss_INCLUDE_PATH}" "${PROCPS_INCLUDE_DIR}") + target_sources(${LIB_NAME} PRIVATE src/linux/advanced-scene-switcher-nix.cpp) + set("${PROJECT_NAME}_PLATFORM_LIBS" Xss ${PROCPS_LIBRARY}) + find_package(CURL) + find_package(Libcurl) + if(CURL_FOUND) + target_include_directories(${LIB_NAME} PRIVATE "${CURL_INCLUDE_DIRS}") + elseif(Libcurl_FOUND) + target_include_directories(${LIB_NAME} PRIVATE "${LIBCURL_INCLUDE_DIRS}") else() - message( - WARNING - "OBS version ${LibObs_VERSION_MAJOR} found - disabling virtual camera and hide/show transition functionality" - ) - endif() - if(LibObs_VERSION_MAJOR GREATER_EQUAL 26) - add_definitions(-DREPLAYBUFFER_SUPPORTED) - else() - message( - WARNING - "OBS version ${LibObs_VERSION_MAJOR} found - disabling replay buffer and screenshot functionality" - ) - list(REMOVE_ITEM advanced-scene-switcher_SOURCES - src/macro-action-screenshot.cpp) - list(REMOVE_ITEM advanced-scene-switcher_HEADERS - src/headers/macro-action-screenshot.hpp) + message(FATAL_ERROR "Couldn't find CURL or Libcurl - abort") endif() endif() +# --- End of section --- -add_library( - advanced-scene-switcher SHARED - ${advanced-scene-switcher_HEADERS} - ${advanced-scene-switcher_SOURCES} - ${advanced-scene-switcher_UI_HEADERS} - ${advanced-scene-switcher_PLATFORM_SOURCES} - ${advanced-scene-switcher_PLATFORM_HEADERS}) +target_link_libraries(${LIB_NAME} PUBLIC ${${PROJECT_NAME}_PLATFORM_LIBS}) +setup_plugin_target(${PROJECT_NAME}) +install_advss_lib(${LIB_NAME}) -# Out of tree build -if(BUILD_OUT_OF_TREE) - target_link_libraries( - advanced-scene-switcher ${advanced-scene-switcher_PLATFORM_LIBS} - ${LIBOBS_LIB} ${LIBOBS_FRONTEND_API_LIB} Qt5::Core Qt5::Widgets) +# --- Helpers for debian package creation --- +if(DEB_INSTALL) # Additional commands to install the module in the correct place. Find all the # translation files so we can copy them to the correct place later on. file(GLOB ASS_TRANSLATION_FILES "data/locale/*.ini") - # OSX - if(APPLE) - set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "") - endif() - # Linux if(UNIX AND NOT APPLE) if(NOT LIB_OUT_DIR) set(LIB_OUT_DIR "/lib/obs-plugins") endif() if(NOT DATA_OUT_DIR) - set(DATA_OUT_DIR "/share/obs/obs-plugins/advanced-scene-switcher") + set(DATA_OUT_DIR "/share/obs/obs-plugins/${PROJECT_NAME}") endif() - set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "") - install(TARGETS advanced-scene-switcher + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR}) install(DIRECTORY data/locale DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR}) install(DIRECTORY data/res DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR}) endif() -else() - # In tree build - target_link_libraries( - advanced-scene-switcher ${advanced-scene-switcher_PLATFORM_LIBS} - obs-frontend-api Qt5::Widgets libobs) - install_obs_plugin_with_data(advanced-scene-switcher data) endif() +# --- End of section --- + add_subdirectory(src/external-macro-modules) diff --git a/cmake/AdvSSHelpers.cmake b/cmake/AdvSSHelpers.cmake new file mode 100644 index 00000000..ca120a6e --- /dev/null +++ b/cmake/AdvSSHelpers.cmake @@ -0,0 +1,267 @@ +# --- Helper functions ---# + +# Subfolder for advanced scene switcher plugins +set(_PLUGIN_FOLDER "adv-ss-plugins") + +# --- MACOS section --- +if(OS_MACOS) + set(ADVSS_BUNDLE_DIR "${CMAKE_INSTALL_PREFIX}/advanced-scene-switcher.plugin") + set(ADVSS_BUNDLE_MODULE_DIR "${ADVSS_BUNDLE_DIR}/Contents/MacOS") + set(ADVSS_BUNDLE_PLUGIN_DIR ${ADVSS_BUNDLE_MODULE_DIR}/${_PLUGIN_FOLDER}) + + function(resign_advss target) + set(_COMMAND "codesign --force --deep --sign - ${ADVSS_BUNDLE_DIR}") + install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")") + endfunction() + + function(install_advss_lib_helper target where) + install( + TARGETS ${target} + RUNTIME DESTINATION "${where}" COMPONENT advss_plugins + LIBRARY DESTINATION "${where}" COMPONENT advss_plugins + FRAMEWORK DESTINATION "${where}" COMPONENT advss_plugins) + resign_advss(${target}) + endfunction() + + function(install_advss_lib target) + install_advss_lib_helper(${target} "${ADVSS_BUNDLE_MODULE_DIR}") + set(_COMMAND + "${CMAKE_INSTALL_NAME_TOOL} \\ + -change @rpath/advanced-scene-switcher-lib.so @loader_path/advanced-scene-switcher-lib.so \\ + \\\"${ADVSS_BUNDLE_MODULE_DIR}/advanced-scene-switcher\\\"") + install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")" + COMPONENT obs_plugins) + endfunction() + + function(install_advss_plugin target) + install_advss_lib_helper(${target} "${ADVSS_BUNDLE_PLUGIN_DIR}") + endfunction() + + function(install_advss_plugin_dependency_target target dep) + install( + IMPORTED_RUNTIME_ARTIFACTS + ${dep} + RUNTIME + DESTINATION + "${ADVSS_BUNDLE_PLUGIN_DIR}" + COMPONENT + ${dep}_Runtime + LIBRARY + DESTINATION + "${ADVSS_BUNDLE_PLUGIN_DIR}" + COMPONENT + ${dep}_Runtime + NAMELINK_COMPONENT + ${dep}_Development) + resign_advss(${target}) + endfunction() + + function(install_advss_plugin_dependency_file ${target} dep) + target_sources(advanced-scene-switcher PRIVATE ${dep}) + set_source_files_properties(${dep} PROPERTIES MACOSX_PACKAGE_LOCATION + ${ADVSS_BUNDLE_PLUGIN_DIR}) + resign_advss(${target}) + endfunction() + + # --- End of section --- +else() + # --- Windows / Linux section --- + function(plugin_install_helper what where where_deb) + install( + TARGETS ${what} + RUNTIME DESTINATION "${where}" COMPONENT ${what}_Runtime + LIBRARY DESTINATION "${where}" + COMPONENT ${what}_Runtime + NAMELINK_COMPONENT ${what}_Development) + install( + FILES $ + DESTINATION $/${where} + COMPONENT ${what}_rundir + EXCLUDE_FROM_ALL) + + if(OS_WINDOWS) + install( + FILES $ + CONFIGURATIONS "RelWithDebInfo" "Debug" + DESTINATION ${where} + COMPONENT ${what}_Runtime + OPTIONAL) + install( + FILES $ + CONFIGURATIONS "RelWithDebInfo" "Debug" + DESTINATION $/${where} + COMPONENT ${what}_rundir + OPTIONAL EXCLUDE_FROM_ALL) + endif() + + add_custom_command( + TARGET ${what} + POST_BUILD + COMMAND + "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_OUTPUT_DIR} + -DCMAKE_INSTALL_COMPONENT=${what}_rundir + -DCMAKE_INSTALL_CONFIG_NAME=$ -P + ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake + COMMENT "Installing ${what} to plugin rundir ${OBS_OUTPUT_DIR}/${where}\n" + VERBATIM) + + if(OS_POSIX AND DEB_INSTALL) + if(NOT LIB_OUT_DIR) + set(LIB_OUT_DIR "/lib/obs-plugins") + endif() + install( + TARGETS ${what} + LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR}/${where_deb}) + endif() + endfunction() + + function(install_advss_lib target) + plugin_install_helper("${target}" "${OBS_PLUGIN_DESTINATION}" "") + endfunction() + + function(install_advss_plugin target) + plugin_install_helper( + "${target}" "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + "${_PLUGIN_FOLDER}") + message(STATUS "ADVSS: ENABLED PLUGIN ${target}") + endfunction() + + function(install_advss_plugin_dependency_target target dep) + install( + IMPORTED_RUNTIME_ARTIFACTS + ${dep} + RUNTIME + DESTINATION + "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT + ${dep}_Runtime + LIBRARY + DESTINATION + "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT + ${dep}_Runtime + NAMELINK_COMPONENT + ${dep}_Development) + + install( + IMPORTED_RUNTIME_ARTIFACTS + ${dep} + RUNTIME + DESTINATION + "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT + obs_${dep} + EXCLUDE_FROM_ALL + LIBRARY + DESTINATION + "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT + obs_${dep} + EXCLUDE_FROM_ALL) + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND + "${CMAKE_COMMAND}" --install .. --config $ --prefix + ${OBS_OUTPUT_DIR}/$ --component obs_${dep} > + "$,nul,/dev/null>" + COMMENT "Installing ${dep} to OBS rundir\n" + VERBATIM) + endfunction() + + function(install_advss_plugin_dependency_file target dep) + get_filename_component(_FILENAME ${dep} NAME) + string(REGEX REPLACE "\\.[^.]*$" "" _FILENAMENOEXT ${_FILENAME}) + set(_DEP_NAME "${target}-${_FILENAMENOEXT}") + + install( + FILES "${dep}" + DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT ${_DEP_NAME}_Runtime + DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT ${_DEP_NAME}_Runtime + NAMELINK_COMPONENT ${_DEP_NAME}_Development) + + install( + FILES "${dep}" + DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT obs_${_DEP_NAME} + EXCLUDE_FROM_ALL + DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" + COMPONENT obs_${_DEP_NAME} + EXCLUDE_FROM_ALL) + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND + "${CMAKE_COMMAND}" --install .. --config $ --prefix + ${OBS_OUTPUT_DIR}/$ --component obs_${_DEP_NAME} > + "$,nul,/dev/null>" + COMMENT "Installing ${_DEP_NAME} to OBS rundir\n" + VERBATIM) + endfunction() +endif() + +# --- End of section --- + +function(setup_advss_plugin target) + if(BUILD_OUT_OF_TREE) + target_link_libraries(${target} PUBLIC OBS::libobs OBS::obs-frontend-api) + else() + target_link_libraries(${target} PUBLIC OBS::libobs OBS::frontend-api) + endif() + + find_qt(COMPONENTS Widgets Core) + target_link_libraries(${target} PRIVATE Qt::Core Qt::Widgets) + + set_target_properties( + ${target} + PROPERTIES AUTOMOC ON + AUTOUIC ON + AUTORCC ON) + + target_link_libraries(${target} PRIVATE advanced-scene-switcher-lib) + + get_target_property(ADVSS_SOURCE_DIR advanced-scene-switcher-lib SOURCE_DIR) + get_target_property(ADVSS_BINARY_DIR advanced-scene-switcher-lib BINARY_DIR) + + if(OS_MACOS) + set(_INSTALL_RPATH "@loader_path" "@loader_path/..") + set_target_properties(${target} PROPERTIES INSTALL_RPATH + "${_INSTALL_RPATH}") + endif() + + # Set up include directories for headers generated by Qt + target_include_directories( + ${target} + PRIVATE "${ADVSS_BINARY_DIR}/advanced-scene-switcher-lib_autogen/include") + foreach(_CONF Release RelWithDebInfo Debug MinSizeRe) + target_include_directories( + ${target} + PRIVATE + "${ADVSS_BINARY_DIR}/advanced-scene-switcher-lib_autogen/include_${_CONF}" + ) + endforeach() + + # General includes + target_include_directories(${target} + PRIVATE "${ADVSS_SOURCE_DIR}/src/headers") +endfunction() + +function(install_advss_plugin_dependency) + cmake_parse_arguments(PARSED_ARGS "" "TARGET" "DEPENDENCIES" ${ARGN}) + if(NOT PARSED_ARGS_TARGET) + message(FATAL_ERROR "You must provide a target") + endif() + set(_PLUGIN_FOLDER "adv-ss-plugins") + foreach(_DEPENDENCY ${PARSED_ARGS_DEPENDENCIES}) + if(EXISTS ${_DEPENDENCY}) + install_advss_plugin_dependency_file(${PARSED_ARGS_TARGET} ${_DEPENDENCY}) + else() + install_advss_plugin_dependency_target(${PARSED_ARGS_TARGET} + ${_DEPENDENCY}) + endif() + endforeach() +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake index db291a9b..adabb6a2 100644 --- a/cmake/GetGitRevisionDescription.cmake +++ b/cmake/GetGitRevisionDescription.cmake @@ -1,279 +1,269 @@ -# - Returns a version string from Git +# * Returns a version string from Git # -# These functions force a re-configure on each git commit so that you can -# trust the values of the variables in your build system. +# These functions force a re-configure on each git commit so that you can trust +# the values of the variables in your build system. # -# get_git_head_revision( [ ...]) +# get_git_head_revision( [ ...]) # # Returns the refspec and sha hash of the current head revision # -# git_describe( [ ...]) +# git_describe( [ ...]) # -# Returns the results of git describe on the source tree, and adjusting -# the output so that it tests false if an error occurs. +# Returns the results of git describe on the source tree, and adjusting the +# output so that it tests false if an error occurs. # -# git_describe_working_tree( [ ...]) +# git_describe_working_tree( [ ...]) # -# Returns the results of git describe on the working tree (--dirty option), -# and adjusting the output so that it tests false if an error occurs. +# Returns the results of git describe on the working tree (--dirty option), and +# adjusting the output so that it tests false if an error occurs. # -# git_get_exact_tag( [ ...]) +# git_get_exact_tag( [ ...]) # -# Returns the results of git describe --exact-match on the source tree, -# and adjusting the output so that it tests false if there was no exact -# matching tag. +# Returns the results of git describe --exact-match on the source tree, and +# adjusting the output so that it tests false if there was no exact matching +# tag. # -# git_local_changes() +# git_local_changes() # -# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. -# Uses the return code of "git diff-index --quiet HEAD --". -# Does not regard untracked files. +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. Uses +# the return code of "git diff-index --quiet HEAD --". Does not regard untracked +# files. # # Requires CMake 2.6 or newer (uses the 'function' command) # -# Original Author: -# 2009-2020 Ryan Pavlik -# http://academic.cleardefinition.com +# Original Author: 2009-2020 Ryan Pavlik +# http://academic.cleardefinition.com # -# Copyright 2009-2013, Iowa State University. -# Copyright 2013-2020, Ryan Pavlik -# Copyright 2013-2020, Contributors -# SPDX-License-Identifier: BSL-1.0 -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) +# Copyright 2009-2013, Iowa State University. Copyright 2013-2020, Ryan Pavlik +# Copyright 2013-2020, Contributors SPDX-License-Identifier: BSL-1.0 Distributed +# under the Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) if(__get_git_revision_description) - return() + return() endif() set(__get_git_revision_description YES) -# We must run the following at "include" time, not at function call time, -# to find the path to this module rather than the path to a calling list file +# We must run the following at "include" time, not at function call time, to +# find the path to this module rather than the path to a calling list file get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) -# Function _git_find_closest_git_dir finds the next closest .git directory -# that is part of any directory in the path defined by _start_dir. -# The result is returned in the parent scope variable whose name is passed -# as variable _git_dir_var. If no .git directory can be found, the -# function returns an empty string via _git_dir_var. +# Function _git_find_closest_git_dir finds the next closest .git directory that +# is part of any directory in the path defined by _start_dir. The result is +# returned in the parent scope variable whose name is passed as variable +# _git_dir_var. If no .git directory can be found, the function returns an empty +# string via _git_dir_var. # # Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and -# neither foo nor bar contain a file/directory .git. This wil return -# C:/bla/.git +# neither foo nor bar contain a file/directory .git. This wil return C:/bla/.git # function(_git_find_closest_git_dir _start_dir _git_dir_var) - set(cur_dir "${_start_dir}") - set(git_dir "${_start_dir}/.git") - while(NOT EXISTS "${git_dir}") - # .git dir not found, search parent directories - set(git_previous_parent "${cur_dir}") - get_filename_component(cur_dir ${cur_dir} DIRECTORY) - if(cur_dir STREQUAL git_previous_parent) - # We have reached the root directory, we are not in git - set(${_git_dir_var} - "" - PARENT_SCOPE) - return() - endif() - set(git_dir "${cur_dir}/.git") - endwhile() - set(${_git_dir_var} - "${git_dir}" - PARENT_SCOPE) + set(cur_dir "${_start_dir}") + set(git_dir "${_start_dir}/.git") + while(NOT EXISTS "${git_dir}") + # .git dir not found, search parent directories + set(git_previous_parent "${cur_dir}") + get_filename_component(cur_dir ${cur_dir} DIRECTORY) + if(cur_dir STREQUAL git_previous_parent) + # We have reached the root directory, we are not in git + set(${_git_dir_var} + "" + PARENT_SCOPE) + return() + endif() + set(git_dir "${cur_dir}/.git") + endwhile() + set(${_git_dir_var} + "${git_dir}" + PARENT_SCOPE) endfunction() function(get_git_head_revision _refspecvar _hashvar) - _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) + _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) - if(NOT "${GIT_DIR}" STREQUAL "") - file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}" - "${GIT_DIR}") - if("${_relative_to_source_dir}" MATCHES "[.][.]") - # We've gone above the CMake root dir. - set(GIT_DIR "") - endif() + if(NOT "${GIT_DIR}" STREQUAL "") + file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}" + "${GIT_DIR}") + if("${_relative_to_source_dir}" MATCHES "[.][.]") + # We've gone above the CMake root dir. + set(GIT_DIR "") endif() - if("${GIT_DIR}" STREQUAL "") - set(${_refspecvar} - "GITDIR-NOTFOUND" - PARENT_SCOPE) - set(${_hashvar} - "GITDIR-NOTFOUND" - PARENT_SCOPE) - return() - endif() - - # Check if the current source dir is a git submodule or a worktree. - # In both cases .git is a file instead of a directory. - # - if(NOT IS_DIRECTORY ${GIT_DIR}) - # The following git command will return a non empty string that - # points to the super project working tree if the current - # source dir is inside a git submodule. - # Otherwise the command will return an empty string. - # - execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse - --show-superproject-working-tree - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT "${out}" STREQUAL "") - # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule - file(READ ${GIT_DIR} submodule) - string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE - ${submodule}) - string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) - get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) - get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} - ABSOLUTE) - set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") - else() - # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree - file(READ ${GIT_DIR} worktree_ref) - # The .git directory contains a path to the worktree information directory - # inside the parent git repo of the worktree. - # - string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir - ${worktree_ref}) - string(STRIP ${git_worktree_dir} git_worktree_dir) - _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) - set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") - endif() - else() - set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") - endif() - set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") - if(NOT EXISTS "${GIT_DATA}") - file(MAKE_DIRECTORY "${GIT_DATA}") - endif() - - if(NOT EXISTS "${HEAD_SOURCE_FILE}") - return() - endif() - set(HEAD_FILE "${GIT_DATA}/HEAD") - configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) - - configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" - "${GIT_DATA}/grabRef.cmake" @ONLY) - include("${GIT_DATA}/grabRef.cmake") - + endif() + if("${GIT_DIR}" STREQUAL "") set(${_refspecvar} - "${HEAD_REF}" + "GITDIR-NOTFOUND" PARENT_SCOPE) set(${_hashvar} - "${HEAD_HASH}" + "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # Check if the current source dir is a git submodule or a worktree. In both + # cases .git is a file instead of a directory. + # + if(NOT IS_DIRECTORY ${GIT_DIR}) + # The following git command will return a non empty string that points to + # the super project working tree if the current source dir is inside a git + # submodule. Otherwise the command will return an empty string. + # + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse --show-superproject-working-tree + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT "${out}" STREQUAL "") + # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE ${submodule}) + string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} + ABSOLUTE) + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") + else() + # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree + file(READ ${GIT_DIR} worktree_ref) + # The .git directory contains a path to the worktree information directory + # inside the parent git repo of the worktree. + # + string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir + ${worktree_ref}) + string(STRIP ${git_worktree_dir} git_worktree_dir) + _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) + set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") + endif() + else() + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${HEAD_SOURCE_FILE}") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} + "${HEAD_REF}" + PARENT_SCOPE) + set(${_hashvar} + "${HEAD_HASH}" + PARENT_SCOPE) endfunction() function(git_describe _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - get_git_head_revision(refspec hash) - if(NOT GIT_FOUND) - set(${_var} - "GIT-NOTFOUND" - PARENT_SCOPE) - return() - endif() - if(NOT hash) - set(${_var} - "HEAD-HASH-NOTFOUND" - PARENT_SCOPE) - return() - endif() - - # TODO sanitize - #if((${ARGN}" MATCHES "&&") OR - # (ARGN MATCHES "||") OR - # (ARGN MATCHES "\\;")) - # message("Please report the following error to the project!") - # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") - #endif() - - #message(STATUS "Arguments to execute_process: ${ARGN}") - - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") - endif() - + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) set(${_var} - "${out}" + "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + # TODO sanitize if((${ARGN}" MATCHES "&&") OR (ARGN MATCHES "||") OR (ARGN + # MATCHES "\\;")) message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with + # git_describe! Passed arguments ${ARGN}") endif() + + # message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} + "${out}" + PARENT_SCOPE) endfunction() function(git_describe_working_tree _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - if(NOT GIT_FOUND) - set(${_var} - "GIT-NOTFOUND" - PARENT_SCOPE) - return() - endif() - - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") - endif() - + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + if(NOT GIT_FOUND) set(${_var} - "${out}" + "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} + "${out}" + PARENT_SCOPE) endfunction() function(git_get_exact_tag _var) - git_describe(out --exact-match ${ARGN}) - set(${_var} - "${out}" - PARENT_SCOPE) + git_describe(out --exact-match ${ARGN}) + set(${_var} + "${out}" + PARENT_SCOPE) endfunction() function(git_local_changes _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - get_git_head_revision(refspec hash) - if(NOT GIT_FOUND) - set(${_var} - "GIT-NOTFOUND" - PARENT_SCOPE) - return() - endif() - if(NOT hash) - set(${_var} - "HEAD-HASH-NOTFOUND" - PARENT_SCOPE) - return() - endif() + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) + return() + endif() - execute_process( - COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD -- - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(res EQUAL 0) - set(${_var} - "CLEAN" - PARENT_SCOPE) - else() - set(${_var} - "DIRTY" - PARENT_SCOPE) - endif() + execute_process( + COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD -- + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(res EQUAL 0) + set(${_var} + "CLEAN" + PARENT_SCOPE) + else() + set(${_var} + "DIRTY" + PARENT_SCOPE) + endif() endfunction() diff --git a/cmake/ObsPluginHelpers.cmake b/cmake/ObsPluginHelpers.cmake new file mode 100644 index 00000000..2548a45b --- /dev/null +++ b/cmake/ObsPluginHelpers.cmake @@ -0,0 +1,487 @@ +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() + +set(OBS_STANDALONE_PLUGIN_DIR ${CMAKE_SOURCE_DIR}/release) +set(INCLUDED_LIBOBS_CMAKE_MODULES ON) + +include(GNUInstallDirs) +if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(OS_MACOS ON) + set(OS_POSIX ON) +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD") + set(OS_POSIX ON) + string(TOUPPER "${CMAKE_SYSTEM_NAME}" _SYSTEM_NAME_U) + set(OS_${_SYSTEM_NAME_U} ON) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + set(OS_WINDOWS ON) + set(OS_POSIX OFF) +endif() + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND (OS_WINDOWS OR OS_MACOS)) + set(CMAKE_INSTALL_PREFIX + ${OBS_STANDALONE_PLUGIN_DIR} + CACHE STRING "Directory to install OBS plugin after building" FORCE) +endif() + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE + "RelWithDebInfo" + CACHE STRING + "OBS build type [Release, RelWithDebInfo, Debug, MinSizeRel]" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Release RelWithDebInfo + Debug MinSizeRel) +endif() + +if(NOT QT_VERSION) + set(QT_VERSION + AUTO + CACHE STRING "OBS Qt version [AUTO, 5, 6]" FORCE) + set_property(CACHE QT_VERSION PROPERTY STRINGS AUTO 5 6) +endif() + +macro(find_qt) + set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX) + cmake_parse_arguments(FIND_QT "" "${oneValueArgs}" "${multiValueArgs}" + ${ARGN}) + set(QT_NO_CREATE_VERSIONLESS_TARGETS ON) + find_package( + Qt5 + COMPONENTS Core + QUIET) + find_package( + Qt6 + COMPONENTS Core + QUIET) + + if(NOT _QT_VERSION AND QT_VERSION STREQUAL AUTO) + if(TARGET Qt6::Core) + set(_QT_VERSION + 6 + CACHE INTERNAL "") + elseif(TARGET Qt5::Core) + set(_QT_VERSION + 5 + CACHE INTERNAL "") + endif() + message(STATUS "Qt version: ${_QT_VERSION}") + elseif(NOT _QT_VERSION) + if(TARGET Qt${QT_VERSION}::Core) + set(_QT_VERSION + ${QT_VERSION} + CACHE INTERNAL "") + else() + if(QT_VERSION EQUAL 6) + set(FALLBACK_QT_VERSION 5) + else() + set(FALLBACK_QT_VERSION 6) + endif() + message( + WARNING + "Qt${QT_VERSION} was not found, falling back to Qt${FALLBACK_QT_VERSION}" + ) + + if(TARGET Qt${FALLBACK_QT_VERSION}::Core) + set(_QT_VERSION + ${FALLBACK_QT_VERSION} + CACHE INTERNAL "") + endif() + endif() + message(STATUS "Qt version: ${_QT_VERSION}") + endif() + + set(QT_NO_CREATE_VERSIONLESS_TARGETS OFF) + + if(NOT _QT_VERSION) + message(FATAL_ERROR "Neither Qt5 or Qt6 were found") + endif() + + if(OS_WINDOWS) + find_package( + Qt${_QT_VERSION} + COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_WIN} + REQUIRED) + elseif(OS_MACOS) + find_package( + Qt${_QT_VERSION} + COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_MAC} + REQUIRED) + else() + find_package( + Qt${_QT_VERSION} + COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_LINUX} + REQUIRED) + endif() + + list(APPEND FIND_QT_COMPONENTS "Core") + + if("Gui" IN_LIST FIND_QT_COMPONENTS_LINUX) + list(APPEND FIND_QT_COMPONENTS_LINUX "GuiPrivate") + endif() + + foreach(_COMPONENT IN LISTS FIND_QT_COMPONENTS FIND_QT_COMPONENTS_WIN + FIND_QT_COMPONENTS_MAC FIND_QT_COMPONENTS_LINUX) + if(NOT TARGET Qt::${_COMPONENT} AND TARGET Qt${_QT_VERSION}::${_COMPONENT}) + + add_library(Qt::${_COMPONENT} INTERFACE IMPORTED) + set_target_properties( + Qt::${_COMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES + "Qt${_QT_VERSION}::${_COMPONENT}") + endif() + endforeach() +endmacro() + +file(RELATIVE_PATH RELATIVE_INSTALL_PATH ${CMAKE_SOURCE_DIR} + ${CMAKE_INSTALL_PREFIX}) +file(RELATIVE_PATH RELATIVE_BUILD_PATH ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) + +# Set up OS-specific environment and helper functions +if(OS_POSIX) + find_program(CCACHE_PROGRAM "ccache") + set(CCACHE_SUPPORT + ON + CACHE BOOL "Enable ccache support") + mark_as_advanced(CCACHE_PROGRAM) + if(CCACHE_PROGRAM AND CCACHE_SUPPORT) + set(CMAKE_CXX_COMPILER_LAUNCHER + ${CCACHE_PROGRAM} + CACHE INTERNAL "") + set(CMAKE_C_COMPILER_LAUNCHER + ${CCACHE_PROGRAM} + CACHE INTERNAL "") + set(CMAKE_OBJC_COMPILER_LAUNCHER + ${CCACHE_PROGRAM} + CACHE INTERNAL "") + set(CMAKE_OBJCXX_COMPILER_LAUNCHER + ${CCACHE_PROGRAM} + CACHE INTERNAL "") + set(CMAKE_CUDA_COMPILER_LAUNCHER + ${CCACHE_PROGRAM} + CACHE INTERNAL "") # CMake 3.9+ + endif() +endif() + +if(OS_MACOS) + set(CMAKE_OSX_ARCHITECTURES + "x86_64" + CACHE STRING + "OBS build architecture for macOS - x86_64 required at least") + set_property(CACHE CMAKE_OSX_ARCHITECTURES PROPERTY STRINGS x86_64 arm64 + "x86_64;arm64") + + set(CMAKE_OSX_DEPLOYMENT_TARGET + "10.15" + CACHE STRING "OBS deployment target for macOS - 10.15+ required") + set_property(CACHE CMAKE_OSX_DEPLOYMENT_TARGET PROPERTY STRINGS 10.15 11.0 + 12.0 13.0) + + set(OBS_BUNDLE_CODESIGN_IDENTITY + "-" + CACHE STRING "OBS code signing identity for macOS") + set(OBS_CODESIGN_ENTITLEMENTS + ${CMAKE_SOURCE_DIR}/cmake/bundle/macos/entitlements.plist + CACHE INTERNAL "Path to codesign entitlements plist") + set(OBS_CODESIGN_LINKER + ON + CACHE BOOL "Enable linker code-signing on macOS (macOS 11+ required)") + + # Xcode configuration + if(XCODE) + # Tell Xcode to pretend the linker signed binaries so that editing with + # install_name_tool preserves ad-hoc signatures. This option is supported by + # codesign on macOS 11 or higher. See CMake Issue 21854: + # https://gitlab.kitware.com/cmake/cmake/-/issues/21854 + + set(CMAKE_XCODE_GENERATE_SCHEME ON) + if(OBS_CODESIGN_LINKER) + set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "-o linker-signed") + endif() + endif() + + # Set default options for bundling on macOS + set(CMAKE_MACOSX_RPATH ON) + set(CMAKE_SKIP_BUILD_RPATH OFF) + set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF) + set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks/") + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF) + + function(setup_plugin_target target) + if(NOT DEFINED MACOSX_PLUGIN_GUI_IDENTIFIER) + message( + FATAL_ERROR + "No 'MACOSX_PLUGIN_GUI_IDENTIFIER' set, but is required to build plugin bundles on macOS - example: 'com.yourname.pluginname'" + ) + endif() + + if(NOT DEFINED MACOSX_PLUGIN_BUNDLE_VERSION) + message( + FATAL_ERROR + "No 'MACOSX_PLUGIN_BUNDLE_VERSION' set, but is required to build plugin bundles on macOS - example: '25'" + ) + endif() + + if(NOT DEFINED MACOSX_PLUGIN_SHORT_VERSION_STRING) + message( + FATAL_ERROR + "No 'MACOSX_PLUGIN_SHORT_VERSION_STRING' set, but is required to build plugin bundles on macOS - example: '1.0.2'" + ) + endif() + + set(MACOSX_PLUGIN_BUNDLE_NAME + "${target}" + PARENT_SCOPE) + set(MACOSX_PLUGIN_BUNDLE_VERSION + "${MACOSX_BUNDLE_BUNDLE_VERSION}" + PARENT_SCOPE) + set(MACOSX_PLUGIN_SHORT_VERSION_STRING + "${MACOSX_BUNDLE_SHORT_VERSION_STRING}" + PARENT_SCOPE) + set(MACOSX_PLUGIN_EXECUTABLE_NAME + "${target}" + PARENT_SCOPE) + set(MACOSX_PLUGIN_BUNDLE_TYPE + "BNDL" + PARENT_SCOPE) + + install( + TARGETS ${target} + LIBRARY DESTINATION "." + COMPONENT obs_plugins + NAMELINK_COMPONENT ${target}_Development) + + if(${QT_VERSION} EQUAL 5) + set(_QT_FW_VERSION "${QT_VERSION}") + else() + set(_QT_FW_VERSION "A") + endif() + + set(_COMMAND + "${CMAKE_INSTALL_NAME_TOOL} \\ + -change ${CMAKE_PREFIX_PATH}/lib/QtWidgets.framework/Versions/${QT_VERSION}/QtWidgets @rpath/QtWidgets.framework/Versions/${_QT_FW_VERSION}/QtWidgets \\ + -change ${CMAKE_PREFIX_PATH}/lib/QtCore.framework/Versions/${QT_VERSION}/QtCore @rpath/QtCore.framework/Versions/${_QT_FW_VERSION}/QtCore \\ + -change ${CMAKE_PREFIX_PATH}/lib/QtGui.framework/Versions/${QT_VERSION}/QtGui @rpath/QtGui.framework/Versions/${_QT_FW_VERSION}/QtGui \\ + \\\"\${CMAKE_INSTALL_PREFIX}/${target}.plugin/Contents/MacOS/${target}\\\"" + ) + install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")" + COMPONENT obs_plugins) + unset(_QT_FW_VERSION) + + if(NOT XCODE) + set(_COMMAND + "/usr/bin/codesign --force \\ + --sign \\\"${OBS_BUNDLE_CODESIGN_IDENTITY}\\\" \\ + --options runtime \\ + --entitlements \\\"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/bundle/macOS/entitlements.plist\\\" \\ + \\\"\${CMAKE_INSTALL_PREFIX}/${target}.plugin\\\"") + install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")" + COMPONENT obs_plugins) + endif() + + set_target_properties( + ${target} + PROPERTIES + BUNDLE ON + BUNDLE_EXTENSION "plugin" + OUTPUT_NAME ${target} + MACOSX_BUNDLE_INFO_PLIST + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/bundle/macOS/Plugin-Info.plist.in" + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER + "${MACOSX_PLUGIN_GUI_IDENTIFIER}" + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${OBS_BUNDLE_CODESIGN_IDENTITY}" + XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/bundle/macOS/entitlements.plist") + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND + /bin/sh -c + "codesign --force --sign \"-\" $<$:--options linker-signed >\"$\"" + COMMENT "Codesigning ${target}" + VERBATIM) + + install_bundle_resources(${target}) + endfunction() + + function(install_bundle_resources target) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/data) + file(GLOB_RECURSE _DATA_FILES "${CMAKE_CURRENT_SOURCE_DIR}/data/*") + foreach(_DATA_FILE IN LISTS _DATA_FILES) + file(RELATIVE_PATH _RELATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/data/ + ${_DATA_FILE}) + get_filename_component(_RELATIVE_PATH ${_RELATIVE_PATH} PATH) + target_sources(${target} PRIVATE ${_DATA_FILE}) + set_source_files_properties( + ${_DATA_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION + Resources/${_RELATIVE_PATH}) + string(REPLACE "\\" "\\\\" _GROUP_NAME ${_RELATIVE_PATH}) + source_group("Resources\\${_GROUP_NAME}" FILES ${_DATA_FILE}) + endforeach() + endif() + endfunction() +else() + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_ARCH_SUFFIX 64) + else() + set(_ARCH_SUFFIX 32) + endif() + set(OBS_OUTPUT_DIR ${CMAKE_BINARY_DIR}/rundir) + + if(OS_POSIX) + option(LINUX_PORTABLE "Build portable version (Linux)" ON) + if(NOT LINUX_PORTABLE) + set(OBS_LIBRARY_DESTINATION ${CMAKE_INSTALL_LIBDIR}) + set(OBS_PLUGIN_DESTINATION ${OBS_LIBRARY_DESTINATION}/obs-plugins) + set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) + set(OBS_DATA_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/obs) + else() + set(OBS_LIBRARY_DESTINATION bin/${_ARCH_SUFFIX}bit) + set(OBS_PLUGIN_DESTINATION obs-plugins/${_ARCH_SUFFIX}bit) + set(CMAKE_INSTALL_RPATH + "$ORIGIN/" "${CMAKE_INSTALL_PREFIX}/${OBS_LIBRARY_DESTINATION}") + set(OBS_DATA_DESTINATION "data") + endif() + + if(OS_LINUX) + set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${LINUX_MAINTAINER_EMAIL}") + set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}") + set(CPACK_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-linux-x86_64") + + set(CPACK_GENERATOR "DEB") + set(CPACK_DEBIAN_PACKAGE_DEPENDS + "obs-studio (>= 27.0.0), libqt5core5a (>= 5.9.0~beta), libqt5gui5 (>= 5.3.0), libqt5widgets5 (>= 5.7.0)" + ) + + set(CPACK_OUTPUT_FILE_PREFIX ${CMAKE_SOURCE_DIR}/release) + + if(NOT LINUX_PORTABLE) + set(CPACK_SET_DESTDIR ON) + endif() + include(CPack) + endif() + else() + set(OBS_LIBRARY_DESTINATION "bin/${_ARCH_SUFFIX}bit") + set(OBS_LIBRARY32_DESTINATION "bin/32bit") + set(OBS_LIBRARY64_DESTINATION "bin/64bit") + set(OBS_PLUGIN_DESTINATION "obs-plugins/${_ARCH_SUFFIX}bit") + set(OBS_PLUGIN32_DESTINATION "obs-plugins/32bit") + set(OBS_PLUGIN64_DESTINATION "obs-plugins/64bit") + + set(OBS_DATA_DESTINATION "data") + endif() + + function(setup_plugin_target target) + set_target_properties(${target} PROPERTIES PREFIX "") + + install( + TARGETS ${target} + RUNTIME DESTINATION "${OBS_PLUGIN_DESTINATION}" + COMPONENT ${target}_Runtime + LIBRARY DESTINATION "${OBS_PLUGIN_DESTINATION}" + COMPONENT ${target}_Runtime + NAMELINK_COMPONENT ${target}_Development) + + install( + FILES $ + DESTINATION $/${OBS_PLUGIN_DESTINATION} + COMPONENT obs_rundir + EXCLUDE_FROM_ALL) + + if(OS_WINDOWS) + install( + FILES $ + CONFIGURATIONS "RelWithDebInfo" "Debug" + DESTINATION ${OBS_PLUGIN_DESTINATION} + COMPONENT ${target}_Runtime + OPTIONAL) + + install( + FILES $ + CONFIGURATIONS "RelWithDebInfo" "Debug" + DESTINATION $/${OBS_PLUGIN_DESTINATION} + COMPONENT obs_rundir + OPTIONAL EXCLUDE_FROM_ALL) + endif() + + if(MSVC) + target_link_options( + ${target} + PRIVATE + "LINKER:/OPT:REF" + "$<$>:LINKER\:/SAFESEH\:NO>" + "$<$:LINKER\:/INCREMENTAL:NO>" + "$<$:LINKER\:/INCREMENTAL:NO>") + endif() + + setup_target_resources(${target} obs-plugins/${target}) + + if(OS_WINDOWS AND DEFINED OBS_BUILD_DIR) + setup_target_for_testing(${target} obs-plugins/${target}) + endif() + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND + "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_OUTPUT_DIR} + -DCMAKE_INSTALL_COMPONENT=obs_rundir + -DCMAKE_INSTALL_CONFIG_NAME=$ -P + ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake + COMMENT "Installing to plugin rundir" + VERBATIM) + endfunction() + + function(setup_target_resources target destination) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/data) + install( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/ + DESTINATION ${OBS_DATA_DESTINATION}/${destination} + USE_SOURCE_PERMISSIONS + COMPONENT obs_plugins) + + install( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data + DESTINATION $/${OBS_DATA_DESTINATION}/${destination} + USE_SOURCE_PERMISSIONS + COMPONENT obs_rundir + EXCLUDE_FROM_ALL) + endif() + endfunction() + + if(OS_WINDOWS) + function(setup_target_for_testing target destination) + install( + FILES $ + DESTINATION $/${OBS_PLUGIN_DESTINATION} + COMPONENT obs_testing + EXCLUDE_FROM_ALL) + + install( + FILES $ + CONFIGURATIONS "RelWithDebInfo" "Debug" + DESTINATION $/${OBS_PLUGIN_DESTINATION} + COMPONENT obs_testing + OPTIONAL EXCLUDE_FROM_ALL) + + install( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/ + DESTINATION $/${OBS_DATA_DESTINATION}/${destination} + USE_SOURCE_PERMISSIONS + COMPONENT obs_testing + EXCLUDE_FROM_ALL) + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND + "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_BUILD_DIR}/rundir + -DCMAKE_INSTALL_COMPONENT=obs_testing + -DCMAKE_INSTALL_CONFIG_NAME=$ -P + ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake + COMMENT "Installing to OBS test directory" + VERBATIM) + endfunction() + endif() +endif() diff --git a/cmake/version.cpp.in b/cmake/version.cpp.in index a281c4cc..fdd5224e 100644 --- a/cmake/version.cpp.in +++ b/cmake/version.cpp.in @@ -1,4 +1,4 @@ -#include "src/headers/version.h" +#include "headers/version.h" #define GIT_SHA1 "@GIT_SHA1@" #define GIT_TAG "@GIT_TAG@" const char g_GIT_SHA1[] = GIT_SHA1; diff --git a/src/external-macro-modules/CMakeLists.txt b/src/external-macro-modules/CMakeLists.txt index e37c2780..f8abc3a8 100644 --- a/src/external-macro-modules/CMakeLists.txt +++ b/src/external-macro-modules/CMakeLists.txt @@ -1,59 +1,21 @@ -# Helper function to install plugins to correct location -function(install_advss_plugin target) - set(plugin_folder "adv-ss-plugins") - if(APPLE) - set(_bit_suffix "") - elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_bit_suffix "64bit/") - else() - set(_bit_suffix "32bit/") - endif() - - set_target_properties(${target} PROPERTIES PREFIX "") - - install( - TARGETS ${target} - LIBRARY DESTINATION "${OBS_PLUGIN_DESTINATION}/${plugin_folder}" - RUNTIME DESTINATION "${OBS_PLUGIN_DESTINATION}/${plugin_folder}") - add_custom_command( - TARGET ${target} - POST_BUILD - COMMAND - "${CMAKE_COMMAND}" -E copy "$" - "${OBS_OUTPUT_DIR}/$/obs-plugins/${_bit_suffix}/${plugin_folder}/$" - VERBATIM) - - if(DEFINED ENV{obsInstallerTempDir}) - add_custom_command( - TARGET ${target} - POST_BUILD - COMMAND - "${CMAKE_COMMAND}" -E copy "$" - "$ENV{obsInstallerTempDir}/${OBS_PLUGIN_DESTINATION}/${plugin_folder}/$" - VERBATIM) - endif() - - if(MSVC) - obs_debug_copy_helper( - ${target} - "${OBS_OUTPUT_DIR}/$/obs-plugins/${_bit_suffix}/${plugin_folder}" - ) - - if(DEFINED ENV{obsInstallerTempDir}) - obs_debug_copy_helper( - ${target} - "$ENV{obsInstallerTempDir}/${OBS_PLUGIN_DESTINATION}/${plugin_folder}") - endif() - - install( - DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pdbs/" - DESTINATION "${OBS_PLUGIN_DESTINATION}/${plugin_folder}" - CONFIGURATIONS Debug RelWithDebInfo) - endif() -endfunction() - # Add macro conditions or actions which have dependencies to external libraries -# or other components which might potentially not be fulfilled by the user and -# thus cause issues. +# or other components which might potentially not be fulfilled. + +#[[ +To add a new plugin with external dependencies append a ... + +add_subdirectory() + +... call to the end of this file. + +In the plugins cmake file call the helper functions ... + +install_advss_plugin() +... and ... +install_advss_plugin_dependency(...) + +... to install the plugin and its dependencies. +#]] + add_subdirectory(opencv) add_subdirectory(openvr) diff --git a/src/external-macro-modules/opencv/CMakeLists.txt b/src/external-macro-modules/opencv/CMakeLists.txt index c7ad8110..88e717cd 100644 --- a/src/external-macro-modules/opencv/CMakeLists.txt +++ b/src/external-macro-modules/opencv/CMakeLists.txt @@ -1,63 +1,47 @@ cmake_minimum_required(VERSION 3.14) project(advanced-scene-switcher-opencv) -add_definitions(-DADVSS_MODULE) +# --- Check OpenCV requirements --- find_package(OpenCV) -if(OpenCV_FOUND) - include_directories("${OpenCV_INCLUDE_DIRS}") -else() - set(OpenCV_LIBRARIES "") +if(NOT OpenCV_FOUND) message( WARNING - "OpenCV not found! Functionality relying on OpenCV will be disabled!\nOpenCV sources are available under: ${CMAKE_CURRENT_SOURCE_DIR}/deps/opencv" + "OpenCV not found! Video condition will be disabled!\nOpenCV sources are available under: ${CMAKE_CURRENT_SOURCE_DIR}/../../../deps/opencv" ) return() endif() -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../headers") -set(module_SOURCES - area-selection.cpp - area-selection.hpp - macro-condition-video.cpp - macro-condition-video.hpp - opencv-helpers.cpp - opencv-helpers.hpp - preview-dialog.cpp - preview-dialog.hpp - threshold-slider.cpp - threshold-slider.hpp - video-selection.cpp - video-selection.hpp) -add_library(advanced-scene-switcher-opencv MODULE ${module_SOURCES}) +# --- End of section --- -if(BUILD_OUT_OF_TREE) - target_link_libraries( - advanced-scene-switcher-opencv - advanced-scene-switcher - ${LIBOBS_LIB} - ${LIBOBS_FRONTEND_API_LIB} - ${OpenCV_LIBRARIES} - Qt5::Core - Qt5::Widgets) +add_library(advanced-scene-switcher-opencv MODULE) +target_sources( + ${PROJECT_NAME} + PRIVATE area-selection.cpp + area-selection.hpp + macro-condition-video.cpp + macro-condition-video.hpp + opencv-helpers.cpp + opencv-helpers.hpp + preview-dialog.cpp + preview-dialog.hpp + threshold-slider.cpp + threshold-slider.hpp + video-selection.cpp + video-selection.hpp) - if(UNIX AND NOT APPLE) - if(NOT LIB_OUT_DIR) - set(LIB_OUT_DIR "/lib/obs-plugins") - endif() - set_target_properties(advanced-scene-switcher-opencv PROPERTIES PREFIX "") - install( - TARGETS advanced-scene-switcher-opencv - LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR}/adv-ss-plugins) - endif() -else() - target_link_libraries( - advanced-scene-switcher-opencv - advanced-scene-switcher - obs-frontend-api - ${OpenCV_LIBRARIES} - Qt5::Core - Qt5::Widgets - libobs) - install_advss_plugin(advanced-scene-switcher-opencv) +setup_advss_plugin(${PROJECT_NAME}) +set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") + +# --- OpenCV build settings --- + +target_include_directories(${PROJECT_NAME} PRIVATE "${OpenCV_INCLUDE_DIRS}") +target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenCV_LIBRARIES}) + +# --- End of section --- + +install_advss_plugin(${PROJECT_NAME}) +if(NOT OS_LINUX) + install_advss_plugin_dependency(TARGET ${PROJECT_NAME} DEPENDENCIES + ${OpenCV_LIBS}) endif() diff --git a/src/external-macro-modules/openvr/CMakeLists.txt b/src/external-macro-modules/openvr/CMakeLists.txt index 5d87a80a..efcc0bb0 100644 --- a/src/external-macro-modules/openvr/CMakeLists.txt +++ b/src/external-macro-modules/openvr/CMakeLists.txt @@ -1,15 +1,25 @@ cmake_minimum_required(VERSION 3.14) project(advanced-scene-switcher-openvr) +# --- Check OpenCV requirements --- + if(NOT WIN32) message( WARNING "OpenVR condition is only supported on Windows builds for now.") return() endif(NOT WIN32) -add_definitions(-DADVSS_MODULE) +# --- End of section --- + +add_library(${PROJECT_NAME} MODULE) +target_sources(${PROJECT_NAME} PRIVATE macro-condition-openvr.cpp + macro-condition-openvr.hpp) + +setup_advss_plugin(${PROJECT_NAME}) +set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") + +# --- OpenVR build settings --- -# openvr if(NOT OpenVR_DIR) set(OpenVR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../deps/openvr) endif() @@ -44,7 +54,7 @@ if(EXISTS ${OpenVR_DIR}) endif() if(OpenVR_FOUND) - include_directories("${OpenVR_INCLUDE_DIRS}") + target_include_directories(${PROJECT_NAME} PRIVATE "${OpenVR_INCLUDE_DIRS}") else() set(OpenVR_LIBRARIES "") message( @@ -54,37 +64,10 @@ else() ()) endif() -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../headers") -set(module_SOURCES macro-condition-openvr.cpp macro-condition-openvr.hpp) -add_library(advanced-scene-switcher-openvr MODULE ${module_SOURCES}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenVR_LIBRARIES}) -if(BUILD_OUT_OF_TREE) - target_link_libraries( - advanced-scene-switcher-openvr - advanced-scene-switcher - ${LIBOBS_LIB} - ${LIBOBS_FRONTEND_API_LIB} - ${OpenVR_LIBRARIES} - Qt5::Core - Qt5::Widgets) +# --- End of section --- - if(UNIX AND NOT APPLE) - if(NOT LIB_OUT_DIR) - set(LIB_OUT_DIR "/lib/obs-plugins") - endif() - set_target_properties(advanced-scene-switcher-openvr PROPERTIES PREFIX "") - install( - TARGETS advanced-scene-switcher-openvr - LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR}/adv-ss-plugins) - endif() -else() - target_link_libraries( - advanced-scene-switcher-openvr - advanced-scene-switcher - obs-frontend-api - ${OpenVR_LIBRARIES} - Qt5::Core - Qt5::Widgets - libobs) - install_advss_plugin(advanced-scene-switcher-openvr) -endif() +install_advss_plugin(${PROJECT_NAME}) +install_advss_plugin_dependency(TARGET ${PROJECT_NAME} DEPENDENCIES + ${OpenVR_BINARIES}) diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 0a499c5b..0407c98f 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -1,15 +1,10 @@ #pragma once -#ifdef BUILD_OUT_OF_TREE -#include "../../forms/ui_advanced-scene-switcher.h" -#elif defined ADVSS_MODULE -#include "../../../ui_advanced-scene-switcher.h" -#else -#include "ui_advanced-scene-switcher.h" -#endif #include "macro-segment-list.hpp" #include "switcher-data-structs.hpp" #include "platform-funcs.hpp" +#include + #define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__) #define vblog(level, msg, ...) \ if (switcher->verbose) { \