diff --git a/.github/scripts/.Aptfile b/.github/scripts/.Aptfile index 09efc11..a017204 100644 --- a/.github/scripts/.Aptfile +++ b/.github/scripts/.Aptfile @@ -4,3 +4,10 @@ package 'git' package 'jq' package 'ninja-build', bin: 'ninja' package 'pkg-config' + +# FFmpeg dev libraries: the MoQ source decodes video with libav*, found via +# pkg-config on Linux (macOS/Windows use the obs-deps bundle instead). +package 'libavcodec-dev' +package 'libavutil-dev' +package 'libswscale-dev' +package 'libswresample-dev' diff --git a/.github/scripts/build-macos b/.github/scripts/build-macos index fece23b..4b6bb9e 100755 --- a/.github/scripts/build-macos +++ b/.github/scripts/build-macos @@ -126,10 +126,12 @@ build() { } } + # arm64-only: the plugin links a published libmoq release, which ships + # per-architecture (no universal archive), so a universal plugin can't link + # the x86_64 slice. Build arm64 only to match the fetched libmoq. local -a build_args=( ONLY_ACTIVE_ARCH=NO -arch arm64 - -arch x86_64 -project ${product_name}.xcodeproj -target ${product_name} -destination "generic/platform=macOS,name=Any Mac" diff --git a/CMakeLists.txt b/CMakeLists.txt index 36589e9..1c1e61e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,12 +15,21 @@ add_library(obs-moq MODULE) if(${BUILD_PLUGIN}) find_package(libobs REQUIRED) - # FFmpeg dependency - include(FindPkgConfig) - pkg_check_modules(FFMPEG REQUIRED libavcodec libavutil libswscale libswresample) - target_include_directories(obs-moq PRIVATE ${FFMPEG_INCLUDE_DIRS}) - target_link_directories(obs-moq PRIVATE ${FFMPEG_LIBRARY_DIRS}) - target_link_libraries(obs-moq PRIVATE ${FFMPEG_LIBRARIES}) + # FFmpeg dependency (used by the MoQ source to decode subscribed video). On + # macOS and Windows, link the ffmpeg the obs-deps bundle ships -- the same one + # OBS itself uses at runtime -- via the vendored FindFFmpeg finder (obs-deps + # ship ffmpeg with no pkg-config .pc files, so it searches the prefix). On + # Linux there's no obs-deps; pkg-config finds the system ffmpeg. + if(WIN32 OR APPLE) + find_package(FFmpeg REQUIRED avcodec avutil swscale swresample) + target_link_libraries(obs-moq PRIVATE FFmpeg::avcodec FFmpeg::avutil FFmpeg::swscale FFmpeg::swresample) + else() + include(FindPkgConfig) + pkg_check_modules(FFMPEG REQUIRED libavcodec libavutil libswscale libswresample) + target_include_directories(obs-moq PRIVATE ${FFMPEG_INCLUDE_DIRS}) + target_link_directories(obs-moq PRIVATE ${FFMPEG_LIBRARY_DIRS}) + target_link_libraries(obs-moq PRIVATE ${FFMPEG_LIBRARIES}) + endif() else() find_package(FFmpeg REQUIRED avcodec avutil swscale swresample) target_link_libraries(obs-moq PRIVATE FFmpeg::avcodec FFmpeg::avutil FFmpeg::swscale FFmpeg::swresample) diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..96aee56 --- /dev/null +++ b/build.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Build and package the obs-moq plugin for release. +# Usage: ./build.sh [--target TARGET] [--version VERSION] [--output DIR] +# +# The required toolchain must already be on PATH; this script only drives +# CMake. Per platform: +# Linux - run inside `nix develop` (provides cmake/ninja/obs-studio/qt6/ffmpeg) +# macOS - full Xcode, run OUTSIDE nix (libobs/Qt6/ffmpeg all come from the +# obs-deps bundle downloaded by buildspec.json at configure time) +# Windows - Visual Studio 2022; run from Git Bash with cmake on PATH +# (libobs/Qt6 downloaded by buildspec.json) +# +# Produces $OUTPUT_DIR/obs-moq-$VERSION-$TARGET.{tar.gz,zip}. The archive is +# unsigned; macOS Gatekeeper / Windows SmartScreen will warn on first load. + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +TARGET="" +VERSION="" +OUTPUT_DIR="dist" +MOQ_RELEASE="" + +while [[ $# -gt 0 ]]; do + case $1 in + --target) + TARGET="$2" + shift 2 + ;; + --version) + VERSION="$2" + shift 2 + ;; + --output) + OUTPUT_DIR="$2" + shift 2 + ;; + --libmoq-release) + # Link a published libmoq release of this version instead of + # building rs/libmoq from source. CMake fetches the matching + # moq-- archive from the GitHub release and the + # plugin is versioned to match. Used by CI on a libmoq-v* tag. + MOQ_RELEASE="$2" + shift 2 + ;; + -h | --help) + echo "Usage: $0 [--target TARGET] [--version VERSION] [--output DIR] [--libmoq-release VERSION]" + exit 0 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + +# In libmoq-release mode the plugin version tracks the libmoq version. +if [[ -n "$MOQ_RELEASE" ]]; then + VERSION="$MOQ_RELEASE" +fi + +if [[ -z "$TARGET" ]]; then + TARGET=$(cc -dumpmachine 2>/dev/null || echo unknown) + echo "Detected target: $TARGET" +fi + +# Default the version from buildspec.json's top-level "version" (the nested +# dependency entries also have "version" keys, hence the leading-indent anchor). +if [[ -z "$VERSION" ]]; then + VERSION=$(grep -E '^[[:space:]]{4}"version"' "$SCRIPT_DIR/buildspec.json" | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/') + echo "Detected version: $VERSION" +fi + +# Map the target triple to a CMake preset and build tree. +case "$TARGET" in +*-linux-*) + PRESET="ubuntu-x86_64" + BUILD_DIR="$SCRIPT_DIR/build_x86_64" + KIND="unix" + ;; +*-apple-darwin) + PRESET="macos" + BUILD_DIR="$SCRIPT_DIR/build_macos" + KIND="macos" + ;; +*-windows-*) + PRESET="windows-x64" + BUILD_DIR="$SCRIPT_DIR/build_x64" + KIND="windows" + ;; +*) + echo "Unsupported target: $TARGET" >&2 + exit 1 + ;; +esac + +# Resolve the output dir to an absolute path before we cd into the plugin +# directory (cmake --preset reads CMakePresets.json from the current dir). +mkdir -p "$OUTPUT_DIR" +OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)" +cd "$SCRIPT_DIR" + +echo "Building obs-moq $VERSION for $TARGET (preset: $PRESET)..." +CONFIGURE_ARGS=() +# Stamp the plugin's compiled-in version (project version, macOS Info.plist, +# Windows resource) to match what we're building, not buildspec.json's 0.0.1. +if [[ -n "$VERSION" ]]; then + CONFIGURE_ARGS+=("-DPLUGIN_VERSION_OVERRIDE=$VERSION") +fi +if [[ -n "$MOQ_RELEASE" ]]; then + # Empty MOQ_LOCAL forces CMake's release-download branch; MOQ_VERSION and + # MOQ_TARGET steer it at this target's archive (the presets hard-code an + # x86_64/stale default). MOQ_ARCHIVE is correct per preset already. + echo "Linking libmoq release v$MOQ_RELEASE ($TARGET)" + CONFIGURE_ARGS+=(-DMOQ_LOCAL= "-DMOQ_VERSION=$MOQ_RELEASE" "-DMOQ_TARGET=$TARGET") +fi +cmake --preset "$PRESET" ${CONFIGURE_ARGS[@]+"${CONFIGURE_ARGS[@]}"} +cmake --build --preset "$PRESET" + +NAME="obs-moq-${VERSION}-${TARGET}" +STAGE="$OUTPUT_DIR/$NAME" +rm -rf "$STAGE" +mkdir -p "$OUTPUT_DIR" + +if [[ "$KIND" == "macos" ]]; then + # Self-contained loadable bundle; drop into the OBS plugins directory. + PLUGIN=$(find "$BUILD_DIR" -name 'obs-moq.plugin' -maxdepth 4 -print -quit) + [[ -n "$PLUGIN" ]] || { + echo "obs-moq.plugin not found under $BUILD_DIR" >&2 + exit 1 + } + mkdir -p "$STAGE" + cp -R "$PLUGIN" "$STAGE/" +else + # OBS portable-plugin layout: extract into your OBS plugins directory. + LIB=$(find "$BUILD_DIR" \( -name 'obs-moq.so' -o -name 'obs-moq.dll' \) -print -quit) + [[ -n "$LIB" ]] || { + echo "obs-moq.{so,dll} not found under $BUILD_DIR" >&2 + exit 1 + } + mkdir -p "$STAGE/obs-moq/bin/64bit" + cp "$LIB" "$STAGE/obs-moq/bin/64bit/" + cp -R "$SCRIPT_DIR/data" "$STAGE/obs-moq/" +fi + +cp "$SCRIPT_DIR/LICENSE" "$STAGE/" +cp "$SCRIPT_DIR/README.md" "$STAGE/" + +# Archive with CMake's tar so we don't depend on zip/gtar being present +# (notably on the Windows runner). tar.gz on unix, zip on macOS/Windows. +( + cd "$OUTPUT_DIR" + if [[ "$KIND" == "unix" ]]; then + ARCHIVE="$NAME.tar.gz" + cmake -E tar czf "$ARCHIVE" "$NAME" + else + ARCHIVE="$NAME.zip" + cmake -E tar cf "$ARCHIVE" --format=zip "$NAME" + fi + rm -rf "$NAME" + echo "Created: $OUTPUT_DIR/$ARCHIVE" +) diff --git a/cmake/common/FindFFmpeg.cmake b/cmake/common/FindFFmpeg.cmake new file mode 100644 index 0000000..d5200ce --- /dev/null +++ b/cmake/common/FindFFmpeg.cmake @@ -0,0 +1,366 @@ +#[=======================================================================[.rst +FindFFmpeg +---------- + +FindModule for FFmpeg and associated libraries + +.. versionchanged:: 3.0 + Updated FindModule to CMake standards + +Components +^^^^^^^^^^ + +.. versionadded:: 1.0 + +This module contains provides several components: + +``avcodec`` +``avdevice`` +``avfilter`` +``avformat`` +``avutil`` +``postproc`` +``swscale`` +``swresample`` + +Import targets exist for each component. + +Imported Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 2.0 + +This module defines the :prop_tgt:`IMPORTED` targets: + +``FFmpeg::avcodec`` + AVcodec component + +``FFmpeg::avdevice`` + AVdevice component + +``FFmpeg::avfilter`` + AVfilter component + +``FFmpeg::avformat`` + AVformat component + +``FFmpeg::avutil`` + AVutil component + +``FFmpeg::postproc`` + postproc component + +``FFmpeg::swscale`` + SWscale component + +``FFmpeg::swresample`` + SWresample component + +Result Variables +^^^^^^^^^^^^^^^^ + +This module sets the following variables: + +``FFmpeg_FOUND`` + True, if all required components and the core library were found. +``FFmpeg_VERSION`` + Detected version of found FFmpeg libraries. +``FFmpeg_INCLUDE_DIRS`` + Include directories needed for FFmpeg. +``FFmpeg_LIBRARIES`` + Libraries needed to link to FFmpeg. +``FFmpeg_DEFINITIONS`` + Compiler flags required for FFmpeg. + +``FFmpeg__VERSION`` + Detected version of found FFmpeg component library. +``FFmpeg__INCLUDE_DIRS`` + Include directories needed for FFmpeg component. +``FFmpeg__LIBRARIES`` + Libraries needed to link to FFmpeg component. +``FFmpeg__DEFINITIONS`` + Compiler flags required for FFmpeg component. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``FFmpeg__LIBRARY`` + Path to the library component of FFmpeg. +``FFmpeg__INCLUDE_DIR`` + Directory containing ``.h``. + +#]=======================================================================] + +include(FindPackageHandleStandardArgs) + +set( + _DEFAULT_COMPONENTS + avcodec + avdevice + avformat + avfilter + avresample + avutil + postproc + swscale + swresample +) + +set(component_avcodec libavcodec avcodec avcodec.h) +set(component_avdevice libavdevice avdevice avdevice.h) +set(component_avformat libavformat avformat avformat.h) +set(component_avfilter libavfilter avfilter avfilter.h) +set(component_avresample libavresample avresample avresample.h) +set(component_avutil libavutil avutil avutil.h) +set(component_postproc libpostproc postproc postprocess.h) +set(component_swscale libswscale swscale swscale.h) +set(component_swresample libswresample swresample swresample.h) + +if(NOT FFmpeg_FIND_COMPONENTS) + set(FFmpeg_FIND_COMPONENTS ${_DEFAULT_COMPONENTS}) +endif() + +# FFmpeg_find_component: Find and set up requested FFmpeg component +macro(FFmpeg_find_component component) + list(GET component_${component} 0 component_libname) + list(GET component_${component} 1 component_name) + list(GET component_${component} 2 component_header) + + if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + pkg_search_module(PC_FFmpeg_${component} QUIET ${component_libname}) + endif() + endif() + + find_path( + FFmpeg_${component}_INCLUDE_DIR + NAMES ${component_libname}/${component_header} ${component_libname}/version.h + HINTS ${PC_FFmpeg_${component}_INCLUDE_DIRS} + PATHS /usr/include /usr/local/include + DOC "FFmpeg component ${component_name} include directory" + ) + + ffmpeg_check_version() + + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + find_library( + FFmpeg_${component}_IMPLIB + NAMES ${component_libname} ${component_name} + DOC "FFmpeg component ${component_name} import library location" + ) + + ffmpeg_find_dll() + else() + find_library( + FFmpeg_${component}_LIBRARY + NAMES ${component_libname} ${component_name} + HINTS ${PC_FFmpeg_${component}_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib + DOC "FFmpeg component ${component_name} location" + ) + endif() + + if(FFmpeg_${component}_LIBRARY AND FFmpeg_${component}_INCLUDE_DIR) + set(FFmpeg_${component}_FOUND TRUE) + set(FFmpeg_${component}_LIBRARIES ${${_library_var}}) + set(FFmpeg_${component}_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIR}) + set(FFmpeg_${component}_DEFINITIONS ${PC_FFmpeg_${component}_CFLAGS_OTHER}) + mark_as_advanced(FFmpeg_${component}_LIBRARY FFmpeg_${component}_INCLUDE_DIR FFmpeg_${component}_IMPLIB) + endif() +endmacro() + +# FFmpeg_find_dll: Macro to find DLL for corresponding import library +macro(FFmpeg_find_dll) + cmake_path(GET FFmpeg_${component}_IMPLIB PARENT_PATH _implib_path) + cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin") + + string(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" _dll_version "${FFmpeg_${component}_VERSION}") + + find_program( + FFmpeg_${component}_LIBRARY + NAMES ${component_name}-${_dll_version}.dll + HINTS ${_implib_path} ${_bin_path} + DOC "FFmpeg component ${component_name} DLL location" + ) + + if(NOT FFmpeg_${component}_LIBRARY) + set(FFmpeg_${component}_LIBRARY "${FFmpeg_${component}_IMPLIB}") + endif() + + unset(_implib_path) + unset(_bin_path) + unset(_dll_version) +endmacro() + +# FFmpeg_check_version: Macro to help extract version number from FFmpeg headers +macro(FFmpeg_check_version) + if(PC_FFmpeg_${component}_VERSION) + set(FFmpeg_${component}_VERSION ${PC_FFmpeg_${component}_VERSION}) + elseif(EXISTS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h") + if(EXISTS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version_major.h") + file( + STRINGS + "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version_major.h" + _version_string + REGEX "^.*VERSION_MAJOR[ \t]+[0-9]+[ \t]*$" + ) + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}") + + file( + STRINGS + "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h" + _version_string + REGEX "^.*VERSION_(MINOR|MICRO)[ \t]+[0-9]+[ \t]*$" + ) + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}") + string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" _version_patch "${_version_string}") + else() + file( + STRINGS + "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h" + _version_string + REGEX "^.*VERSION_(MAJOR|MINOR|MICRO)[ \t]+[0-9]+[ \t]*$" + ) + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}") + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}") + string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" _version_patch "${_version_string}") + endif() + + set(FFmpeg_${component}_VERSION "${_version_major}.${_version_minor}.${_version_patch}") + unset(_version_major) + unset(_version_minor) + unset(_version_patch) + else() + if(NOT FFmpeg_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find ${component_name} version.") + endif() + set(FFmpeg_${component}_VERSION 0.0.0) + endif() +endmacro() + +# FFmpeg_set_soname: Set SONAME property on imported library targets +macro(FFmpeg_set_soname) + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + execute_process( + COMMAND sh -c "otool -D '${FFmpeg_${component}_LIBRARY}' | grep -v '${FFmpeg_${component}_LIBRARY}'" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0 AND _output MATCHES "^@rpath/") + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_SONAME "${_output}") + endif() + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + execute_process( + COMMAND sh -c "objdump -p '${FFmpeg_${component}_LIBRARY}' | grep SONAME" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0) + string(REGEX REPLACE "[ \t]+SONAME[ \t]+([^ \t]+)" "\\1" _soname "${_output}") + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_SONAME "${_soname}") + unset(_soname) + endif() + endif() + unset(_output) + unset(_result) +endmacro() + +foreach(component IN LISTS FFmpeg_FIND_COMPONENTS) + if(NOT component IN_LIST _DEFAULT_COMPONENTS) + message(FATAL_ERROR "Unknown FFmpeg component specified: ${component}.") + endif() + + if(NOT FFmpeg_${component}_FOUND) + ffmpeg_find_component(${component}) + endif() + + if(FFmpeg_${component}_FOUND) + list(APPEND FFmpeg_LIBRARIES ${FFmpeg_${component}_LIBRARY}) + list(APPEND FFmpeg_DEFINITIONS ${FFmpeg_${component}_DEFINITIONS}) + list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIR}) + endif() +endforeach() + +if(NOT FFmpeg_avutil_FOUND) + ffmpeg_find_component(avutil) +endif() + +if(EXISTS "${FFmpeg_avutil_INCLUDE_DIR}/libavutil/ffversion.h") + file( + STRINGS + "${FFmpeg_avutil_INCLUDE_DIR}/libavutil/ffversion.h" + _version_string + REGEX "^.*FFMPEG_VERSION[ \t]+\"n?[0-9a-z\\~+.-]+\"[ \t]*$" + ) + string(REGEX REPLACE ".*FFMPEG_VERSION[ \t]+\"n?([0-9]+\\.[0-9]).*\".*" "\\1" FFmpeg_VERSION "${_version_string}") +endif() + +list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS) +list(REMOVE_DUPLICATES FFmpeg_LIBRARIES) +list(REMOVE_DUPLICATES FFmpeg_DEFINITIONS) + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows") + set(FFmpeg_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.") +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + set(FFmpeg_ERROR_REASON "Ensure that required FFmpeg libraries are installed on the system.") +endif() + +find_package_handle_standard_args( + FFmpeg + REQUIRED_VARS FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS + VERSION_VAR FFmpeg_VERSION + HANDLE_COMPONENTS + REASON_FAILURE_MESSAGE "${FFmpeg_ERROR_REASON}" +) + +if(FFmpeg_FOUND AND NOT TARGET FFmpeg::FFmpeg) + add_library(FFmpeg::FFmpeg INTERFACE IMPORTED) +endif() + +foreach(component IN LISTS FFmpeg_FIND_COMPONENTS) + if(FFmpeg_${component}_FOUND AND NOT TARGET FFmpeg::${component}) + if(IS_ABSOLUTE "${FFmpeg_${component}_LIBRARY}") + if(DEFINED FFmpeg_${component}_IMPLIB) + if(FFmpeg_${component}_IMPLIB STREQUAL FFmpeg_${component}_LIBRARY) + add_library(FFmpeg::${component} STATIC IMPORTED) + else() + add_library(FFmpeg::${component} SHARED IMPORTED) + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_IMPLIB "${FFmpeg_${component}_IMPLIB}") + endif() + else() + add_library(FFmpeg::${component} UNKNOWN IMPORTED) + ffmpeg_set_soname() + endif() + + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_LOCATION "${FFmpeg_${component}_LIBRARY}") + else() + add_library(FFmpeg::${component} INTERFACE IMPORTED) + set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_LIBNAME "${FFmpeg_${component}_LIBRARY}") + endif() + set_target_properties( + FFmpeg::${component} + PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_FFmpeg_${component}_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${FFmpeg_${component}_INCLUDE_DIR}" + VERSION ${FFmpeg_${component}_VERSION} + ) + + get_target_property(_ffmpeg_interface_libraries FFmpeg::FFmpeg INTERFACE_LINK_LIBRARIES) + if(NOT FFmpeg::${component} IN_LIST _ffmpeg_interface_libraries) + set_property(TARGET FFmpeg::FFmpeg APPEND PROPERTY INTERFACE_LINK_LIBRARIES FFmpeg::${component}) + endif() + endif() +endforeach() + +include(FeatureSummary) +set_package_properties( + FFmpeg + PROPERTIES + URL "https://www.ffmpeg.org" + DESCRIPTION "A complete, cross-platform solution to record, convert and stream audio and video." +) diff --git a/cmake/common/bootstrap.cmake b/cmake/common/bootstrap.cmake index 3a526a0..c38b7d0 100644 --- a/cmake/common/bootstrap.cmake +++ b/cmake/common/bootstrap.cmake @@ -52,6 +52,13 @@ string(JSON _email GET ${buildspec} email) string(JSON _version GET ${buildspec} version) string(JSON _bundleId GET ${buildspec} platformConfig macos bundleId) +# Release CI builds the plugin against a specific libmoq release and versions it +# to match (see build.sh --libmoq-release), so allow overriding the buildspec +# version. Everything below derives PLUGIN_VERSION_* from _version. +if(DEFINED PLUGIN_VERSION_OVERRIDE AND NOT PLUGIN_VERSION_OVERRIDE STREQUAL "") + set(_version "${PLUGIN_VERSION_OVERRIDE}") +endif() + set(PLUGIN_AUTHOR ${_author}) set(PLUGIN_WEBSITE ${_website}) set(PLUGIN_EMAIL ${_email}) diff --git a/cmake/macos/buildspec.cmake b/cmake/macos/buildspec.cmake index c189782..a86e4d8 100644 --- a/cmake/macos/buildspec.cmake +++ b/cmake/macos/buildspec.cmake @@ -22,10 +22,12 @@ function(_check_dependencies_macos) _check_dependencies() + # Best-effort: strip Gatekeeper quarantine from the downloaded deps. Not all + # files carry the attribute (and build outputs under .deps may be read-only), + # so a non-zero exit here is expected and must not abort configuration. execute_process( COMMAND "xattr" -r -d com.apple.quarantine "${dependencies_dir}" RESULT_VARIABLE result - COMMAND_ERROR_IS_FATAL ANY ) list(APPEND CMAKE_FRAMEWORK_PATH "${dependencies_dir}/Frameworks")