From 8e7955984e5d2ce30d8289bd389291d84554c1bb Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Sat, 3 Feb 2024 21:44:51 +0100 Subject: [PATCH] Update cmake Based on obs-plugintemplate@68e9fcd --- .cmake-format.json | 40 ++ CMakeLists.txt | 133 ++--- CMakePresets.json | 190 +++++++ cmake/ObsPluginHelpers.cmake | 492 ------------------ cmake/bundle/macos/Plugin-Info.plist.in | 26 - cmake/bundle/macos/entitlements.plist | 17 - .../advss_helpers.cmake} | 72 +-- cmake/common/bootstrap.cmake | 83 +++ cmake/common/buildnumber.cmake | 21 + cmake/common/buildspec_common.cmake | 226 ++++++++ cmake/common/ccache.cmake | 22 + cmake/common/compiler_common.cmake | 87 ++++ .../get_git_revision_description.cmake} | 2 +- .../get_git_revision_description.cmake.in} | 2 +- cmake/common/helpers_common.cmake | 149 ++++++ cmake/common/osconfig.cmake | 23 + cmake/{ => common}/version.cpp.in | 0 cmake/linux/compilerconfig.cmake | 91 ++++ cmake/linux/defaults.cmake | 93 ++++ cmake/linux/helpers.cmake | 80 +++ .../toolchains/aarch64-linux-clang.cmake | 56 ++ .../linux/toolchains/aarch64-linux-gcc.cmake | 20 + .../linux/toolchains/x86_64-linux-clang.cmake | 56 ++ cmake/linux/toolchains/x86_64-linux-gcc.cmake | 20 + cmake/macos/buildspec.cmake | 34 ++ cmake/macos/compilerconfig.cmake | 65 +++ cmake/macos/defaults.cmake | 53 ++ cmake/macos/helpers.cmake | 106 ++++ cmake/macos/resources/ccache-launcher-c.in | 17 + cmake/macos/resources/ccache-launcher-cxx.in | 17 + cmake/macos/resources/create-package.cmake.in | 41 ++ cmake/macos/resources/distribution.in | 33 ++ .../resources}/installer-macos.pkgproj.in | 10 +- cmake/macos/xcode.cmake | 199 +++++++ cmake/windows/buildspec.cmake | 24 + cmake/windows/compilerconfig.cmake | 62 +++ cmake/windows/defaults.cmake | 8 + cmake/windows/helpers.cmake | 149 ++++++ .../resources}/installer-Windows.iss.in | 8 +- cmake/windows/resources/resource.rc.in | 32 ++ plugins/midi/CMakeLists.txt | 14 +- plugins/video/CMakeLists.txt | 3 + tests/CMakeLists.txt | 4 + 43 files changed, 2234 insertions(+), 646 deletions(-) create mode 100644 .cmake-format.json create mode 100644 CMakePresets.json delete mode 100644 cmake/ObsPluginHelpers.cmake delete mode 100644 cmake/bundle/macos/Plugin-Info.plist.in delete mode 100644 cmake/bundle/macos/entitlements.plist rename cmake/{AdvSSHelpers.cmake => common/advss_helpers.cmake} (87%) create mode 100644 cmake/common/bootstrap.cmake create mode 100644 cmake/common/buildnumber.cmake create mode 100644 cmake/common/buildspec_common.cmake create mode 100644 cmake/common/ccache.cmake create mode 100644 cmake/common/compiler_common.cmake rename cmake/{GetGitRevisionDescription.cmake => common/get_git_revision_description.cmake} (99%) rename cmake/{GetGitRevisionDescription.cmake.in => common/get_git_revision_description.cmake.in} (95%) create mode 100644 cmake/common/helpers_common.cmake create mode 100644 cmake/common/osconfig.cmake rename cmake/{ => common}/version.cpp.in (100%) create mode 100644 cmake/linux/compilerconfig.cmake create mode 100644 cmake/linux/defaults.cmake create mode 100644 cmake/linux/helpers.cmake create mode 100644 cmake/linux/toolchains/aarch64-linux-clang.cmake create mode 100644 cmake/linux/toolchains/aarch64-linux-gcc.cmake create mode 100644 cmake/linux/toolchains/x86_64-linux-clang.cmake create mode 100644 cmake/linux/toolchains/x86_64-linux-gcc.cmake create mode 100644 cmake/macos/buildspec.cmake create mode 100644 cmake/macos/compilerconfig.cmake create mode 100644 cmake/macos/defaults.cmake create mode 100644 cmake/macos/helpers.cmake create mode 100644 cmake/macos/resources/ccache-launcher-c.in create mode 100644 cmake/macos/resources/ccache-launcher-cxx.in create mode 100644 cmake/macos/resources/create-package.cmake.in create mode 100644 cmake/macos/resources/distribution.in rename cmake/{bundle/macos => macos/resources}/installer-macos.pkgproj.in (98%) create mode 100644 cmake/macos/xcode.cmake create mode 100644 cmake/windows/buildspec.cmake create mode 100644 cmake/windows/compilerconfig.cmake create mode 100644 cmake/windows/defaults.cmake create mode 100644 cmake/windows/helpers.cmake rename cmake/{bundle/windows => windows/resources}/installer-Windows.iss.in (90%) create mode 100644 cmake/windows/resources/resource.rc.in diff --git a/.cmake-format.json b/.cmake-format.json new file mode 100644 index 00000000..67919c2c --- /dev/null +++ b/.cmake-format.json @@ -0,0 +1,40 @@ +{ + "format": { + "line_width": 80, + "tab_size": 2, + "enable_sort": true, + "autosort": true + }, + "additional_commands": { + "find_qt": { + "flags": [], + "kwargs": { + "COMPONENTS": "+", + "COMPONENTS_WIN": "+", + "COMPONENTS_MACOS": "+", + "COMPONENTS_LINUX": "+" + } + }, + "set_target_properties_obs": { + "pargs": 1, + "flags": [], + "kwargs": { + "PROPERTIES": { + "kwargs": { + "PREFIX": 1, + "OUTPUT_NAME": 1, + "FOLDER": 1, + "VERSION": 1, + "SOVERSION": 1, + "AUTOMOC": 1, + "AUTOUIC": 1, + "AUTORCC": 1, + "AUTOUIC_SEARCH_PATHS": 1, + "BUILD_RPATH": 1, + "INSTALL_RPATH": 1 + } + } + } + } + } +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 99fe5203..ed7477a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,6 @@ -cmake_minimum_required(VERSION 3.16.3) +cmake_minimum_required(VERSION 3.16...3.26) 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") -set(MACOS_PACKAGE_UUID "3F0D2A6A-2583-11ED-861D-0242AC120002") -set(MACOS_INSTALLER_UUID "B7F15A6E-2583-11ED-861D-0242AC120002") -set(WINDOWS_INSTALLER_UUID "A4ADDF26-4426-4D2E-B26A-C7C878DA8FC9") message(STATUS "CMAKE_PROJECT_NAME is ${CMAKE_PROJECT_NAME}") if(${CMAKE_PROJECT_NAME} STREQUAL "obs-studio") @@ -22,11 +12,22 @@ else() message(STATUS "${PROJECT_NAME} configured for out-of-tree build") endif() -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") -include(GetGitRevisionDescription) +if(BUILD_OUT_OF_TREE) + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake" + NO_POLICY_SCOPE) + include(compilerconfig) + include(defaults) + include(helpers) +endif() + +set(LIB_NAME "${PROJECT_NAME}-lib") +add_library(${PROJECT_NAME} MODULE) +add_library(${LIB_NAME} SHARED) + +include(cmake/common/get_git_revision_description.cmake) get_git_head_revision(GIT_REFSPEC GIT_SHA1) git_describe(GIT_TAG) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cpp.in" +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/lib/version.cpp" @ONLY) # --- Set target sources --- @@ -229,17 +230,25 @@ target_sources( # --- End of section --- -if(BUILD_OUT_OF_TREE) - include(cmake/ObsPluginHelpers.cmake) -endif() -include(cmake/AdvSSHelpers.cmake) +include(cmake/common/advss_helpers.cmake) setup_obs_lib_dependency(${LIB_NAME}) setup_obs_lib_dependency(${PROJECT_NAME}) -target_link_libraries(${PROJECT_NAME} PUBLIC ${LIB_NAME}) - find_qt(COMPONENTS Widgets Core) -target_link_libraries(${LIB_NAME} PUBLIC Qt::Core Qt::Widgets) +target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Core Qt::Widgets) +target_link_libraries(${LIB_NAME} PRIVATE Qt::Core Qt::Widgets) +target_compile_options( + ${PROJECT_NAME} + PRIVATE + $<$:-Wno-quoted-include-in-framework-header + -Wno-comma>) +set_target_properties( + ${PROJECT_NAME} + PROPERTIES AUTOMOC ON + AUTOUIC ON + AUTORCC ON) + +target_link_libraries(${PROJECT_NAME} PUBLIC ${LIB_NAME}) # --- Platform-independent build settings --- @@ -271,21 +280,36 @@ target_include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib" "${CMAKE_CURRENT_SOURCE_DIR}/deps/exprtk") -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/deps/json/CMakeLists.txt") +if(NOT nlohmann_json_DIR + AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/deps/json/CMakeLists.txt") add_subdirectory(deps/json) else() find_package(nlohmann_json REQUIRED) endif() target_link_libraries(${LIB_NAME} PUBLIC nlohmann_json::nlohmann_json) + +find_package(CURL QUIET) +find_package(Libcurl QUIET) +if(CURL_FOUND) + if(NOT DEFINED CURL_INCLUDE_DIRS AND TARGET CURL::libcurl) + get_target_property(CURL_INCLUDE_DIR CURL::libcurl + INTERFACE_INCLUDE_DIRECTORIES) + target_include_directories(${LIB_NAME} PUBLIC "${CURL_INCLUDE_DIR}") + else() + target_include_directories(${LIB_NAME} PUBLIC "${CURL_INCLUDE_DIRS}") + endif() +elseif(Libcurl_FOUND) + target_include_directories(${LIB_NAME} PUBLIC "${LIBCURL_INCLUDE_DIRS}") +else() + message(FATAL_ERROR "Couldn't find CURL or Libcurl - abort") +endif() + target_compile_definitions(${LIB_NAME} PRIVATE ADVSS_EXPORT_SYMBOLS=1) # --- 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) - target_compile_definitions(${LIB_NAME} PRIVATE UNICODE _UNICODE) if(MSVC) target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267 @@ -297,33 +321,12 @@ if(OS_WINDOWS) # -- 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++) - set_target_properties(${LIB_NAME} PROPERTIES PREFIX "" SUFFIX ".so") find_library(COCOA Cocoa) target_include_directories(${LIB_NAME} PRIVATE ${COCOA}) target_link_libraries(${LIB_NAME} PRIVATE ${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() - target_sources(${LIB_NAME} PRIVATE lib/osx/advanced-scene-switcher-osx.mm) set_source_files_properties(advanced-scene-switcher-osx.mm PROPERTIES COMPILE_FLAGS "-fobjc-arc") @@ -332,7 +335,6 @@ elseif(OS_MACOS) # --- Linux-specific build settings and tasks --- else() set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "$ORIGIN") - target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra) set_target_properties(${LIB_NAME} PROPERTIES PREFIX "") set_target_properties(${LIB_NAME} PROPERTIES SOVERSION 1) @@ -362,21 +364,24 @@ else() ) endif() target_include_directories(${LIB_NAME} PRIVATE "${PROC_INCLUDE_DIR}") - - 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() - target_sources(${LIB_NAME} PRIVATE lib/linux/advanced-scene-switcher-nix.cpp) endif() + +if(NOT OS_WINDOWS) + target_compile_options( + ${LIB_NAME} + PUBLIC -Wno-error=unused-parameter -Wno-error=conversion -Wno-error=shadow + -Wno-error=float-conversion -Wno-error=enum-conversion + -Wno-error=deprecated-declarations) +endif() + # --- End of section --- +add_subdirectory(plugins) +add_subdirectory(tests) + +# --- Install --- + if(DEB_INSTALL) file(GLOB ASS_TRANSLATION_FILES "data/locale/*.ini") if(NOT LIB_OUT_DIR) @@ -394,11 +399,11 @@ if(DEB_INSTALL) install(DIRECTORY data/res DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR}) else() - setup_plugin_target(${PROJECT_NAME}) install_advss_lib(${LIB_NAME}) + if(BUILD_OUT_OF_TREE) + set_target_properties_plugin(${PROJECT_NAME} PROPERTIES OUTPUT_NAME + ${_name}) + else() + set_target_properties_obs(${PROJECT_NAME} PROPERTIES PREFIX "") + endif() endif() - -# --- End of section --- - -add_subdirectory(plugins) -add_subdirectory(tests) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000..44557f46 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,190 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 22, + "patch": 0 + }, + "configurePresets": [ + { + "name": "template", + "hidden": true, + "cacheVariables": { + "ENABLE_FRONTEND_API": true, + "ENABLE_QT": true + } + }, + { + "name": "macos", + "displayName": "macOS Universal", + "description": "Build for macOS 11.0+ (Universal binary)", + "inherits": ["template"], + "binaryDir": "${sourceDir}/build_macos", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + }, + "generator": "Xcode", + "warnings": {"dev": true, "deprecated": true}, + "cacheVariables": { + "QT_VERSION": "6", + "CMAKE_OSX_DEPLOYMENT_TARGET": "11.0", + "CODESIGN_IDENTITY": "$penv{CODESIGN_IDENT}", + "CODESIGN_TEAM": "$penv{CODESIGN_TEAM}" + } + }, + { + "name": "macos-ci", + "inherits": ["macos"], + "displayName": "macOS Universal CI build", + "description": "Build for macOS 11.0+ (Universal binary) for CI", + "generator": "Xcode", + "cacheVariables": { + "CMAKE_COMPILE_WARNING_AS_ERROR": true + } + }, + { + "name": "windows-x64", + "displayName": "Windows x64", + "description": "Build for Windows x64", + "inherits": ["template"], + "binaryDir": "${sourceDir}/build_x64", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "generator": "Visual Studio 17 2022", + "architecture": "x64", + "warnings": {"dev": true, "deprecated": true}, + "cacheVariables": { + "QT_VERSION": "6", + "CMAKE_SYSTEM_VERSION": "10.0.18363.657" + } + }, + { + "name": "windows-ci-x64", + "inherits": ["windows-x64"], + "displayName": "Windows x64 CI build", + "description": "Build for Windows x64 on CI", + "cacheVariables": { + "CMAKE_COMPILE_WARNING_AS_ERROR": true + } + }, + { + "name": "linux-x86_64", + "displayName": "Linux x86_64", + "description": "Build for Linux x86_64", + "inherits": ["template"], + "binaryDir": "${sourceDir}/build_x86_64", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + }, + "generator": "Ninja", + "warnings": {"dev": true, "deprecated": true}, + "cacheVariables": { + "QT_VERSION": "6", + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "linux-ci-x86_64", + "inherits": ["linux-x86_64"], + "displayName": "Linux x86_64 CI build", + "description": "Build for Linux x86_64 on CI", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CMAKE_COMPILE_WARNING_AS_ERROR": true + } + }, + { + "name": "linux-aarch64", + "displayName": "Linux aarch64", + "description": "Build for Linux aarch64", + "inherits": ["template"], + "binaryDir": "${sourceDir}/build_aarch64", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + }, + "generator": "Ninja", + "warnings": {"dev": true, "deprecated": true}, + "cacheVariables": { + "QT_VERSION": "6", + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "linux-ci-aarch64", + "inherits": ["linux-aarch64"], + "displayName": "Linux aarch64 CI build", + "description": "Build for Linux aarch64 on CI", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CMAKE_COMPILE_WARNING_AS_ERROR": true + } + } + ], + "buildPresets": [ + { + "name": "macos", + "configurePreset": "macos", + "displayName": "macOS Universal", + "description": "macOS build for Universal architectures", + "configuration": "Release" + }, + { + "name": "macos-ci", + "configurePreset": "macos-ci", + "displayName": "macOS Universal CI", + "description": "macOS CI build for Universal architectures", + "configuration": "RelWithDebInfo" + }, + { + "name": "windows-x64", + "configurePreset": "windows-x64", + "displayName": "Windows x64", + "description": "Windows build for x64", + "configuration": "RelWithDebInfo" + }, + { + "name": "windows-ci-x64", + "configurePreset": "windows-ci-x64", + "displayName": "Windows x64 CI", + "description": "Windows CI build for x64 (RelWithDebInfo configuration)", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-x86_64", + "configurePreset": "linux-x86_64", + "displayName": "Linux x86_64", + "description": "Linux build for x86_64", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-ci-x86_64", + "configurePreset": "linux-ci-x86_64", + "displayName": "Linux x86_64 CI", + "description": "Linux CI build for x86_64", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-aarch64", + "configurePreset": "linux-aarch64", + "displayName": "Linux aarch64", + "description": "Linux build for aarch64", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-ci-aarch64", + "configurePreset": "linux-ci-aarch64", + "displayName": "Linux aarch64 CI", + "description": "Linux CI build for aarch64", + "configuration": "RelWithDebInfo" + } + ] +} diff --git a/cmake/ObsPluginHelpers.cmake b/cmake/ObsPluginHelpers.cmake deleted file mode 100644 index 1b39b951..00000000 --- a/cmake/ObsPluginHelpers.cmake +++ /dev/null @@ -1,492 +0,0 @@ -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}-linux-x86_64") - - set(CPACK_GENERATOR "DEB") - if(${QT_VERSION} STREQUAL "6") - set(CPACK_DEBIAN_PACKAGE_DEPENDS - "obs-studio (>= 28.0.0), libqt6core6 (>= 6.2.0), libqt6gui6 (>= 6.1.2), libqt6widgets6 (>= 6.1.2)" - ) - else() - set(CPACK_DEBIAN_PACKAGE_DEPENDS - "obs-studio (>= 28.0.0), libqt5core5a (>= 5.9.0~beta), libqt5gui5 (>= 5.3.0), libqt5widgets5 (>= 5.7.0)" - ) - endif() - - 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/bundle/macos/Plugin-Info.plist.in b/cmake/bundle/macos/Plugin-Info.plist.in deleted file mode 100644 index 1b0f234a..00000000 --- a/cmake/bundle/macos/Plugin-Info.plist.in +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleName - ${MACOSX_PLUGIN_BUNDLE_NAME} - CFBundleIdentifier - ${MACOSX_PLUGIN_GUI_IDENTIFIER} - CFBundleVersion - ${MACOSX_PLUGIN_BUNDLE_VERSION} - CFBundleShortVersionString - ${MACOSX_PLUGIN_SHORT_VERSION_STRING} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleExecutable - ${MACOSX_PLUGIN_EXECUTABLE_NAME} - CFBundlePackageType - ${MACOSX_PLUGIN_BUNDLE_TYPE} - CFBundleSupportedPlatforms - - MacOSX - - LSMinimumSystemVersion - 10.13 - - diff --git a/cmake/bundle/macos/entitlements.plist b/cmake/bundle/macos/entitlements.plist deleted file mode 100644 index 516d0d52..00000000 --- a/cmake/bundle/macos/entitlements.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.device.camera - - com.apple.security.device.audio-input - - com.apple.security.cs.disable-library-validation - - - com.apple.security.cs.allow-dyld-environment-variables - - - diff --git a/cmake/AdvSSHelpers.cmake b/cmake/common/advss_helpers.cmake similarity index 87% rename from cmake/AdvSSHelpers.cmake rename to cmake/common/advss_helpers.cmake index 1b12043b..3f5a4894 100644 --- a/cmake/AdvSSHelpers.cmake +++ b/cmake/common/advss_helpers.cmake @@ -1,36 +1,41 @@ # --- Helper functions ---# +if(BUILD_OUT_OF_TREE) + if(OS_WINDOWS) + set(OBS_PLUGIN_DESTINATION "obs-plugins/64bit") + else() + set(OBS_PLUGIN_DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-plugins") + endif() +endif() + # 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_DIR "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) + + # Tell the advanced scene switcher plugin where to find the lib + string(JSON _name GET ${buildspec} name) + add_custom_command( + TARGET ${_name} + POST_BUILD + COMMAND + ${CMAKE_INSTALL_NAME_TOOL} -change @rpath/$ + @loader_path/$ $) endfunction() function(install_advss_plugin target) @@ -53,14 +58,12 @@ if(OS_MACOS) ${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 --- @@ -77,11 +80,10 @@ else() else() install( TARGETS ${what} - RUNTIME DESTINATION "${where}" COMPONENT ${what}_Runtime LIBRARY DESTINATION "${where}" COMPONENT ${what}_Runtime - NAMELINK_COMPONENT ${what}_Development) - + NAMELINK_COMPONENT ${what}_Development + RUNTIME DESTINATION "${where}") install( FILES $ DESTINATION $/${where} @@ -102,21 +104,24 @@ else() 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(OBS_OUTPUT_DIR) + 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) + endif() endfunction() function(install_advss_lib target) plugin_install_helper("${target}" "${OBS_PLUGIN_DESTINATION}" "") - if(OS_POSIX) + if(NOT OS_WINDOWS) set_target_properties(${target} PROPERTIES INSTALL_RPATH "$ORIGIN") endif() endfunction() @@ -125,7 +130,7 @@ else() plugin_install_helper( "${target}" "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}" "${_PLUGIN_FOLDER}") - if(OS_POSIX) + if(NOT OS_WINDOWS) set_target_properties(${target} PROPERTIES INSTALL_RPATH "$ORIGIN:$ORIGIN/..") endif() @@ -273,9 +278,10 @@ function(setup_advss_plugin target) 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}") + set(_COMMAND + "${CMAKE_INSTALL_NAME_TOOL} -add_rpath @loader_path \\\"$\\\"" + ) + install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")") endif() # Set up include directories for headers generated by Qt diff --git a/cmake/common/bootstrap.cmake b/cmake/common/bootstrap.cmake new file mode 100644 index 00000000..25cf3a75 --- /dev/null +++ b/cmake/common/bootstrap.cmake @@ -0,0 +1,83 @@ +cmake_minimum_required(VERSION 3.16...3.26) + +include_guard(GLOBAL) + +# Enable automatic PUSH and POP of policies to parent scope +if(POLICY CMP0011) + cmake_policy(SET CMP0011 NEW) +endif() + +# Enable distinction between Clang and AppleClang +if(POLICY CMP0025) + cmake_policy(SET CMP0025 NEW) +endif() + +# Enable strict checking of "break()" usage +if(POLICY CMP0055) + cmake_policy(SET CMP0055 NEW) +endif() + +# Honor visibility presets for all target types (executable, shared, module, +# static) +if(POLICY CMP0063) + cmake_policy(SET CMP0063 NEW) +endif() + +# Disable export function calls to populate package registry by default +if(POLICY CMP0090) + cmake_policy(SET CMP0090 NEW) +endif() + +# Prohibit in-source builds +if("${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + message( + FATAL_ERROR + "In-source builds are not supported. " + "Specify a build directory via 'cmake -S -B ' instead." + ) + file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt" + "${CMAKE_CURRENT_SOURCE_DIR}/CMakeFiles") +endif() + +# Use folders for source file organization with IDE generators (Visual +# Studio/Xcode) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +# Add common module directories to default search path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/common") + +file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + +# cmake-format: off +string(JSON _name GET ${buildspec} name) +string(JSON _website GET ${buildspec} website) +string(JSON _author GET ${buildspec} author) +string(JSON _email GET ${buildspec} email) +string(JSON _version GET ${buildspec} version) +string(JSON _bundleId GET ${buildspec} platformConfig macos bundleId) +string(JSON _windowsAppUUID GET ${buildspec} uuids windowsApp) +# cmake-format: on + +set(PLUGIN_AUTHOR ${_author}) +set(PLUGIN_WEBSITE ${_website}) +set(PLUGIN_EMAIL ${_email}) +set(PLUGIN_VERSION ${_version}) +set(MACOS_BUNDLEID ${_bundleId}) + +include(buildnumber) +include(osconfig) + +# Allow selection of common build types via UI +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() + +# Disable exports automatically going into the CMake package registry +set(CMAKE_EXPORT_PACKAGE_REGISTRY FALSE) +# Enable default inclusion of targets' source and binary directory +set(CMAKE_INCLUDE_CURRENT_DIR TRUE) diff --git a/cmake/common/buildnumber.cmake b/cmake/common/buildnumber.cmake new file mode 100644 index 00000000..bc37420b --- /dev/null +++ b/cmake/common/buildnumber.cmake @@ -0,0 +1,21 @@ +# CMake build number module + +include_guard(GLOBAL) + +# Define build number cache file +set(_BUILD_NUMBER_CACHE + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/.CMakeBuildNumber" + CACHE INTERNAL "OBS build number cache file") + +# Read build number from cache file or manual override +if(NOT DEFINED PLUGIN_BUILD_NUMBER AND EXISTS "${_BUILD_NUMBER_CACHE}") + file(READ "${_BUILD_NUMBER_CACHE}" PLUGIN_BUILD_NUMBER) + math(EXPR PLUGIN_BUILD_NUMBER "${PLUGIN_BUILD_NUMBER}+1") +elseif(NOT DEFINED PLUGIN_BUILD_NUMBER) + if($ENV{CI} AND $ENV{GITHUB_RUN_ID}) + set(PLUGIN_BUILD_NUMBER "$ENV{GITHUB_RUN_ID}") + else() + set(PLUGIN_BUILD_NUMBER "1") + endif() +endif() +file(WRITE "${_BUILD_NUMBER_CACHE}" "${PLUGIN_BUILD_NUMBER}") diff --git a/cmake/common/buildspec_common.cmake b/cmake/common/buildspec_common.cmake new file mode 100644 index 00000000..8c3b87f2 --- /dev/null +++ b/cmake/common/buildspec_common.cmake @@ -0,0 +1,226 @@ +# Common build dependencies module + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-lint: disable=E1126 +# cmake-lint: disable=R0912 +# cmake-lint: disable=R0915 +# cmake-format: on + +include_guard(GLOBAL) + +# _check_deps_version: Checks for obs-deps VERSION file in prefix paths +function(_check_deps_version version) + # cmake-format: off + set(found FALSE PARENT_SCOPE) + # cmake-format: on + + foreach(path IN LISTS CMAKE_PREFIX_PATH) + if(EXISTS "${path}/share/obs-deps/VERSION") + if(dependency STREQUAL qt6 AND NOT EXISTS + "${path}/lib/cmake/Qt6/Qt6Config.cmake") + # cmake-format: off + set(found FALSE PARENT_SCOPE) + # cmake-format: on + continue() + endif() + + file(READ "${path}/share/obs-deps/VERSION" _check_version) + string(REPLACE "\n" "" _check_version "${_check_version}") + string(REPLACE "-" "." _check_version "${_check_version}") + string(REPLACE "-" "." version "${version}") + + if(_check_version VERSION_EQUAL version) + # cmake-format: off + set(found TRUE PARENT_SCOPE) + # cmake-format: on + break() + elseif(_check_version VERSION_LESS version) + message(AUTHOR_WARNING "Older ${label} version detected in ${path}: \n" + "Found ${_check_version}, require ${version}") + list(REMOVE_ITEM CMAKE_PREFIX_PATH "${path}") + list(APPEND CMAKE_PREFIX_PATH "${path}") + # cmake-format: off + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE) + # cmake-format: on + continue() + else() + message(AUTHOR_WARNING "Newer ${label} version detected in ${path}: \n" + "Found ${_check_version}, require ${version}") + # cmake-format: off + set(found TRUE PARENT_SCOPE) + # cmake-format: on + break() + endif() + endif() + endforeach() +endfunction() + +# _setup_obs_studio: Create obs-studio build project, then build libobs and +# obs-frontend-api +function(_setup_obs_studio) + if(NOT libobs_DIR) + set(_is_fresh --fresh) + endif() + + if(OS_WINDOWS) + set(_cmake_generator "${CMAKE_GENERATOR}") + set(_cmake_arch "-A ${arch}") + set(_cmake_extra + "-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} -DCMAKE_ENABLE_SCRIPTING=OFF" + ) + set(_cmake_version "2.0.0") + elseif(OS_MACOS) + set(_cmake_generator "Xcode") + set(_cmake_arch "-DCMAKE_OSX_ARCHITECTURES:STRING='arm64;x86_64'") + set(_cmake_extra + "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") + set(_cmake_version "3.0.0") + endif() + + message(STATUS "Configure ${label} (${arch})") + execute_process( + COMMAND + "${CMAKE_COMMAND}" -S "${dependencies_dir}/${_obs_destination}" -B + "${dependencies_dir}/${_obs_destination}/build_${arch}" -G + ${_cmake_generator} "${_cmake_arch}" + -DOBS_CMAKE_VERSION:STRING=${_cmake_version} -DENABLE_PLUGINS:BOOL=OFF + -DENABLE_UI:BOOL=OFF -DOBS_VERSION_OVERRIDE:STRING=${_obs_version} + "-DCMAKE_PREFIX_PATH='${CMAKE_PREFIX_PATH}'" ${_is_fresh} ${_cmake_extra} + RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY + OUTPUT_QUIET) + message(STATUS "Configure ${label} (${arch}) - done") + + message(STATUS "Build ${label} (${arch})") + execute_process( + COMMAND "${CMAKE_COMMAND}" --build build_${arch} --target obs-frontend-api + --config Debug --parallel + WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}" + RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY + OUTPUT_QUIET) + message(STATUS "Build ${label} (${arch}) - done") + + message(STATUS "Install ${label} (${arch})") + if(OS_WINDOWS) + set(_cmake_extra "--component obs_libraries") + else() + set(_cmake_extra "") + endif() + execute_process( + COMMAND "${CMAKE_COMMAND}" --install build_${arch} --component Development + --config Debug --prefix "${dependencies_dir}" ${_cmake_extra} + WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}" + RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY + OUTPUT_QUIET) + message(STATUS "Install ${label} (${arch}) - done") +endfunction() + +# _check_dependencies: Fetch and extract pre-built OBS build dependencies +function(_check_dependencies) + if(NOT buildspec) + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + endif() + + # cmake-format: off + string(JSON dependency_data GET ${buildspec} dependencies) + # cmake-format: on + + foreach(dependency IN LISTS dependencies_list) + # cmake-format: off + string(JSON data GET ${dependency_data} ${dependency}) + string(JSON version GET ${data} version) + string(JSON hash GET ${data} hashes ${platform}) + string(JSON url GET ${data} baseUrl) + string(JSON label GET ${data} label) + string(JSON revision ERROR_VARIABLE error GET ${data} revision ${platform}) + # cmake-format: on + + message(STATUS "Setting up ${label} (${arch})") + + set(file "${${dependency}_filename}") + set(destination "${${dependency}_destination}") + string(REPLACE "VERSION" "${version}" file "${file}") + string(REPLACE "VERSION" "${version}" destination "${destination}") + string(REPLACE "ARCH" "${arch}" file "${file}") + string(REPLACE "ARCH" "${arch}" destination "${destination}") + if(revision) + string(REPLACE "_REVISION" "_v${revision}" file "${file}") + string(REPLACE "-REVISION" "-v${revision}" file "${file}") + else() + string(REPLACE "_REVISION" "" file "${file}") + string(REPLACE "-REVISION" "" file "${file}") + endif() + + set(skip FALSE) + if(dependency STREQUAL prebuilt OR dependency STREQUAL qt6) + _check_deps_version(${version}) + + if(found) + set(skip TRUE) + endif() + endif() + + if(skip) + message(STATUS "Setting up ${label} (${arch}) - skipped") + continue() + endif() + + if(dependency STREQUAL obs-studio) + set(url ${url}/${file}) + else() + set(url ${url}/${version}/${file}) + endif() + + if(NOT EXISTS "${dependencies_dir}/${file}") + message(STATUS "Downloading ${url}") + file( + DOWNLOAD "${url}" "${dependencies_dir}/${file}" + STATUS download_status + EXPECTED_HASH SHA256=${hash}) + + list(GET download_status 0 error_code) + list(GET download_status 1 error_message) + if(error_code GREATER 0) + message(STATUS "Downloading ${url} - Failure") + message( + FATAL_ERROR + "Unable to download ${url}, failed with error: ${error_message}") + file(REMOVE "${dependencies_dir}/${file}") + else() + message(STATUS "Downloading ${url} - done") + endif() + endif() + + if(NOT EXISTS "${dependencies_dir}/${destination}") + file(MAKE_DIRECTORY "${dependencies_dir}/${destination}") + if(dependency STREQUAL obs-studio) + file(ARCHIVE_EXTRACT INPUT "${dependencies_dir}/${file}" DESTINATION + "${dependencies_dir}") + else() + file(ARCHIVE_EXTRACT INPUT "${dependencies_dir}/${file}" DESTINATION + "${dependencies_dir}/${destination}") + endif() + endif() + + if(dependency STREQUAL prebuilt) + list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}/${destination}") + elseif(dependency STREQUAL qt6) + list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}/${destination}") + elseif(dependency STREQUAL obs-studio) + set(_obs_version ${version}) + set(_obs_destination "${destination}") + list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}") + + endif() + + message(STATUS "Setting up ${label} (${arch}) - done") + endforeach() + + list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH) + + # cmake-format: off + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} CACHE PATH "CMake prefix search path" FORCE) + # cmake-format: on + + _setup_obs_studio() +endfunction() diff --git a/cmake/common/ccache.cmake b/cmake/common/ccache.cmake new file mode 100644 index 00000000..acfff5a5 --- /dev/null +++ b/cmake/common/ccache.cmake @@ -0,0 +1,22 @@ +# CMake ccache module + +include_guard(GLOBAL) + +if(NOT DEFINED CCACHE_PROGRAM) + message(DEBUG "Trying to find ccache on build host...") + find_program(CCACHE_PROGRAM "ccache") + mark_as_advanced(CCACHE_PROGRAM) +endif() + +if(CCACHE_PROGRAM) + message(DEBUG "Ccache found as ${CCACHE_PROGRAM}...") + option(ENABLE_CCACHE "Enable compiler acceleration with ccache" ON) + + if(ENABLE_CCACHE) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_OBJC_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_OBJCXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_CUDA_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + endif() +endif() diff --git a/cmake/common/compiler_common.cmake b/cmake/common/compiler_common.cmake new file mode 100644 index 00000000..8ac423f1 --- /dev/null +++ b/cmake/common/compiler_common.cmake @@ -0,0 +1,87 @@ +# CMake common compiler options module + +include_guard(GLOBAL) + +# Set C and C++ language standards to C17 and C++17 +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) + set(CMAKE_C_STANDARD 17) +else() + set(CMAKE_C_STANDARD 11) +endif() +set(CMAKE_C_STANDARD_REQUIRED TRUE) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) + +# Set symbols to be hidden by default for C and C++ +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) + +# clang options for C +set(_obs_clang_c_options + # cmake-format: sortable + -fno-strict-aliasing + -Wbool-conversion + -Wcomma + -Wconstant-conversion + -Wdeprecated-declarations + -Wempty-body + -Wenum-conversion + -Werror=return-type + -Wextra + -Wformat + -Wformat-security + -Wfour-char-constants + -Winfinite-recursion + -Wint-conversion + -Wnewline-eof + -Wno-conversion + -Wno-float-conversion + -Wno-implicit-fallthrough + -Wno-missing-braces + -Wno-missing-field-initializers + -Wno-missing-prototypes + -Wno-semicolon-before-method-body + -Wno-shadow + -Wno-sign-conversion + -Wno-strict-prototypes + -Wno-trigraphs + -Wno-unknown-pragmas + -Wno-unused-function + -Wno-unused-label + -Wnon-literal-null-conversion + -Wobjc-literal-conversion + -Wparentheses + -Wpointer-sign + -Wquoted-include-in-framework-header + -Wshadow + -Wshorten-64-to-32 + -Wuninitialized + -Wunreachable-code + -Wunused-parameter + -Wunused-value + -Wunused-variable + -Wvla) + +# clang options for C++ +set(_obs_clang_cxx_options + # cmake-format: sortable + ${_obs_clang_c_options} + -Wconversion + -Wdeprecated-implementations + -Wduplicate-method-match + -Wfloat-conversion + -Wfour-char-constants + -Wimplicit-retain-self + -Winvalid-offsetof + -Wmove + -Wno-c++11-extensions + -Wno-exit-time-destructors + -Wno-implicit-atomic-properties + -Wno-objc-interface-ivars + -Wno-overloaded-virtual + -Wrange-loop-analysis) + +if(NOT DEFINED CMAKE_COMPILE_WARNING_AS_ERROR) + set(CMAKE_COMPILE_WARNING_AS_ERROR ON) +endif() diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/common/get_git_revision_description.cmake similarity index 99% rename from cmake/GetGitRevisionDescription.cmake rename to cmake/common/get_git_revision_description.cmake index adabb6a2..4d16b3f4 100644 --- a/cmake/GetGitRevisionDescription.cmake +++ b/cmake/common/get_git_revision_description.cmake @@ -148,7 +148,7 @@ function(get_git_head_revision _refspecvar _hashvar) set(HEAD_FILE "${GIT_DATA}/HEAD") configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) - configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + configure_file("${_gitdescmoddir}/get_git_revision_description.cmake.in" "${GIT_DATA}/grabRef.cmake" @ONLY) include("${GIT_DATA}/grabRef.cmake") diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/common/get_git_revision_description.cmake.in similarity index 95% rename from cmake/GetGitRevisionDescription.cmake.in rename to cmake/common/get_git_revision_description.cmake.in index 6d8b708e..88598020 100644 --- a/cmake/GetGitRevisionDescription.cmake.in +++ b/cmake/common/get_git_revision_description.cmake.in @@ -1,5 +1,5 @@ # -# Internal file for GetGitRevisionDescription.cmake +# Internal file for get_git_revision_description.cmake.in # # Requires CMake 2.6 or newer (uses the 'function' command) # diff --git a/cmake/common/helpers_common.cmake b/cmake/common/helpers_common.cmake new file mode 100644 index 00000000..bdcdc471 --- /dev/null +++ b/cmake/common/helpers_common.cmake @@ -0,0 +1,149 @@ +# CMake common helper functions module + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-format: on + +include_guard(GLOBAL) + +# * Use QT_VERSION value as a hint for desired Qt version +# * If "AUTO" was specified, prefer Qt6 over Qt5 +# * Creates versionless targets of desired component if none had been created by +# Qt itself (Qt versions < 5.15) +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() + +# find_qt: Macro to find best possible Qt version for use with the project: +macro(find_qt) + set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX) + cmake_parse_arguments(find_qt "" "${oneValueArgs}" "${multiValueArgs}" + ${ARGN}) + + # Do not use versionless targets in the first step to avoid Qt::Core being + # clobbered by later opportunistic find_package runs + set(QT_NO_CREATE_VERSIONLESS_TARGETS TRUE) + + message(DEBUG "Start Qt version discovery...") + # Loop until _QT_VERSION is set or FATAL_ERROR aborts script execution early + while(NOT _QT_VERSION) + message(DEBUG "QT_VERSION set to ${QT_VERSION}") + if(QT_VERSION STREQUAL AUTO AND NOT qt_test_version) + set(qt_test_version 6) + elseif(NOT QT_VERSION STREQUAL AUTO) + set(qt_test_version ${QT_VERSION}) + endif() + message(DEBUG "Attempting to find Qt${qt_test_version}") + + find_package( + Qt${qt_test_version} + COMPONENTS Core + QUIET) + + if(TARGET Qt${qt_test_version}::Core) + set(_QT_VERSION + ${qt_test_version} + CACHE INTERNAL "") + message(STATUS "Qt version found: ${_QT_VERSION}") + unset(qt_test_version) + break() + elseif(QT_VERSION STREQUAL AUTO) + if(qt_test_version EQUAL 6) + message(WARNING "Qt6 was not found, falling back to Qt5") + set(qt_test_version 5) + continue() + endif() + endif() + message(FATAL_ERROR "Neither Qt6 nor Qt5 found.") + endwhile() + + # Enable versionless targets for the remaining Qt components + set(QT_NO_CREATE_VERSIONLESS_TARGETS FALSE) + + set(qt_components ${find_qt_COMPONENTS}) + if(OS_WINDOWS) + list(APPEND qt_components ${find_qt_COMPONENTS_WIN}) + elseif(OS_MACOS) + list(APPEND qt_components ${find_qt_COMPONENTS_MAC}) + else() + list(APPEND qt_components ${find_qt_COMPONENTS_LINUX}) + endif() + message(DEBUG "Trying to find Qt components ${qt_components}...") + + find_package(Qt${_QT_VERSION} REQUIRED ${qt_components}) + + list(APPEND qt_components Core) + + if("Gui" IN_LIST find_qt_COMPONENTS_LINUX) + list(APPEND qt_components "GuiPrivate") + endif() + + # Check for versionless targets of each requested component and create if + # necessary + foreach(component IN LISTS qt_components) + message(DEBUG "Checking for target Qt::${component}") + 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() + set_property(TARGET Qt::${component} PROPERTY INTERFACE_COMPILE_FEATURES "") + endforeach() + +endmacro() + +# check_uuid: Helper function to check for valid UUID +function(check_uuid uuid_string return_value) + set(valid_uuid TRUE) + set(uuid_token_lengths 8 4 4 4 12) + set(token_num 0) + + string(REPLACE "-" ";" uuid_tokens ${uuid_string}) + list(LENGTH uuid_tokens uuid_num_tokens) + + if(uuid_num_tokens EQUAL 5) + message(DEBUG "UUID ${uuid_string} is valid with 5 tokens.") + foreach(uuid_token IN LISTS uuid_tokens) + list(GET uuid_token_lengths ${token_num} uuid_target_length) + string(LENGTH "${uuid_token}" uuid_actual_length) + if(uuid_actual_length EQUAL uuid_target_length) + string(REGEX MATCH "[0-9a-fA-F]+" uuid_hex_match ${uuid_token}) + if(NOT uuid_hex_match STREQUAL uuid_token) + set(valid_uuid FALSE) + break() + endif() + else() + set(valid_uuid FALSE) + break() + endif() + math(EXPR token_num "${token_num}+1") + endforeach() + else() + set(valid_uuid FALSE) + endif() + message(DEBUG "UUID ${uuid_string} valid: ${valid_uuid}") + set(${return_value} + ${valid_uuid} + PARENT_SCOPE) +endfunction() + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/plugin-support.c.in") + configure_file(src/plugin-support.c.in plugin-support.c @ONLY) + add_library(plugin-support STATIC) + target_sources( + plugin-support + PRIVATE plugin-support.c + PUBLIC src/plugin-support.h) + target_include_directories(plugin-support + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src") + if(OS_LINUX + OR OS_FREEBSD + OR OS_OPENBSD) + # add fPIC on Linux to prevent shared object errors + set_property(TARGET plugin-support PROPERTY POSITION_INDEPENDENT_CODE ON) + endif() +endif() diff --git a/cmake/common/osconfig.cmake b/cmake/common/osconfig.cmake new file mode 100644 index 00000000..52f9b55c --- /dev/null +++ b/cmake/common/osconfig.cmake @@ -0,0 +1,23 @@ +# CMake operating system bootstrap module + +include_guard(GLOBAL) + +# Set minimum CMake version specific to host operating system, add OS-specific +# module directory to default search paths, and set helper variables for OS +# detection in other CMake list files. +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(CMAKE_C_EXTENSIONS FALSE) + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows") + set(OS_WINDOWS TRUE) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(CMAKE_C_EXTENSIONS FALSE) + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos") + set(OS_MACOS TRUE) +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") + string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) + set(OS_${_SYSTEM_NAME_U} TRUE) +endif() diff --git a/cmake/version.cpp.in b/cmake/common/version.cpp.in similarity index 100% rename from cmake/version.cpp.in rename to cmake/common/version.cpp.in diff --git a/cmake/linux/compilerconfig.cmake b/cmake/linux/compilerconfig.cmake new file mode 100644 index 00000000..d7ea99de --- /dev/null +++ b/cmake/linux/compilerconfig.cmake @@ -0,0 +1,91 @@ +# CMake Linux compiler configuration module + +include_guard(GLOBAL) + +include(ccache) +include(compiler_common) + +option(ENABLE_COMPILER_TRACE + "Enable Clang time-trace (required Clang and Ninja)" OFF) +mark_as_advanced(ENABLE_COMPILER_TRACE) + +# gcc options for C +set(_obs_gcc_c_options + # cmake-format: sortable + -fno-strict-aliasing + -fopenmp-simd + -Wdeprecated-declarations + -Wempty-body + -Wenum-conversion + -Werror=return-type + -Wextra + -Wformat + -Wformat-security + -Wno-conversion + -Wno-float-conversion + -Wno-implicit-fallthrough + -Wno-missing-braces + -Wno-missing-field-initializers + -Wno-shadow + -Wno-sign-conversion + -Wno-trigraphs + -Wno-unknown-pragmas + -Wno-unused-function + -Wno-unused-label + -Wparentheses + -Wshadow + -Wuninitialized + -Wunreachable-code + -Wunused-parameter + -Wunused-value + -Wunused-variable + -Wvla) + +# gcc options for C++ +set(_obs_gcc_cxx_options + # cmake-format: sortable + ${_obs_gcc_c_options} -Wconversion -Wfloat-conversion -Winvalid-offsetof + -Wno-overloaded-virtual) + +add_compile_options( + -fopenmp-simd + "$<$:${_obs_gcc_c_options}>" + "$<$:-Wint-conversion;-Wno-missing-prototypes;-Wno-strict-prototypes;-Wpointer-sign>" + "$<$:${_obs_gcc_cxx_options}>" + "$<$:${_obs_clang_c_options}>" + "$<$:${_obs_clang_cxx_options}>") + +# Add support for color diagnostics and CMake switch for warnings as errors to +# CMake < 3.24 +if(CMAKE_VERSION VERSION_LESS 3.24.0) + add_compile_options($<$:-fcolor-diagnostics> + $<$:-fcolor-diagnostics>) + if(CMAKE_COMPILE_WARNING_AS_ERROR) + add_compile_options(-Werror) + endif() +else() + set(CMAKE_COLOR_DIAGNOSTICS ON) +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL GNU) + # Disable false-positive warning in GCC 12.1.0 and later + add_compile_options(-Wno-error=maybe-uninitialized) + + # Add warning for infinite recursion (added in GCC 12) + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0.0) + add_compile_options(-Winfinite-recursion) + endif() +endif() + +# Enable compiler and build tracing (requires Ninja generator) +if(ENABLE_COMPILER_TRACE AND CMAKE_GENERATOR STREQUAL "Ninja") + add_compile_options($<$:-ftime-trace> + $<$:-ftime-trace>) +else() + set(ENABLE_COMPILER_TRACE + OFF + CACHE STRING "Enable Clang time-trace (required Clang and Ninja)" FORCE) +endif() + +add_compile_definitions($<$:DEBUG> $<$:_DEBUG> + SIMDE_ENABLE_OPENMP) diff --git a/cmake/linux/defaults.cmake b/cmake/linux/defaults.cmake new file mode 100644 index 00000000..184e4563 --- /dev/null +++ b/cmake/linux/defaults.cmake @@ -0,0 +1,93 @@ +# CMake Linux defaults module + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-lint: disable=C0111 +# cmake-format: on + +include_guard(GLOBAL) + +include(GNUInstallDirs) + +# Enable find_package targets to become globally available targets +set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) + +set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") +set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}") +set(CPACK_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_C_LIBRARY_ARCHITECTURE}" +) + +set(CPACK_GENERATOR "DEB") +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PLUGIN_EMAIL}") +set(CPACK_SET_DESTDIR ON) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.25.0 OR NOT CMAKE_CROSSCOMPILING) + set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON) +endif() + +set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/release") + +set(CPACK_SOURCE_GENERATOR "TXZ") +set(CPACK_SOURCE_IGNORE_FILES + # cmake-format: sortable + ".*~$" + \\.git/ + \\.github/ + \\.gitignore + build_.* + cmake/\\.CMakeBuildNumber + release/) + +set(CPACK_VERBATIM_VARIABLES YES) +set(CPACK_SOURCE_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-source") +set(CPACK_ARCHIVE_THREADS 0) + +include(CPack) + +find_package(libobs QUIET) + +if(NOT TARGET OBS::libobs) + find_package(LibObs REQUIRED) + add_library(OBS::libobs ALIAS libobs) + + if(ENABLE_FRONTEND_API) + find_path( + obs-frontend-api_INCLUDE_DIR + NAMES obs-frontend-api.h + PATHS /usr/include /usr/local/include + PATH_SUFFIXES obs) + + find_library( + obs-frontend-api_LIBRARY + NAMES obs-frontend-api + PATHS /usr/lib /usr/local/lib) + + if(obs-frontend-api_LIBRARY) + if(NOT TARGET OBS::obs-frontend-api) + if(IS_ABSOLUTE "${obs-frontend-api_LIBRARY}") + add_library(OBS::obs-frontend-api UNKNOWN IMPORTED) + set_property(TARGET OBS::obs-frontend-api + PROPERTY IMPORTED_LOCATION "${obs-frontend-api_LIBRARY}") + else() + add_library(OBS::obs-frontend-api INTERFACE IMPORTED) + set_property(TARGET OBS::obs-frontend-api + PROPERTY IMPORTED_LIBNAME "${obs-frontend-api_LIBRARY}") + endif() + + set_target_properties( + OBS::obs-frontend-api PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${obs-frontend-api_INCLUDE_DIR}") + endif() + endif() + endif() + + macro(find_package) + if(NOT "${ARGV0}" STREQUAL libobs AND NOT "${ARGV0}" STREQUAL + obs-frontend-api) + _find_package(${ARGV}) + endif() + endmacro() +endif() diff --git a/cmake/linux/helpers.cmake b/cmake/linux/helpers.cmake new file mode 100644 index 00000000..257fd165 --- /dev/null +++ b/cmake/linux/helpers.cmake @@ -0,0 +1,80 @@ +# CMake Linux helper functions module + +include_guard(GLOBAL) + +include(helpers_common) + +# set_target_properties_plugin: Set target properties for use in obs-studio +function(set_target_properties_plugin target) + set(options "") + set(oneValueArgs "") + set(multiValueArgs PROPERTIES) + cmake_parse_arguments(PARSE_ARGV 0 _STPO "${options}" "${oneValueArgs}" + "${multiValueArgs}") + + message(DEBUG "Setting additional properties for target ${target}...") + + while(_STPO_PROPERTIES) + list(POP_FRONT _STPO_PROPERTIES key value) + set_property(TARGET ${target} PROPERTY ${key} "${value}") + endwhile() + + set_target_properties( + ${target} + PROPERTIES VERSION 0 + SOVERSION ${PLUGIN_VERSION} + PREFIX "") + + install( + TARGETS ${target} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/obs-plugins) + + if(TARGET plugin-support) + target_link_libraries(${target} PRIVATE plugin-support) + endif() + + target_install_resources(${target}) + + get_target_property(target_sources ${target} SOURCES) + set(target_ui_files ${target_sources}) + list(FILTER target_ui_files INCLUDE REGEX ".+\\.(ui|qrc)") + source_group( + TREE "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX "UI Files" + FILES ${target_ui_files}) +endfunction() + +# Helper function to add resources into bundle +function(target_install_resources target) + message(DEBUG "Installing resources for target ${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) + cmake_path( + RELATIVE_PATH data_file BASE_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}/data/" OUTPUT_VARIABLE relative_path) + cmake_path(GET relative_path PARENT_PATH relative_path) + target_sources(${target} PRIVATE "${data_file}") + source_group("Resources/${relative_path}" FILES "${data_file}") + endforeach() + + install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/" + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/obs/obs-plugins/${target} + USE_SOURCE_PERMISSIONS) + endif() +endfunction() + +# Helper function to add a specific resource to a bundle +function(target_add_resource target resource) + message( + DEBUG + "Add resource '${resource}' to target ${target} at destination '${target_destination}'..." + ) + + install(FILES "${resource}" + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/obs/obs-plugins/${target}) + + source_group("Resources" FILES "${resource}") +endfunction() diff --git a/cmake/linux/toolchains/aarch64-linux-clang.cmake b/cmake/linux/toolchains/aarch64-linux-clang.cmake new file mode 100644 index 00000000..3cf41424 --- /dev/null +++ b/cmake/linux/toolchains/aarch64-linux-clang.cmake @@ -0,0 +1,56 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) +set(CMAKE_CROSSCOMPILING TRUE) + +set(CMAKE_C_COMPILER /usr/bin/clang) +set(CMAKE_CXX_COMPILER /usr/bin/clang++) + +set(CMAKE_C_COMPILER_TARGET aarch64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET aarch64-linux-gnu) + +set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(PKG_CONFIG_EXECUTABLE + /usr/bin/aarch64-linux-gnu-pkg-config + CACHE FILEPATH "pkg-config executable") + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-ranlib + OUTPUT_VARIABLE CMAKE_RANLIB + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-ar + OUTPUT_VARIABLE CMAKE_LLVM_AR + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-readelf + OUTPUT_VARIABLE READELF + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-objcopy + OUTPUT_VARIABLE CMAKE_LLVM_OBJCOPY + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-objdump + OUTPUT_VARIABLE CMAKE_LLVM_OBJDUMP + OUTPUT_STRIP_TRAILING_WHITESPACE) + +set(CMAKE_AR + "${CMAKE_LLVM_AR}" + CACHE INTERNAL "${CMAKE_SYSTEM_NAME} ar" FORCE) +set(CMAKE_OBJCOPY + "${CMAKE_LLVM_OBJCOPY}" + CACHE INTERNAL "${CMAKE_SYSTEM_NAME} objcopy" FORCE) +set(CMAKE_OBJDUMP + "${CMAKE_LLVM_OBJDUMP}" + CACHE INTERNAL "${CMAKE_SYSTEM_NAME} objdump" FORCE) + +set(CPACK_READELF_EXECUTABLE "${READELF}") +set(CPACK_OBJCOPY_EXECUTABLE "${CMAKE_LLVM_OBJCOPY}") +set(CPACK_OBJDUMP_EXECUTABLE "${CMAKE_LLVM_OBJDUMP}") +set(CPACK_PACKAGE_ARCHITECTURE arm64) +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64) diff --git a/cmake/linux/toolchains/aarch64-linux-gcc.cmake b/cmake/linux/toolchains/aarch64-linux-gcc.cmake new file mode 100644 index 00000000..1809c74e --- /dev/null +++ b/cmake/linux/toolchains/aarch64-linux-gcc.cmake @@ -0,0 +1,20 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) +set(CMAKE_CROSSCOMPILING TRUE) + +set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++) + +set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +set(PKG_CONFIG_EXECUTABLE + /usr/bin/aarch64-linux-gnu-pkg-config + CACHE FILEPATH "pkg-config executable") + +set(CPACK_READELF_EXECUTABLE /usr/bin/aarch64-linux-gnu-readelf) +set(CPACK_OBJCOPY_EXECUTABLE /usr/bin/aarch64-linux-gnu-objcopy) +set(CPACK_OBJDUMP_EXECUTABLE /usr/bin/aarch64-linux-gnu-objdump) +set(CPACK_PACKAGE_ARCHITECTURE arm64) +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64) diff --git a/cmake/linux/toolchains/x86_64-linux-clang.cmake b/cmake/linux/toolchains/x86_64-linux-clang.cmake new file mode 100644 index 00000000..6d429cf8 --- /dev/null +++ b/cmake/linux/toolchains/x86_64-linux-clang.cmake @@ -0,0 +1,56 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR x86_64) +set(CMAKE_CROSSCOMPILING TRUE) + +set(CMAKE_C_COMPILER /usr/bin/clang) +set(CMAKE_CXX_COMPILER /usr/bin/clang++) + +set(CMAKE_C_COMPILER_TARGET x86_64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET x86_64-linux-gnu) + +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-linux-gnu) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(PKG_CONFIG_EXECUTABLE + /usr/bin/x86_64-linux-gnu-pkg-config + CACHE FILEPATH "pkg-config executable") + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-ranlib + OUTPUT_VARIABLE CMAKE_RANLIB + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-ar + OUTPUT_VARIABLE CMAKE_LLVM_AR + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-readelf + OUTPUT_VARIABLE READELF + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-objcopy + OUTPUT_VARIABLE CMAKE_LLVM_OBJCOPY + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-prog-name=llvm-objdump + OUTPUT_VARIABLE CMAKE_LLVM_OBJDUMP + OUTPUT_STRIP_TRAILING_WHITESPACE) + +set(CMAKE_AR + "${CMAKE_LLVM_AR}" + CACHE INTERNAL "${CMAKE_SYSTEM_NAME} ar" FORCE) +set(CMAKE_OBJCOPY + "${CMAKE_LLVM_OBJCOPY}" + CACHE INTERNAL "${CMAKE_SYSTEM_NAME} objcopy" FORCE) +set(CMAKE_OBJDUMP + "${CMAKE_LLVM_OBJDUMP}" + CACHE INTERNAL "${CMAKE_SYSTEM_NAME} objdump" FORCE) + +set(CPACK_READELF_EXECUTABLE "${READELF}") +set(CPACK_OBJCOPY_EXECUTABLE "${CMAKE_LLVM_OBJCOPY}") +set(CPACK_OBJDUMP_EXECUTABLE "${CMAKE_LLVM_OBJDUMP}") +set(CPACK_PACKAGE_ARCHITECTURE x86_64) +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE x86_64) diff --git a/cmake/linux/toolchains/x86_64-linux-gcc.cmake b/cmake/linux/toolchains/x86_64-linux-gcc.cmake new file mode 100644 index 00000000..0fded322 --- /dev/null +++ b/cmake/linux/toolchains/x86_64-linux-gcc.cmake @@ -0,0 +1,20 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR x86_64) +set(CMAKE_CROSSCOMPILING TRUE) + +set(CMAKE_C_COMPILER /usr/bin/x86_64-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER /usr/bin/x86_64-linux-gnu-g++) + +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-linux-gnu) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +set(PKG_CONFIG_EXECUTABLE + /usr/bin/x86_64-linux-gnu-pkg-config + CACHE FILEPATH "pkg-config executable") + +set(CPACK_READELF_EXECUTABLE /usr/bin/x86_64-linux-gnu-readelf) +set(CPACK_OBJCOPY_EXECUTABLE /usr/bin/x86_64-linux-gnu-objcopy) +set(CPACK_OBJDUMP_EXECUTABLE /usr/bin/x86_64-linux-gnu-objdump) +set(CPACK_PACKAGE_ARCHITECTURE x86_64) +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE x86_64) diff --git a/cmake/macos/buildspec.cmake b/cmake/macos/buildspec.cmake new file mode 100644 index 00000000..5761ea22 --- /dev/null +++ b/cmake/macos/buildspec.cmake @@ -0,0 +1,34 @@ +# CMake macOS build dependencies module + +include_guard(GLOBAL) + +include(buildspec_common) + +# _check_dependencies_macos: Set up macOS slice for _check_dependencies +function(_check_dependencies_macos) + set(arch universal) + set(platform macos) + + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + + set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps") + set(prebuilt_filename "macos-deps-VERSION-ARCH_REVISION.tar.xz") + set(prebuilt_destination "obs-deps-VERSION-ARCH") + set(qt6_filename "macos-deps-qt6-VERSION-ARCH-REVISION.tar.xz") + set(qt6_destination "obs-deps-qt6-VERSION-ARCH") + set(obs-studio_filename "VERSION.tar.gz") + set(obs-studio_destination "obs-studio-VERSION") + set(dependencies_list prebuilt qt6 obs-studio) + + _check_dependencies() + + execute_process(COMMAND "xattr" -r -d com.apple.quarantine + "${dependencies_dir}" RESULT_VARIABLE result) + + list(APPEND CMAKE_FRAMEWORK_PATH "${dependencies_dir}/Frameworks") + set(CMAKE_FRAMEWORK_PATH + ${CMAKE_FRAMEWORK_PATH} + PARENT_SCOPE) +endfunction() + +_check_dependencies_macos() diff --git a/cmake/macos/compilerconfig.cmake b/cmake/macos/compilerconfig.cmake new file mode 100644 index 00000000..731d5c44 --- /dev/null +++ b/cmake/macos/compilerconfig.cmake @@ -0,0 +1,65 @@ +# CMake macOS compiler configuration module + +include_guard(GLOBAL) + +include(ccache) +include(compiler_common) + +add_compile_options(-fopenmp-simd) + +if(XCODE) + # Use Xcode's standard architecture selection + set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)") + # Enable dSYM generation for Release builds + string(APPEND CMAKE_C_FLAGS_RELEASE " -g") + string(APPEND CMAKE_CXX_FLAGS_RELEASE " -g") +else() + option(ENABLE_COMPILER_TRACE "Enable clang time-trace (requires Ninja)" OFF) + mark_as_advanced(ENABLE_COMPILER_TRACE) + + # clang options for ObjC + set(_obs_clang_objc_options + # cmake-format: sortable + -Werror=block-capture-autoreleasing + -Wno-selector + -Wno-strict-selector-match + -Wnon-virtual-dtor + -Wprotocol + -Wundeclared-selector) + + # clang options for ObjC++ + set(_obs_clang_objcxx_options + # cmake-format: sortable + ${_obs_clang_objc_options} -Warc-repeated-use-of-weak + -Wno-arc-maybe-repeated-use-of-weak) + + add_compile_options( + "$<$:${_obs_clang_c_options}>" + "$<$:${_obs_clang_cxx_options}>" + "$<$:${_obs_clang_objc_options}>" + "$<$:${_obs_clang_objcxx_options}>") + + # Enable stripping of dead symbols when not building for Debug configuration + set(_release_configs RelWithDebInfo Release MinSizeRel) + if(CMAKE_BUILD_TYPE IN_LIST _release_configs) + add_link_options(LINKER:-dead_strip) + endif() + + # Enable color diagnostics for AppleClang + set(CMAKE_COLOR_DIAGNOSTICS ON) + # Set universal architectures via CMake flag for non-Xcode generators + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") + + # Enable compiler and build tracing (requires Ninja generator) + if(ENABLE_COMPILER_TRACE AND CMAKE_GENERATOR STREQUAL "Ninja") + add_compile_options($<$:-ftime-trace> + $<$:-ftime-trace>) + else() + set(ENABLE_COMPILER_TRACE + OFF + CACHE STRING "Enable clang time-trace (requires Ninja)" FORCE) + endif() +endif() + +add_compile_definitions($<$:DEBUG> $<$:_DEBUG> + SIMDE_ENABLE_OPENMP) diff --git a/cmake/macos/defaults.cmake b/cmake/macos/defaults.cmake new file mode 100644 index 00000000..792040e7 --- /dev/null +++ b/cmake/macos/defaults.cmake @@ -0,0 +1,53 @@ +# CMake macOS defaults module + +include_guard(GLOBAL) + +# Set empty codesigning team if not specified as cache variable +if(NOT CODESIGN_TEAM) + set(CODESIGN_TEAM + "" + CACHE STRING "OBS code signing team for macOS" FORCE) + + # Set ad-hoc codesigning identity if not specified as cache variable + if(NOT CODESIGN_IDENTITY) + set(CODESIGN_IDENTITY + "-" + CACHE STRING "OBS code signing identity for macOS" FORCE) + endif() +endif() + +if(XCODE) + include(xcode) +endif() + +include(buildspec) + +# Set default deployment target to 11.0 if not set and enable selection in GUI +# up to 13.0 +if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) + set(CMAKE_OSX_DEPLOYMENT_TARGET + 11.0 + CACHE + STRING + "Minimum macOS version to target for deployment (at runtime). Newer APIs will be weak-linked." + FORCE) +endif() +set_property(CACHE CMAKE_OSX_DEPLOYMENT_TARGET PROPERTY STRINGS 13.0 12.0 11.0) + +# Use Applications directory as default install destination +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX + "$ENV{HOME}/Library/Application Support/obs-studio/plugins" + CACHE STRING "Directory to install OBS after building" FORCE) +endif() + +# Enable find_package targets to become globally available targets +set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) +# Enable RPATH support for generated binaries +set(CMAKE_MACOSX_RPATH TRUE) +# Use RPATHs from build tree _in_ the build tree +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +# Do not add default linker search paths to RPATH +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) +# Use common bundle-relative RPATH for installed targets +set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks") diff --git a/cmake/macos/helpers.cmake b/cmake/macos/helpers.cmake new file mode 100644 index 00000000..b2a1138e --- /dev/null +++ b/cmake/macos/helpers.cmake @@ -0,0 +1,106 @@ +# CMake macOS helper functions module + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-lint: disable=C0307 +# cmake-format: on + +include_guard(GLOBAL) + +include(helpers_common) + +# set_target_properties_obs: Set target properties for use in obs-studio +function(set_target_properties_plugin target) + set(options "") + set(oneValueArgs "") + set(multiValueArgs PROPERTIES) + cmake_parse_arguments(PARSE_ARGV 0 _STPO "${options}" "${oneValueArgs}" + "${multiValueArgs}") + + message(DEBUG "Setting additional properties for target ${target}...") + + while(_STPO_PROPERTIES) + list(POP_FRONT _STPO_PROPERTIES key value) + set_property(TARGET ${target} PROPERTY ${key} "${value}") + endwhile() + + string(TIMESTAMP CURRENT_YEAR "%Y") + set_target_properties( + ${target} + PROPERTIES BUNDLE TRUE + BUNDLE_EXTENSION plugin + XCODE_ATTRIBUTE_PRODUCT_NAME ${target} + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER ${MACOS_BUNDLEID} + XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION ${PLUGIN_BUILD_NUMBER} + XCODE_ATTRIBUTE_MARKETING_VERSION ${PLUGIN_VERSION} + XCODE_ATTRIBUTE_GENERATE_INFOPLIST_FILE YES + XCODE_ATTRIBUTE_INFOPLIST_FILE "" + XCODE_ATTRIBUTE_INFOPLIST_KEY_CFBundleDisplayName ${target} + XCODE_ATTRIBUTE_INFOPLIST_KEY_NSHumanReadableCopyright + "(c) ${CURRENT_YEAR} ${PLUGIN_AUTHOR}" + XCODE_ATTRIBUTE_INSTALL_PATH + "$(USER_LIBRARY_DIR)/Application Support/obs-studio/plugins") + + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist") + set_target_properties( + ${target} + PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist") + endif() + + if(TARGET plugin-support) + target_link_libraries(${target} PRIVATE plugin-support) + endif() + + target_install_resources(${target}) + + get_target_property(target_sources ${target} SOURCES) + set(target_ui_files ${target_sources}) + list(FILTER target_ui_files INCLUDE REGEX ".+\\.(ui|qrc)") + source_group( + TREE "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX "UI Files" + FILES ${target_ui_files}) + + install(TARGETS ${target} LIBRARY DESTINATION .) + install( + FILES "$.dsym" + CONFIGURATIONS Release + DESTINATION . + OPTIONAL) + + configure_file(cmake/macos/resources/distribution.in + "${CMAKE_CURRENT_BINARY_DIR}/distribution" @ONLY) + configure_file(cmake/macos/resources/create-package.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/create-package.cmake" @ONLY) + install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/create-package.cmake") +endfunction() + +# target_install_resources: Helper function to add resources into bundle +function(target_install_resources target) + message(DEBUG "Installing resources for target ${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) + cmake_path( + RELATIVE_PATH data_file BASE_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}/data/" OUTPUT_VARIABLE relative_path) + cmake_path(GET relative_path PARENT_PATH relative_path) + target_sources(${target} PRIVATE "${data_file}") + set_property(SOURCE "${data_file}" PROPERTY MACOSX_PACKAGE_LOCATION + "Resources/${relative_path}") + source_group("Resources/${relative_path}" FILES "${data_file}") + endforeach() + endif() +endfunction() + +# target_add_resource: Helper function to add a specific resource to a bundle +function(target_add_resource target resource) + message( + DEBUG + "Add resource ${resource} to target ${target} at destination ${destination}..." + ) + target_sources(${target} PRIVATE "${resource}") + set_property(SOURCE "${resource}" PROPERTY MACOSX_PACKAGE_LOCATION Resources) + source_group("Resources" FILES "${resource}") +endfunction() diff --git a/cmake/macos/resources/ccache-launcher-c.in b/cmake/macos/resources/ccache-launcher-c.in new file mode 100644 index 00000000..0a14027c --- /dev/null +++ b/cmake/macos/resources/ccache-launcher-c.in @@ -0,0 +1,17 @@ +#!/bin/sh + +if [[ "$1" == "${CMAKE_C_COMPILER}" ]] ; then + shift +fi + +export CCACHE_CPP2=true +export CCACHE_DEPEND=true +export CCACHE_DIRECT=true +export CCACHE_FILECLONE=true +export CCACHE_INODECACHE=true +export CCACHE_NOCOMPILERCHECK='content' +export CCACHE_SLOPPINESS='include_file_mtime,include_file_ctime,clang_index_store,system_headers' +if [[ "${CI}" ]]; then + export CCACHE_NOHASHDIR=true +fi +exec "${CMAKE_C_COMPILER_LAUNCHER}" "${CMAKE_C_COMPILER}" "$@" diff --git a/cmake/macos/resources/ccache-launcher-cxx.in b/cmake/macos/resources/ccache-launcher-cxx.in new file mode 100644 index 00000000..2f03378f --- /dev/null +++ b/cmake/macos/resources/ccache-launcher-cxx.in @@ -0,0 +1,17 @@ +#!/bin/sh + +if [[ "$1" == "${CMAKE_CXX_COMPILER}" ]] ; then + shift +fi + +export CCACHE_CPP2=true +export CCACHE_NODEPEND=true +export CCACHE_DIRECT=true +export CCACHE_FILECLONE=true +export CCACHE_INODECACHE=true +export CCACHE_NOCOMPILERCHECK='content' +export CCACHE_SLOPPINESS='include_file_mtime,include_file_ctime,clang_index_store,system_headers' +if [[ "${CI}" ]]; then + export CCACHE_NOHASHDIR=true +fi +exec "${CMAKE_CXX_COMPILER_LAUNCHER}" "${CMAKE_CXX_COMPILER}" "$@" diff --git a/cmake/macos/resources/create-package.cmake.in b/cmake/macos/resources/create-package.cmake.in new file mode 100644 index 00000000..cd2ff35c --- /dev/null +++ b/cmake/macos/resources/create-package.cmake.in @@ -0,0 +1,41 @@ +make_directory("$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/package/Library/Application Support/obs-studio/plugins") + +if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.plugin" AND NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.plugin") + file(INSTALL DESTINATION "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/package/Library/Application Support/obs-studio/plugins" + TYPE DIRECTORY FILES "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.plugin" USE_SOURCE_PERMISSIONS) + + if(CMAKE_INSTALL_CONFIG_NAME MATCHES "^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$" OR CMAKE_INSTALL_CONFIG_NAME MATCHES "^([Mm][Ii][Nn][Ss][Ii][Zz][Ee][Rr][Ee][Ll])$") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.plugin.dSYM" AND NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.plugin.dSYM") + file(INSTALL DESTINATION "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/package/Library/Application Support/obs-studio/plugins" TYPE DIRECTORY FILES "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.plugin.dSYM" USE_SOURCE_PERMISSIONS) + endif() + endif() +endif() + +make_directory("$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/temp") + +execute_process( + COMMAND + codesign --force --deep --sign - + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/package/Library/Application Support/obs-studio/plugins/@CMAKE_PROJECT_NAME@.plugin" +) + +execute_process( + COMMAND /usr/bin/pkgbuild + --identifier '@MACOS_BUNDLEID@' + --version '@CMAKE_PROJECT_VERSION@' + --root "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/package" + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/temp/@CMAKE_PROJECT_NAME@.pkg" + COMMAND_ERROR_IS_FATAL ANY + ) + +execute_process( + COMMAND /usr/bin/productbuild + --distribution "@CMAKE_CURRENT_BINARY_DIR@/distribution" + --package-path "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/temp" + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.pkg" + COMMAND_ERROR_IS_FATAL ANY) + +if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/@CMAKE_PROJECT_NAME@.pkg") + file(REMOVE_RECURSE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/temp") + file(REMOVE_RECURSE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/package") +endif() diff --git a/cmake/macos/resources/distribution.in b/cmake/macos/resources/distribution.in new file mode 100644 index 00000000..016043b0 --- /dev/null +++ b/cmake/macos/resources/distribution.in @@ -0,0 +1,33 @@ + + + + + @CMAKE_PROJECT_NAME@ + + + + + + + #@CMAKE_PROJECT_NAME@.pkg + + + diff --git a/cmake/bundle/macos/installer-macos.pkgproj.in b/cmake/macos/resources/installer-macos.pkgproj.in similarity index 98% rename from cmake/bundle/macos/installer-macos.pkgproj.in rename to cmake/macos/resources/installer-macos.pkgproj.in index 09918431..9a3f8943 100644 --- a/cmake/bundle/macos/installer-macos.pkgproj.in +++ b/cmake/macos/resources/installer-macos.pkgproj.in @@ -63,7 +63,7 @@ GID 80 PATH - ../@RELATIVE_INSTALL_PATH@/@CMAKE_PROJECT_NAME@.plugin + ../release/@CMAKE_INSTALL_CONFIG_NAME@/@CMAKE_PROJECT_NAME@.plugin PATH_TYPE 1 PERMISSIONS @@ -538,7 +538,7 @@ TYPE 0 UUID - @MACOS_PACKAGE_UUID@ + @UUID_PACKAGE@ PROJECT @@ -584,13 +584,13 @@ 1 PACKAGE_UUID - @MACOS_PACKAGE_UUID@ + @UUID_PACKAGE@ TITLE TYPE 0 UUID - @MACOS_INSTALLER_UUID@ + @UUID_INSTALLER@ REMOVED @@ -732,7 +732,7 @@ BUILD_PATH PATH - ../@RELATIVE_BUILD_PATH@ + . PATH_TYPE 1 diff --git a/cmake/macos/xcode.cmake b/cmake/macos/xcode.cmake new file mode 100644 index 00000000..03db6d85 --- /dev/null +++ b/cmake/macos/xcode.cmake @@ -0,0 +1,199 @@ +# CMake macOS Xcode module + +include_guard(GLOBAL) + +# Use a compiler wrapper to enable ccache in Xcode projects +if(ENABLE_CCACHE AND CCACHE_PROGRAM) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/resources/ccache-launcher-c.in" + ccache-launcher-c) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/resources/ccache-launcher-cxx.in" + ccache-launcher-cxx) + + execute_process( + COMMAND chmod a+rx "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-c" + "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-cxx") + set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-c") + set(CMAKE_XCODE_ATTRIBUTE_CXX + "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-cxx") + set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") + set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}") +endif() + +# Set project variables +set(CMAKE_XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION ${PLUGIN_BUILD_NUMBER}) +set(CMAKE_XCODE_ATTRIBUTE_DYLIB_COMPATIBILITY_VERSION 1.0.0) +set(CMAKE_XCODE_ATTRIBUTE_MARKETING_VERSION ${PLUGIN_VERSION}) + +# Set deployment target +set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET + ${CMAKE_OSX_DEPLOYMENT_TARGET}) + +if(NOT CODESIGN_TEAM) + # Switch to manual codesigning if no codesigning team is provided + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${CODESIGN_IDENTITY}") +else() + if(CODESIGN_IDENTITY AND NOT CODESIGN_IDENTITY STREQUAL "-") + # Switch to manual codesigning if a non-adhoc codesigning identity is + # provided + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${CODESIGN_IDENTITY}") + else() + # Switch to automatic codesigning via valid team ID + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development") + endif() + set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${CODESIGN_TEAM}") +endif() + +# Only create a single Xcode project file +set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE) +# Add all libraries to project link phase (lets Xcode handle linking) +set(CMAKE_XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION) + +# Enable codesigning with secure timestamp when not in Debug configuration +# (required for Notarization) +set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=Release] "--timestamp") +set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=RelWithDebInfo] + "--timestamp") +set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=MinSizeRel] + "--timestamp") + +# Enable codesigning with hardened runtime option when not in Debug +# configuration (required for Notarization) +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=Release] YES) +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=RelWithDebInfo] YES) +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=MinSizeRel] YES) + +# Disable injection of Xcode's base entitlements used for debugging when not in +# Debug configuration (required for Notarization) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=Release] + NO) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=RelWithDebInfo] + NO) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=MinSizeRel] + NO) + +# Use Swift version 5.0 by default +set(CMAKE_XCODE_ATTRIBUTE_SWIFT_VERSION 5.0) + +# Use DWARF with separate dSYM files when in Release or MinSizeRel +# configuration. +# +# * Currently overruled by CMake's Xcode generator, requires adding '-g' flag to +# raw compiler command line for desired output configuration. Report to +# KitWare. +# +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Debug] dwarf) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=RelWithDebInfo] + dwarf) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Release] + dwarf-with-dsym) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=MinSizeRel] + dwarf-with-dsym) + +# Make all symbols hidden by default (currently overriden by CMake's compiler +# flags) +set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN YES) + +# Strip unused code +set(CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING YES) + +# Display mangled names in Debug configuration +set(CMAKE_XCODE_ATTRIBUTE_LINKER_DISPLAYS_MANGLED_NAMES[variant=Debug] YES) + +# Build active architecture only in Debug configuration +set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH[variant=Debug] YES) + +# Enable testability in Debug configuration +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_TESTABILITY[variant=Debug] YES) + +# Enable using ARC in ObjC by default +set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) +# Enable weak references in manual retain release +set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES) +# Disable strict aliasing +set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO) + +# Set C++ language default to c17 +# +# * CMake explicitly sets the version via compiler flag when transitive +# dependencies require specific compiler feature set, resulting in the flag +# being added twice. Report to KitWare as a feature request for Xcode +# generator +# * See also: https://gitlab.kitware.com/cmake/cmake/-/issues/17183 +# +# set(CMAKE_XCODE_ATTRIBUTE_GCC_C_LANGUAGE_STANDARD c17) +# +# Set C++ language default to c++17 +# +# * See above. Report to KitWare as a feature request for Xcode generator +# +# set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD c++17) + +# Enable support for module imports in ObjC +set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES YES) +# Enable automatic linking of imported modules in ObjC +set(CMAKE_XCODE_ATTRIBUTE_CLANG_MODULES_AUTOLINK YES) +# Enable strict msg_send rules for ObjC +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_STRICT_OBJC_MSGSEND YES) + +# Set default warnings for ObjC and C++ +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING YES_ERROR) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_BOOL_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_COMMA YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_CONSTANT_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_EMPTY_BODY YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_ENUM_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_INFINITE_RECURSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_INT_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_NON_LITERAL_NULL_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_OBJC_LITERAL_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_RANGE_LOOP_ANALYSIS YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_STRICT_PROTOTYPES NO) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION NO) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_MOVE YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_UNREACHABLE_CODE YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN__DUPLICATE_METHOD_MATCH YES) + +# Set default warnings for C and C++ +set(CMAKE_XCODE_ATTRIBUTE_GCC_NO_COMMON_BLOCKS YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_NEWLINE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_RETURN_TYPE YES_ERROR) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_CHECK_SWITCH_STATEMENTS YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_FOUR_CHARACTER_CONSTANTS YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SHADOW NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SIGN_COMPARE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_TYPECHECK_CALLS_TO_PRINTF YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNDECLARED_SELECTOR YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNINITIALIZED_AUTOS YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_FUNCTION NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES) + +# Add additional warning compiler flags +set(CMAKE_XCODE_ATTRIBUTE_WARNING_CFLAGS + "-Wvla -Wformat-security -Wno-inconsistent-missing-override -Wno-error=braced-scalar-init -Wno-error=unreachable-code-loop-increment" +) + +if(CMAKE_COMPILE_WARNING_AS_ERROR) + set(CMAKE_XCODE_ATTRIBUTE_GCC_TREAT_WARNINGS_AS_ERRORS YES) +endif() + +# Enable color diagnostics +set(CMAKE_COLOR_DIAGNOSTICS TRUE) + +# Disable usage of RPATH in build or install configurations +set(CMAKE_SKIP_RPATH TRUE) +# Have Xcode set default RPATH entries +set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS + "@executable_path/../Frameworks") diff --git a/cmake/windows/buildspec.cmake b/cmake/windows/buildspec.cmake new file mode 100644 index 00000000..75f2dca2 --- /dev/null +++ b/cmake/windows/buildspec.cmake @@ -0,0 +1,24 @@ +# CMake Windows build dependencies module + +include_guard(GLOBAL) + +include(buildspec_common) + +# _check_dependencies_windows: Set up Windows slice for _check_dependencies +function(_check_dependencies_windows) + set(arch ${CMAKE_GENERATOR_PLATFORM}) + set(platform windows-${arch}) + + set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps") + set(prebuilt_filename "windows-deps-VERSION-ARCH-REVISION.zip") + set(prebuilt_destination "obs-deps-VERSION-ARCH") + set(qt6_filename "windows-deps-qt6-VERSION-ARCH-REVISION.zip") + set(qt6_destination "obs-deps-qt6-VERSION-ARCH") + set(obs-studio_filename "VERSION.zip") + set(obs-studio_destination "obs-studio-VERSION") + set(dependencies_list prebuilt qt6 obs-studio) + + _check_dependencies() +endfunction() + +_check_dependencies_windows() diff --git a/cmake/windows/compilerconfig.cmake b/cmake/windows/compilerconfig.cmake new file mode 100644 index 00000000..d4938cdc --- /dev/null +++ b/cmake/windows/compilerconfig.cmake @@ -0,0 +1,62 @@ +# CMake Windows compiler configuration module + +include_guard(GLOBAL) + +include(compiler_common) + +# CMake 3.24 introduces a bug mistakenly interpreting MSVC as supporting the +# '-pthread' compiler flag +if(CMAKE_VERSION VERSION_EQUAL 3.24.0) + set(THREADS_HAVE_PTHREAD_ARG FALSE) +endif() + +# CMake 3.25 changed the way symbol generation is handled on Windows +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.25.0) + if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT ProgramDatabase) + else() + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded) + endif() +endif() + +message( + DEBUG + "Current Windows API version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") +if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM) + message( + DEBUG + "Maximum Windows API version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM}" + ) +endif() + +if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION VERSION_LESS 10.0.20348) + message( + FATAL_ERROR + "OBS requires Windows 10 SDK version 10.0.20348.0 or more recent.\n" + "Please download and install the most recent Windows platform SDK.") +endif() + +add_compile_options( + /W3 + /utf-8 + "$<$:/MP>" + "$<$:/MP>" + "$<$:${_obs_clang_c_options}>" + "$<$:${_obs_clang_cxx_options}>" + $<$>:/Gy>) + +add_compile_definitions( + UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS + $<$:DEBUG> $<$:_DEBUG>) + +# cmake-format: off +add_link_options($<$>:/OPT:REF> + $<$>:/OPT:ICF> + $<$>:/INCREMENTAL:NO> + /DEBUG + /Brepro) +# cmake-format: on + +if(CMAKE_COMPILE_WARNING_AS_ERROR) + add_link_options(/WX) +endif() diff --git a/cmake/windows/defaults.cmake b/cmake/windows/defaults.cmake new file mode 100644 index 00000000..fd40d221 --- /dev/null +++ b/cmake/windows/defaults.cmake @@ -0,0 +1,8 @@ +# CMake Windows defaults module + +include_guard(GLOBAL) + +# Enable find_package targets to become globally available targets +set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) + +include(buildspec) diff --git a/cmake/windows/helpers.cmake b/cmake/windows/helpers.cmake new file mode 100644 index 00000000..194cafeb --- /dev/null +++ b/cmake/windows/helpers.cmake @@ -0,0 +1,149 @@ +# CMake Windows helper functions module + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-format: on + +include_guard(GLOBAL) + +include(helpers_common) + +# set_target_properties_plugin: Set target properties for use in obs-studio +function(set_target_properties_plugin target) + set(options "") + set(oneValueArgs "") + set(multiValueArgs PROPERTIES) + cmake_parse_arguments(PARSE_ARGV 0 _STPO "${options}" "${oneValueArgs}" + "${multiValueArgs}") + + message(DEBUG "Setting additional properties for target ${target}...") + + while(_STPO_PROPERTIES) + list(POP_FRONT _STPO_PROPERTIES key value) + set_property(TARGET ${target} PROPERTY ${key} "${value}") + endwhile() + + string(TIMESTAMP CURRENT_YEAR "%Y") + + set_target_properties(${target} PROPERTIES VERSION 0 SOVERSION + ${PLUGIN_VERSION}) + + install( + TARGETS ${target} + RUNTIME DESTINATION bin/64bit + LIBRARY DESTINATION obs-plugins/64bit) + + install( + FILES "$" + CONFIGURATIONS RelWithDebInfo Debug Release + DESTINATION obs-plugins/64bit + OPTIONAL) + + if(OBS_BUILD_DIR) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory + "${OBS_BUILD_DIR}/obs-plugins/64bit" + COMMAND + "${CMAKE_COMMAND}" -E copy_if_different "$" + "$<$:$>" + "${OBS_BUILD_DIR}/obs-plugins/64bit" + COMMENT "Copy ${target} to obs-studio directory ${OBS_BUILD_DIR}" + VERBATIM) + endif() + + if(TARGET plugin-support) + target_link_libraries(${target} PRIVATE plugin-support) + endif() + + target_install_resources(${target}) + + get_target_property(target_sources ${target} SOURCES) + set(target_ui_files ${target_sources}) + list(FILTER target_ui_files INCLUDE REGEX ".+\\.(ui|qrc)") + source_group( + TREE "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX "UI Files" + FILES ${target_ui_files}) + + set(valid_uuid FALSE) + check_uuid(${_windowsAppUUID} valid_uuid) + if(NOT valid_uuid) + message( + FATAL_ERROR + "Specified Windows package UUID is not a valid UUID value: ${_windowsAppUUID}" + ) + else() + set(UUID_APP ${_windowsAppUUID}) + endif() + + configure_file(cmake/windows/resources/installer-Windows.iss.in + "${CMAKE_CURRENT_BINARY_DIR}/installer-Windows.generated.iss") + + configure_file(cmake/windows/resources/resource.rc.in + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.rc") + target_sources(${CMAKE_PROJECT_NAME} + PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.rc") +endfunction() + +# Helper function to add resources into bundle +function(target_install_resources target) + message(DEBUG "Installing resources for target ${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) + cmake_path( + RELATIVE_PATH data_file BASE_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}/data/" OUTPUT_VARIABLE relative_path) + cmake_path(GET relative_path PARENT_PATH relative_path) + target_sources(${target} PRIVATE "${data_file}") + source_group("Resources/${relative_path}" FILES "${data_file}") + endforeach() + + install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/" + DESTINATION data/obs-plugins/${target} + USE_SOURCE_PERMISSIONS) + + if(OBS_BUILD_DIR) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory + "${OBS_BUILD_DIR}/data/obs-plugins/${target}" + COMMAND + "${CMAKE_COMMAND}" -E copy_directory + "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${OBS_BUILD_DIR}/data/obs-plugins/${target}" + COMMENT "Copy ${target} resources to data directory" + VERBATIM) + endif() + endif() +endfunction() + +# Helper function to add a specific resource to a bundle +function(target_add_resource target resource) + message( + DEBUG + "Add resource '${resource}' to target ${target} at destination '${target_destination}'..." + ) + + install( + FILES "${resource}" + DESTINATION data/obs-plugins/${target} + COMPONENT Runtime) + + if(OBS_BUILD_DIR) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory + "${OBS_BUILD_DIR}/data/obs-plugins/${target}" + COMMAND "${CMAKE_COMMAND}" -E copy "${resource}" + "${OBS_BUILD_DIR}/data/obs-plugins/${target}" + COMMENT "Copy ${target} resource ${resource} to library directory" + VERBATIM) + endif() + source_group("Resources" FILES "${resource}") +endfunction() diff --git a/cmake/bundle/windows/installer-Windows.iss.in b/cmake/windows/resources/installer-Windows.iss.in similarity index 90% rename from cmake/bundle/windows/installer-Windows.iss.in rename to cmake/windows/resources/installer-Windows.iss.in index 2e0683a1..bcaf099e 100644 --- a/cmake/bundle/windows/installer-Windows.iss.in +++ b/cmake/windows/resources/installer-Windows.iss.in @@ -1,13 +1,13 @@ #define MyAppName "@CMAKE_PROJECT_NAME@" -#define MyAppVersion "@GIT_TAG@" +#define MyAppVersion "@CMAKE_PROJECT_VERSION@" #define MyAppPublisher "@PLUGIN_AUTHOR@" -#define MyAppURL "http://www.mywebsite.com" +#define MyAppURL "@PLUGIN_WEBSITE@" [Setup] ; NOTE: The value of AppId uniquely identifies this application. ; Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) -AppId={{@WINDOWS_INSTALLER_UUID@} +AppId={{@UUID_APP@} AppName={#MyAppName} AppVersion={#MyAppVersion} AppPublisher={#MyAppPublisher} @@ -25,7 +25,7 @@ DirExistsWarning=no Name: "english"; MessagesFile: "compiler:Default.isl" [Files] -Source: "..\release\*"; Excludes: "*.zip"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "..\release\Package\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "..\LICENSE"; Flags: dontcopy ; NOTE: Don't use "Flags: ignoreversion" on any shared system files diff --git a/cmake/windows/resources/resource.rc.in b/cmake/windows/resources/resource.rc.in new file mode 100644 index 00000000..5f3b00ec --- /dev/null +++ b/cmake/windows/resources/resource.rc.in @@ -0,0 +1,32 @@ +1 VERSIONINFO + FILEVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},0 + PRODUCTVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},0 + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x0L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "${PLUGIN_AUTHOR}" + VALUE "FileDescription", "${PROJECT_NAME}" + VALUE "FileVersion", "${PROJECT_VERSION}" + VALUE "InternalName", "${PROJECT_NAME}" + VALUE "LegalCopyright", "(C) ${CURRENT_YEAR} ${PLUGIN_AUTHOR}" + VALUE "OriginalFilename", "${PROJECT_NAME}" + VALUE "ProductName", "${PROJECT_NAME}" + VALUE "ProductVersion", "${PROJECT_VERSION}" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/plugins/midi/CMakeLists.txt b/plugins/midi/CMakeLists.txt index 38335c7e..733daac1 100644 --- a/plugins/midi/CMakeLists.txt +++ b/plugins/midi/CMakeLists.txt @@ -13,9 +13,17 @@ if(NOT EXISTS "${LIBREMIDI_DIR}/CMakeLists.txt") endif() add_subdirectory("${LIBREMIDI_DIR}" "${LIBREMIDI_DIR}/build" EXCLUDE_FROM_ALL) -if(MSVC) - target_compile_options(libremidi PRIVATE /wd4251 /wd4267 /wd4275) -endif(MSVC) +if(OS_WINDOWS) + if(MSVC) + target_compile_options(libremidi PUBLIC /wd4251 /wd4267 /wd4275) + endif() +else() + target_compile_options( + libremidi + PUBLIC -Wno-error=conversion -Wno-error=unused-result -Wno-error=shadow + -Wno-error=unused-parameter -Wno-error=deprecated-declarations + -Wno-error=sign-compare) +endif() # --- End of section --- diff --git a/plugins/video/CMakeLists.txt b/plugins/video/CMakeLists.txt index 770e45b6..b487a118 100644 --- a/plugins/video/CMakeLists.txt +++ b/plugins/video/CMakeLists.txt @@ -29,6 +29,9 @@ if(Leptonica_FOUND AND Tesseract_FOUND) ${Leptonica_LIBRARIES}) target_include_directories(${PROJECT_NAME} PRIVATE ${Tesseract_INCLUDE_DIRS} ${Leptonica_INCLUDE_DIRS}) + if(OS_WINDOWS) + set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") + endif() else() message( WARNING "OCR capabilities of video condition disabled!\n" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 322c9558..35aa8bdd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -64,6 +64,10 @@ target_include_directories(${PROJECT_NAME} if(MSVC) target_compile_options(${PROJECT_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267 /bigobj) +else() + target_compile_options( + ${PROJECT_NAME} PUBLIC -Wno-error=unused-parameter -Wno-error=conversion + -Wno-error=unused-value) endif() # --- regex --- #