# Copyright (C) 2017 Michael Fabian Dirks # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # CMake Setup cmake_minimum_required(VERSION 3.13...4.0) if(${CMAKE_VERSION} VERSION_LESS 3.19) set(LOGPREFIX "[StreamFX] ") else() list(APPEND CMAKE_MESSAGE_INDENT "[StreamFX] ") set(LOGPREFIX "") endif() # MacOSX: Require at least MacOSX 10.15 for C++17 support. if(APPLE) if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.15) CacheSet(CMAKE_OSX_DEPLOYMENT_TARGET "10.15") endif() endif() ################################################################################ # Modules ################################################################################ # Search Paths set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/clang" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/codesign" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/version" "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ) # Include include("util") # CacheClear, CacheSet include("version") # version() include("CheckIPOSupported") # check_ipo_supported ################################################################################ # Detect if we are building with OBS Studio (different from Grouped builds) ################################################################################ set(STANDALONE ON) if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}") set(GROUPED OFF) set(PREFIX "") else() set(GROUPED ON) set(PREFIX "StreamFX_") if(GROUPED AND ((TARGET libobs) OR (TARGET OBS::libobs))) set(STANDALONE OFF) endif() endif() if(STANDALONE) message(STATUS "${LOGPREFIX}This is a standalone build, please make sure you've followed the instructions.") else() message(STATUS "${LOGPREFIX}This is a combined build.") endif() ################################################################################ # Versioning ################################################################################ # For automatic versioning, which version is the "root" of the current changes? set(_VERSION_GIT_BASE "0.11.0") # What is our version goal? set(_VERSION "0.12.0") version(PARSE _VERSION "${_VERSION}") # If possible, automatically generate versions from git. if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git") find_program(GIT NAMES git git.exe ) if(EXISTS "${GIT}") # Calculate the Tweak version component from the given base version. execute_process( COMMAND "${GIT}" describe --tags --long --match "${_VERSION_GIT_BASE}" --abbrev=8 HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE GIT_RESULT OUTPUT_VARIABLE _VERSION_GIT ERROR_VARIABLE GIT_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) if(GIT_RESULT EQUAL 0) # Some minor string editing so the output conforms to SemVer 2.0.0. string(REPLACE "-" ";" _VERSION_GIT "${_VERSION_GIT}") # Parse as SemVer 2.0.0 list(GET _VERSION_GIT 1 _VERSION_GIT_TWEAK) list(GET _VERSION_GIT 2 _VERSION_GIT_BUILD) # Update our global version. version(MODIFY _VERSION "${_VERSION}" COMPRESS TWEAK "${_VERSION_GIT_TWEAK}" BUILD "${_VERSION_GIT_BUILD}" PRERELEASE "a" REQUIRE PATCH TWEAK ) version(PARSE _VERSION "${_VERSION}" REQUIRE PATCH TWEAK) else() message(WARNING "${LOGPREFIX}Unable to detect Tweak and Build component with 'git'.") endif() # Is there a tag on the current commit? execute_process( COMMAND "${GIT}" tag "--sort=-v:refname" "--points-at" HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE GIT_RESULT OUTPUT_VARIABLE _VERSION_TAG ERROR_VARIABLE GIT_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) if((GIT_RESULT EQUAL 0) AND (NOT "${_VERSION_TAG}" STREQUAL "")) # Some minor string editing so the output conforms to SemVer 2.0.0. string(REGEX REPLACE "[\r\n]+.*" "" _VERSION_TAG "${_VERSION_TAG}") # Parse as SemVer 2.0.0 version(PARSE _VERSION_TAG "${_VERSION_TAG}" REQUIRE PATCH TWEAK) if(_VERSION_TAG_PRERELEASE) string(SUBSTRING "${_VERSION_TAG_PRERELEASE}" 1 -1 _VERSION_TAG_TWEAK) string(SUBSTRING "${_VERSION_TAG_PRERELEASE}" 0 1 _VERSION_TAG_PRERELEASE) if(NOT _VERSION_TAG_TWEAK STREQUAL _VERSION_GIT_TWEAK) message(WARNING "${LOGPREFIX}'git' tag mismatches detected version: '${_VERSION_TAG_TWEAK}' != '${_VERSION_GIT_TWEAK}'.") endif() endif() # Update our global version. version(GENERATE _VERSION COMPRESS MAJOR "${_VERSION_TAG_MAJOR}" MINOR "${_VERSION_TAG_MINOR}" PATCH "${_VERSION_TAG_PATCH}" TWEAK "${_VERSION_TAG_TWEAK}" PRERELEASE "${_VERSION_TAG_PRERELEASE}" BUILD "${_VERSION_BUILD}" REQUIRE PATCH TWEAK ) version(PARSE _VERSION "${_VERSION}" REQUIRE PATCH TWEAK) endif() else() message(STATUS "${LOGPREFIX}'git' not found, automatic version detection disabled.") endif() else() message(STATUS "${LOGPREFIX}Not a git repository, automatic version detection disabled.") endif() # Allow manual overrides of the detected version. set(${PREFIX}VERSION "" CACHE STRING "Override detected or pre-configured version with this string. Accepts strings in CMake and SemVer 2.0.0 format.") if(NOT ("${${PREFIX}VERSION}" STREQUAL "")) version(PARSE _VERSION_CFG "${${PREFIX}VERSION}" REQUIRE PATCH TWEAK) if("${_VERSION_CFG_BUILD}" STREQUAL "") set(_VERSION_CFG_BUILD "${_VERSION_BUILD}") endif() version(GENERATE _VERSION COMPRESS MAJOR "${_VERSION_CFG_MAJOR}" MINOR "${_VERSION_CFG_MINOR}" PATCH "${_VERSION_CFG_PATCH}" TWEAK "${_VERSION_CFG_TWEAK}" PRERELEASE "${_VERSION_CFG_PRERELEASE}" BUILD "${_VERSION_CFG_BUILD}" ) endif() set(_VERSION_THIN "${_VERSION_MAJOR}.${_VERSION_MINOR}.${_VERSION_PATCH}") if(NOT (_VERSION_PRERELEASE STREQUAL "")) set(_VERSION_THIN "${_VERSION_THIN}${_VERSION_PRERELEASE}${_VERSION_TWEAK}") endif() if(NOT (VERSION_COMMIT STREQUAL "")) set(_VERSION_THIN "${_VERSION_THIN}-${_VERSION_BUILD}") endif() # Parse & Log the detected version. message(STATUS "${LOGPREFIX}Version ${_VERSION}") ################################################################################ # Project ################################################################################ # Metadata version(GENERATE PROJECT_VERSION MAJOR "${_VERSION_MAJOR}" MINOR "${_VERSION_MINOR}" PATCH "${_VERSION_PATCH}" TWEAK "${_VERSION_TWEAK}" REQUIRE PATCH TWEAK ) project( StreamFX VERSION ${PROJECT_VERSION} DESCRIPTION "Additional sources, filters, transitions and encoders for OBS Studio." HOMEPAGE_URL "https://streamfx.xaymar.com/" ) set(PROJECT_TITLE "StreamFX (for OBS Studio)") set(PROJECT_AUTHORS "Michael Fabian 'Xaymar' Dirks ") set(PROJECT_COPYRIGHT "2017 - 2022, Michael Fabian Dirks. All Rights Reserved") set(PROJECT_TRADEMARKS "") list(APPEND PROJECT_TRADEMARKS "AMD is a trademark of Advanced Micro Devices Inc." "NVIDIA is a trademark of Nvidia Corporation" ) ################################################################################ # Platform Setup ################################################################################ # Operating System if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set(D_PLATFORM_OS "windows") set(D_PLATFORM_WINDOWS 1) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(D_PLATFORM_OS "linux") set(D_PLATFORM_LINUX 1) elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(D_PLATFORM_OS "macos") set(D_PLATFORM_MAC 1) else() set(D_PLATFORM_OS "unknown") set(D_PLATFORM_UNKNOWN 1) message(WARNING "${LOGPREFIX}The operating system '${CMAKE_SYSTEM_NAME}' is unknown to to this script, continue at your own risk.") endif() # Architecture set(ARCH_INSTR_32 "i386;i686;x86;arm;ARM") set(ARCH_INSTR_64 "x86_64;AMD64;IA64;arm64;ARM64") set(ARCH_INSTR_X86 "i386;i686;x86;x86_64;AMD64") set(ARCH_INSTR_ARM "arm;ARM;arm64;ARM64") set(ARCH_INSTR_ITANIUM "IA64") set(ARCH_BITS 0) set(ARCH_BITS_POINTER 0) set(ARCH_INST "") # - Bitness list(FIND ARCH_INSTR_32 "${CMAKE_SYSTEM_PROCESSOR}" FOUND) if(FOUND GREATER -1) set(ARCH_BITS 32) endif() list(FIND ARCH_INSTR_64 "${CMAKE_SYSTEM_PROCESSOR}" FOUND) if(FOUND GREATER -1) set(ARCH_BITS 64) endif() set(D_PLATFORM_BITS ${ARCH_BITS}) # - Pointer Size (bits) math(EXPR ARCH_BITS_POINTER "8*${CMAKE_SIZEOF_VOID_P}") set(D_PLATFORM_BITS_PTR ${ARCH_BITS_POINTER}) # - Basic Instruction Set list(FIND ARCH_INSTR_X86 "${CMAKE_SYSTEM_PROCESSOR}" FOUND) if(FOUND GREATER -1) list(APPEND ARCH_INST "x86") set(D_PLATFORM_INSTR_X86 ON) set(D_PLATFORM_ARCH_X86 ON) endif() list(FIND ARCH_INSTR_ARM "${CMAKE_SYSTEM_PROCESSOR}" FOUND) if(FOUND GREATER -1) list(APPEND ARCH_INST "ARM") set(D_PLATFORM_INSTR_ARM ON) set(D_PLATFORM_ARCH_ARM ON) endif() list(FIND ARCH_INSTR_ITANIUM "${CMAKE_SYSTEM_PROCESSOR}" FOUND) if(FOUND GREATER -1) list(APPEND ARCH_INST "Itanium") set(D_PLATFORM_INSTR_ITANIUM ON) set(D_PLATFORM_ARCH_ITANIUM ON) endif() check_ipo_supported(RESULT D_HAS_IPO) set(D_PLATFORM_INSTR ${ARCH_INST}) set(D_PLATFORM_ARCH ${ARCH_INST}) message(STATUS "${LOGPREFIX}Target is ${D_PLATFORM_BITS}bit ${ARCH_INST} with a pointer size of ${D_PLATFORM_BITS_PTR}bit.") ################################################################################ # Options ################################################################################ # Dependencies if(STANDALONE) set(libobs_DIR "" CACHE PATH "Path to libobs and obs-frontend-api") set(Qt_DIR "" CACHE PATH "Path to Qt6 or Qt5") set(CURL_DIR "" CACHE PATH "Path to CURL") set(FFmpeg_DIR "" CACHE PATH "Path to FFmpeg") endif() set(AOM_DIR "" CACHE PATH "Path to AOM library") # Features ## Encoders set(${PREFIX}ENABLE_ENCODER_FFMPEG ON CACHE BOOL "Enable FFmpeg Encoder integration.") set(${PREFIX}ENABLE_ENCODER_FFMPEG_AMF ON CACHE BOOL "Enable AMF Encoder in FFmpeg.") set(${PREFIX}ENABLE_ENCODER_FFMPEG_NVENC ON CACHE BOOL "Enable NVENC Encoder in FFmpeg.") set(${PREFIX}ENABLE_ENCODER_FFMPEG_PRORES ON CACHE BOOL "Enable ProRes Encoder in FFmpeg.") set(${PREFIX}ENABLE_ENCODER_FFMPEG_DNXHR ON CACHE BOOL "Enable DNXHR Encoder in FFmpeg.") set(${PREFIX}ENABLE_ENCODER_AOM_AV1 ON CACHE BOOL "Enable AOM AV1 Encoder.") ## Filters set(${PREFIX}ENABLE_FILTER_AUTOFRAMING ON CACHE BOOL "Enable Auto-Framing Filter") set(${PREFIX}ENABLE_FILTER_AUTOFRAMING_NVIDIA ON CACHE BOOL "Enable NVIDIA provider(s) Auto-Framing Filter") set(${PREFIX}ENABLE_FILTER_BLUR ON CACHE BOOL "Enable Blur Filter") set(${PREFIX}ENABLE_FILTER_COLOR_GRADE ON CACHE BOOL "Enable Color Grade Filter") set(${PREFIX}ENABLE_FILTER_DENOISING ON CACHE BOOL "Enable Denoising filter") set(${PREFIX}ENABLE_FILTER_DENOISING_NVIDIA ON CACHE BOOL "Enable NVIDIA provider(s) for Denoising Filter") set(${PREFIX}ENABLE_FILTER_DISPLACEMENT ON CACHE BOOL "Enable Displacement Filter") set(${PREFIX}ENABLE_FILTER_DYNAMIC_MASK ON CACHE BOOL "Enable Dynamic Mask Filter") set(${PREFIX}ENABLE_FILTER_SDF_EFFECTS ON CACHE BOOL "Enable SDF Effects Filter") set(${PREFIX}ENABLE_FILTER_SHADER ON CACHE BOOL "Enable Shader Filter") set(${PREFIX}ENABLE_FILTER_TRANSFORM ON CACHE BOOL "Enable Transform Filter") set(${PREFIX}ENABLE_FILTER_UPSCALING ON CACHE BOOL "Enable Upscaling Filter") set(${PREFIX}ENABLE_FILTER_UPSCALING_NVIDIA ON CACHE BOOL "Enable NVIDIA provider(s) for Upscaling Filter") set(${PREFIX}ENABLE_FILTER_VIRTUAL_GREENSCREEN ON CACHE BOOL "Enable Virtual Greenscreen Filter") set(${PREFIX}ENABLE_FILTER_VIRTUAL_GREENSCREEN_NVIDIA ON CACHE BOOL "Enable NVIDIA provider(s) for Virtual Greenscreen Filter") ## Sources set(${PREFIX}ENABLE_SOURCE_MIRROR ON CACHE BOOL "Enable Mirror Source") set(${PREFIX}ENABLE_SOURCE_SHADER ON CACHE BOOL "Enable Shader Source") ## Transitions set(${PREFIX}ENABLE_TRANSITION_SHADER ON CACHE BOOL "Enable Shader Transition") ## FrontEnd & UI set(${PREFIX}ENABLE_FRONTEND ON CACHE BOOL "Enable Frontend code.") set(${PREFIX}ENABLE_UPDATER ON CACHE BOOL "Enable automatic update checks.") ## Code Related set(${PREFIX}ENABLE_CLANG OFF CACHE BOOL "Enable Clang integration for supported compilers.") set(${PREFIX}ENABLE_CODESIGN OFF CACHE BOOL "Enable Code Signing integration for supported environments.") set(${PREFIX}ENABLE_PROFILING OFF CACHE BOOL "Enable CPU and GPU performance tracking, which has a non-zero overhead at all times. Do not enable this for release builds.") ## Compile/Link Related set(${PREFIX}ENABLE_LTO ${D_HAS_IPO} CACHE BOOL "Enable Link Time Optimization for faster and smaller binaries.") set(${PREFIX}ENABLE_FASTMATH ON CACHE BOOL "Enable fast math optimizations, which sacrifice precision and stability.") if(D_PLATFORM_ARCH_X86) set(${PREFIX}TARGET_X86_64_V4 OFF CACHE BOOL "Target x86-64-v4 (x86-64-v3, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL).") set(${PREFIX}TARGET_X86_64_V3 OFF CACHE BOOL "Target x86-64-v3 (x86-64-v2, AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, OSXSAVE).") set(${PREFIX}TARGET_X86_64_V2_EX ON CACHE BOOL "Target extended x86-64-v2 (x86-64-v2, AVX, BMI1, BMI2, F16C, FMA, MOVBE).") set(${PREFIX}TARGET_X86_64_V2 ON CACHE BOOL "Target x86-64-v2 (x86-64, CMPXCHG16B, LAHF-SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3).") set(${PREFIX}TARGET_X86_64 ON CACHE BOOL "Target x86-64 (CMOV, CX8, FPU, FXSR, MMX, OSFXSR, SCE, SSE, SSE2).") endif() if(NOT MSVC) set(${PREFIX}TARGET_NATIVE OFF CACHE BOOL "Target the native CPU architecture. Enable it for development or personal builds, but disable it for distribution.") endif() # Installation / Packaging if(STANDALONE) set(STRUCTURE_UNIFIED CACHE BOOL "Install for use in a Plugin Manager") if(D_PLATFORM_LINUX) set(STRUCTURE_PACKAGEMANAGER CACHE BOOL "Install for use in a Package Manager (system-wide installation)") endif() set(PACKAGE_PREFIX "${CMAKE_BINARY_DIR}" CACHE PATH "Where to place the packages?") set(PACKAGE_NAME "${PROJECT_NAME}" CACHE STRING "What should the package be called?") set(PACKAGE_SUFFIX "" CACHE STRING "Any suffix for the package name? (Defaults to the current version string)") endif() ################################################################################ # Clang ################################################################################ if(${PREFIX}ENABLE_CLANG AND (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/clang/Clang.cmake")) include("cmake/clang/Clang.cmake") set(HAVE_CLANG ON) endif() ################################################################################ # Codesign ################################################################################ if(${PREFIX}ENABLE_CODESIGN AND (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/codesign/CodeSign.cmake")) include("cmake/codesign/CodeSign.cmake") set(HAVE_CODESIGN ON) set(${PREFIX}CODESIGN_FILE "" CACHE FILEPATH "Path to Code-Signing certificate.") if(WIN32) set(${PREFIX}CODESIGN_NAME "" CACHE STRING "Name of Code-Signing certificate in Windows's certificate storage.") endif() set(${PREFIX}CODESIGN_PASS "" CACHE STRING "Password for Code-Signing certificate.") set(${PREFIX}CODESIGN_TIMESTAMPS ON CACHE BOOL "Should the resulting binary be timestamped?") set(_CODESIGN_FILE "$ENV{${PREFIX}CODESIGN_FILE}") if(${PREFIX}CODESIGN_FILE) set(_CODESIGN_FILE "${${PREFIX}CODESIGN_FILE}") endif() set(_CODESIGN_NAME "$ENV{${PREFIX}CODESIGN_NAME}") if(${PREFIX}CODESIGN_NAME) set(_CODESIGN_NAME "${${PREFIX}CODESIGN_NAME}") endif() set(_CODESIGN_PASS "$ENV{${PREFIX}CODESIGN_PASS}") if(${PREFIX}CODESIGN_PASS) set(_CODESIGN_PASS "${${PREFIX}CODESIGN_PASS}") endif() endif() ################################################################################ # Component search paths ################################################################################ list(APPEND CMAKE_PREFIX_PATH "${${PREFIX}AOM_PATH}" "${${PREFIX}OBSDEPS_PATH}" "${${PREFIX}QT_PATH}" "${AOM_DIR}" "${CURL_DIR}" "${DepsPath}" "${FFmpeg_DIR}" "${libobs_DIR}" "${Qt_DIR}" "${Qt5_DIR}" "${Qt6_DIR}" "${QTDIR}" ) if(D_PLATFORM_MAC) list(APPEND CMAKE_PREFIX_PATH "${${PREFIX}AOM_PATH}/Frameworks" "${${PREFIX}OBSDEPS_PATH}/Frameworks" "${${PREFIX}QT_PATH}/Frameworks" "${AOM_DIR}/Frameworks" "${CURL_DIR}/Frameworks" "${DepsPath}/Frameworks" "${FFmpeg_DIR}/Frameworks" "${libobs_DIR}/Frameworks" "${Qt_DIR}/Frameworks" "${Qt5_DIR}/Frameworks" "${Qt6_DIR}/Frameworks" "${QTDIR}/Frameworks" ) endif() ################################################################################ # Components ################################################################################ # Component resolving: # 1. Check which features are enabled. For each feature, set what they require to ON. # 2. Try and find required items. # 3. Again check which features are enabled, if their requirements are missing, warn about it and disable them. # TODO: Consider making this an error instead. macro(is_feature_enabled FEATURE OUTPUT) set(T_ENABLED ${${PREFIX}ENABLE_${FEATURE}}) set(T_DISABLED ${${PREFIX}DISABLE_${FEATURE}}) if(T_ENABLED AND NOT T_DISABLED) set(${OUTPUT} ON) else() # set(${PREFIX}DISABLE_${FEATURE} ON CACHE INTERNAL "" FORCE) set(${OUTPUT} OFF) endif() endmacro() macro(set_feature_disabled FEATURE DISABLED) set(${PREFIX}DISABLE_${FEATURE} ${DISABLED} CACHE INTERNAL "" FORCE) endmacro() # Features function(feature_encoder_ffmpeg RESOLVE) is_feature_enabled(ENCODER_FFMPEG T_CHECK) if(RESOLVE AND T_CHECK) if(NOT HAVE_FFMPEG) message(WARNING "${LOGPREFIX}FFmpeg Encoder requires FFmpeg. Disabling...") set_feature_disabled(ENCODER_FFMPEG ON) else() # AMF is_feature_enabled(ENCODER_FFMPEG_AMF T_CHECK) if(T_CHECK AND D_PLATFORM_MAC) message(WARNING "${LOGPREFIX}FFmpeg Encoder 'AMF' requires Windows or Linux. Disabling...") set_feature_disabled(ENCODER_FFMPEG_AMF ON) endif() # NVENC is_feature_enabled(ENCODER_FFMPEG_NVENC T_CHECK) if(T_CHECK AND D_PLATFORM_MAC) message(WARNING "${LOGPREFIX}FFmpeg Encoder 'NVENC' requires Windows or Linux. Disabling...") set_feature_disabled(ENCODER_FFMPEG_NVENC ON) endif() # ProRes is_feature_enabled(ENCODER_FFMPEG_PRORES T_CHECK) # DNxHR is_feature_enabled(ENCODER_FFMPEG_DNXHR T_CHECK) endif() elseif(T_CHECK) set(REQUIRE_FFMPEG ON PARENT_SCOPE) endif() endfunction() function(feature_encoder_aom_av1 RESOLVE) is_feature_enabled(ENCODER_AOM_AV1 T_CHECK) if(RESOLVE AND T_CHECK) if(NOT HAVE_AOM) message(WARNING "${LOGPREFIX}AOM AV1 encoder missing AOM library. Disabling...") set_feature_disabled(ENCODER_AOM_AV1 ON) endif() elseif(T_CHECK) set(REQUIRE_AOM ON PARENT_SCOPE) endif() endfunction() function(feature_filter_autoframing RESOLVE) is_feature_enabled(FILTER_AUTOFRAMING T_CHECK) if(RESOLVE AND T_CHECK) # Verify that the requirements for the providers are available if(NOT HAVE_NVIDIA_AR_SDK) message(WARNING "${LOGPREFIX}'NVIDIA Augmented Reality SDK' is missing. Disabling NVIDIA provider...") set_feature_disabled(FILTER_AUTOFRAMING_NVIDIA ON) endif() # Verify that we have at least one provider for Auto-Framing. is_feature_enabled(FILTER_AUTOFRAMING_NVIDIA T_CHECK_NVIDIA) if(NOT T_CHECK_NVIDIA) message(WARNING "${LOGPREFIX}Auto-Framing has no available providers. Disabling...") set_feature_disabled(FILTER_AUTOFRAMING ON) endif() elseif(T_CHECK) set(REQUIRE_NVIDIA_AR_SDK ON PARENT_SCOPE) set(REQUIRE_NVIDIA_CUDA ON PARENT_SCOPE) endif() endfunction() function(feature_filter_blur RESOLVE) is_feature_enabled(FILTER_BLUR T_CHECK) endfunction() function(feature_filter_color_grade RESOLVE) is_feature_enabled(FILTER_COLOR_GRADE T_CHECK) endfunction() function(feature_filter_denoising RESOLVE) is_feature_enabled(FILTER_DENOISING T_CHECK) if(RESOLVE AND T_CHECK) # Verify that the requirements for the providers are available if(NOT HAVE_NVIDIA_VFX_SDK) message(WARNING "${LOGPREFIX}'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider...") set_feature_disabled(FILTER_DENOISING_NVIDIA ON) endif() # Verify that we have at least one provider for Video Denoising. is_feature_enabled(FILTER_DENOISING_NVIDIA T_CHECK_NVIDIA) if(NOT T_CHECK_NVIDIA) message(WARNING "${LOGPREFIX}Denoising has no available providers. Disabling...") set_feature_disabled(FILTER_DENOISING ON) endif() elseif(T_CHECK) set(REQUIRE_NVIDIA_VFX_SDK ON PARENT_SCOPE) endif() endfunction() function(feature_filter_displacement RESOLVE) is_feature_enabled(FILTER_DISPLACEMENT T_CHECK) endfunction() function(feature_filter_dynamic_mask RESOLVE) is_feature_enabled(FILTER_DYNAMIC_MASK T_CHECK) endfunction() function(feature_filter_sdf_effects RESOLVE) is_feature_enabled(FILTER_SDF_EFFECTS T_CHECK) endfunction() function(feature_filter_shader RESOLVE) is_feature_enabled(FILTER_SHADER T_CHECK) endfunction() function(feature_filter_transform RESOLVE) is_feature_enabled(FILTER_TRANSFORM T_CHECK) endfunction() function(feature_filter_upscaling RESOLVE) is_feature_enabled(FILTER_UPSCALING T_CHECK) if(RESOLVE AND T_CHECK) # Verify that the requirements for the providers are available if(NOT HAVE_NVIDIA_VFX_SDK) message(WARNING "${LOGPREFIX}'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider(s)...") set_feature_disabled(FILTER_UPSCALING_NVIDIA ON) endif() # Verify that we have at least one provider for Video Super-Resolution. is_feature_enabled(FILTER_UPSCALING_NVIDIA T_CHECK_NVIDIA) if(NOT T_CHECK_NVIDIA) message(WARNING "${LOGPREFIX}Upscaling has no available providers. Disabling...") set_feature_disabled(FILTER_UPSCALING ON) endif() elseif(T_CHECK) set(REQUIRE_NVIDIA_VFX_SDK ON PARENT_SCOPE) endif() endfunction() function(feature_filter_virtual_greenscreen RESOLVE) is_feature_enabled(FILTER_VIRTUAL_GREENSCREEN T_CHECK) if(RESOLVE AND T_CHECK) # Verify that the requirements for the providers are available if(NOT HAVE_NVIDIA_VFX_SDK) message(WARNING "${LOGPREFIX}'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider(s)...") set_feature_disabled(FILTER_VIRTUAL_GREENSCREEN_NVIDIA ON) endif() # Verify that we have at least one provider for Video Super-Resolution. is_feature_enabled(FILTER_VIRTUAL_GREENSCREEN_NVIDIA T_CHECK_NVIDIA) if(NOT T_CHECK_NVIDIA) message(WARNING "${LOGPREFIX}Virtual Greenscreen has no available providers. Disabling...") set_feature_disabled(FILTER_VIRTUAL_GREENSCREEN ON) endif() elseif(T_CHECK) set(REQUIRE_NVIDIA_VFX_SDK ON PARENT_SCOPE) endif() endfunction() function(feature_source_mirror RESOLVE) is_feature_enabled(SOURCE_MIRROR T_CHECK) endfunction() function(feature_source_shader RESOLVE) is_feature_enabled(SOURCE_SHADER T_CHECK) endfunction() function(feature_transition_shader RESOLVE) is_feature_enabled(TRANSITION_SHADER T_CHECK) endfunction() function(feature_frontend RESOLVE) is_feature_enabled(FRONTEND T_CHECK) if(RESOLVE AND T_CHECK) if(NOT (Qt6_FOUND OR Qt5_FOUND)) message(WARNING "${LOGPREFIX}Front-End requires Qt. Disabling...") set_feature_disabled(FRONTEND ON) elseif(NOT obs-frontend-api_FOUND) message(WARNING "${LOGPREFIX}Front-End requires OBS FrontEnd API. Disabling...") set_feature_disabled(FRONTEND ON) endif() elseif(T_CHECK) set(REQUIRE_QT ON PARENT_SCOPE) set(REQUIRE_OBS_FRONTEND_API ON PARENT_SCOPE) endif() endfunction() function(feature_updater RESOLVE) is_feature_enabled(UPDATER T_CHECK) if(RESOLVE AND T_CHECK) if(NOT CURL_FOUND) message(WARNING "${LOGPREFIX}Updater requires CURL. Disabling...") set_feature_disabled(UPDATER ON) elseif(NOT HAVE_JSON) message(WARNING "${LOGPREFIX}Updater requires nlohmann::json. Disabling...") set_feature_disabled(UPDATER ON) endif() elseif(T_CHECK) set(REQUIRE_CURL ON PARENT_SCOPE) set(REQUIRE_JSON ON PARENT_SCOPE) endif() endfunction() # Set Requirements feature_encoder_ffmpeg(OFF) feature_encoder_aom_av1(OFF) feature_filter_autoframing(OFF) feature_filter_blur(OFF) feature_filter_color_grade(OFF) feature_filter_denoising(OFF) feature_filter_displacement(OFF) feature_filter_dynamic_mask(OFF) feature_filter_sdf_effects(OFF) feature_filter_shader(OFF) feature_filter_transform(OFF) feature_filter_upscaling(OFF) feature_filter_virtual_greenscreen(OFF) feature_source_mirror(OFF) feature_source_shader(OFF) feature_transition_shader(OFF) feature_frontend(OFF) feature_updater(OFF) # Fulfill Requirements #- OBS: Library if(STANDALONE) find_package("libobs" REQUIRED CONFIG) elseif(NOT TARGET OBS::libobs) # Add the missing OBS::libobs alias target if possible. add_library(OBS::libobs ALIAS libobs) endif() if(D_PLATFORM_MAC) # We may need to reconstruct the include directories on MacOS. get_target_property(libobs_INTERFACE_INCLUDE_DIRECTORIES OBS::libobs INTERFACE_INCLUDE_DIRECTORIES) if("${libobs_INTERFACE_INCLUDE_DIRECTORIES}" STREQUAL "libobs_INTERFACE_INCLUDE_DIRECTORIES-NOTFOUND") get_target_property(libobs_IMPORTED_LOCATION_RELEASE OBS::libobs IMPORTED_LOCATION_RELEASE) get_filename_component(libobs_IMPORTED_LOCATION_RELEASE "${libobs_IMPORTED_LOCATION_RELEASE}" DIRECTORY) get_filename_component(libobs_IMPORTED_LOCATION_RELEASE "${libobs_IMPORTED_LOCATION_RELEASE}" DIRECTORY) get_filename_component(libobs_IMPORTED_LOCATION_RELEASE "${libobs_IMPORTED_LOCATION_RELEASE}" DIRECTORY) set(libobs_IMPORTED_LOCATION_RELEASE "${libobs_IMPORTED_LOCATION_RELEASE}/Headers") set_target_properties(OBS::libobs PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${libobs_IMPORTED_LOCATION_RELEASE}" ) endif() endif() #- OBS: Front-End API set(obs-frontend-api_FOUND OFF) if(REQUIRE_OBS_FRONTEND_API) if(STANDALONE) find_package("obs-frontend-api" CONFIG) set(obs-frontend-api_FOUND "${obs-frontend-api_FOUND}") elseif(TARGET obs-frontend-api) set(obs-frontend-api_FOUND ON) endif() if(NOT TARGET OBS::obs-frontend-api) add_library(OBS::obs-frontend-api ALIAS obs-frontend-api) endif() endif() #- CURL set(CURL_FOUND OFF) if(REQUIRE_CURL) find_package("CURL") endif() #- FFmpeg set(HAVE_FFMPEG OFF) if(REQUIRE_FFMPEG) find_package("FFmpeg" COMPONENTS "avutil" "avcodec" "swscale" ) set(HAVE_FFMPEG ${FFmpeg_FOUND}) endif() #- AOM set(HAVE_AOM OFF) if(REQUIRE_AOM) if(NOT D_PLATFORM_MAC) find_package("AOM") set(HAVE_AOM ${AOM_FOUND}) endif() endif() #- JSON set(HAVE_JSON OFF) if(REQUIRE_JSON) if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third-party/nlohmann-json/single_include") message(FATAL_ERROR "${LOGPREFIX}Please make sure to update git submodules to their latest supported version.") return() else() set(JSON_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/third-party/nlohmann-json/single_include") set(HAVE_JSON ON) endif() endif() #- NVIDIA Augmented Reality SDK set(HAVE_NVIDIA_AR_SDK OFF) if(REQUIRE_NVIDIA_AR_SDK AND D_PLATFORM_WINDOWS) if(EXISTS "${PROJECT_SOURCE_DIR}/third-party/nvidia-maxine-ar-sdk/version.h") set(HAVE_NVIDIA_AR_SDK ON) endif() if(NOT TARGET NVIDIA::AR) add_library(NVIDIA::AR IMPORTED INTERFACE) target_include_directories(NVIDIA::AR INTERFACE "${PROJECT_SOURCE_DIR}/third-party/nvidia-maxine-ar-sdk/nvar/include/" "${PROJECT_SOURCE_DIR}/third-party/nvidia-maxine-ar-sdk/nvar/src/" ) endif() endif() #- NVIDIA Video Effects SDK set(HAVE_NVIDIA_VFX_SDK OFF) if(REQUIRE_NVIDIA_VFX_SDK AND D_PLATFORM_WINDOWS) if(EXISTS "${PROJECT_SOURCE_DIR}/third-party/nvidia-maxine-vfx-sdk/version.h") set(HAVE_NVIDIA_VFX_SDK ON) endif() if(NOT TARGET NVIDIA::VFX) add_library(NVIDIA::VFX IMPORTED INTERFACE) target_include_directories(NVIDIA::VFX INTERFACE "${PROJECT_SOURCE_DIR}/third-party/nvidia-maxine-vfx-sdk/nvvfx/include/" "${PROJECT_SOURCE_DIR}/third-party/nvidia-maxine-vfx-sdk/nvvfx/src/" ) endif() set(REQUIRE_NVIDIA_CUDA ON) endif() #- NVIDIA CUDA (Windows) set(HAVE_NVIDIA_CUDA OFF) if(REQUIRE_NVIDIA_CUDA AND D_PLATFORM_WINDOWS) set(HAVE_NVIDIA_CUDA ON) endif() #- Qt if(REQUIRE_QT) # Try Qt6 first... find_package("Qt6" COMPONENTS Core Gui Widgets CONFIG ) # If Qt6 isn't present, try Qt5 if(NOT Qt6_FOUND) find_package("Qt5" COMPONENTS Core Gui Widgets CONFIG ) endif() if(Qt6_FOUND) message(STATUS "${LOGPREFIX}Using Qt6.") elseif(Qt5_FOUND) message(STATUS "${LOGPREFIX}Using Qt5.") endif() endif() # Verify Requirements feature_encoder_ffmpeg(ON) feature_encoder_aom_av1(ON) feature_filter_autoframing(ON) feature_filter_blur(ON) feature_filter_color_grade(ON) feature_filter_denoising(ON) feature_filter_displacement(ON) feature_filter_dynamic_mask(ON) feature_filter_sdf_effects(ON) feature_filter_shader(ON) feature_filter_transform(ON) feature_filter_upscaling(ON) feature_filter_virtual_greenscreen(ON) feature_source_mirror(ON) feature_source_shader(ON) feature_transition_shader(ON) feature_frontend(ON) feature_updater(ON) ################################################################################ # Code ################################################################################ set(PROJECT_DATA ) set(PROJECT_LIBRARIES ) set(PROJECT_LIBRARIES_DELAYED ) set(PROJECT_INCLUDE_DIRS ) set(PROJECT_TEMPLATES ) set(PROJECT_PRIVATE_GENERATED ) set(PROJECT_PRIVATE_SOURCE ) set(PROJECT_UI ) set(PROJECT_UI_SOURCE ) set(PROJECT_DEFINITIONS ) set(PROJECT_MEDIA ) # Data file(GLOB_RECURSE PROJECT_DATA "data/*") # Media file(GLOB_RECURSE PROJECT_MEDIA "media/*") # Configure Files configure_file( "templates/config.hpp.in" "generated/config.hpp" ) LIST(APPEND PROJECT_TEMPLATES "templates/config.hpp.in") LIST(APPEND PROJECT_PRIVATE_GENERATED "${PROJECT_BINARY_DIR}/generated/config.hpp") configure_file( "templates/version.hpp.in" "generated/version.hpp" ) LIST(APPEND PROJECT_TEMPLATES "templates/version.hpp.in") LIST(APPEND PROJECT_PRIVATE_GENERATED "${PROJECT_BINARY_DIR}/generated/version.hpp") configure_file( "templates/module.cpp.in" "generated/module.cpp" ) LIST(APPEND PROJECT_TEMPLATES "templates/module.cpp.in") LIST(APPEND PROJECT_PRIVATE_GENERATED "${PROJECT_BINARY_DIR}/generated/module.cpp") if(D_PLATFORM_WINDOWS) # Windows Support set(PROJECT_PRODUCT_NAME "${PROJECT_FULL_NAME}") set(PROJECT_COMPANY_NAME "${PROJECT_AUTHORS}") set(PROJECT_COPYRIGHT "${PROJECT_AUTHORS} © ${PROJECT_COPYRIGHT_YEARS}") set(PROJECT_LEGAL_TRADEMARKS_1 "") set(PROJECT_LEGAL_TRADEMARKS_2 "") configure_file( "templates/windows/version.rc.in" "generated/version.rc" ) LIST(APPEND PROJECT_TEMPLATES "templates/windows/version.rc.in") LIST(APPEND PROJECT_PRIVATE_GENERATED "${PROJECT_BINARY_DIR}/generated/version.rc") endif() # Minimum Dependencies list(APPEND PROJECT_LIBRARIES OBS::libobs) # Components if(CURL_FOUND) list(APPEND PROJECT_PRIVATE_SOURCE "source/util/util-curl.hpp" "source/util/util-curl.cpp" ) list(APPEND PROJECT_LIBRARIES CURL::libcurl) endif() if(HAVE_FFMPEG) list(APPEND PROJECT_LIBRARIES ${FFMPEG_LIBRARIES} ) list(APPEND PROJECT_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} ) endif() if(HAVE_JSON) list(APPEND PROJECT_INCLUDE_DIRS ${JSON_INCLUDE_DIR}) endif() if(TRUE) # OpenGL if(NOT TARGET khronos_glad) add_library(khronos_glad STATIC "${PROJECT_SOURCE_DIR}/third-party/khronos/glad/src/gl.c" ) target_include_directories(khronos_glad PRIVATE "${PROJECT_SOURCE_DIR}/third-party/khronos/glad/include" INTERFACE "${PROJECT_SOURCE_DIR}/third-party/khronos/glad/include" PUBLIC "${PROJECT_SOURCE_DIR}/third-party/khronos/glad/include" ) if(D_PLATFORM_WINDOWS) target_sources(khronos_glad PRIVATE "${PROJECT_SOURCE_DIR}/third-party/khronos/glad/src/wgl.c" ) elseif(D_PLATFORM_LINUX) target_sources(khronos_glad PRIVATE "${PROJECT_SOURCE_DIR}/third-party/khronos/glad/src/glx.c" ) endif() # Requires for shared/static mixing. set_property(TARGET khronos_glad PROPERTY POSITION_INDEPENDENT_CODE ON) endif() list(APPEND PROJECT_LIBRARIES khronos_glad) endif() if(HAVE_NVIDIA_VFX_SDK OR HAVE_NVIDIA_AR_SDK) list(APPEND PROJECT_PRIVATE_SOURCE "source/nvidia/cv/nvidia-cv.hpp" "source/nvidia/cv/nvidia-cv.cpp" "source/nvidia/cv/nvidia-cv-image.hpp" "source/nvidia/cv/nvidia-cv-image.cpp" "source/nvidia/cv/nvidia-cv-texture.hpp" "source/nvidia/cv/nvidia-cv-texture.cpp" ) endif() if(HAVE_NVIDIA_AR_SDK) list(APPEND PROJECT_PRIVATE_SOURCE "source/nvidia/ar/nvidia-ar.hpp" "source/nvidia/ar/nvidia-ar.cpp" "source/nvidia/ar/nvidia-ar-feature.hpp" "source/nvidia/ar/nvidia-ar-feature.cpp" "source/nvidia/ar/nvidia-ar-facedetection.hpp" "source/nvidia/ar/nvidia-ar-facedetection.cpp" ) list(APPEND PROJECT_LIBRARIES NVIDIA::AR ) endif() if(HAVE_NVIDIA_VFX_SDK) list(APPEND PROJECT_PRIVATE_SOURCE "source/nvidia/vfx/nvidia-vfx.hpp" "source/nvidia/vfx/nvidia-vfx.cpp" "source/nvidia/vfx/nvidia-vfx-denoising.hpp" "source/nvidia/vfx/nvidia-vfx-denoising.cpp" "source/nvidia/vfx/nvidia-vfx-effect.hpp" "source/nvidia/vfx/nvidia-vfx-effect.cpp" "source/nvidia/vfx/nvidia-vfx-greenscreen.hpp" "source/nvidia/vfx/nvidia-vfx-greenscreen.cpp" "source/nvidia/vfx/nvidia-vfx-superresolution.hpp" "source/nvidia/vfx/nvidia-vfx-superresolution.cpp" ) list(APPEND PROJECT_LIBRARIES NVIDIA::VFX ) endif() if(HAVE_NVIDIA_CUDA) list(APPEND PROJECT_PRIVATE_SOURCE "source/nvidia/cuda/nvidia-cuda.hpp" "source/nvidia/cuda/nvidia-cuda.cpp" "source/nvidia/cuda/nvidia-cuda-obs.hpp" "source/nvidia/cuda/nvidia-cuda-obs.cpp" "source/nvidia/cuda/nvidia-cuda-context.hpp" "source/nvidia/cuda/nvidia-cuda-context.cpp" "source/nvidia/cuda/nvidia-cuda-gs-texture.hpp" "source/nvidia/cuda/nvidia-cuda-gs-texture.cpp" "source/nvidia/cuda/nvidia-cuda-memory.hpp" "source/nvidia/cuda/nvidia-cuda-memory.cpp" "source/nvidia/cuda/nvidia-cuda-stream.hpp" "source/nvidia/cuda/nvidia-cuda-stream.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_NVIDIA_CUDA ) endif() if(REQUIRE_OBS_FRONTEND_API AND obs-frontend-api_FOUND) list(APPEND PROJECT_LIBRARIES OBS::obs-frontend-api) endif() if(REQUIRE_QT) if(Qt5_FOUND) list(APPEND PROJECT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets) elseif(Qt6_FOUND) list(APPEND PROJECT_LIBRARIES Qt6::Core Qt6::Gui Qt6::Widgets) endif() endif() ################################################################################ # Features ################################################################################ # Core list(APPEND PROJECT_PRIVATE_SOURCE "source/warning-disable.hpp" "source/warning-enable.hpp" "source/configuration.hpp" "source/configuration.cpp" "source/common.hpp" "source/strings.hpp" "source/plugin.hpp" "source/plugin.cpp" "source/util/utility.hpp" "source/util/utility.cpp" "source/util/util-bitmask.hpp" "source/util/util-event.hpp" "source/util/util-library.cpp" "source/util/util-library.hpp" "source/util/util-logging.cpp" "source/util/util-logging.hpp" "source/util/util-platform.hpp" "source/util/util-platform.cpp" "source/util/util-threadpool.cpp" "source/util/util-threadpool.hpp" "source/gfx/gfx-debug.hpp" "source/gfx/gfx-debug.cpp" "source/gfx/gfx-opengl.hpp" "source/gfx/gfx-opengl.cpp" "source/gfx/gfx-source-texture.hpp" "source/gfx/gfx-source-texture.cpp" "source/obs/gs/gs-helper.hpp" "source/obs/gs/gs-helper.cpp" "source/obs/gs/gs-effect.hpp" "source/obs/gs/gs-effect.cpp" "source/obs/gs/gs-effect-parameter.hpp" "source/obs/gs/gs-effect-parameter.cpp" "source/obs/gs/gs-effect-pass.hpp" "source/obs/gs/gs-effect-pass.cpp" "source/obs/gs/gs-effect-technique.hpp" "source/obs/gs/gs-effect-technique.cpp" "source/obs/gs/gs-indexbuffer.hpp" "source/obs/gs/gs-indexbuffer.cpp" "source/obs/gs/gs-limits.hpp" "source/obs/gs/gs-mipmapper.hpp" "source/obs/gs/gs-mipmapper.cpp" "source/obs/gs/gs-rendertarget.hpp" "source/obs/gs/gs-rendertarget.cpp" "source/obs/gs/gs-sampler.hpp" "source/obs/gs/gs-sampler.cpp" "source/obs/gs/gs-texture.hpp" "source/obs/gs/gs-texture.cpp" "source/obs/gs/gs-vertex.hpp" "source/obs/gs/gs-vertex.cpp" "source/obs/gs/gs-vertexbuffer.hpp" "source/obs/gs/gs-vertexbuffer.cpp" "source/obs/obs-signal-handler.hpp" "source/obs/obs-signal-handler.cpp" "source/obs/obs-source-tracker.hpp" "source/obs/obs-source-tracker.cpp" "source/obs/obs-tools.hpp" "source/obs/obs-tools.cpp" # obs_encoder_info_t, obs_encoder_t, obs_weak_encoder_t "source/obs/obs-encoder-factory.hpp" "source/obs/obs-encoder-factory.cpp" # obs_source_info_t, obs_source_t, obs_weak_source_t "source/obs/obs-source-factory.hpp" "source/obs/obs-source-factory.cpp" "source/obs/obs-source-info.hpp" "source/obs/obs-source-info.cpp" "source/obs/obs-source.hpp" "source/obs/obs-source.cpp" "source/obs/obs-source-active-child.hpp" "source/obs/obs-source-active-child.cpp" "source/obs/obs-source-active-reference.hpp" "source/obs/obs-source-active-reference.cpp" "source/obs/obs-source-showing-reference.hpp" "source/obs/obs-source-showing-reference.cpp" "source/obs/obs-weak-source.hpp" "source/obs/obs-weak-source.cpp" ) list(APPEND PROJECT_DATA "data/effects/color_conversion_rgb_hsl.effect" "data/effects/color_conversion_rgb_hsv.effect" "data/effects/color_conversion_rgb_yuv.effect" "data/effects/mipgen.effect" "data/effects/pack-unpack.effect" "data/effects/standard.effect" "data/effects/shared.effect" "data/locale/en-US.ini" ) list(APPEND PROJECT_INCLUDE_DIRS "${PROJECT_BINARY_DIR}/generated" "${PROJECT_SOURCE_DIR}/source" ) # Encoder/FFmpeg is_feature_enabled(ENCODER_FFMPEG T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE # FFmpeg "source/ffmpeg/avframe-queue.cpp" "source/ffmpeg/avframe-queue.hpp" "source/ffmpeg/swscale.hpp" "source/ffmpeg/swscale.cpp" "source/ffmpeg/tools.hpp" "source/ffmpeg/tools.cpp" "source/ffmpeg/hwapi/base.hpp" "source/ffmpeg/hwapi/base.cpp" "source/ffmpeg/hwapi/d3d11.hpp" "source/ffmpeg/hwapi/d3d11.cpp" # Encoders "source/encoders/encoder-ffmpeg.hpp" "source/encoders/encoder-ffmpeg.cpp" # Encoders/Codecs "source/encoders/codecs/hevc.hpp" "source/encoders/codecs/hevc.cpp" "source/encoders/codecs/h264.hpp" "source/encoders/codecs/h264.cpp" "source/encoders/codecs/prores.hpp" "source/encoders/codecs/prores.cpp" "source/encoders/codecs/dnxhr.hpp" "source/encoders/codecs/dnxhr.cpp" # Encoders/Handlers "source/encoders/handlers/handler.hpp" "source/encoders/handlers/handler.cpp" "source/encoders/handlers/debug_handler.hpp" "source/encoders/handlers/debug_handler.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_ENCODER_FFMPEG ) # AMF is_feature_enabled(ENCODER_FFMPEG_AMF T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/encoders/handlers/amf_shared.hpp" "source/encoders/handlers/amf_shared.cpp" "source/encoders/handlers/amf_h264_handler.hpp" "source/encoders/handlers/amf_h264_handler.cpp" "source/encoders/handlers/amf_hevc_handler.hpp" "source/encoders/handlers/amf_hevc_handler.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_ENCODER_FFMPEG_AMF ) endif() # NVENC is_feature_enabled(ENCODER_FFMPEG_NVENC T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/encoders/handlers/nvenc_shared.hpp" "source/encoders/handlers/nvenc_shared.cpp" "source/encoders/handlers/nvenc_h264_handler.hpp" "source/encoders/handlers/nvenc_h264_handler.cpp" "source/encoders/handlers/nvenc_hevc_handler.hpp" "source/encoders/handlers/nvenc_hevc_handler.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_ENCODER_FFMPEG_NVENC ) endif() # ProRES is_feature_enabled(ENCODER_FFMPEG_PRORES T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/encoders/handlers/prores_aw_handler.hpp" "source/encoders/handlers/prores_aw_handler.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_ENCODER_FFMPEG_PRORES ) endif() # DNxHR is_feature_enabled(ENCODER_FFMPEG_DNXHR T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/encoders/handlers/dnxhd_handler.hpp" "source/encoders/handlers/dnxhd_handler.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_ENCODER_FFMPEG_DNXHR ) endif() endif() # Encoder/AOM-AV1 is_feature_enabled(ENCODER_AOM_AV1 T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/encoders/codecs/av1.hpp" "source/encoders/codecs/av1.cpp" "source/encoders/encoder-aom-av1.hpp" "source/encoders/encoder-aom-av1.cpp" ) list(APPEND PROJECT_INCLUDE_DIRS ${AOM_INCLUDE_DIR} ) list(APPEND PROJECT_DEFINITIONS ENABLE_ENCODER_AOM_AV1 ) endif() # Filter/Auto-Framing is_feature_enabled(FILTER_AUTOFRAMING T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-autoframing.hpp" "source/filters/filter-autoframing.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_AUTOFRAMING ) is_feature_enabled(FILTER_AUTOFRAMING_NVIDIA T_CHECK) if(T_CHECK) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_AUTOFRAMING_NVIDIA ) endif() endif() # Filter/Blur is_feature_enabled(FILTER_BLUR T_CHECK) if(T_CHECK) list(APPEND PROJECT_DATA "data/effects/mask.effect" "data/effects/blur/common.effect" "data/effects/blur/box.effect" "data/effects/blur/box-linear.effect" "data/effects/blur/dual-filtering.effect" "data/effects/blur/gaussian.effect" "data/effects/blur/gaussian-linear.effect" ) list(APPEND PROJECT_PRIVATE_SOURCE "source/gfx/blur/gfx-blur-base.hpp" "source/gfx/blur/gfx-blur-base.cpp" "source/gfx/blur/gfx-blur-box.hpp" "source/gfx/blur/gfx-blur-box.cpp" "source/gfx/blur/gfx-blur-box-linear.hpp" "source/gfx/blur/gfx-blur-box-linear.cpp" "source/gfx/blur/gfx-blur-dual-filtering.hpp" "source/gfx/blur/gfx-blur-dual-filtering.cpp" "source/gfx/blur/gfx-blur-gaussian.hpp" "source/gfx/blur/gfx-blur-gaussian.cpp" "source/gfx/blur/gfx-blur-gaussian-linear.hpp" "source/gfx/blur/gfx-blur-gaussian-linear.cpp" "source/filters/filter-blur.hpp" "source/filters/filter-blur.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_BLUR ) endif() # Filter/Color Grade is_feature_enabled(FILTER_COLOR_GRADE T_CHECK) if(T_CHECK) list(APPEND PROJECT_DATA "data/effects/color-grade.effect" ) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-color-grade.hpp" "source/filters/filter-color-grade.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_COLOR_GRADE ) set(REQUIRE_LUT ON) endif() # Filter/Displacement is_feature_enabled(FILTER_DISPLACEMENT T_CHECK) if(T_CHECK) list(APPEND PROJECT_DATA "data/effects/displace.effect" ) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-displacement.hpp" "source/filters/filter-displacement.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_DISPLACEMENT ) endif() # Filter/Dynamic Mask is_feature_enabled(FILTER_DYNAMIC_MASK T_CHECK) if(T_CHECK) list(APPEND PROJECT_DATA "data/effects/channel-mask.effect" ) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-dynamic-mask.hpp" "source/filters/filter-dynamic-mask.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_DYNAMIC_MASK ) endif() # Filter/SDF Effects is_feature_enabled(FILTER_SDF_EFFECTS T_CHECK) if(T_CHECK) list(APPEND PROJECT_DATA "data/effects/sdf/sdf-producer.effect" "data/effects/sdf/sdf-consumer.effect" ) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-sdf-effects.hpp" "source/filters/filter-sdf-effects.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_SDF_EFFECTS ) endif() # Filter/Shader is_feature_enabled(FILTER_SHADER T_CHECK) if(T_CHECK) set(REQUIRE_PART_SHADER ON) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-shader.hpp" "source/filters/filter-shader.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_SHADER ) endif() # Filter/Transform is_feature_enabled(FILTER_TRANSFORM T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-transform.hpp" "source/filters/filter-transform.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_TRANSFORM ) endif() # Filter/Denoising is_feature_enabled(FILTER_DENOISING T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-denoising.hpp" "source/filters/filter-denoising.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_DENOISING ) is_feature_enabled(FILTER_DENOISING_NVIDIA T_CHECK) if(T_CHECK) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_DENOISING_NVIDIA ) endif() endif() # Filter/Upscaling is_feature_enabled(FILTER_UPSCALING T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-upscaling.hpp" "source/filters/filter-upscaling.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_UPSCALING ) is_feature_enabled(FILTER_UPSCALING_NVIDIA T_CHECK) if(T_CHECK) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_UPSCALING_NVIDIA ) endif() endif() # Filter/Virtual Greenscreen is_feature_enabled(FILTER_VIRTUAL_GREENSCREEN T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/filters/filter-virtual-greenscreen.hpp" "source/filters/filter-virtual-greenscreen.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_VIRTUAL_GREENSCREEN ) is_feature_enabled(FILTER_VIRTUAL_GREENSCREEN_NVIDIA T_CHECK) if(T_CHECK) list(APPEND PROJECT_DEFINITIONS ENABLE_FILTER_VIRTUAL_GREENSCREEN_NVIDIA ) endif() endif() # Source/Mirror is_feature_enabled(SOURCE_MIRROR T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/sources/source-mirror.hpp" "source/sources/source-mirror.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_SOURCE_MIRROR ) endif() # Source/Shader is_feature_enabled(SOURCE_SHADER T_CHECK) if(T_CHECK) set(REQUIRE_PART_SHADER ON) list(APPEND PROJECT_PRIVATE_SOURCE "source/sources/source-shader.hpp" "source/sources/source-shader.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_SOURCE_SHADER ) endif() # Transition/Shader is_feature_enabled(TRANSITION_SHADER T_CHECK) if(T_CHECK) set(REQUIRE_PART_SHADER ON) list(APPEND PROJECT_PRIVATE_SOURCE "source/transitions/transition-shader.hpp" "source/transitions/transition-shader.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_TRANSITION_SHADER ) endif() # Profiling is_feature_enabled(PROFILING T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/util/util-profiler.cpp" "source/util/util-profiler.hpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_PROFILING ) endif() # Updater is_feature_enabled(UPDATER T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE "source/updater.hpp" "source/updater.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_UPDATER ) endif() # Frontend is_feature_enabled(FRONTEND T_CHECK) if(T_CHECK) list(APPEND PROJECT_UI "ui/streamfx.qrc" "ui/about.ui" "ui/about-entry.ui" ) list(APPEND PROJECT_UI_SOURCE "source/ui/ui-common.hpp" "source/ui/ui.hpp" "source/ui/ui.cpp" "source/ui/ui-about.hpp" "source/ui/ui-about.cpp" "source/ui/ui-about-entry.hpp" "source/ui/ui-about-entry.cpp" ) list(APPEND PROJECT_INCLUDE_DIRS "source/ui" ) list(APPEND PROJECT_DEFINITIONS ENABLE_FRONTEND ) is_feature_enabled(UPDATER T_CHECK) if(T_CHECK) list(APPEND PROJECT_UI_SOURCE "source/ui/ui-updater.hpp" "source/ui/ui-updater.cpp" ) list(APPEND PROJECT_UI "ui/updater.ui" ) endif() endif() ################################################################################ # Parts ################################################################################ # Shaders if(REQUIRE_PART_SHADER) list(APPEND PROJECT_PRIVATE_SOURCE "source/gfx/shader/gfx-shader.hpp" "source/gfx/shader/gfx-shader.cpp" "source/gfx/shader/gfx-shader-param.hpp" "source/gfx/shader/gfx-shader-param.cpp" "source/gfx/shader/gfx-shader-param-audio.hpp" "source/gfx/shader/gfx-shader-param-audio.cpp" "source/gfx/shader/gfx-shader-param-basic.hpp" "source/gfx/shader/gfx-shader-param-basic.cpp" "source/gfx/shader/gfx-shader-param-matrix.hpp" "source/gfx/shader/gfx-shader-param-matrix.cpp" "source/gfx/shader/gfx-shader-param-texture.hpp" "source/gfx/shader/gfx-shader-param-texture.cpp" ) endif() # LUT if(REQUIRE_LUT) list(APPEND PROJECT_PRIVATE_SOURCE "source/gfx/lut/gfx-lut.hpp" "source/gfx/lut/gfx-lut.cpp" "source/gfx/lut/gfx-lut-consumer.hpp" "source/gfx/lut/gfx-lut-consumer.cpp" "source/gfx/lut/gfx-lut-producer.hpp" "source/gfx/lut/gfx-lut-producer.cpp" ) list(APPEND PROJECT_DATA "data/effects/lut.effect" "data/effects/lut-consumer.effect" "data/effects/lut-producer.effect" ) endif() # Windows if(D_PLATFORM_WINDOWS) list(APPEND PROJECT_PRIVATE_SOURCE "source/windll.cpp" ) list(APPEND PROJECT_LIBRARIES Delayimp.lib ) # Disable/Enable a ton of things. list(APPEND PROJECT_DEFINITIONS # Microsoft Visual C++ _CRT_SECURE_NO_WARNINGS _ENABLE_EXTENDED_ALIGNED_STORAGE # windows.h WIN32_LEAN_AND_MEAN NOGPICAPMASKS NOVIRTUALKEYCODES #NOWINMESSAGES NOWINSTYLES NOSYSMETRICS NOMENUS NOICONS NOKEYSTATES NOSYSCOMMANDS NORASTEROPS #NOSHOWWINDOW NOATOM NOCLIPBOARD NOCOLOR #NOCTLMGR NODRAWTEXT #NOGDI NOKERNEL #NOUSER #NONLS NOMB NOMEMMGR NOMETAFILE NOMINMAX #NOMSG NOOPENFILE NOSCROLL NOSERVICE NOSOUND #NOTEXTMETRIC NOWH NOWINOFFSETS NOCOMM NOKANJI #NOHELP NOPROFILER NODEFERWINDOWPOS NOMCX NOIME NOMDI NOINOUT ) endif() # GCC before 9.0, Clang before 9.0 if((CMAKE_C_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_C_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) list(APPEND PROJECT_LIBRARIES "stdc++fs" ) endif() endif() ################################################################################ # Register Library ################################################################################ # Combine all variables that matter. set(PROJECT_FILES # Always exist ${PROJECT_DATA} ${PROJECT_PRIVATE_GENERATED} ${PROJECT_PRIVATE_SOURCE} ${PROJECT_TEMPLATES} # UI-only (empty if not enabled) ${PROJECT_UI} ${PROJECT_UI_SOURCE} # Media ${PROJECT_MEDIA} ) # Set source groups for IDE generators. source_group(TREE "${PROJECT_SOURCE_DIR}/data" PREFIX "Data" FILES ${PROJECT_DATA}) source_group(TREE "${PROJECT_SOURCE_DIR}/source" PREFIX "Source" FILES ${PROJECT_PRIVATE_SOURCE} ${PROJECT_UI_SOURCE}) source_group(TREE "${PROJECT_BINARY_DIR}/generated" PREFIX "Source" FILES ${PROJECT_PRIVATE_GENERATED}) source_group(TREE "${PROJECT_SOURCE_DIR}/templates" PREFIX "Templates" FILES ${PROJECT_TEMPLATES}) source_group(TREE "${PROJECT_SOURCE_DIR}/ui" PREFIX "User Interface" FILES ${PROJECT_UI}) source_group(TREE "${PROJECT_SOURCE_DIR}/media" PREFIX "Media" FILES ${PROJECT_MEDIA}) # Prevent unwanted files from being built as source. set_source_files_properties(${PROJECT_DATA} ${PROJECT_TEMPLATES} ${PROJECT_UI} ${PROJECT_MEDIA} PROPERTIES HEADER_FILE_ONLY ON ) # Prevent non-UI files from being Qt'd if(Qt5_Found OR Qt6_FOUND) set_source_files_properties(${PROJECT_DATA} ${PROJECT_TEMPLATES} ${PROJECT_MEDIA} ${PROJECT_PRIVATE_GENERATED} ${PROJECT_PRIVATE_SOURCE} PROPERTIES SKIP_AUTOGEN ON SKIP_AUTOMOC ON SKIP_AUTORCC ON SKIP_AUTOUIC ON ) endif() # Register the library add_library(${PROJECT_NAME} MODULE ${PROJECT_FILES}) # We are a module for libOBS. target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_LIBRARIES}) target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE_DIRS}) target_compile_definitions(${PROJECT_NAME} PRIVATE ${PROJECT_DEFINITIONS}) # Always generate position independent code. set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON ) # Set C++ Standard and Extensions set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF ) # Link-Time/Interprocedural Optimization if(${PREFIX}ENABLE_LTO) set_target_properties(${PROJECT_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON ) endif() # C/C++ Compiler Adjustments if(D_PLATFORM_WINDOWS AND ((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))) # MSVC/ClangCL message(STATUS "${LOGPREFIX}Applying custom flags for MSVC style build.") # - Dynamically link Microsoft C/C++ Redistributable. target_compile_options(${PROJECT_NAME} PRIVATE $<$:/MD> $<$:/MDd> $<$:/MD> $<$:/MD> $<$:/MD> ) # - Treat Warnings as Errors target_compile_options(${PROJECT_NAME} PRIVATE "/Wall") # - Disable useless warnings set(DISABLED_WARNINGS # Don't warn about unused variables, parameters, labels, functions, or typedefs. "4100" "4101" "4102" "4505" "4514" "5245" # Don't warn about unreferenced variables or parameters which are assigned/initialized. "4189" # Don't warn about not-explicitly-handled enumeration identifiers "4061" # Ignore automatic padding warnings. "4820" # Ignore assignment/move/copy being implicit '= delete;'. "4623" "4625" "4626" "5026" "5027" # Relative include paths are fine. "4464" # Buggy warning: printf expects string literal "4774" # Buggy warning: subobject initialization should be wrapped in braces "5246" # Ignore undefined, unused or unreferenced pre-processor macros "4688" # Ignore non-inlined functions "4710" # Ignore Spectre mitigation insertions "5045" ) foreach(WARN ${DISABLED_WARNINGS}) target_compile_options(${PROJECT_NAME} PRIVATE "/wd${WARN}") endforeach() # - Require enabled instruction sets. if(D_PLATFORM_ARCH_X86) if(${PREFIX}TARGET_X86_64_V4) target_compile_options(${PROJECT_NAME} PRIVATE "/arch:AVX512") message(STATUS "${LOGPREFIX}Targeting x86-64-v4.") elseif(${PREFIX}TARGET_X86_64_V3) target_compile_options(${PROJECT_NAME} PRIVATE "/arch:AVX2") message(STATUS "${LOGPREFIX}Targeting x86-64-v3.") elseif(${PREFIX}TARGET_X86_64_V2_EX) target_compile_options(${PROJECT_NAME} PRIVATE "/arch:AVX") message(STATUS "${LOGPREFIX}Targeting extended x86-64-v2.") elseif(${PREFIX}TARGET_X86_64_V2) target_compile_options(${PROJECT_NAME} PRIVATE "/d2archSSE42") message(STATUS "${LOGPREFIX}Targeting x86-64-v2.") elseif(${PREFIX}TARGET_X86_64) #target_compile_options(${PROJECT_NAME} PRIVATE "/arch:SSE2") message(STATUS "${LOGPREFIX}Targeting x86-64.") endif() endif() # - Use fast unordered math if possible. if(${PREFIX}ENABLE_FASTMATH) target_compile_options(${PROJECT_NAME} PRIVATE "/fp:fast") else() target_compile_options(${PROJECT_NAME} PRIVATE "/fp:precise") if(MSVC_VERSION GREATER 1930) # Keep original behavior in VS2022 and up. target_compile_options(${PROJECT_NAME} PRIVATE "/fp:contract") endif() endif() # - Disable incremental builds target_compile_options(${PROJECT_NAME} PRIVATE "/INCREMENTAL:NO") # - Enable C++ exceptions with SEH exceptions. target_compile_options(${PROJECT_NAME} PRIVATE "/EHa") # - Enable multi-processor compiling. target_compile_options(${PROJECT_NAME} PRIVATE "/MP") # - Enable updated __cplusplus macro target_compile_options(${PROJECT_NAME} PRIVATE "/Zc:__cplusplus") # - Generic Optimizations for Release/RelWithDebInfo/MinSizeRel set(FLAGS "/OPT:REF" "/OPT:ICF=3" "/GL" "/Gy" "/GF" "/Ox" "/Ob3" ) foreach(FLAG ${FLAGS}) target_compile_options(${PROJECT_NAME} PRIVATE "$<$:${FLAG}>") endforeach() elseif(D_PLATFORM_LINUX AND ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))) # GCC/Clang message(STATUS "${LOGPREFIX}Applying custom flags for GCC/Clang style build.") # - Enable all warnings. target_compile_options(${PROJECT_NAME} PRIVATE "-Wall") target_compile_options(${PROJECT_NAME} PRIVATE "-Wextra") # - Disable useless warnings set(DISABLED_WARNINGS # Don't warn about unused variables, parameters, labels, functions, or typedefs. "unused-function" "unused-label" "unused-local-typedefs" "unused-parameter" "unused-result" "unused-const-variable" "unused-variable" "unused-value" # Don't warn about unreferenced variables or parameters which are assigned/initialized. "unused-but-set-parameter" "unused-but-set-variable" # Don't warn about not-explicitly-handled enumeration identifiers "switch" # Ignore automatic padding warnings. "padded" # Ignore implicit '= delete;'. # Ignore extra arguments for printf "format-extra-args" # Ignore undefined, unused or unreferenced pre-processor macros "unused-macros" ) foreach(WARN ${DISABLED_WARNINGS}) target_compile_options(${PROJECT_NAME} PRIVATE "-Wno-${WARN}") endforeach() # - Require enabled instruction sets. if(${PREFIX}TARGET_NATIVE) target_compile_options(${PROJECT_NAME} PRIVATE "-march=native" ) message(WARNING "${LOGPREFIX}Targeting native architecture. Binaries will not be distributable to other systems!") elseif(D_PLATFORM_ARCH_X86) if(${PREFIX}TARGET_X86_64_V4) target_compile_options(${PROJECT_NAME} PRIVATE "-march=x86-64-v4" ) message(STATUS "${LOGPREFIX}Targeting x86-64-v4.") elseif(${PREFIX}TARGET_X86_64_V3) target_compile_options(${PROJECT_NAME} PRIVATE "-march=x86-64-v3" ) message(STATUS "${LOGPREFIX}Targeting x86-64-v3.") elseif(${PREFIX}TARGET_X86_64_V2_EX) target_compile_options(${PROJECT_NAME} PRIVATE "-march=x86-64-v2" "-mavx" "-mbmi2" "-mbmi" "-mfma" "-mf16c" "-mmovbe" "-mpclmul" "-mpopcnt" ) message(STATUS "${LOGPREFIX}Targeting extended x86-64-v2.") elseif(${PREFIX}TARGET_X86_64_V2) target_compile_options(${PROJECT_NAME} PRIVATE "-march=x86-64-v2" ) message(STATUS "${LOGPREFIX}Targeting x86-64-v2.") elseif(${PREFIX}TARGET_X86_64) target_compile_options(${PROJECT_NAME} PRIVATE "-march=x86-64" ) message(STATUS "${LOGPREFIX}Targeting x86-64.") endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") target_compile_options(${PROJECT_NAME} PRIVATE "-mtune=generic" ) else() target_compile_options(${PROJECT_NAME} PRIVATE "-mtune=x86-64" ) endif() endif() # - Use fast unordered math if possible. if(${PREFIX}ENABLE_FASTMATH) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") target_compile_options(${PROJECT_NAME} PRIVATE "-ffast-math" ) else() target_compile_options(${PROJECT_NAME} PRIVATE "-ffp-model=fast" ) endif() else() target_compile_options(${PROJECT_NAME} PRIVATE "-ffp-model=precise" ) endif() # - Don't export by default, require attributes. # add_compile_options("-fvisibility=hidden") elseif(D_PLATFORM_MAC AND (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) # AppleClang message(STATUS "${LOGPREFIX}Applying custom flags for AppleClang style build.") # - Enable most useful warnings. target_compile_options(${PROJECT_NAME} PRIVATE "-Wall") target_compile_options(${PROJECT_NAME} PRIVATE "-Wextra") # - Require enabled instruction sets. if(${PREFIX}TARGET_NATIVE) target_compile_options(${PROJECT_NAME} PRIVATE "-march=native" ) message(WARNING "${LOGPREFIX}Targeting native architecture. Binaries will not be distributable to other systems!") endif() # - Use fast unordered math if possible. # FIXME: Appears to not be supported. # - Don't export by default, require attributes. # add_compile_options("-fvisibility=hidden") endif() # Remove prefix on other platforms. set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" IMPORT_PREFIX "" ) # Set file version set_target_properties(${PROJECT_NAME} PROPERTIES MACHO_COMPATIBILITY_VERSION ${_VERSION_MAJOR}.${_VERSION_MINOR} MACHO_CURRENT_VERSION ${PROJECT_VERSION} SOVERSION ${_VERSION_MAJOR}.${_VERSION_MINOR} VERSION ${PROJECT_VERSION} ) # Enable Qt if needed if(Qt5_FOUND OR Qt6_FOUND) set_target_properties(${PROJECT_NAME} PROPERTIES AUTOUIC ON AUTOUIC_SEARCH_PATHS "${PROJECT_SOURCE_DIR};${PROJECT_SOURCE_DIR}/ui" AUTOMOC ON AUTORCC ON AUTOGEN_BUILD_DIR "${PROJECT_BINARY_DIR}/generated" ) endif() # Windows exclusive changes if(D_PLATFORM_WINDOWS) foreach(DELAYLOAD ${PROJECT_LIBRARIES_DELAYED}) get_target_property(_lf ${PROJECT_NAME} LINK_FLAGS) if(NOT _lf) set(_lf "") endif() set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${_lf} /DELAYLOAD:${DELAYLOAD}") add_link_options("/DELAYLOAD:${DELAYLOAD}") endforeach() endif() # MacOS exclusive Changes if(D_PLATFORM_MAC) set_target_properties(${PROJECT_NAME} PROPERTIES # No automatic code signing in XCode XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO" # @rpath in installed binaries INSTALL_RPATH "@executable_path/../Frameworks/;@loader_path/../Frameworks/;@loader_path/../Resources/" ) if(STANDALONE) set_target_properties(${PROJECT_NAME} PROPERTIES # @rpath in built binaries BUILD_WITH_INSTALL_RPATH ON ) endif() endif() ################################################################################ # Extra Tools ################################################################################ # Clang is_feature_enabled(CLANG T_CHECK) if(T_CHECK AND HAVE_CLANG) generate_compile_commands_json( TARGETS ${PROJECT_NAME} ) clang_tidy( TARGETS ${PROJECT_NAME} VERSION 14.0.0 ) clang_format( TARGETS ${PROJECT_NAME} DEPENDENCY VERSION 14.0.0 ) endif() # Code Sign if(HAVE_CODESIGN) set(_CODESIGN_TIMESTAMP "") if(${PREFIX}CODESIGN_TIMESTAMPS) set(_CODESIGN_TIMESTAMP "TIMESTAMPS") endif() codesign( TARGETS ${PROJECT_NAME} CERTIFICATE_FILE "${_CODESIGN_FILE}" CERTIFICATE_NAME "${_CODESIGN_NAME}" CERTIFICATE_PASS "${_CODESIGN_PASS}" ${_CODESIGN_TIMESTAMP} ) endif() ################################################################################ # Installation ################################################################################ if(STANDALONE) if(STRUCTURE_UNIFIED) install( DIRECTORY "data/" DESTINATION "data/" FILE_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE DIRECTORY_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) if(D_PLATFORM_WINDOWS) install( TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "bin/windows-${D_PLATFORM_INSTR}-${D_PLATFORM_BITS}/" COMPONENT StreamFX LIBRARY DESTINATION "bin/windows-${D_PLATFORM_INSTR}-${D_PLATFORM_BITS}/" COMPONENT StreamFX PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) if(MSVC) install( FILES $ DESTINATION "bin/windows-${D_PLATFORM_INSTR}-${D_PLATFORM_BITS}/" COMPONENT StreamFX OPTIONAL ) endif() # Dependency: AOM if(HAVE_AOM AND AOM_BINARY AND D_PLATFORM_WINDOWS) install( FILES ${AOM_BINARY} DESTINATION "data/" COMPONENT StreamFX ) endif() elseif(D_PLATFORM_LINUX) install( TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "bin/linux-${D_PLATFORM_INSTR}-${D_PLATFORM_BITS}/" COMPONENT StreamFX LIBRARY DESTINATION "bin/linux-${D_PLATFORM_INSTR}-${D_PLATFORM_BITS}/" COMPONENT StreamFX PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) elseif(D_PLATFORM_MAC) install( TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "bin/mac-${D_PLATFORM_INSTR}-${D_PLATFORM_BITS}/" COMPONENT StreamFX LIBRARY DESTINATION "bin/mac-${D_PLATFORM_INSTR}-${D_PLATFORM_BITS}/" COMPONENT StreamFX PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) endif() install( FILES LICENSE DESTINATION "LICENSE" COMPONENT StreamFX ) install( FILES icon.png DESTINATION "icon.png" COMPONENT StreamFX ) elseif(D_PLATFORM_WINDOWS) install( TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "obs-plugins/${D_PLATFORM_BITS}bit/" COMPONENT StreamFX LIBRARY DESTINATION "obs-plugins/${D_PLATFORM_BITS}bit/" COMPONENT StreamFX ) install( DIRECTORY "data/" DESTINATION "data/obs-plugins/${PROJECT_NAME}/" ) if(MSVC) install( FILES $ DESTINATION "obs-plugins/${D_PLATFORM_BITS}bit/" OPTIONAL ) endif() # Dependency: AOM if(HAVE_AOM AND AOM_BINARY) install( FILES "${AOM_BINARY}" DESTINATION "data/obs-plugins/${PROJECT_NAME}/" COMPONENT StreamFX ) endif() elseif(D_PLATFORM_LINUX) if(STRUCTURE_PACKAGEMANAGER) install( TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "lib/obs-plugins/" COMPONENT StreamFX LIBRARY DESTINATION "lib/obs-plugins/" COMPONENT StreamFX PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) install( DIRECTORY "data/" DESTINATION "share/obs/obs-plugins/${PROJECT_NAME}" COMPONENT StreamFX FILE_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE DIRECTORY_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) else() install( TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "plugins/${PROJECT_NAME}/bin/${D_PLATFORM_BITS}bit/" COMPONENT StreamFX LIBRARY DESTINATION "plugins/${PROJECT_NAME}/bin/${D_PLATFORM_BITS}bit/" COMPONENT StreamFX PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) install( DIRECTORY "data/" DESTINATION "plugins/${PROJECT_NAME}/data/" COMPONENT StreamFX FILE_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE DIRECTORY_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) endif() elseif(D_PLATFORM_MAC) install( TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${PROJECT_NAME}/bin/" COMPONENT StreamFX LIBRARY DESTINATION "${PROJECT_NAME}/bin/" COMPONENT StreamFX PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) install( DIRECTORY "data/" DESTINATION "${PROJECT_NAME}/data/" COMPONENT StreamFX FILE_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE DIRECTORY_PERMISSIONS WORLD_EXECUTE;WORLD_READ;OWNER_EXECUTE;OWNER_READ;OWNER_WRITE;GROUP_EXECUTE;GROUP_READ;GROUP_WRITE ) endif() else() if(COMMAND setup_plugin_target) setup_plugin_target(${PROJECT_NAME}) # Seems like we lost the ability to customize which directoy resources are in, and instead are forced to use '/data'. if(HAVE_AOM AND AOM_BINARY) # Dependency: AOM add_target_resource(${PROJECT_NAME} "${AOM_BINARY}" "obs-plugins/${PROJECT_NAME}") endif() elseif(COMMAND install_obs_plugin_with_data) install_obs_plugin_with_data(${PROJECT_NAME} data) if(HAVE_AOM AND AOM_BINARY) # Dependency: AOM install( FILES "${AOM_BINARY}" DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/${PROJECT_NAME}" ) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy "${AOM_BINARY}" "${OBS_DATA_DESTINATION}/obs-plugins/${PROJECT_NAME}" VERBATIM) endif() endif() endif() ################################################################################ # Packaging ################################################################################ if(STANDALONE) # Packaging if(NOT PACKAGE_SUFFIX) set(_PACKAGE_SUFFIX_OVERRIDE "${_VERSION_THIN}") else() set(_PACKAGE_SUFFIX_OVERRIDE "${PACKAGE_SUFFIX}") endif() set(_PACKAGE_FULL_NAME "${PACKAGE_PREFIX}/${PACKAGE_NAME}-${_PACKAGE_SUFFIX_OVERRIDE}") if(STRUCTURE_UNIFIED) add_custom_target( PACKAGE_ZIP ${CMAKE_COMMAND} -E tar cfv "${_PACKAGE_FULL_NAME}.obs" --format=zip -- "." WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" ) else() add_custom_target( PACKAGE_7Z ${CMAKE_COMMAND} -E tar cfv "${_PACKAGE_FULL_NAME}.7z" --format=7zip -- "." WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" ) add_custom_target( PACKAGE_ZIP ${CMAKE_COMMAND} -E tar cfv "${_PACKAGE_FULL_NAME}.zip" --format=zip -- "." WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" ) # Windows if(D_PLATFORM_WINDOWS) ## Installer (InnoSetup) get_filename_component(ISS_FILES_DIR "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) file(TO_NATIVE_PATH "${ISS_FILES_DIR}" ISS_FILES_DIR) get_filename_component(ISS_PACKAGE_DIR "${PACKAGE_PREFIX}" ABSOLUTE) file(TO_NATIVE_PATH "${ISS_PACKAGE_DIR}" ISS_PACKAGE_DIR) get_filename_component(ISS_SOURCE_DIR "${PROJECT_SOURCE_DIR}" ABSOLUTE) file(TO_NATIVE_PATH "${ISS_SOURCE_DIR}" ISS_SOURCE_DIR) get_filename_component(ISS_MSVCHELPER_PATH "${msvc-redist-helper_BUILD_DIR}" ABSOLUTE) file(TO_NATIVE_PATH "${ISS_MSVCHELPER_PATH}" ISS_MSVCHELPER_PATH) if(HAVE_CODESIGN) codesign_command_win32( SHA1 RETURN_BIN ISS_CODESIGN_BIN_SHA1 RETURN_ARGS ISS_CODESIGN_CMD_SHA1 CERTIFICATE_FILE "${_CODESIGN_FILE}" CERTIFICATE_NAME "${_CODESIGN_NAME}" CERTIFICATE_PASS "${_CODESIGN_PASS}" ${_CODESIGN_TIMESTAMP} ) codesign_command_win32( SHA2 APPEND RETURN_BIN ISS_CODESIGN_BIN_SHA2 RETURN_ARGS ISS_CODESIGN_CMD_SHA2 CERTIFICATE_FILE "${_CODESIGN_FILE}" CERTIFICATE_NAME "${_CODESIGN_NAME}" CERTIFICATE_PASS "${_CODESIGN_PASS}" ${_CODESIGN_TIMESTAMP} ) list(JOIN ISS_CODESIGN_CMD_SHA1 " " ISS_CODESIGN_CMD_SHA1) list(JOIN ISS_CODESIGN_CMD_SHA2 " " ISS_CODESIGN_CMD_SHA2) configure_file( "templates/windows/installer-signed.iss.in" "installer.iss" ) else() configure_file( "templates/windows/installer.iss.in" "installer.iss" ) endif() endif() # Apple MacOS if(D_PLATFORM_MAC) # .pkg Installer configure_file( "templates/macos/installer.pkgproj.in" "installer.pkgproj" ) endif() endif() endif()