mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-30 07:13:01 +00:00
1677 lines
52 KiB
CMake
1677 lines
52 KiB
CMake
# AUTOGENERATED COPYRIGHT HEADER START
|
|
# Copyright (C) 2017-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
|
|
# Copyright (C) 2019 Cat Stevens <catb0t@protonmail.ch>
|
|
# Copyright (C) 2020 Brandon Edens <brandonedens@gmail.com>
|
|
# Copyright (C) 2021 Christopher P Yarger <cpyarger@gmail.com>
|
|
# Copyright (C) 2022 Carsten Braun <info@braun-cloud.de>
|
|
# Copyright (C) 2022 Romain Vigier <romain@romainvigier.fr>
|
|
# AUTOGENERATED COPYRIGHT HEADER END
|
|
|
|
# CMake Setup
|
|
cmake_minimum_required(VERSION 3.26)
|
|
list(APPEND CMAKE_MESSAGE_INDENT "[StreamFX] ")
|
|
project(StreamFX)
|
|
|
|
################################################################################
|
|
# Modules
|
|
################################################################################
|
|
|
|
# Search Paths
|
|
set(CMAKE_MODULE_PATH
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/clang"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/version"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
|
|
)
|
|
|
|
# Include required Modules
|
|
# - Stock
|
|
include("CheckIPOSupported")
|
|
# - Custom
|
|
include("util")
|
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/version/version.cmake")
|
|
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version/version.cmake")
|
|
else()
|
|
message(FATAL_ERROR "Please ensure you've cloned recursively and try again. Thank you!")
|
|
endif()
|
|
|
|
# Include optional Modules
|
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/clang/Clang.cmake")
|
|
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/clang/Clang.cmake")
|
|
endif()
|
|
|
|
################################################################################
|
|
# Bootstrapping
|
|
################################################################################
|
|
|
|
# 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()
|
|
|
|
# Check if this is standalone or bundled.
|
|
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()
|
|
|
|
# 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 "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()
|
|
|
|
# Interprocedural Optimization
|
|
check_ipo_supported(RESULT D_HAS_IPO)
|
|
|
|
set(D_PLATFORM_INSTR ${ARCH_INST})
|
|
set(D_PLATFORM_ARCH ${ARCH_INST})
|
|
message(STATUS "Target is ${D_PLATFORM_BITS}bit ${ARCH_INST} with a pointer size of ${D_PLATFORM_BITS_PTR}bit.")
|
|
|
|
################################################################################
|
|
# Versioning
|
|
################################################################################
|
|
|
|
version(GENERATE _VERSION COMPRESSED MAJOR 0 MINOR 0 PATCH 0 TWEAK 0 REQUIRE "PATCH;")
|
|
version(PARSE _VERSION "${_VERSION}" REQUIRE "PATCH;TWEAK")
|
|
|
|
# If possible, automatically generate versions from git.
|
|
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git")
|
|
find_program(GIT
|
|
NAMES
|
|
git
|
|
git.exe
|
|
)
|
|
|
|
if(EXISTS "${GIT}")
|
|
# Try and calculate the exist version using git.
|
|
execute_process(COMMAND "${GIT}" describe --tags --long --abbrev=8 HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE GIT_RESULT OUTPUT_VARIABLE GIT_OUTPUT ERROR_VARIABLE GIT_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
|
if((GIT_RESULT EQUAL 0) AND (NOT "${GIT_OUTPUT}" STREQUAL ""))
|
|
# Result will be MAJOR.MINOR.PATCH-TWEAK-gHASH
|
|
string(REPLACE "-" ";" GIT_OUTPUT "${GIT_OUTPUT}")
|
|
string(REPLACE "." ";" GIT_OUTPUT "${GIT_OUTPUT}")
|
|
|
|
# Split into components
|
|
list(GET GIT_OUTPUT 0 GIT_OUTPUT_MAJOR)
|
|
list(GET GIT_OUTPUT 1 GIT_OUTPUT_MINOR)
|
|
list(GET GIT_OUTPUT 2 GIT_OUTPUT_PATCH)
|
|
list(GET GIT_OUTPUT 3 GIT_OUTPUT_TWEAK)
|
|
list(GET GIT_OUTPUT 4 GIT_OUTPUT_BUILD)
|
|
|
|
# Special case: Tag contains prerelease
|
|
if(GIT_OUTPUT_PATCH MATCHES "([0-9]+)([a-zA-Z]+)([0-9]*)")
|
|
# Patch requires special parsing.
|
|
set(GIT_OUTPUT_PATCH "${CMAKE_MATCH_1}")
|
|
if(CMAKE_MATCH_3 GREATER 0)
|
|
set(GIT_OUTPUT_PRERELEASE "${CMAKE_MATCH_2}")
|
|
else()
|
|
set(GIT_OUTPUT_PRERELEASE "a")
|
|
endif()
|
|
MATH(EXPR GIT_OUTPUT_TWEAK "${GIT_OUTPUT_TWEAK} + ${CMAKE_MATCH_3}")
|
|
|
|
# Modify the global version
|
|
version(MODIFY _VERSION "${_VERSION}" COMPRESS
|
|
MAJOR "${GIT_OUTPUT_MAJOR}"
|
|
MINOR "${GIT_OUTPUT_MINOR}"
|
|
PATCH "${GIT_OUTPUT_PATCH}"
|
|
TWEAK "${GIT_OUTPUT_TWEAK}"
|
|
BUILD "${GIT_OUTPUT_BUILD}"
|
|
PRERELEASE "${GIT_OUTPUT_PRERELEASE}"
|
|
REQUIRE "PATCH;TWEAK"
|
|
)
|
|
else()
|
|
# Modify the global version
|
|
version(MODIFY _VERSION "${_VERSION}" COMPRESS
|
|
MAJOR "${GIT_OUTPUT_MAJOR}"
|
|
MINOR "${GIT_OUTPUT_MINOR}"
|
|
PATCH "${GIT_OUTPUT_PATCH}"
|
|
TWEAK "${GIT_OUTPUT_TWEAK}"
|
|
BUILD "${GIT_OUTPUT_BUILD}"
|
|
PRERELEASE "a"
|
|
REQUIRE "PATCH;TWEAK"
|
|
)
|
|
endif()
|
|
else()
|
|
execute_process(COMMAND "${GIT}" rev-list --count HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE GIT_RESULT OUTPUT_VARIABLE GIT_OUTPUT ERROR_VARIABLE GIT_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
|
if((GIT_RESULT EQUAL 0) AND (NOT "${GIT_OUTPUT}" STREQUAL ""))
|
|
version(MODIFY _VERSION "${_VERSION}" COMPRESS
|
|
TWEAK "${GIT_OUTPUT}"
|
|
PRERELEASE "a"
|
|
REQUIRE "PATCH;TWEAK"
|
|
)
|
|
|
|
# Determine the build using git.
|
|
execute_process(COMMAND "${GIT}" log -1 "--pretty=format:g%h" --abbrev=8 HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE GIT_RESULT OUTPUT_VARIABLE GIT_OUTPUT ERROR_VARIABLE GIT_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
|
if((GIT_RESULT EQUAL 0) AND (NOT "${GIT_OUTPUT}" STREQUAL ""))
|
|
version(MODIFY _VERSION "${_VERSION}" COMPRESS
|
|
BUILD "${GIT_OUTPUT}"
|
|
REQUIRE "PATCH;TWEAK"
|
|
)
|
|
else()
|
|
message(WARNING "Failed to detect build version with 'git'.")
|
|
endif()
|
|
else()
|
|
message(WARNING "Failed to automatically detect version with 'git'.")
|
|
endif()
|
|
endif()
|
|
else()
|
|
message(WARNING "'git' not found, automatic version detection disabled.")
|
|
endif()
|
|
else()
|
|
message(STATUS "Not a git repository, automatic version detection disabled.")
|
|
endif()
|
|
version(PARSE _VERSION "${_VERSION}" REQUIRE "PATCH;TWEAK")
|
|
|
|
# Allow manual overrides of the detected version.
|
|
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 "Version ${_VERSION_THIN}")
|
|
|
|
################################################################################
|
|
# Options
|
|
################################################################################
|
|
|
|
# Don't enable stability affecting features by default.
|
|
if(_VERSION_PRERELEASE STREQUAL "a")
|
|
set(FEATURE_DEPRECATED ON)
|
|
set(FEATURE_EXPERIMENTAL ON)
|
|
set(FEATURE_UNSTABLE ON)
|
|
set(FEATURE_STABLE ON)
|
|
elseif(_VERSION_PRERELEASE STREQUAL "b")
|
|
set(FEATURE_DEPRECATED ON)
|
|
set(FEATURE_EXPERIMENTAL ON)
|
|
set(FEATURE_UNSTABLE ON)
|
|
set(FEATURE_STABLE ON)
|
|
elseif(_VERSION_PRERELEASE STREQUAL "c")
|
|
set(FEATURE_DEPRECATED ON)
|
|
set(FEATURE_EXPERIMENTAL OFF)
|
|
set(FEATURE_UNSTABLE ON)
|
|
set(FEATURE_STABLE ON)
|
|
else()
|
|
set(FEATURE_DEPRECATED ON)
|
|
set(FEATURE_EXPERIMENTAL OFF)
|
|
set(FEATURE_UNSTABLE OFF)
|
|
set(FEATURE_STABLE ON)
|
|
endif()
|
|
|
|
# Version override
|
|
set(${PREFIX}VERSION "" CACHE STRING "Specify an override for the automatically detected version. Accepts a mixture of SemVer 2.0 and CMake Version.")
|
|
|
|
# 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)
|
|
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 "StreamFX" 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()
|
|
|
|
# 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")
|
|
|
|
################################################################################
|
|
# 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_IDENTIFER "com.xaymar.StreamFX.obs")
|
|
set(PROJECT_TITLE "StreamFX (for OBS Studio)")
|
|
set(PROJECT_AUTHORS "Michael Fabian 'Xaymar' Dirks <info@xaymar.com>")
|
|
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"
|
|
)
|
|
|
|
# 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()
|
|
|
|
set_property(GLOBAL PROPERTY AUTOGEN_SOURCE_GROUP "User-Interface Files/Generated")
|
|
|
|
################################################################################
|
|
# Dependencies
|
|
################################################################################
|
|
|
|
#- 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
|
|
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()
|
|
|
|
#- CURL
|
|
find_package("CURL")
|
|
|
|
#- JSON
|
|
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third-party/nlohmann-json/single_include")
|
|
message(FATAL_ERROR "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")
|
|
endif()
|
|
|
|
#- Qt 6
|
|
find_package("Qt6"
|
|
COMPONENTS Core Gui Widgets
|
|
CONFIG
|
|
)
|
|
|
|
################################################################################
|
|
# Code
|
|
################################################################################
|
|
set(PROJECT_DATA )
|
|
set(PROJECT_LIBRARIES )
|
|
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/*")
|
|
|
|
# Templates
|
|
file(GLOB_RECURSE PROJECT_TEMPLATES "templates/*")
|
|
|
|
# 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")
|
|
# Minimum Dependencies
|
|
list(APPEND PROJECT_LIBRARIES OBS::libobs)
|
|
|
|
# Dependencies
|
|
list(APPEND PROJECT_PRIVATE_SOURCE
|
|
"source/util/util-curl.hpp"
|
|
"source/util/util-curl.cpp"
|
|
)
|
|
list(APPEND PROJECT_LIBRARIES CURL::libcurl)
|
|
|
|
list(APPEND PROJECT_INCLUDE_DIRS ${JSON_INCLUDE_DIR})
|
|
|
|
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()
|
|
|
|
list(APPEND PROJECT_LIBRARIES OBS::obs-frontend-api)
|
|
list(APPEND PROJECT_UI_SOURCE
|
|
"source/obs/browser/obs-browser-panel.hpp"
|
|
)
|
|
|
|
list(APPEND PROJECT_LIBRARIES Qt6::Core Qt6::Gui Qt6::Widgets)
|
|
|
|
################################################################################
|
|
# 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-util.hpp"
|
|
"source/gfx/gfx-util.cpp"
|
|
"source/gfx/gfx-mipmapper.hpp"
|
|
"source/gfx/gfx-mipmapper.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-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.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"
|
|
)
|
|
|
|
# Profiling
|
|
list(APPEND PROJECT_PRIVATE_SOURCE
|
|
"source/util/util-profiler.cpp"
|
|
"source/util/util-profiler.hpp"
|
|
)
|
|
|
|
# Updater
|
|
list(APPEND PROJECT_PRIVATE_SOURCE
|
|
"source/updater.hpp"
|
|
"source/updater.cpp"
|
|
)
|
|
|
|
# Frontend
|
|
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"
|
|
"source/ui/ui-obs-browser-widget.hpp"
|
|
"source/ui/ui-obs-browser-widget.cpp"
|
|
)
|
|
list(APPEND PROJECT_INCLUDE_DIRS
|
|
"source/ui"
|
|
)
|
|
|
|
list(APPEND PROJECT_UI_SOURCE
|
|
"source/ui/ui-updater.hpp"
|
|
"source/ui/ui-updater.cpp"
|
|
)
|
|
list(APPEND PROJECT_UI
|
|
"ui/updater.ui"
|
|
)
|
|
|
|
################################################################################
|
|
# Parts
|
|
################################################################################
|
|
|
|
# Windows
|
|
if(D_PLATFORM_WINDOWS)
|
|
# 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()
|
|
|
|
################################################################################
|
|
# Helpers
|
|
################################################################################
|
|
define_property(TARGET PROPERTY COMPONENT_LABEL)
|
|
define_property(TARGET PROPERTY COMPONENT_NAME)
|
|
define_property(TARGET PROPERTY COMPONENT_OPTION)
|
|
define_property(TARGET PROPERTY COMPONENT_RESOLVER)
|
|
define_property(TARGET PROPERTY COMPONENT_DEPENDS)
|
|
|
|
function(streamfx_add_library TARGET_NAME TARGET_TYPE)
|
|
add_library(${TARGET_NAME} ${TARGET_TYPE})
|
|
|
|
set_target_properties(${TARGET_NAME} PROPERTIES
|
|
# Always generate position independent code.
|
|
POSITION_INDEPENDENT_CODE ON
|
|
|
|
# Set C++ Standard and Extensions
|
|
C_STANDARD 17
|
|
C_STANDARD_REQUIRED ON
|
|
CXX_STANDARD 17
|
|
CXX_STANDARD_REQUIRED ON
|
|
CXX_EXTENSIONS OFF
|
|
|
|
# Remove prefix from generated files.
|
|
PREFIX ""
|
|
IMPORT_PREFIX ""
|
|
)
|
|
if(D_PLATFORM_MAC)
|
|
set_target_properties(${TARGET_NAME} PROPERTIES
|
|
# @rpath in installed binaries
|
|
INSTALL_RPATH "@executable_path/../Frameworks/;@loader_path/../Frameworks/;@loader_path/../Resources/"
|
|
)
|
|
if(STANDALONE)
|
|
set_target_properties(${TARGET_NAME} PROPERTIES
|
|
# @rpath in built binaries
|
|
BUILD_WITH_INSTALL_RPATH ON
|
|
)
|
|
endif()
|
|
endif()
|
|
|
|
target_compile_definitions(${TARGET_NAME} PRIVATE
|
|
__STDC_WANT_LIB_EXT1__=1
|
|
)
|
|
if(D_PLATFORM_WINDOWS)
|
|
target_compile_definitions(${TARGET_NAME}
|
|
PUBLIC
|
|
# Microsoft Visual C++
|
|
_CRT_SECURE_NO_WARNINGS
|
|
_ENABLE_EXTENDED_ALIGNED_STORAGE
|
|
|
|
PUBLIC
|
|
# windows.h
|
|
# - Disable MIN/MAX macro as this breaks a lot of code.
|
|
NOMINMAX
|
|
# - Disable IN/OUT macro as this breaks a lot of code.
|
|
NOINOUT
|
|
)
|
|
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
|
|
|
|
# - Dynamically link Microsoft C/C++ Redistributable.
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
$<$<CONFIG:>:/MD>
|
|
$<$<CONFIG:Debug>:/MDd>
|
|
$<$<CONFIG:Release>:/MD>
|
|
$<$<CONFIG:RelWithDebInfo>:/MD>
|
|
$<$<CONFIG:MinSizeRel>:/MD>
|
|
)
|
|
|
|
# - Treat Warnings as Errors
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/Wall")
|
|
|
|
# - Explicitly disable treating all Warnings as Errors
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/WX-")
|
|
|
|
# - 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"
|
|
# Ignore inserted padding.
|
|
"4324"
|
|
)
|
|
foreach(WARN ${DISABLED_WARNINGS})
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/wd${WARN}")
|
|
endforeach()
|
|
|
|
# - Require enabled instruction sets.
|
|
if(D_PLATFORM_ARCH_X86)
|
|
if(${PREFIX}TARGET_X86_64_V4)
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/arch:AVX512")
|
|
elseif(${PREFIX}TARGET_X86_64_V3)
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/arch:AVX2")
|
|
elseif(${PREFIX}TARGET_X86_64_V2_EX)
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/arch:AVX")
|
|
elseif(${PREFIX}TARGET_X86_64_V2)
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/d2archSSE42")
|
|
elseif(${PREFIX}TARGET_X86_64)
|
|
#target_compile_options(${TARGET_NAME} PRIVATE "/arch:SSE2")
|
|
endif()
|
|
endif()
|
|
|
|
# - Use fast unordered math if possible.
|
|
if(${PREFIX}ENABLE_FASTMATH)
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/fp:fast")
|
|
else()
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/fp:precise")
|
|
if(MSVC_VERSION GREATER 1930)
|
|
# Keep original behavior in VS2022 and up.
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/fp:contract")
|
|
endif()
|
|
endif()
|
|
|
|
# - Disable incremental builds
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/INCREMENTAL:NO")
|
|
|
|
# - Enable C++ exceptions with SEH exceptions.
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/EHa")
|
|
|
|
# - Enable multi-processor compiling.
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/MP")
|
|
|
|
# - Enable updated __cplusplus macro
|
|
target_compile_options(${TARGET_NAME} PRIVATE "/Zc:__cplusplus")
|
|
elseif(D_PLATFORM_LINUX AND ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
|
|
# GCC/Clang
|
|
|
|
# - Enable all warnings.
|
|
target_compile_options(${TARGET_NAME} PRIVATE "-Wall")
|
|
target_compile_options(${TARGET_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(${TARGET_NAME} PRIVATE "-Wno-${WARN}")
|
|
endforeach()
|
|
|
|
# - Require enabled instruction sets.
|
|
if(${PREFIX}TARGET_NATIVE)
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-march=native"
|
|
)
|
|
elseif(D_PLATFORM_ARCH_X86)
|
|
if(${PREFIX}TARGET_X86_64_V4)
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-march=x86-64-v4"
|
|
)
|
|
elseif(${PREFIX}TARGET_X86_64_V3)
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-march=x86-64-v3"
|
|
)
|
|
elseif(${PREFIX}TARGET_X86_64_V2_EX)
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-march=x86-64-v2"
|
|
"-mavx"
|
|
"-mbmi2"
|
|
"-mbmi"
|
|
"-mfma"
|
|
"-mf16c"
|
|
"-mmovbe"
|
|
"-mpclmul"
|
|
"-mpopcnt"
|
|
)
|
|
elseif(${PREFIX}TARGET_X86_64_V2)
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-march=x86-64-v2"
|
|
)
|
|
elseif(${PREFIX}TARGET_X86_64)
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-march=x86-64"
|
|
)
|
|
endif()
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-mtune=generic"
|
|
)
|
|
else()
|
|
target_compile_options(${TARGET_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(${TARGET_NAME} PRIVATE
|
|
"-ffast-math"
|
|
)
|
|
else()
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-ffp-model=fast"
|
|
)
|
|
endif()
|
|
else()
|
|
target_compile_options(${TARGET_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
|
|
|
|
# - Enable most useful warnings.
|
|
target_compile_options(${TARGET_NAME} PRIVATE "-Wall")
|
|
target_compile_options(${TARGET_NAME} PRIVATE "-Wextra")
|
|
|
|
# - Require enabled instruction sets.
|
|
if(${PREFIX}TARGET_NATIVE)
|
|
target_compile_options(${TARGET_NAME} PRIVATE
|
|
"-march=native"
|
|
)
|
|
message(WARNING "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()
|
|
endfunction()
|
|
|
|
function(streamfx_sanitize_name TEXT _OUTPUT_NAME _OUTPUT_TARGET _OUTPUT_OPTION)
|
|
string(REGEX REPLACE "^[ \t]+" "" TEXT "${TEXT}")
|
|
string(REGEX REPLACE "[ \t]+$" "" TEXT "${TEXT}")
|
|
string(REGEX REPLACE "[^a-zA-Z0-9_-]+" "_" TEXT2 "${TEXT}")
|
|
string(REGEX REPLACE "_[_]+" "_" TEXT2 "${TEXT2}")
|
|
string(TOUPPER "${TEXT2}" TEXT3)
|
|
|
|
set(${_OUTPUT_NAME} "${TEXT}" PARENT_SCOPE)
|
|
set(${_OUTPUT_TARGET} "${TEXT2}" PARENT_SCOPE)
|
|
set(${_OUTPUT_OPTION} "${TEXT3}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(streamfx_add_component COMPONENT_NAME)
|
|
cmake_parse_arguments(PARSE_ARGV 1 _ARG
|
|
""
|
|
"RESOLVER"
|
|
""
|
|
)
|
|
|
|
# Sanitize name for further use.
|
|
streamfx_sanitize_name("${COMPONENT_NAME}" COMPONENT_NAME COMPONENT_SANITIZED_NAME COMPONENT_OPTION_NAME)
|
|
set(COMPONENT_OPTION "${PREFIX}COMPONENT_${COMPONENT_OPTION_NAME}")
|
|
set(COMPONENT_OPTION "${COMPONENT_OPTION}" PARENT_SCOPE)
|
|
|
|
# Define the necessary targets.
|
|
set(COMPONENT_TARGET "StreamFX_${COMPONENT_SANITIZED_NAME}")
|
|
set(COMPONENT_TARGET "${COMPONENT_TARGET}" PARENT_SCOPE)
|
|
set(COMPONENT_ALIAS "StreamFX::${COMPONENT_SANITIZED_NAME}")
|
|
set(COMPONENT_ALIAS "${COMPONENT_ALIAS}" PARENT_SCOPE)
|
|
|
|
streamfx_add_library(${COMPONENT_TARGET} STATIC EXCLUDE_FROM_ALL)
|
|
add_library(${COMPONENT_ALIAS} ALIAS ${COMPONENT_TARGET})
|
|
set_target_properties(${COMPONENT_TARGET} PROPERTIES
|
|
COMPONENT_LABEL "${COMPONENT_NAME}"
|
|
COMPONENT_NAME "${COMPONENT_ALIAS}"
|
|
COMPONENT_OPTION "${COMPONENT_OPTION}"
|
|
)
|
|
|
|
# Always depend on StreamFX::Core
|
|
target_link_libraries(${COMPONENT_TARGET} PRIVATE $<LINK_LIBRARY:WHOLE_ARCHIVE,StreamFX_Core>)
|
|
|
|
# Register the component globally.
|
|
get_target_property(_DEPENDS StreamFX COMPONENT_DEPENDS)
|
|
if(_DEPENDS)
|
|
list(APPEND _DEPENDS "${COMPONENT_SANITIZED_NAME}")
|
|
else()
|
|
set(_DEPENDS "${COMPONENT_SANITIZED_NAME}")
|
|
endif()
|
|
set_target_properties(StreamFX PROPERTIES
|
|
COMPONENT_DEPENDS "${_DEPENDS}"
|
|
)
|
|
|
|
# If there is a resolver function, register it.
|
|
if(_ARG_RESOLVER)
|
|
set_target_properties(${COMPONENT_TARGET} PROPERTIES
|
|
COMPONENT_RESOLVER "${_ARG_RESOLVER}"
|
|
)
|
|
endif()
|
|
|
|
# Allow disabling this component.
|
|
set(${COMPONENT_OPTION} ON CACHE BOOL "Enable the ${COMPONENT_NAME} component?")
|
|
set(${COMPONENT_OPTION}_DISABLED OFF CACHE INTERNAL "Disable the ${_NAME} component?" FORCE)
|
|
|
|
# Add common include directories
|
|
target_include_directories(${COMPONENT_TARGET}
|
|
PRIVATE
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/source"
|
|
PUBLIC
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
|
)
|
|
|
|
# Add files in common places.
|
|
file(GLOB_RECURSE TEMPLATES FOLLOW_SYMLINKS CONFIGURE_DEPENDS "templates/*")
|
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/templates" PREFIX "Templates" FILES ${TEMPLATES})
|
|
|
|
file(GLOB_RECURSE DATA FOLLOW_SYMLINKS CONFIGURE_DEPENDS "data/*")
|
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/data" PREFIX "Data" FILES ${DATA})
|
|
|
|
file(GLOB_RECURSE SOURCE_PRIVATE FOLLOW_SYMLINKS CONFIGURE_DEPENDS "ui/*")
|
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/ui" PREFIX "User-Interface Files" FILES ${USERINTERFACE})
|
|
|
|
file(GLOB_RECURSE SOURCE_PRIVATE FOLLOW_SYMLINKS CONFIGURE_DEPENDS "source/*")
|
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/source" PREFIX "Private Files" FILES ${SOURCE_PRIVATE})
|
|
file(GLOB_RECURSE UI_PRIVATE FOLLOW_SYMLINKS CONFIGURE_DEPENDS "source/ui/*")
|
|
file(GLOB_RECURSE GENERATED_PRIVATE FOLLOW_SYMLINKS CONFIGURE_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/source/*")
|
|
source_group(TREE "${CMAKE_CURRENT_BINARY_DIR}/source" PREFIX "Private Files/Generated" FILES ${GENERATED_PRIVATE})
|
|
|
|
file(GLOB_RECURSE SOURCE_PUBLIC FOLLOW_SYMLINKS CONFIGURE_DEPENDS "include/*")
|
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/include" PREFIX "Public Files" FILES ${SOURCE_PUBLIC})
|
|
file(GLOB_RECURSE UI_PUBLIC FOLLOW_SYMLINKS CONFIGURE_DEPENDS "include/ui/*")
|
|
file(GLOB_RECURSE GENERATED_PUBLIC FOLLOW_SYMLINKS CONFIGURE_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/include/*")
|
|
source_group(TREE "${CMAKE_CURRENT_BINARY_DIR}/include" PREFIX "Public Files/Generated" FILES ${GENERATED_PUBLIC})
|
|
|
|
target_sources(${COMPONENT_TARGET}
|
|
PRIVATE
|
|
${DATA}
|
|
${TEMPLATES}
|
|
${USERINTERFACE}
|
|
${SOURCE_PRIVATE}
|
|
${GENERATED_PRIVATE}
|
|
PUBLIC
|
|
${SOURCE_PUBLIC}
|
|
${GENERATED_PUBLIC}
|
|
)
|
|
|
|
# Ignore data only files.
|
|
set_source_files_properties(
|
|
${DATA}
|
|
${TEMPLATES}
|
|
${USERINTERFACE}
|
|
PROPERTIES
|
|
HEADER_FILE_ONLY ON
|
|
)
|
|
|
|
# Enable Qt if needed
|
|
set_target_properties(${TARGET_NAME} PROPERTIES
|
|
AUTOUIC ON
|
|
AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/ui"
|
|
AUTOMOC ON
|
|
AUTORCC ON
|
|
AUTOGEN_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated"
|
|
)
|
|
set_source_files_properties(
|
|
${TEMPLATES}
|
|
${SOURCE_PRIVATE}
|
|
${GENERATED_PRIVATE}
|
|
${SOURCE_PUBLIC}
|
|
${GENERATED_PUBLIC}
|
|
PROPERTIES
|
|
SKIP_AUTOGEN ON
|
|
SKIP_AUTOMOC ON
|
|
SKIP_AUTORCC ON
|
|
SKIP_AUTOUIC ON
|
|
)
|
|
set_source_files_properties(
|
|
${UI_PRIVATE}
|
|
${UI_PUBLIC}
|
|
PROPERTIES
|
|
SKIP_AUTOGEN OFF
|
|
SKIP_AUTOMOC OFF
|
|
SKIP_AUTORCC OFF
|
|
SKIP_AUTOUIC OFF
|
|
)
|
|
endfunction()
|
|
|
|
function(streamfx_has_component _NAME _OUTPUT)
|
|
streamfx_sanitize_name("${_NAME}" _NAME _TARGET _OPTION)
|
|
|
|
set(${_OUTPUT} OFF PARENT_SCOPE)
|
|
if(TARGET "StreamFX_${_TARGET}")
|
|
set(${_OUTPUT} ON PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
function(streamfx_enabled_component _NAME _OUTPUT)
|
|
streamfx_sanitize_name("${_NAME}" _NAME _TARGET _OPTION)
|
|
if(NOT TARGET "StreamFX_${_TARGET}")
|
|
message(FATAL_ERROR "Unknown component '${_NAME}'.")
|
|
endif()
|
|
|
|
get_target_property(_OPTION "StreamFX_${_TARGET}" COMPONENT_OPTION)
|
|
set(${_OUTPUT} OFF PARENT_SCOPE)
|
|
if(${_OPTION} AND NOT (${_OPTION}_DISABLED))
|
|
set(${_OUTPUT} ON PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
# Use this to add a dependency on another component.
|
|
function(streamfx_add_component_dependency _NAME)
|
|
cmake_parse_arguments(PARSE_ARGV 1 _ARG
|
|
"OPTIONAL"
|
|
""
|
|
""
|
|
)
|
|
|
|
streamfx_sanitize_name("${_NAME}" _NAME _TARGET _OPTION)
|
|
|
|
set(DEPENDENCY "${_TARGET}")
|
|
if(_ARG_OPTIONAL)
|
|
list(APPEND DEPENDENCY "OPTIONAL")
|
|
endif()
|
|
string(REPLACE ";" "\\;" DEPENDENCY "${DEPENDENCY}")
|
|
|
|
get_target_property(DEPENDS "${COMPONENT_TARGET}" COMPONENT_DEPENDS)
|
|
if(DEPENDS)
|
|
list(APPEND DEPENDS "${DEPENDENCY}")
|
|
else()
|
|
set(DEPENDS "${DEPENDENCY}")
|
|
endif()
|
|
set_target_properties("${COMPONENT_TARGET}" PROPERTIES COMPONENT_DEPENDS "${DEPENDS}")
|
|
endfunction()
|
|
|
|
# Use this to disable a component via script.
|
|
function(streamfx_disable_component _NAME)
|
|
cmake_parse_arguments(PARSE_ARGV 1 _ARG
|
|
""
|
|
"REASON"
|
|
""
|
|
)
|
|
|
|
streamfx_sanitize_name("${_NAME}" _NAME _TARGET _OPTION)
|
|
if(NOT (_TARGET MATCHES "^StreamFX_"))
|
|
set(_TARGET "StreamFX_${_TARGET}")
|
|
endif()
|
|
|
|
# If the component doesn't exist, skip it.
|
|
if(NOT TARGET ${_TARGET})
|
|
message(WARNING "Not disabling invalid component '${_NAME}'.")
|
|
return()
|
|
endif()
|
|
|
|
get_target_property(_LABEL ${_TARGET} COMPONENT_LABEL)
|
|
get_target_property(_OPTION ${_TARGET} COMPONENT_OPTION)
|
|
|
|
CacheSet(${_OPTION}_DISABLED ON)
|
|
if(_ARG_REASON)
|
|
message(STATUS "[${_LABEL}] Disabled due to: ${_ARG_REASON}")
|
|
endif()
|
|
endfunction()
|
|
|
|
################################################################################
|
|
# Register Library
|
|
################################################################################
|
|
streamfx_add_library(StreamFX MODULE) # We are a module for libOBS.
|
|
|
|
target_include_directories(StreamFX PRIVATE
|
|
"source"
|
|
"include"
|
|
"${PROJECT_BINARY_DIR}/generated"
|
|
)
|
|
|
|
# Ensure there is at least one file.
|
|
if(D_PLATFORM_WINDOWS)
|
|
target_sources(StreamFX
|
|
PRIVATE
|
|
"source/windll.cpp"
|
|
)
|
|
else()
|
|
target_sources(StreamFX
|
|
PRIVATE
|
|
"/dev/null"
|
|
)
|
|
endif()
|
|
|
|
if(D_PLATFORM_WINDOWS) # Windows-exclusive
|
|
# Version Resource
|
|
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"
|
|
)
|
|
target_sources(StreamFX
|
|
PRIVATE
|
|
"templates/windows/version.rc.in"
|
|
"${PROJECT_BINARY_DIR}/generated/version.rc"
|
|
)
|
|
elseif(D_PLATFORM_MAC) # MacOS exclusive Changes
|
|
set_target_properties(StreamFX 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(StreamFX PROPERTIES
|
|
# @rpath in built binaries
|
|
BUILD_WITH_INSTALL_RPATH ON
|
|
)
|
|
endif()
|
|
endif()
|
|
|
|
# Set file version
|
|
set_target_properties(StreamFX PROPERTIES
|
|
MACHO_COMPATIBILITY_VERSION ${_VERSION_MAJOR}.${_VERSION_MINOR}
|
|
MACHO_CURRENT_VERSION ${PROJECT_VERSION}
|
|
SOVERSION ${_VERSION_MAJOR}.${_VERSION_MINOR}
|
|
VERSION ${PROJECT_VERSION}
|
|
)
|
|
|
|
################################################################################
|
|
# Add Core
|
|
################################################################################
|
|
streamfx_add_library(StreamFX_Core STATIC EXCLUDE_FROM_ALL)
|
|
add_library(StreamFX::Core ALIAS StreamFX_Core)
|
|
|
|
# Register the library
|
|
target_link_libraries(StreamFX_Core
|
|
PRIVATE ${PROJECT_LIBRARIES}
|
|
PUBLIC OBS::libobs
|
|
)
|
|
target_include_directories(StreamFX_Core
|
|
PRIVATE ${PROJECT_INCLUDE_DIRS}
|
|
PUBLIC
|
|
"${PROJECT_SOURCE_DIR}/source"
|
|
"${PROJECT_BINARY_DIR}/generated"
|
|
)
|
|
target_compile_definitions(StreamFX_Core
|
|
PRIVATE ${PROJECT_DEFINITIONS}
|
|
)
|
|
|
|
# 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
|
|
)
|
|
|
|
# Enable Qt if needed
|
|
set_target_properties(StreamFX_Core PROPERTIES
|
|
AUTOUIC ON
|
|
AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/ui"
|
|
AUTOMOC ON
|
|
AUTORCC ON
|
|
AUTOGEN_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated"
|
|
)
|
|
|
|
# Prevent non-UI files from being Qt'd
|
|
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
|
|
)
|
|
|
|
target_sources(StreamFX_Core PRIVATE ${PROJECT_FILES})
|
|
|
|
################################################################################
|
|
# Components
|
|
################################################################################
|
|
# As the above monolithic approach started to show its weaknesses, it was time
|
|
# for an improved system which suffers under less issues. This new component
|
|
# system should address the main necessary parts,
|
|
|
|
#- Registration
|
|
file(GLOB COMPONENTS RELATIVE ${PROJECT_SOURCE_DIR} CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/components/*)
|
|
foreach(COMPONENT ${COMPONENTS})
|
|
# Ignore directories with no CMakeLists.txt
|
|
if(EXISTS "${PROJECT_SOURCE_DIR}/${COMPONENT}/CMakeLists.txt")
|
|
add_subdirectory(${COMPONENT} EXCLUDE_FROM_ALL)
|
|
endif()
|
|
endforeach()
|
|
|
|
get_target_property(_UNRESOLVED StreamFX COMPONENT_DEPENDS)
|
|
set(_RESOLVED "")
|
|
set(_DISABLED "")
|
|
|
|
#- Cleanup
|
|
list(REMOVE_DUPLICATES _UNRESOLVED)
|
|
foreach(_ENTITY ${_UNRESOLVED})
|
|
# Remove any invalid entries.
|
|
if(NOT TARGET "StreamFX_${_ENTITY}")
|
|
message(WARNING "Encountered invalid component '${_ENTITY}', removing...")
|
|
list(REMOVE_ITEM _UNRESOLVED "${_ENTITY}")
|
|
continue()
|
|
endif()
|
|
endforeach()
|
|
|
|
#- Resolve Dependencies in a loop
|
|
set(_UNRESOLVED_LOOP 0)
|
|
while(_UNRESOLVED)
|
|
MATH(EXPR _UNRESOLVED_LOOP "${_UNRESOLVED_LOOP}+1")
|
|
if(_UNRESOLVED_LOOP GREATER_EQUAL 10)
|
|
message(FATAL_ERROR "Infinite loop while resolving components: ${_UNRESOLVED}")
|
|
endif()
|
|
|
|
# Attempt to resolve while there are still unresolved entries.
|
|
foreach(_ENTITY ${_UNRESOLVED})
|
|
set(RENTITY "StreamFX_${_ENTITY}")
|
|
|
|
get_target_property(_ALIAS "${RENTITY}" COMPONENT_NAME)
|
|
get_target_property(_LABEL "${RENTITY}" COMPONENT_LABEL)
|
|
get_target_property(_OPTION "${RENTITY}" COMPONENT_OPTION)
|
|
get_target_property(_DEPENDS "${RENTITY}" COMPONENT_DEPENDS)
|
|
get_target_property(_RESOLVER "${RENTITY}" COMPONENT_RESOLVER)
|
|
|
|
# Remove any that have been disabled.
|
|
if(NOT ${_OPTION})
|
|
message(STATUS "[${_LABEL}] Disabled by user.")
|
|
list(REMOVE_ITEM _UNRESOLVED "${_ENTITY}")
|
|
list(APPEND _DISABLED "${_ENTITY}")
|
|
continue()
|
|
elseif(${_OPTION}_DISABLED) # Test for pre-resolve disabling.
|
|
message(STATUS "[${_LABEL}] Disabled by build script.")
|
|
list(REMOVE_ITEM _UNRESOLVED "${_ENTITY}")
|
|
list(APPEND _DISABLED "${_ENTITY}")
|
|
continue()
|
|
endif()
|
|
|
|
# Check if all dependencies are resolved.
|
|
set(_HAS_UNRESOLVED_DEPENDS OFF)
|
|
set(_HAS_DISABLED_DEPENDS OFF)
|
|
set(_HAS_UNRESOLVED_OPTIONAL_DEPENDS OFF)
|
|
if(_DEPENDS)
|
|
foreach(_DEPEND ${_DEPENDS})
|
|
list(GET _DEPEND 0 _ENTITY2)
|
|
set(RENTITY2 "StreamFX_${_ENTITY2}")
|
|
|
|
get_target_property(_ENTITY2_LABEL "${RENTITY2}" COMPONENT_LABEL)
|
|
|
|
if(NOT ("OPTIONAL" IN_LIST _DEPEND))
|
|
if("${_ENTITY2}" IN_LIST _DISABLED)
|
|
message("[${_LABEL}] Required dependency '${_ENTITY2_LABEL}' is disabled.")
|
|
set(_HAS_DISABLED_DEPENDS ON)
|
|
endif()
|
|
if("${_ENTITY2}" IN_LIST _UNRESOLVED)
|
|
set(_HAS_UNRESOLVED_DEPENDS ON)
|
|
endif()
|
|
else()
|
|
if("${_ENTITY2}" IN_LIST _UNRESOLVED)
|
|
set(_HAS_UNRESOLVED_OPTIONAL_DEPENDS ON)
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
list(JOIN _DEPENDS ", " _DEPENDS)
|
|
else()
|
|
set(_DEPENDS "")
|
|
endif()
|
|
if(_HAS_DISABLED_DEPENDS) # A required dependency is disabled, so disable this entry.
|
|
message(STATUS "[${_LABEL}] Disabled by dependency.")
|
|
list(REMOVE_ITEM _UNRESOLVED "${_ENTITY}")
|
|
list(APPEND _DISABLED "${_ENTITY}")
|
|
streamfx_disable_component(${_ENTITY})
|
|
continue()
|
|
elseif(_HAS_UNRESOLVED_DEPENDS)
|
|
continue()
|
|
elseif(_HAS_UNRESOLVED_OPTIONAL_DEPENDS AND (_UNRESOLVED_LOOP LESS 8))
|
|
# Temporarily skip this element while there are still remaining loops.
|
|
continue()
|
|
endif()
|
|
|
|
# Call Resolver function
|
|
if(_RESOLVER)
|
|
set(COMPONENT_TARGET "${RENTITY}")
|
|
set(COMPONENT_ALIAS "${_ALIAS}")
|
|
set(COMPONENT_OPTION "${_OPTION}")
|
|
cmake_language(CALL ${_RESOLVER})
|
|
endif()
|
|
if(${_OPTION}_DISABLED) # Test for resolve disabling.
|
|
message(STATUS "[${_LABEL}] Disabled by resolver.")
|
|
list(REMOVE_ITEM _UNRESOLVED "${_ENTITY}")
|
|
list(APPEND _DISABLED "${_ENTITY}")
|
|
continue()
|
|
endif()
|
|
|
|
# Finally, if everything went well, we now have a resolved entity.
|
|
list(REMOVE_ITEM _UNRESOLVED "${_ENTITY}")
|
|
list(APPEND _RESOLVED "${_ENTITY}")
|
|
message(STATUS "[${_LABEL}] Enabled. Depends: ${_DEPENDS}")
|
|
endforeach()
|
|
endwhile()
|
|
|
|
#- Linking
|
|
foreach(_ENTITY ${_RESOLVED})
|
|
set(RENTITY "StreamFX_${_ENTITY}")
|
|
get_target_property(_DEPENDS "${RENTITY}" COMPONENT_DEPENDS)
|
|
|
|
# Finally if everything is correct, do things.
|
|
if(_DEPENDS)
|
|
foreach(_DEPEND ${_DEPENDS})
|
|
list(GET _DEPEND 0 _ENTITY2)
|
|
set(RENTITY2 "StreamFX_${_ENTITY2}")
|
|
|
|
streamfx_enabled_component(${_ENTITY2} T_CHECK)
|
|
if(T_CHECK)
|
|
target_link_libraries(${RENTITY}
|
|
PUBLIC
|
|
$<LINK_LIBRARY:WHOLE_ARCHIVE,${RENTITY2}>
|
|
)
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
target_link_libraries(StreamFX
|
|
PRIVATE
|
|
$<LINK_LIBRARY:WHOLE_ARCHIVE,${RENTITY}>
|
|
)
|
|
endforeach()
|
|
|
|
target_link_libraries(StreamFX PUBLIC $<LINK_LIBRARY:WHOLE_ARCHIVE,StreamFX_Core>)
|
|
|
|
################################################################################
|
|
# Installation
|
|
################################################################################
|
|
|
|
if(STANDALONE)
|
|
if(D_PLATFORM_WINDOWS)
|
|
install(
|
|
TARGETS StreamFX
|
|
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/StreamFX/"
|
|
)
|
|
if(MSVC)
|
|
install(
|
|
FILES $<TARGET_PDB_FILE:StreamFX>
|
|
DESTINATION "obs-plugins/${D_PLATFORM_BITS}bit/"
|
|
OPTIONAL
|
|
)
|
|
endif()
|
|
elseif(D_PLATFORM_LINUX)
|
|
if(STRUCTURE_PACKAGEMANAGER)
|
|
install(
|
|
TARGETS StreamFX
|
|
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/StreamFX"
|
|
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 StreamFX
|
|
RUNTIME DESTINATION "plugins/StreamFX/bin/${D_PLATFORM_BITS}bit/" COMPONENT StreamFX
|
|
LIBRARY DESTINATION "plugins/StreamFX/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/StreamFX/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)
|
|
# Bundle Information
|
|
set(MACOSX_BUNDLE_BUNDLE_NAME "StreamFX")
|
|
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}")
|
|
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}")
|
|
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_IDENTIFER}")
|
|
set(MACOSX_BUNDLE_ICON_FILE "icon.png")
|
|
set(MACOSX_BUNDLE_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
|
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${_VERSION}")
|
|
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
|
|
set_target_properties(StreamFX PROPERTIES
|
|
BUNDLE ON
|
|
BUNDLE_EXTENSION "plugin"
|
|
OUTPUT_NAME StreamFX
|
|
MACOSX_BUNDLE_INFO_PLIST "${PROJECT_SOURCE_DIR}/templates/macos/Info.plist.in"
|
|
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${MACOSX_BUNDLE_GUI_IDENTIFIER}"
|
|
)
|
|
|
|
# Proper location for resources in Bundles
|
|
foreach(FILE IN LISTS PROJECT_DATA)
|
|
cmake_path(ABSOLUTE_PATH FILE OUTPUT_VARIABLE FILE_PATH)
|
|
cmake_path(RELATIVE_PATH FILE_PATH BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/data/")
|
|
cmake_path(GET FILE_PATH PARENT_PATH FILE_PATH)
|
|
set_source_files_properties("${FILE}" PROPERTIES
|
|
MACOSX_PACKAGE_LOCATION "Resources/${FILE_PATH}"
|
|
)
|
|
endforeach()
|
|
|
|
# Bundle Icon
|
|
set_source_files_properties("media/icon.png" PROPERTIES
|
|
MACOSX_PACKAGE_LOCATION "Resources"
|
|
)
|
|
|
|
install(
|
|
TARGETS StreamFX
|
|
RUNTIME DESTINATION "." COMPONENT StreamFX
|
|
LIBRARY DESTINATION "." COMPONENT StreamFX
|
|
BUNDLE DESTINATION "." COMPONENT StreamFX
|
|
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(StreamFX)
|
|
# Seems like we lost the ability to customize which directoy resources are in, and instead are forced to use '/data'.
|
|
elseif(COMMAND install_obs_plugin_with_data)
|
|
install_obs_plugin_with_data(StreamFX data)
|
|
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(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)
|
|
|
|
configure_file(
|
|
"templates/windows/installer.iss.in"
|
|
"installer.iss"
|
|
)
|
|
elseif(D_PLATFORM_MAC)
|
|
# .pkg Installer
|
|
set(PACKAGES_PATH_NAME "StreamFX")
|
|
set(PACKAGES_PATH_NAME "${PACKAGES_PATH_NAME}.plugin")
|
|
configure_file(
|
|
"templates/macos/installer.pkgproj.in"
|
|
"installer.pkgproj"
|
|
)
|
|
elseif(D_PLATFORM_LINUX)
|
|
add_custom_target(
|
|
PACKAGE
|
|
${CMAKE_COMMAND} -E tar cfv "${_PACKAGE_FULL_NAME}.7z" --format=7zip --
|
|
"."
|
|
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
|
|
)
|
|
endif()
|
|
endif()
|