diff --git a/.swift-format b/.swift-format new file mode 100644 index 000000000..d09b0d3e8 --- /dev/null +++ b/.swift-format @@ -0,0 +1,12 @@ +{ + "version": 1, + "lineLength": 120, + "indentation": { + "spaces": 4 + }, + "tabWidth": 4, + "maximumBlankLines": 1, + "respectsExistingLineBreaks": true, + "lineBreakBeforeControlFlowKeywords": false, + "lineBreakBeforeEachArgument": false +} diff --git a/buildspec.json b/buildspec.json new file mode 100644 index 000000000..091f5c5ee --- /dev/null +++ b/buildspec.json @@ -0,0 +1,74 @@ +{ + "dependencies": { + "prebuilt": { + "version": "2023-03-20", + "baseUrl": "https://github.com/obsproject/obs-deps/releases/download", + "label": "Pre-Built obs-deps", + "hashes": { + "macos-x86_64": "bd4d3866c2e4b630410ff29b3f31a2553844af60b30fa0306d35d80a70f903ba", + "macos-arm64": "90078e2141818a37def7ebdceb3dcde71dc4adc1ce81d6e31ba21916f85c77bf", + "macos-universal": "a1c7f38701e0b6c0bd4224d3ab1a7b54d8eaf592dcee3223ce94404dc6787595", + "windows-x64": "79b259f65a0be9726b80b35ab86c07a1d5dc333bd3ef1391f6a0168ea6d28828", + "linux-x86_64": "36af10f49491193185dc1a115a29de31f9f2f4f7c01e4ebfe8a81b8094cd12f4" + } + }, + "qt6": { + "version": "2023-03-20", + "baseUrl": "https://github.com/obsproject/obs-deps/releases/download", + "label": "Pre-Built Qt6", + "hashes": { + "macos-x86_64": "8f5e1a865310898635d34b92e6d93c99c62f39289a17d6db140e776ba9b2e455", + "macos-arm64": "0011e2395afbb02aaa5e8641c4486680e30decc60e063ca5a73d6faf3649e723", + "macos-universal": "5bcbb8fee4b70a26912e04a62960c615153828eac66b9f0bcb0b30529193ca6e", + "windows-x64": "e52feb06203c043929e271acc3a8d1b2e959c26d8426c4a1fb6c7337fee4e5c8" + }, + "debugSymbols": { + "windows-x64": "ae16477980e1bc602f244923f6e75c214311df286981211ee29a67ac060d4389" + } + }, + "cef": { + "version": "5060", + "baseUrl": "https://cdn-fastly.obsproject.com/downloads", + "label": "Chromium Embedded Framework", + "hashes": { + "macos-x86_64": "7ef71717ff2e4ff4212274c33f0993729f47c109c464e499544fd3f63586a069", + "macos-arm64": "a9da8909202aefc8f35509d03eff9a7c837b5d3b2ed3afb39b67121cb16d457b", + "linux-x86_64": "bf4aa9388bab7e94fa945cc3bba16b6da63b6a30f9c0342d42235468b39d84bf", + "linux-aarch64": "68d915c9ba2639cba762a54cd3430fce2527aa6355d831d3cfcb6157664206b0", + "windows-x64": "c1b47beb7ee42e98f1a41b6d694c26842a4a3d452e44bdf6f758c9785696533d" + }, + "revision": { + "macos-x86_64": 2, + "macos-arm64": 2 + } + }, + "vlc": { + "version": "3.0.8", + "baseUrl": "https://downloads.videolan.org/vlc", + "label": "VLC", + "hashes": { + "windows-x64": "91f589ef69fce51645a3ecbb215b405c98db7b891479474ec3b5ed3b63c25e4a" + } + } + }, + "platformConfig": { + "macos-x86_64": { + "qtVersion": 6, + "deploymentTarget": "11.0", + "buildTarget": "11.0" + }, + "macos-arm64": { + "qtVersion": 6, + "deploymentTarget": "11.0", + "buildTarget": "11.0" + }, + "windows-x64": { + "qtVersion": 6 + }, + "linux-x86_64": { + "qtVersion": 6, + "generator": "Ninja" + } + }, + "name": "obs-studio" +} diff --git a/cmake/macos/.cmake-format.json b/cmake/macos/.cmake-format.json new file mode 100644 index 000000000..75fd03ad3 --- /dev/null +++ b/cmake/macos/.cmake-format.json @@ -0,0 +1,41 @@ +{ + "format": { + "line_width": 120, + "tab_size": 2, + "dangle_parens": false, + "enable_sort": true, + "autosort": true + }, + "additional_commands": { + "find_qt": { + "flags": [], + "kwargs": { + "COMPONENTS": "+", + "COMPONENTS_WIN": "+", + "COMPONENTS_MACOS": "+", + "COMPONENTS_LINUX": "+" + } + }, + "set_target_properties_obs": { + "pargs": 1, + "flags": [], + "kwargs": { + "PROPERTIES": { + "kwargs": { + "PREFIX": 1, + "OUTPUT_NAME": 1, + "FOLDER": 1, + "VERSION": 1, + "SOVERSION": 1, + "FRAMEWORK": 1, + "BUNDLE": 1, + "AUTOMOC": 1, + "AUTOUIC": 1, + "AUTORCC": 1, + "AUTOUIC_SEARCH_PATHS": 1 + } + } + } + } + } +} diff --git a/cmake/macos/buildspec.cmake b/cmake/macos/buildspec.cmake new file mode 100644 index 000000000..3aa2a4efd --- /dev/null +++ b/cmake/macos/buildspec.cmake @@ -0,0 +1,193 @@ +# OBS CMake macOS build dependencies module + +# cmake-format: off +# cmake-lint: disable=E1126 +# cmake-lint: disable=R0912 +# cmake-lint: disable=R0915 +# cmake-format: on + +# _check_deps_version: Checks for obs-deps VERSION file in prefix paths +macro(_check_deps_version version) + set(found FALSE) + + foreach(path IN LISTS CMAKE_PREFIX_PATH) + if(EXISTS "${path}/share/obs-deps/VERSION") + if(dependency STREQUAL qt6 AND NOT EXISTS "${path}/lib/cmake/Qt6/Qt6Config.cmake") + set(found FALSE) + break() + endif() + + file(READ "${path}/share/obs-deps/VERSION" _check_version) + string(REPLACE "\n" "" _check_version "${_check_version}") + + if(_check_version VERSION_EQUAL version) + set(found TRUE) + break() + elseif(_check_version VERSION_LESS version) + message(AUTHOR_WARNING "Outdated ${label} version detected in ${path}: \n" + "Found ${_check_version}, require ${version}") + list(REMOVE_ITEM CMAKE_PREFIX_PATH "${path}") + list(APPEND CMAKE_PREFIX_PATH "${path}") + continue() + else() + message(AUTHOR_WARNING "Future ${label} version detected in ${path}: \n" + "Found ${_check_version}, require ${version}") + set(found TRUE) + break() + endif() + endif() + endforeach() +endmacro() + +# _check_dependencies: Fetch and extract pre-built OBS build dependencies +function(_check_dependencies) + if(CMAKE_OSX_ARCHITECTURES MATCHES ".+;.+") + set(arch universal) + else() + set(arch ${CMAKE_OSX_ARCHITECTURES}) + endif() + + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + + # cmake-format: off + string(JSON deployment_target GET ${buildspec} platformConfig macos-${arch} deploymentTarget) + string(JSON dependency_data GET ${buildspec} dependencies) + # cmake-format: on + + if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) + set(CMAKE_OSX_DEPLOYMENT_TARGET + ${_deployment_target} + CACHE STRING "Minimum macOS version to target for deployment (at runtime). Newer APIs will be weak-linked." + FORCE) + endif() + + set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps") + set(prebuilt_filename "macos-deps-VERSION-ARCH-REVISION.tar.xz") + set(prebuilt_destination "obs-deps-VERSION-ARCH") + set(qt6_filename "macos-deps-qt6-VERSION-ARCH-REVISION.tar.xz") + set(qt6_destination "obs-deps-qt6-VERSION-ARCH") + set(cef_filename "cef_binary_VERSION_macos_ARCH_REVISION.tar.xz") + set(cef_destination "cef_binary_VERSION_macos_ARCH") + + foreach(dependency IN ITEMS prebuilt qt6 cef) + # cmake-format: off + string(JSON data GET ${dependency_data} ${dependency}) + string(JSON version GET ${data} version) + string(JSON hash GET ${data} hashes macos-${arch}) + string(JSON url GET ${data} baseUrl) + string(JSON label GET ${data} label) + string(JSON revision ERROR_VARIABLE error GET ${data} revision macos-${arch}) + # cmake-format: on + + message(STATUS "Setting up ${label}") + + set(file "${${dependency}_filename}") + set(destination "${${dependency}_destination}") + string(REPLACE "VERSION" "${version}" file "${file}") + string(REPLACE "VERSION" "${version}" destination "${destination}") + string(REPLACE "ARCH" "${arch}" file "${file}") + string(REPLACE "ARCH" "${arch}" destination "${destination}") + if(revision) + string(REPLACE "_REVISION" "_v${revision}" file "${file}") + string(REPLACE "-REVISION" "-v${revision}" file "${file}") + else() + string(REPLACE "_REVISION" "" file "${file}") + string(REPLACE "-REVISION" "" file "${file}") + endif() + + set(skip FALSE) + if(dependency STREQUAL prebuilt OR dependency STREQUAL qt6) + _check_deps_version(${version}) + + if(found) + set(skip TRUE) + endif() + elseif(_dependency STREQUAL sparkle) + find_library(SPARKLE Sparkle) + + if(NOT ENABLE_SPARKLE OR SPARKLE) + set(skip TRUE) + else() + unset(SPARKLE CACHE) + endif() + elseif(dependency STREQUAL vlc) + if(NOT ENABLE_VLC OR (VLC_PATH AND EXISTS "${VLC_PATH}")) + set(skip TRUE) + endif() + elseif(dependency STREQUAL cef) + if(NOT ENABLE_BROWSER OR (CEF_ROOT_DIR AND EXISTS "${CEF_ROOT_DIR}")) + set(skip TRUE) + endif() + endif() + + if(skip) + message(STATUS "Setting up ${label} - skipped") + continue() + endif() + + if(dependency STREQUAL qt6 AND "$ENV{CI}") + # cmake-format: off + string(JSON hash GET ${buildspec} dependencies qt6 hashes macos-universal) + # cmake-format: on + string(REPLACE "${arch}" "universal" file "${file}") + endif() + + if(dependency STREQUAL cef) + set(url ${url}/${file}) + else() + set(url ${url}/${version}/${file}) + endif() + + if(NOT EXISTS "${dependencies_dir}/${file}") + message(STATUS "Downloading ${url}") + file( + DOWNLOAD "${url}" "${dependencies_dir}/${file}" + STATUS download_status + EXPECTED_HASH SHA256=${hash}) + + list(GET download_status 0 error_code) + list(GET download_status 1 error_message) + if(error_code GREATER 0) + message(STATUS "Downloading ${url} - Failure") + message(FATAL_ERROR "Unable to download ${url}, failed with error: ${error_message}") + file(REMOVE "${dependencies_dir}/${file}") + else() + message(STATUS "Downloading ${url} - done") + endif() + endif() + + if(NOT EXISTS "${dependencies_dir}/${destination}") + file(MAKE_DIRECTORY "${dependencies_dir}/${destination}") + if(dependency STREQUAL vlc) + file(ARCHIVE_EXTRACT INPUT "${dependencies_dir}/${file}" DESTINATION "${dependencies_dir}") + else() + file(ARCHIVE_EXTRACT INPUT "${dependencies_dir}/${file}" DESTINATION "${dependencies_dir}/${destination}") + endif() + execute_process(COMMAND "xattr" -r -d com.apple.quarantine "${dependencies_dir}/${destination}" + RESULT_VARIABLE result COMMAND_ERROR_IS_FATAL ANY) + endif() + + if(dependency STREQUAL cef) + set(CEF_ROOT_DIR + "${dependencies_dir}/${destination}" + CACHE PATH "CEF Root directory" FORCE) + elseif(dependency STREQUAL prebuilt) + set(VLC_PATH + "${dependencies_dir}/${destination}" + CACHE PATH "VLC source code directory" FORCE) + list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}/${destination}") + elseif(dependency STREQUAL qt6) + list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}/${destination}") + endif() + + message(STATUS "Setting up ${label} - done") + endforeach() + + list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH) + + set(CMAKE_PREFIX_PATH + ${CMAKE_PREFIX_PATH} + CACHE PATH "CMake prefix search path" FORCE) +endfunction() + +_check_dependencies() diff --git a/cmake/macos/compilerconfig.cmake b/cmake/macos/compilerconfig.cmake new file mode 100644 index 000000000..316ee3f5f --- /dev/null +++ b/cmake/macos/compilerconfig.cmake @@ -0,0 +1,66 @@ +# OBS CMake macOS compiler configuration module + +# Enable distinction between Clang and AppleClang +if(POLICY CMP0025) + cmake_policy(SET CMP0025 NEW) +endif() + +# Honor visibility presets for all target types (executable, shared, module, static) +if(POLICY CMP0063) + cmake_policy(SET CMP0063 NEW) +endif() + +include(ccache) +include(compiler_common) +include(simd) + +# Add default C and C++ compiler options if Xcode generator is not used +if(NOT XCODE) + list( + APPEND + _obs_c_options + -Werror + -Wextra + -Wvla + -Wswitch + -Wformat-security + -Wunused-parameter + -Wno-unused-function + -Wno-missing-field-initializers + -Wformat + -fno-strict-aliasing + -Wno-error=shorten-64-to-32) + + # Set symbols to be hidden by default for C and C++ + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + + set(CMAKE_CXX_VISIBILITY_PRESET hidden) + set(CMAKE_C_VISIBILITY_PRESET hidden) + set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) + + # Enable stripping of dead symbols when not building for Debug configuration + set(_release_configs RelWithDebInfo Release MinSizeRel) + if(CMAKE_BUILD_TYPE IN_LIST _release_configs) + add_link_options(LINKER:-dead_strip) + endif() + + add_compile_options("$<$:${_obs_c_options}>" "$<$:${_obs_c_options}>") + + option(ENABLE_COMPILER_TRACE "Enable clang time-trace (requires Ninja)" OFF) + mark_as_advanced(ENABLE_COMPILER_TRACE) + + # Add time trace option to compiler, if enabled. + if(ENABLE_COMPILER_TRACE AND CMAKE_GENERATOR STREQUAL "Ninja") + add_compile_options($<$:-ftime-trace> $<$:-ftime-trace>) + else() + set(ENABLE_COMPILER_TRACE + OFF + CACHE STRING "Enable clang time-trace (requires Ninja)" FORCE) + endif() + + # Enable color diagnostics for AppleClang + set(CMAKE_COLOR_DIAGNOSTICS ON) +endif() + +add_compile_definitions($<$:DEBUG> $<$:_DEBUG>) diff --git a/cmake/macos/cpackconfig.cmake b/cmake/macos/cpackconfig.cmake new file mode 100644 index 000000000..1dc16150a --- /dev/null +++ b/cmake/macos/cpackconfig.cmake @@ -0,0 +1,49 @@ +# OBS CMake macOS CPack configuration module + +include(cpackconfig_common) + +# Set architecture suffix for package file name based on project target +if(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) + set(_cpack_arch_suffix Apple) +elseif(CMAKE_OSX_ARCHITECTURES STREQUAL x86_64) + set(_cpack_arch_suffix Intel) +else() + set(_cpack_arch_suffix Universal) +endif() + +if(ENABLE_RELEASE_BUILD) + set(CPACK_PACKAGE_VERSION ${OBS_VERSION_CANONICAL}) +else() + set(CPACK_PACKAGE_VERSION ${OBS_VERSION}) +endif() + +set(CPACK_PACKAGE_NAME "OBS") +set(CPACK_PACKAGE_FILE_NAME "obs-studio-${CPACK_PACKAGE_VERSION}-macOS-${_cpack_arch_suffix}") +set(CPACK_COMPONENTS_ALL Application) +set(CPACK_COMPONENT_Application_DISPLAY_NAME "OBS Studio") + +# Set background image and icon for generated Drag&Drop disk image +set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/cmake/macos/resources/background.tiff") +set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/macos/resources/AppIcon.icns") +cmake_path(GET CPACK_DMG_BACKGROUND_IMAGE FILENAME _cpack_dmg_background_filename) + +set(CPACK_GENERATOR DragNDrop) +set(CPACK_DMG_FORMAT UDZO) +set(CPACK_DMG_FILESYSTEM APFS) +set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_BINARY_DIR}/package.applescript") + +set(_dmg_window_x 100) +set(_dmg_window_y 100) +set(_dmg_window_width 540) +set(_dmg_window_height 380) +set(_dmg_icon_size 96) +set(_dmg_text_size 16) +set(_dmg_obs_x 124) +set(_dmg_obs_y 180) +set(_dmg_app_link_x 416) +set(_dmg_app_link_y 180) + +configure_file("${CMAKE_SOURCE_DIR}/cmake/macos/resources/package.applescript.in" + "${CMAKE_BINARY_DIR}/package.applescript" @ONLY) + +include(CPack) diff --git a/cmake/macos/defaults.cmake b/cmake/macos/defaults.cmake new file mode 100644 index 000000000..5a20f2ddb --- /dev/null +++ b/cmake/macos/defaults.cmake @@ -0,0 +1,96 @@ +# OBS CMake macOS defaults module + +# Enable selection between arm64 and x86_64 targets +if(NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_OSX_ARCHITECTURES + arm64 + CACHE STRING "Build architectures for macOS" FORCE) +endif() +set_property(CACHE CMAKE_OSX_ARCHITECTURES PROPERTY STRINGS arm64 x86_64) + +# Set empty codesigning team if not specified as cache variable +if(NOT OBS_CODESIGN_TEAM) + set(OBS_CODESIGN_TEAM + "" + CACHE STRING "OBS code signing team for macOS" FORCE) + + # Set ad-hoc codesigning identity if not specified as cache variable + if(NOT OBS_CODESIGN_IDENTITY) + set(OBS_CODESIGN_IDENTITY + "-" + CACHE STRING "OBS code signing identity for macOS" FORCE) + endif() +endif() + +if(XCODE) + include(xcode) +endif() + +include(buildspec) + +# Set default deployment target to 11.0 if not set and enable selection in GUI up to 13.0 +if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) + set(CMAKE_OSX_DEPLOYMENT_TARGET + 11.0 + CACHE STRING "Minimum macOS version to target for deployment (at runtime). Newer APIs will be weak-linked." FORCE) +endif() +set_property(CACHE CMAKE_OSX_DEPLOYMENT_TARGET PROPERTY STRINGS 13.0 12.0 11.0) + +# Use Applications directory as default install destination +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX + "/Applications" + CACHE STRING "Directory to install OBS after building" FORCE) +endif() + +# Show warning about missing CMAKE_PREFIX_PATH, usually required for successful builds +if(NOT DEFINED CMAKE_PREFIX_PATH) + message( + WARNING "No CMAKE_PREFIX_PATH set: OBS supplies pre-built dependencies for building on macOS.\n" + "While OBS can be built using packages installed via Homebrew, pre-built dependencies " + "contain beneficial patches and fixes for use within OBS and is the suggested source " + "of these dependencies.\n" + "You can download the appropriate obs-deps package for your " + "architecture and set CMAKE_PREFIX_PATH to this directory:\n" + "CMAKE_PREFIX_PATH=\"\"\n" + "Download pre-built OBS dependencies at https://github.com/obsproject/obs-deps/releases\n") +endif() + +# SWIG hard codes the directory to its library directory at compile time. As obs-deps need to be relocatable, we need to +# force SWIG to look for its files in a directory relative to the PREFIX_PATH. The best way to ensure this is to set the +# SWIG_LIB environment variable. + +foreach(path IN LISTS CMAKE_PREFIX_PATH) + if(NOT DEFINED ENV{SWIG_LIB} AND EXISTS "${path}/bin/swig") + set(ENV{SWIG_LIB} "${path}/share/swig/CURRENT") + break() + endif() +endforeach() + +# Set default values for CMake's bundle generator and created Info.plist files +set(MACOSX_BUNDLE_EXECUTABLE_NAME OBS) +set(MACOSX_BUNDLE_BUNDLE_NAME "${OBS_PRODUCT_NAME}") +set(MACOSX_BUNDLE_BUNDLE_VERSION ${OBS_BUILD_NUMBER}) +set(MACOSX_BUNDLE_COPYRIGHT "${OBS_LEGAL_COPYRIGHT}") +set(MACOSX_BUNDLE_GUI_IDENTIFIER com.obsproject.obs-studio) +set(MACOSX_BUNDLE_ICON_FILE AppIcon) +set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${OBS_VERSION_CANONICAL}) +string(TIMESTAMP CURRENT_YEAR "%Y") + +# Enable find_package targets to become globally available targets +set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) +# Enable RPATH support for generated binaries +set(CMAKE_MACOSX_RPATH TRUE) +# Use RPATHs from build tree _in_ the build tree +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +# Do not add default linker search paths to RPATH +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) +# Use common bundle-relative RPATH for installed targets +set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks") + +# Used for library exports only (obs-frontend-api) +set(OBS_LIBRARY_DESTINATION "lib") +set(OBS_INCLUDE_DESTINATION "include/obs") +set(OBS_CMAKE_DESTINATION "lib/cmake") + +include(cpackconfig) diff --git a/cmake/macos/helpers.cmake b/cmake/macos/helpers.cmake new file mode 100644 index 000000000..68b9329c4 --- /dev/null +++ b/cmake/macos/helpers.cmake @@ -0,0 +1,371 @@ +# OBS CMake macOS helper functions module + +# cmake-format: off +# cmake-lint: disable=C0307 +# cmake-lint: disable=R0912 +# cmake-lint: disable=R0915 +# cmake-lint: disable=E1126 +# cmake-format: on + +include(helpers_common) + +# set_target_properties_obs: Set target properties for use in obs-studio +function(set_target_properties_obs target) + set(options "") + set(oneValueArgs "") + set(multiValueArgs PROPERTIES) + cmake_parse_arguments(PARSE_ARGV 0 _STPO "${options}" "${oneValueArgs}" "${multiValueArgs}") + + message(DEBUG "Setting additional properties for target ${target}...") + + while(_STPO_PROPERTIES) + list(POP_FRONT _STPO_PROPERTIES key value) + set_property(TARGET ${target} PROPERTY ${key} "${value}") + endwhile() + get_target_property(target_type ${target} TYPE) + + # Target is a GUI or CLI application + if(target_type STREQUAL EXECUTABLE) + if(target STREQUAL obs-studio) + _check_info_plist() + set_target_properties( + ${target} + PROPERTIES OUTPUT_NAME OBS + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Info.plist.in" + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.obsproject.obs-studio + XCODE_ATTRIBUTE_PRODUCT_NAME OBS + XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon + XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY YES + XCODE_EMBED_PLUGINS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_PLUGINS_CODE_SIGN_ON_COPY YES + XCODE_ATTRIBUTE_COPY_PHASE_STRIP NO + XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) + + get_property(obs_dependencies GLOBAL PROPERTY _OBS_DEPENDENCIES) + add_dependencies(${target} ${obs_dependencies}) + + if(NOT XCODE) + return() + endif() + + get_property(obs_frameworks GLOBAL PROPERTY _OBS_FRAMEWORKS) + set_property( + TARGET ${target} + APPEND + PROPERTY XCODE_EMBED_FRAMEWORKS ${obs_frameworks}) + + if(SPARKLE_APPCAST_URL AND SPARKLE_PUBLIC_KEY) + set_property( + TARGET ${target} + APPEND + PROPERTY XCODE_EMBED_FRAMEWORKS ${SPARKLE}) + endif() + + get_property(obs_executables GLOBAL PROPERTY _OBS_EXECUTABLES) + foreach(executable IN LISTS obs_executables) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$" + "$/MacOS/" + COMMENT "Copy ${executable} to application bundle") + endforeach() + + _check_entitlements() + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND + /usr/bin/sed -i '' 's/font-size: 10pt\;/font-size: 12pt\;/' + "$/Resources/themes/Acri.qss" + "$/Resources/themes/Grey.qss" + "$/Resources/themes/Light.qss" + "$/Resources/themes/Rachni.qss" + "$/Resources/themes/Yami.qss" + COMMENT "Patch Qt stylesheets to use larger default font size on macOS") + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND /bin/ln -fs obs-frontend-api.dylib libobs-frontend-api.1.dylib + WORKING_DIRECTORY "$/Frameworks" + COMMENT "Create symlink for legacy obs-frontend-api") + + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/qt.conf") + target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/qt.conf") + endif() + + target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Assets.xcassets") + target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/../AUTHORS") + + if(TARGET obs-dal-plugin) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory "$" + "$/Resources/$" + COMMENT "Add OBS DAL plugin to application bundle") + endif() + + if(TARGET obspython) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$/obspython.py" + "$/Resources" + COMMENT "Add OBS::python import module") + endif() + + _bundle_dependencies(${target}) + + install(TARGETS ${target} BUNDLE DESTINATION "." COMPONENT Application) + else() + set_property(GLOBAL APPEND PROPERTY _OBS_EXECUTABLES ${target}) + set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target}) + endif() + + _add_entitlements() + elseif(target_type STREQUAL SHARED_LIBRARY) + set_target_properties( + ${target} + PROPERTIES NO_SONAME TRUE + MACHO_COMPATIBILITY_VERSION 1.0 + MACHO_CURRENT_VERSION ${OBS_VERSION_MAJOR} + SOVERSION 0 + VERSION 0 + XCODE_ATTRIBUTE_DYLIB_COMPATIBILITY_VERSION 1.0 + XCODE_ATTRIBUTE_DYLIB_CURRENT_VERSION ${OBS_VERSION_MAJOR} + XCODE_ATTRIBUTE_PRODUCT_NAME ${target} + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}) + + get_target_property(is_framework ${target} FRAMEWORK) + if(is_framework) + _check_info_plist() + set_target_properties( + ${target} + PROPERTIES FRAMEWORK_VERSION A + MACOSX_FRAMEWORK_IDENTIFIER com.obsproject.${target} + MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Info.plist.in") + endif() + + _add_entitlements() + + set_property(GLOBAL APPEND PROPERTY _OBS_FRAMEWORKS ${target}) + set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target}) + elseif(target_type STREQUAL MODULE_LIBRARY) + if(target STREQUAL obspython) + set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_PRODUCT_NAME ${target} + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}) + elseif(target STREQUAL obslua) + set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_PRODUCT_NAME ${target} + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}) + elseif(target STREQUAL obs-dal-plugin) + set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE) + set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target}) + return() + else() + _check_info_plist() + set_target_properties( + ${target} + PROPERTIES BUNDLE TRUE + BUNDLE_EXTENSION plugin + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Info.plist.in" + XCODE_ATTRIBUTE_PRODUCT_NAME ${target} + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}) + + if(target STREQUAL obs-browser) + # Good-enough for now as there are no other variants - in _theory_ we should only add the appropriate variant, + # but that is only known at project generation and not build system configuration. + get_target_property(imported_location CEF::Library IMPORTED_LOCATION_RELEASE) + if(imported_location) + list(APPEND cef_items "${imported_location}") + endif() + + foreach(helper IN ITEMS _gpu _plugin _renderer "") + if(TARGET OBS::browser-helper${helper}) + set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES OBS::browser-helper${helper}) + list(APPEND cef_items OBS::browser-helper${helper}) + endif() + endforeach() + + set_property(GLOBAL APPEND PROPERTY _OBS_FRAMEWORKS ${cef_items}) + endif() + endif() + + set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target}) + set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target}) + endif() + + target_install_resources(${target}) + + get_target_property(target_sources ${target} SOURCES) + set(target_ui_files ${target_sources}) + list(FILTER target_ui_files INCLUDE REGEX ".+\\.(ui|qrc)") + source_group( + TREE "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX "UI Files" + FILES ${target_ui_files}) + + if(${target} STREQUAL libobs) + set(target_source_files ${target_sources}) + set(target_header_files ${target_sources}) + list(FILTER target_source_files INCLUDE REGEX ".+\\.(m|c[cp]?p?|swift)") + list(FILTER target_header_files INCLUDE REGEX ".+\\.h(pp)?") + + source_group( + TREE "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX "Source Files" + FILES ${target_source_files}) + source_group( + TREE "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX "Header Files" + FILES ${target_header_files}) + endif() +endfunction() + +# _check_info_plist: Macro to check if project ships with Info.plist template +macro(_check_info_plist) + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Info.plist.in") + message(FATAL_ERROR "Target ${target} is missing an Info.plist template in its cmake directory.") + endif() +endmacro() + +# _check_entitlements: Macro to check if project ships with entitlements plist +macro(_check_entitlements) + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist") + message(FATAL_ERROR "Target ${target} is missing an entitlements.plist in its cmake directory.") + endif() +endmacro() + +# _add_entitlements: Macro to add entitlements shipped with project +macro(_add_entitlements) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist") + set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist") + endif() +endmacro() + +# target_export: Helper function to export target as CMake package +function(target_export target) + # Exclude CMake package from 'ALL' target + set(exclude_variant EXCLUDE_FROM_ALL) + _target_export(${target}) +endfunction() + +# target_install_resources: Helper function to add resources into bundle +function(target_install_resources target) + message(DEBUG "Installing resources for target ${target}...") + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data") + file(GLOB_RECURSE data_files "${CMAKE_CURRENT_SOURCE_DIR}/data/*") + foreach(data_file IN LISTS data_files) + cmake_path(RELATIVE_PATH data_file BASE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/" OUTPUT_VARIABLE + relative_path) + cmake_path(GET relative_path PARENT_PATH relative_path) + target_sources(${target} PRIVATE "${data_file}") + set_property(SOURCE "${data_file}" PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${relative_path}") + source_group("Resources/${relative_path}" FILES "${data_file}") + endforeach() + endif() +endfunction() + +# target_add_resource: Helper function to add a specific resource to a bundle +function(target_add_resource target resource) + message(DEBUG "Add resource ${resource} to target ${target} at destination ${destination}...") + target_sources(${target} PRIVATE "${resource}") + set_property(SOURCE "${resource}" PROPERTY MACOSX_PACKAGE_LOCATION Resources) + source_group("Resources" FILES "${resource}") +endfunction() + +# _bundle_dependencies: Resolve 3rd party dependencies and add them to macOS app bundle +function(_bundle_dependencies target) + message(DEBUG "Discover dependencies of target ${target}...") + set(found_dependencies) + find_dependencies(TARGET ${target} FOUND_VAR found_dependencies) + + get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) + list(LENGTH obs_module_list num_modules) + if(num_modules GREATER 0) + add_dependencies(${target} ${obs_module_list}) + set_property( + TARGET ${target} + APPEND + PROPERTY XCODE_EMBED_PLUGINS ${obs_module_list}) + foreach(module IN LISTS obs_module_list) + find_dependencies(TARGET ${module} FOUND_VAR found_dependencies) + endforeach() + endif() + + list(REMOVE_DUPLICATES found_dependencies) + + set(library_paths) + set(plugins_list) + file(GLOB sdk_library_paths /Applications/Xcode*.app) + set(system_library_path "/usr/lib/") + + foreach(library IN LISTS found_dependencies) + get_target_property(library_type ${library} TYPE) + get_target_property(is_framework ${library} FRAMEWORK) + get_target_property(is_imported ${library} IMPORTED) + + if(is_imported) + get_target_property(imported_location ${library} LOCATION) + if(NOT imported_location) + continue() + endif() + + set(is_xcode_framework FALSE) + set(is_system_framework FALSE) + + foreach(sdk_library_path IN LISTS sdk_library_paths) + if(is_xcode_framework) + break() + endif() + cmake_path(IS_PREFIX sdk_library_path "${imported_location}" is_xcode_framework) + endforeach() + cmake_path(IS_PREFIX system_library_path "${imported_location}" is_system_framework) + + if(is_system_framework OR is_xcode_framework) + continue() + elseif(is_framework) + file(REAL_PATH "../../.." library_location BASE_DIRECTORY "${imported_location}") + elseif(NOT library_type STREQUAL "STATIC_LIBRARY") + if(NOT imported_location MATCHES ".+\\.a") + set(library_location "${imported_location}") + else() + continue() + endif() + else() + continue() + endif() + + if(library MATCHES "Qt[56]?::.+") + find_qt_plugins(COMPONENT ${library} TARGET ${target} FOUND_VAR plugins_list) + endif() + list(APPEND library_paths ${library_location}) + elseif(NOT imported AND library_type STREQUAL "SHARED_LIBRARY") + message(TRACE "${library} is a project target") + list(APPEND library_paths ${library}) + endif() + endforeach() + + list(REMOVE_DUPLICATES plugins_list) + foreach(plugin IN LISTS plugins_list) + cmake_path(GET plugin PARENT_PATH plugin_path) + set(plugin_base_dir "${plugin_path}/../") + cmake_path(SET plugin_stem_dir NORMALIZE "${plugin_base_dir}") + cmake_path(RELATIVE_PATH plugin_path BASE_DIRECTORY "${plugin_stem_dir}" OUTPUT_VARIABLE plugin_file_name) + target_sources(${target} PRIVATE "${plugin}") + set_source_files_properties("${plugin}" PROPERTIES MACOSX_PACKAGE_LOCATION "plugins/${plugin_file_name}" + XCODE_FILE_ATTRIBUTES "CodeSignOnCopy") + source_group("Qt plugins" FILES "${plugin}") + endforeach() + + list(REMOVE_DUPLICATES library_paths) + set_property( + TARGET ${target} + APPEND + PROPERTY XCODE_EMBED_FRAMEWORKS ${library_paths}) +endfunction() diff --git a/cmake/macos/resources/AppIcon.icns b/cmake/macos/resources/AppIcon.icns new file mode 100644 index 000000000..2f742868f Binary files /dev/null and b/cmake/macos/resources/AppIcon.icns differ diff --git a/cmake/macos/resources/background.tiff b/cmake/macos/resources/background.tiff new file mode 100644 index 000000000..454874005 Binary files /dev/null and b/cmake/macos/resources/background.tiff differ diff --git a/cmake/macos/resources/ccache-launcher-c.in b/cmake/macos/resources/ccache-launcher-c.in new file mode 100644 index 000000000..3e89d480d --- /dev/null +++ b/cmake/macos/resources/ccache-launcher-c.in @@ -0,0 +1,13 @@ +#!/bin/sh + +if [[ "$1" == "${CMAKE_C_COMPILER}" ]] ; then + shift +fi + +export CCACHE_CPP2=true +export CCACHE_DEPEND=true +export CCACHE_DIRECT=true +export CCACHE_FILECLONE=true +export CCACHE_INODECACHE=true +export CCACHE_SLOPPINESS="modules,include_file_mtime,include_file_ctime,pch_defines,clang_index_store,system_headers" +exec "${CMAKE_C_COMPILER_LAUNCHER}" "${CMAKE_C_COMPILER}" "$@" diff --git a/cmake/macos/resources/ccache-launcher-cxx.in b/cmake/macos/resources/ccache-launcher-cxx.in new file mode 100644 index 000000000..bd2b526b3 --- /dev/null +++ b/cmake/macos/resources/ccache-launcher-cxx.in @@ -0,0 +1,13 @@ +#!/bin/sh + +if [[ "$1" == "${CMAKE_CXX_COMPILER}" ]] ; then + shift +fi + +export CCACHE_CPP2=true +export CCACHE_DEPEND=true +export CCACHE_DIRECT=true +export CCACHE_FILECLONE=true +export CCACHE_INODECACHE=true +export CCACHE_SLOPPINESS="modules,include_file_mtime,include_file_ctime,pch_defines,clang_index_store,system_headers" +exec "${CMAKE_CXX_COMPILER_LAUNCHER}" "${CMAKE_CXX_COMPILER}" "$@" diff --git a/cmake/macos/resources/package.applescript.in b/cmake/macos/resources/package.applescript.in new file mode 100644 index 000000000..b11afb89f --- /dev/null +++ b/cmake/macos/resources/package.applescript.in @@ -0,0 +1,66 @@ +on run (volumeName) + tell application "Finder" + tell disk (volumeName as string) + open + + set theXOrigin to @_dmg_window_x@ + set theYOrigin to @_dmg_window_y@ + set theWidth to @_dmg_window_width@ + set theHeight to @_dmg_window_height@ + + set theBottomRightX to (theXOrigin + theWidth) + set theBottomRightY to (theYOrigin + theHeight) + set dsStore to "\"" & "/Volumes/" & volumeName & "/" & ".DS_STORE\"" + + tell container window + set current view to icon view + set toolbar visible to false + set statusbar visible to false + set the bounds to {theXOrigin, theYOrigin, theBottomRightX, theBottomRightY} + set statusbar visible to false + set position of every item to {theBottomRightX + 100, 100} + end tell + + set opts to the icon view options of container window + tell opts + set icon size to @_dmg_icon_size@ + set text size to @_dmg_text_size@ + set arrangement to not arranged + end tell + set background picture of opts to file ".background:@_cpack_dmg_background_filename@" + set position of item "@CPACK_PACKAGE_NAME@.app" to {@_dmg_obs_x@, @_dmg_obs_y@} + set position of item "Applications" to {@_dmg_app_link_x@, @_dmg_app_link_y@} + close + open + -- Force saving of the size + delay 1 + + tell container window + set statusbar visible to false + set the bounds to {theXOrigin, theYOrigin, theBottomRightX - 10, theBottomRightY - 10} + end tell + end tell + + delay 1 + + tell disk (volumeName as string) + tell container window + set statusbar visible to false + set the bounds to {theXOrigin, theYOrigin, theBottomRightX, theBottomRightY} + end tell + end tell + + --give the finder some time to write the .DS_Store file + delay 3 + + set waitTime to 0 + set ejectMe to false + repeat while ejectMe is false + delay 1 + set waitTime to waitTime + 1 + + if (do shell script "[ -f " & dsStore & " ]; echo $?") = "0" then set ejectMe to true + end repeat + log "waited " & waitTime & " seconds for .DS_STORE to be created." + end tell +end run diff --git a/cmake/macos/simd.cmake b/cmake/macos/simd.cmake new file mode 100644 index 000000000..8c224d270 --- /dev/null +++ b/cmake/macos/simd.cmake @@ -0,0 +1,7 @@ +# OBS CMake macOS SIMD module + +# Enable openmp-simd when compiling for arm64 +if(CMAKE_OSX_ARCHITECTURES MATCHES ".*[aA][rR][mM]64e?.*" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(ARCH_SIMD_FLAGS -fopenmp-simd) + set(ARCH_SIMD_DEFINES SIMDE_ENABLE_OPENMP) +endif() diff --git a/cmake/macos/xcode.cmake b/cmake/macos/xcode.cmake new file mode 100644 index 000000000..69039aec6 --- /dev/null +++ b/cmake/macos/xcode.cmake @@ -0,0 +1,134 @@ +# OBS CMake macOS Xcode module + +# Use a compiler wrapper to enable ccache in Xcode projects +if(ENABLE_CCACHE AND CCACHE_PROGRAM) + configure_file("${CMAKE_SOURCE_DIR}/cmake/macos/resources/ccache-launcher-c.in" ccache-launcher-c) + configure_file("${CMAKE_SOURCE_DIR}/cmake/macos/resources/ccache-launcher-cxx.in" ccache-launcher-cxx) + + execute_process(COMMAND chmod a+rx "${CMAKE_BINARY_DIR}/ccache-launcher-c" "${CMAKE_BINARY_DIR}/ccache-launcher-cxx") + set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/ccache-launcher-c") + set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/ccache-launcher-cxx") + set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") + set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}") +endif() + +# Set project variables +set(CMAKE_XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION ${OBS_BUILD_NUMBER}) +set(CMAKE_XCODE_ATTRIBUTE_DYLIB_COMPATIBILITY_VERSION 1.0.0) +set(CMAKE_XCODE_ATTRIBUTE_MARKETING_VERSION ${OBS_VERSION_CANONICAL}) + +# Set deployment target +set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET ${CMAKE_OSX_DEPLOYMENT_TARGET}) + +if(NOT OBS_CODESIGN_TEAM) + # Switch to manual codesigning if no codesigning team is provided + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${OBS_CODESIGN_IDENTITY}") +else() + if(DEFINED OBS_CODESIGN_IDENTITY AND NOT OBS_CODESIGN_IDENTITY STREQUAL "-") + # Switch to manual codesigning if a non-adhoc codesigning identity is provided + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${OBS_CODESIGN_IDENTITY}") + else() + # Switch to automatic codesigning via valid team ID + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic) + endif() + set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${OBS_CODESIGN_TEAM}") +endif() + +# Only create a single Xcode project file +set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE) +# Add all libraries to project link phase (lets Xcode handle linking) +set(CMAKE_XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION) + +# Enable codesigning with secure timestamp when not in Debug configuration (required for Notarization) +set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=Release] "--timestamp") +set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=RelWithDebInfo] "--timestamp") +set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=MinSizeRel] "--timestamp") + +# Enable codesigning with hardened runtime option when not in Debug configuration (required for Notarization) +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=Release] YES) +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=RelWithDebInfo] YES) +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=MinSizeRel] YES) + +# Disable injection of Xcode's base entitlements used for debugging when not in Debug configuration (required for +# Notarization) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=Release] NO) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=RelWithDebInfo] NO) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=MinSizeRel] NO) + +# Use Swift version 5.0 by default +set(CMAKE_XCODE_ATTRIBUTE_SWIFT_VERSION 5.0) + +# Use DWARF with separate dSYM files when in Release or MinSizeRel configuration +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Debug] dwarf) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=RelWithDebInfo] dwarf) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Release] dwarf-with-dsym) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=MinSizeRel] dwarf-with-dsym) + +# Strip generated and installed products only in Release or MinSizeRel configuration +set(CMAKE_XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT[variant=Release] YES) +set(CMAKE_XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT[variant=MinSizeRel] YES) + +# Make all symbols hidden by default +set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN YES) + +# Strip unused code in Release or MinSizeRel configuration only +set(CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Release] YES) +set(CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=MinSizeRel] YES) + +# Display mangled names in Debug configuration +set(CMAKE_XCODE_ATTRIBUTE_LINKER_DISPLAYS_MANGLED_NAMES[variant=Debug] YES) + +# Disable using ARC in ObjC by default (OBS does not support this - yet) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO) +# Disable strict aliasing +set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO) +# cmake-format: off +# Re-enable once the bad goto statements are fixed +# set(CMAKE_XCODE_ATTRIBUTE_GCC_C_LANGUAGE_STANDARD c99) +# cmake-format: on +# Set C++ language default to c++17 +set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD c++17) +# Enable support for module imports in ObjC +set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES NO) +# Enable automatic linking of imported modules in ObjC +set(CMAKE_XCODE_ATTRIBUTE_CLANG_MODULES_AUTOLINK NO) +# Enable strict msg_send rules for ObjC +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_STRICT_OBJC_MSGSEND YES) + +# Set default warnings for ObjC and C++ +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING YES_ERROR) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION NO) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_RANGE_LOOP_ANALYSIS YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_EMPTY_BODY YES) + +# Set default warnings for C and C++ +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_NEWLINE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_RETURN_TYPE YES_ERROR) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_CHECK_SWITCH_STATEMENTS YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_FOUR_CHARACTER_CONSTANTS YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SIGN_COMPARE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SHADOW NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_FUNCTION NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_TYPECHECK_CALLS_TO_PRINTF YES) + +# Add additional warning compiler flags +set(CMAKE_XCODE_ATTRIBUTE_WARNING_CFLAGS "-Wvla -Wformat-security -Wno-error=shorten-64-to-32") + +set(CMAKE_XCODE_ATTRIBUTE_GCC_TREAT_WARNINGS_AS_ERRORS YES) + +# Disable color diagnostics +set(CMAKE_COLOR_DIAGNOSTICS FALSE) + +# Disable usage of RPATH in build or install configurations +set(CMAKE_SKIP_RPATH TRUE) +# Have Xcode set default RPATH entries +set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks")