diff --git a/.cmake-format.json b/.cmake-format.json new file mode 100644 index 000000000..0ccd9bf0a --- /dev/null +++ b/.cmake-format.json @@ -0,0 +1,14 @@ +{ + "additional_commands": { + "find_qt": { + "flags": [], + "kwargs": { + "VERSION": "+", + "COMPONENTS": "+", + "COMPONENTS_WIN": "+", + "COMPONENTS_MACOS": "+", + "COMPONENTS_LINUX": "+" + } + } + } +} diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index ed14ba809..2c6f4f0c1 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,6 +1,12 @@ name: Clang Format Check -on: [push, pull_request] +on: + push: + paths-ignore: ['**.md'] + branches-ignore: [master] + pull_request: + paths-ignore: ['**.md'] + branches-ignore: [master] jobs: clang-format-check: @@ -15,7 +21,7 @@ jobs: run: | sudo apt-get install -y clang-format-12 - - name: Check the Formatting + - name: 'Run clang-format' run: | - ./formatcode.sh ./CI/check-format.sh + ./CI/check-changes.sh diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index a27df29fc..a5536a10d 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -3,12 +3,6 @@ name: Flatpak on: - push: - paths-ignore: ['**.md'] - branches: [master, 'release/**'] - pull_request: - paths-ignore: ['**.md'] - branches: [master, 'release/**'] release: types: [published] branches: [master, 'release/**'] @@ -24,40 +18,6 @@ env: YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }} jobs: - generate_bundle: - name: Generate Flatpak Bundle - runs-on: [ubuntu-latest] - if: github.event_name != 'release' - container: - image: bilelmoussaoui/flatpak-github-actions:kde-5.15-21.08 - options: --privileged - steps: - - name: 'Check for Github Labels' - if: github.event_name == 'pull_request' - shell: bash - run: | - LABELS_URL="$(echo ${{ github.event.pull_request.url }} | sed s'/pulls/issues/')" - LABEL_FOUND="$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "${LABELS_URL}/labels" | sed -n 's/.*"name": "\(.*\)",/\1/p' | grep 'Seeking Testers' || true)" - if [ "${LABEL_FOUND}" = "Seeking Testers" ]; then - echo "SEEKING_TESTERS=1" >> $GITHUB_ENV - else - echo "SEEKING_TESTERS=0" >> $GITHUB_ENV - fi - - - name: Checkout - uses: actions/checkout@v2.3.3 - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - with: - submodules: 'recursive' - - - name: Build Flatpak Manifest - uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4 - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - with: - bundle: obs-studio-${{ github.sha }}.flatpak - manifest-path: CI/flatpak/com.obsproject.Studio.json - cache-key: flatpak-builder-${{ github.sha }} - publish: name: Publish to Flathub runs-on: [ubuntu-latest] diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c164b7ea4..47b17bec4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,24 +1,26 @@ -name: 'CI Multiplatform Build' +name: 'BUILD' on: push: - paths-ignore: - - '**.md' + paths-ignore: ['**.md'] branches: - master - 'release/**' - tags: - - '*' + tags: ['*'] pull_request: - paths-ignore: - - '**.md' - branches: - - master + paths-ignore: ['**.md'] + branches: [master] env: - MACOS_CEF_BUILD_VERSION: '4638' - LINUX_CEF_BUILD_VERSION: '4638' - WINDOWS_CEF_BUILD_VERSION: '4638' + CEF_BUILD_VERSION_MAC: '4638' + CEF_BUILD_VERSION_LINUX: '4638' + CEF_BUILD_VERSION_WIN: '4638' + QT_VERSION_MAC: '5.15.2' + QT_VERSION_WIN: '5.15.2' + DEPS_VERSION_MAC: '2022-02-13' + DEPS_VERSION_WIN: '2022-01-31' + VLC_VERSION_MAC: '3.0.8' + VLC_VERSION_WIN: '3.0.0-git' TWITCH_CLIENTID: ${{ secrets.TWITCH_CLIENT_ID }} TWITCH_HASH: ${{ secrets.TWITCH_HASH }} RESTREAM_CLIENTID: ${{ secrets.RESTREAM_CLIENTID }} @@ -29,687 +31,444 @@ env: YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }} jobs: - macos64: - name: 'macOS 64-bit' - runs-on: [macos-latest] - env: - MIN_MACOS_VERSION: '10.13' - MACOS_DEPS_VERSION: '2022-02-13' - VLC_VERSION: '3.0.8' - SPARKLE_VERSION: '1.23.0' - QT_VERSION: '5.15.2' - SIGN_IDENTITY: '' - HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY != '' && secrets.MACOS_SIGNING_CERT != '' }} + clang_check: + name: '01 - Code Format Check' + runs-on: [ubuntu-latest] steps: - - name: Get Current Arch - shell: bash - id: get_arch - run: echo "CURRENT_ARCH=$(uname -m)" >> $GITHUB_ENV - name: 'Checkout' uses: actions/checkout@v2.3.3 with: submodules: 'recursive' - - name: 'Fetch Git Tags' + + - name: 'Install clang-format' + run: sudo apt-get install -y clang-format-12 + + - name: 'Run clang-format' run: | - git fetch --prune --unshallow - echo "OBS_GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_TAG=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV + ./CI/check-format.sh + ./CI/check-changes.sh + + - name: 'Install cmake-format' + run: sudo pip install cmakelang + + - name: 'Run cmake-format' + run: | + ./CI/check-cmake.sh + + macos_build: + name: '02 - macOS' + runs-on: [macos-11] + strategy: + matrix: + arch: ['x86_64'] + if: always() + needs: [clang_check] + env: + MACOSX_DEPLOYMENT_TARGET: '10.13' + SPARKLE_VERSION: '1.26.0' + SPARKLE_HASH: '8312cbf7528297a49f1b97692c33cb8d33254c396dc51be394e9484e4b6833a0' + BLOCKED_FORMULAS: 'speexdsp curl php composer' + CODESIGN_IDENT: '-' + HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY != '' && secrets.MACOS_SIGNING_CERT != '' }} + defaults: + run: + shell: bash + working-directory: 'obs-studio' + steps: + - name: 'Checkout' + uses: actions/checkout@v2.3.3 + with: + submodules: 'recursive' + path: 'obs-studio' + fetch-depth: 0 + - name: 'Check for Github Labels' if: github.event_name == 'pull_request' run: | - LABELS_URL="$(echo ${{ github.event.pull_request.url }} | sed s'/pulls/issues/')" - LABEL_FOUND="$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "${LABELS_URL}/labels" | sed -n 's/.*"name": "\(.*\)",/\1/p' | grep 'Seeking Testers' || true)" - if [ "${LABEL_FOUND}" = "Seeking Testers" ]; then + if test -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')"; then echo "SEEKING_TESTERS=1" >> $GITHUB_ENV else echo "SEEKING_TESTERS=0" >> $GITHUB_ENV fi - - name: 'Setup build environment (Homebrew + ENV)' - shell: bash - run: | - if [ -d /usr/local/opt/openssl@1.0.2t ]; then - brew uninstall openssl@1.0.2t - brew untap local/openssl - fi - if [ -d /usr/local/opt/python@2.7.17 ]; then - brew uninstall python@2.7.17 - brew untap local/python2 - fi + echo "CACHE_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV + + - name: 'Restore ccache from cache' + id: ccache-cache + uses: actions/cache@v2.1.2 + env: + CACHE_NAME: 'ccache-cache' + with: + path: ${{ github.workspace }}/.ccache + key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ matrix.arch }}-${{ env.CACHE_DATE }} - if [ -d /usr/local/opt/speexdsp ]; then - brew unlink speexdsp - fi - brew uninstall curl php composer - brew bundle --file ./CI/scripts/macos/Brewfile - echo "NPROC=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV - name: 'Restore Chromium Embedded Framework from cache' id: cef-cache uses: actions/cache@v2.1.2 env: CACHE_NAME: 'cef-cache' with: - path: ${{ github.workspace }}/cmbuild/cef_binary_${{ env.MACOS_CEF_BUILD_VERSION }}_macos_x86_64 - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.MACOS_CEF_BUILD_VERSION }}-1 + path: ${{ github.workspace }}/obs-build-dependencies/cef_binary_${{ env.CEF_BUILD_VERSION_MAC }}_macos_${{ matrix.arch }} + key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.CEF_BUILD_VERSION_MAC }}-${{ matrix.arch }} + - name: 'Restore VLC dependency from cache' id: vlc-cache uses: actions/cache@v2.1.2 env: CACHE_NAME: 'vlc-cache' with: - path: ${{ github.workspace }}/cmbuild/vlc-${{ env.VLC_VERSION }} - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.VLC_VERSION }} + path: ${{ github.workspace }}/obs-build-dependencies/vlc-${{ env.VLC_VERSION_MAC }} + key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.VLC_VERSION_MAC }} + - name: 'Restore Sparkle dependency from cache' id: sparkle-cache uses: actions/cache@v2.1.2 env: CACHE_NAME: 'sparkle-cache' with: - path: ${{ github.workspace }}/cmbuild/sparkle + path: ${{ github.workspace }}/obs-build-dependencies/sparkle key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.SPARKLE_VERSION }} - - name: 'Install prerequisite: Pre-built dependencies' - if: steps.deps-cache.outputs.cache-hit != 'true' - shell: bash + + - name: 'Setup build environment' run: | - mkdir /tmp/obsdeps - curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/macos-deps-${{ env.MACOS_DEPS_VERSION }}-${{ env.CURRENT_ARCH }}.tar.xz - tar -xf ./macos-deps-${{ env.MACOS_DEPS_VERSION }}-${{ env.CURRENT_ARCH }}.tar.xz -C "/tmp/obsdeps" - - name: 'Install prerequisite: Pre-built dependency Qt' - if: steps.deps-qt-cache.outputs.cache-hit != 'true' - shell: bash - run: | - curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/macos-deps-qt-${{ env.MACOS_DEPS_VERSION }}-${{ env.CURRENT_ARCH }}.tar.xz - tar -xf ./macos-deps-qt-${{ env.MACOS_DEPS_VERSION }}-${{ env.CURRENT_ARCH }}.tar.xz -C "/tmp/obsdeps" - xattr -r -d com.apple.quarantine /tmp/obsdeps - - name: 'Install prerequisite: VLC' - if: steps.vlc-cache.outputs.cache-hit != 'true' - shell: bash - run: | - curl -L -O https://downloads.videolan.org/vlc/${{ env.VLC_VERSION }}/vlc-${{ env.VLC_VERSION }}.tar.xz - if [ ! -d "${{ github.workspace }}/cmbuild" ]; then mkdir "${{ github.workspace }}/cmbuild"; fi - tar -xf ./vlc-${{ env.VLC_VERSION }}.tar.xz -C "${{ github.workspace }}/cmbuild" - - name: 'Install prerequisite: Sparkle' - if: steps.sparkle-cache.outputs.cache-hit != 'true' - shell: bash - run: | - curl -L -o sparkle.tar.bz2 https://github.com/sparkle-project/Sparkle/releases/download/${{ env.SPARKLE_VERSION }}/Sparkle-${{ env.SPARKLE_VERSION }}.tar.bz2 - mkdir ${{ github.workspace }}/cmbuild/sparkle - tar -xf ./sparkle.tar.bz2 -C ${{ github.workspace }}/cmbuild/sparkle - - name: 'Setup prerequisite: Sparkle' - shell: bash - run: sudo cp -R ${{ github.workspace }}/cmbuild/sparkle/Sparkle.framework /Library/Frameworks/Sparkle.framework - - name: 'Install prerequisite: Chromium Embedded Framework' - if: steps.cef-cache.outputs.cache-hit != 'true' - shell: bash - run: | - curl -L -O https://cdn-fastly.obsproject.com/downloads/cef_binary_${{ env.MACOS_CEF_BUILD_VERSION }}_macos_x86_64.tar.xz - tar -xf ./cef_binary_${{ env.MACOS_CEF_BUILD_VERSION }}_macos_x86_64.tar.xz -C ${{ github.workspace }}/cmbuild/ - cd ${{ github.workspace }}/cmbuild/cef_binary_${{ env.MACOS_CEF_BUILD_VERSION }}_macos_x86_64 - /usr/bin/sed -i '.orig' '/add_subdirectory(tests\/ceftests)/d' ./CMakeLists.txt - /usr/bin/sed -i '.orig' s/\"10.9\"/\"${{ env.MIN_MACOS_VERSION }}\"/ ./cmake/cef_variables.cmake - mkdir build && cd build - cmake -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++ -Wno-deprecated-declarations" -DCMAKE_EXE_LINKER_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_OSX_DEPLOYMENT_TARGET=${{ env.MIN_MACOS_VERSION }} .. - make -j${NPROC:-4} - mkdir libcef_dll - cd ../../ - - name: 'Configure' - shell: bash - run: | - mkdir ./build - cd ./build - LEGACY_BROWSER="$(test "${{ env.MACOS_CEF_BUILD_VERSION }}" -le 3770 && echo "ON" || echo "OFF")" - cmake -DENABLE_UNIT_TESTS=YES -DENABLE_SPARKLE_UPDATER=ON -DCMAKE_OSX_DEPLOYMENT_TARGET=${{ env.MIN_MACOS_VERSION }} -DQTDIR="/tmp/obsdeps" -DSWIGDIR="/tmp/obsdeps" -DDepsPath="/tmp/obsdeps" -DVLCPath="${{ github.workspace }}/cmbuild/vlc-${{ env.VLC_VERSION }}" -DENABLE_VLC=ON -DBUILD_BROWSER=ON -DBROWSER_LEGACY=$LEGACY_BROWSER -DWITH_RTMPS=ON -DCEF_ROOT_DIR="${{ github.workspace }}/cmbuild/cef_binary_${{ env.MACOS_CEF_BUILD_VERSION }}_macos_x86_64" -DTWITCH_CLIENTID='${{ env.TWITCH_CLIENTID }}' -DTWITCH_HASH='${{ env.TWITCH_HASH }}' -DRESTREAM_CLIENTID='${{ env.RESTREAM_CLIENTID }}' -DRESTREAM_HASH='${{ env.RESTREAM_HASH }}' .. - - name: 'Build' - shell: bash - working-directory: ${{ github.workspace }}/build - run: make -j${NPROC:-4} - - name: 'Test' - shell: bash - working-directory: ${{ github.workspace }}/build - run: make CTEST_OUTPUT_ON_FAILURE=1 test - - name: 'Install prerequisite: DMGbuild' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - shell: bash - run: | - pip3 install dmgbuild==1.5.2 + REMOVE_FORMULAS="" + for FORMULA in ${{ env.BLOCKED_FORMULAS }}; do + if [ -d "/usr/local/opt/${FORMULA}" ]; then + REMOVE_FORMULAS="${REMOVE_FORMULAS}${FORMULA} " + fi + done + + if [ -n "${REMOVE_FORMULAS}" ]; then + brew uninstall ${REMOVE_FORMULAS} + fi + + - name: 'Install dependencies' + env: + RESTORED_VLC: ${{ steps.vlc-cache.outputs.cache-hit }} + RESTORED_SPARKLE: ${{ steps.sparkle-cache.outputs.cache-hit }} + RESTORED_CEF: ${{ steps.cef-cache.outputs.cache-hit }} + run: CI/macos/01_install_dependencies.sh --architecture "${{ matrix.arch }}" + - name: 'Install Apple Developer Certificate' - if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' + if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' }} uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071 with: p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }} p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }} + - name: 'Set Signing Identity' - if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' + if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' }} run: | - echo "SIGN_IDENTITY=${{ secrets.MACOS_SIGNING_IDENTITY }}" >> $GITHUB_ENV - - name: 'Create macOS application bundle' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - working-directory: ${{ github.workspace }}/build - shell: bash + echo "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_IDENTITY }}" >> $GITHUB_ENV + echo "BUILD_FOR_DISTRIBUTION=ON" >> $GITHUB_ENV + + - name: 'Build OBS' + run: CI/macos/02_build_obs.sh --codesign --architecture "${{ matrix.arch }}" + + - name: 'Run tests' + if: success() + run: cmake --build build -t test + + - name: 'Create build artifact' + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} run: | - if [ -d ./OBS.app ]; then rm -rf ./OBS.app; fi - mkdir -p OBS.app/Contents/MacOS - mkdir OBS.app/Contents/PlugIns - mkdir OBS.app/Contents/Resources - mkdir OBS.app/Contents/Frameworks + CI/macos/03_package_obs.sh --codesign + ARTIFACT_NAME=$(basename $(/usr/bin/find build -type f -name "obs-studio-*.dmg" -depth 1 | head -1)) + echo "FILE_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV - cp rundir/RelWithDebInfo/bin/obs ./OBS.app/Contents/MacOS - cp rundir/RelWithDebInfo/bin/obs-ffmpeg-mux ./OBS.app/Contents/MacOS - if ! [ "${{ env.MACOS_CEF_BUILD_VERSION }}" -le 3770 ]; then - cp -R "rundir/RelWithDebInfo/bin/OBS Helper.app" "./OBS.app/Contents/Frameworks/OBS Helper.app" - cp -R "rundir/RelWithDebInfo/bin/OBS Helper (GPU).app" "./OBS.app/Contents/Frameworks/OBS Helper (GPU).app" - cp -R "rundir/RelWithDebInfo/bin/OBS Helper (Plugin).app" "./OBS.app/Contents/Frameworks/OBS Helper (Plugin).app" - cp -R "rundir/RelWithDebInfo/bin/OBS Helper (Renderer).app" "./OBS.app/Contents/Frameworks/OBS Helper (Renderer).app" - fi - cp rundir/RelWithDebInfo/bin/libobsglad.0.dylib ./OBS.app/Contents/MacOS - cp -R rundir/RelWithDebInfo/data ./OBS.app/Contents/Resources - cp ../CI/scripts/macos/app/AppIcon.icns ./OBS.app/Contents/Resources - cp -R rundir/RelWithDebInfo/obs-plugins/ ./OBS.app/Contents/PlugIns - cp ../CI/scripts/macos/app/Info.plist ./OBS.app/Contents - - if [ -d ./OBS.app/Contents/Resources/data/obs-scripting ]; then - mv ./OBS.app/Contents/Resources/data/obs-scripting/obslua.so ./OBS.app/Contents/MacOS/ - mv ./OBS.app/Contents/Resources/data/obs-scripting/_obspython.so ./OBS.app/Contents/MacOS/ - mv ./OBS.app/Contents/Resources/data/obs-scripting/obspython.py ./OBS.app/Contents/MacOS/ - rm -rf ./OBS.app/Contents/Resources/data/obs-scripting/ - fi - - /bin/cp -cpR /tmp/obsdeps/lib/*.dylib ./OBS.app/Contents/Frameworks - - BUNDLE_PLUGINS=( - ./OBS.app/Contents/PlugIns/coreaudio-encoder.so - ./OBS.app/Contents/PlugIns/decklink-ouput-ui.so - ./OBS.app/Contents/PlugIns/decklink-captions.so - ./OBS.app/Contents/PlugIns/frontend-tools.so - ./OBS.app/Contents/PlugIns/image-source.so - ./OBS.app/Contents/PlugIns/mac-avcapture.so - ./OBS.app/Contents/PlugIns/mac-capture.so - ./OBS.app/Contents/PlugIns/mac-decklink.so - ./OBS.app/Contents/PlugIns/mac-syphon.so - ./OBS.app/Contents/PlugIns/mac-vth264.so - ./OBS.app/Contents/PlugIns/mac-virtualcam.so - ./OBS.app/Contents/PlugIns/obs-browser.so - ./OBS.app/Contents/PlugIns/obs-ffmpeg.so - ./OBS.app/Contents/PlugIns/obs-filters.so - ./OBS.app/Contents/PlugIns/obs-transitions.so - ./OBS.app/Contents/PlugIns/obs-vst.so - ./OBS.app/Contents/PlugIns/rtmp-services.so - ./OBS.app/Contents/MacOS/obs-ffmpeg-mux - ./OBS.app/Contents/MacOS/obslua.so - ./OBS.app/Contents/MacOS/_obspython.so - ./OBS.app/Contents/PlugIns/obs-x264.so - ./OBS.app/Contents/PlugIns/text-freetype2.so - ./OBS.app/Contents/PlugIns/obs-outputs.so - ) - - if ! [ "${{ env.MACOS_CEF_BUILD_VERSION }}" -le 3770 ]; then - ../CI/scripts/macos/app/dylibBundler -cd -of -a ./OBS.app -q -f \ - -s ./OBS.app/Contents/MacOS \ - -s /tmp/obsdeps/lib \ - -s /tmp/obsdeps/lib/QtSvg.framework \ - -s /tmp/obsdeps/lib/QtXml.framework \ - -s /tmp/obsdeps/lib/QtNetwork.framework \ - -s /tmp/obsdeps/lib/QtCore.framework \ - -s /tmp/obsdeps/lib/QtGui.framework \ - -s /tmp/obsdeps/lib/QtWidgets.framework \ - -s /tmp/obsdeps/lib/QtDBus.framework \ - -s /tmp/obsdeps/lib/QtPrintSupport.framework \ - -s "${{ github.workspace }}/cmbuild/sparkle/Sparkle.framework" \ - -s ./rundir/RelWithDebInfo/bin \ - $(echo "${BUNDLE_PLUGINS[@]/#/-x }") - else - ../CI/scripts/macos/app/dylibBundler -cd -of -a ./OBS.app -q -f \ - -s ./OBS.app/Contents/MacOS \ - -s /tmp/obsdeps/lib \ - -s /tmp/obsdeps/lib/QtSvg.framework \ - -s /tmp/obsdeps/lib/QtXml.framework \ - -s /tmp/obsdeps/lib/QtNetwork.framework \ - -s /tmp/obsdeps/lib/QtCore.framework \ - -s /tmp/obsdeps/lib/QtGui.framework \ - -s /tmp/obsdeps/lib/QtWidgets.framework \ - -s /tmp/obsdeps/lib/QtDBus.framework \ - -s /tmp/obsdeps/lib/QtPrintSupport.framework \ - -s "${{ github.workspace }}/cmbuild/sparkle/Sparkle.framework" \ - -s ./rundir/RelWithDebInfo/bin \ - $(echo "${BUNDLE_PLUGINS[@]/#/-x }") \ - -x ./OBS.app/Contents/PlugIns/obs-browser-page - fi - - mv ./libobs-opengl/libobs-opengl.so ./OBS.app/Contents/Frameworks - - cp -R "${{ github.workspace }}/cmbuild/cef_binary_${{ env.MACOS_CEF_BUILD_VERSION }}_macos_x86_64/Release/Chromium Embedded Framework.framework" ./OBS.app/Contents/Frameworks/ - chown -R $(whoami) ./OBS.app/Contents/Frameworks/ - - cp ../CI/scripts/macos/app/OBSPublicDSAKey.pem ./OBS.app/Contents/Resources - - if [ "${GITHUB_REF:0:10}" = "refs/tags/" ]; then - plutil -insert CFBundleVersion -string ${{ env.OBS_GIT_TAG }} ./OBS.app/Contents/Info.plist - plutil -insert CFBundleShortVersionString -string ${{ env.OBS_GIT_TAG }} ./OBS.app/Contents/Info.plist - else - plutil -insert CFBundleVersion -string ${{ env.OBS_GIT_TAG }}-${{ env.OBS_GIT_HASH }} ./OBS.app/Contents/Info.plist - plutil -insert CFBundleShortVersionString -string ${{ env.OBS_GIT_TAG }}-${{ env.OBS_GIT_HASH }} ./OBS.app/Contents/Info.plist - fi - - plutil -insert OBSFeedsURL -string https://obsproject.com/osx_update/feeds.xml ./OBS.app/Contents/Info.plist - plutil -insert SUFeedURL -string https://obsproject.com/osx_update/stable/updates.xml ./OBS.app/Contents/Info.plist - plutil -insert SUPublicDSAKeyFile -string OBSPublicDSAKey.pem ./OBS.app/Contents/Info.plist - - codesign --force --options runtime --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/fileop" - codesign --force --options runtime --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate" - codesign --force --options runtime --sign "${SIGN_IDENTITY:--}" --deep ./OBS.app/Contents/Frameworks/Sparkle.framework - - codesign --force --options runtime --entitlements "../CI/scripts/macos/app/entitlements.plist" --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libEGL.dylib" - codesign --force --options runtime --entitlements "../CI/scripts/macos/app/entitlements.plist" --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libswiftshader_libEGL.dylib" - codesign --force --options runtime --entitlements "../CI/scripts/macos/app/entitlements.plist" --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libGLESv2.dylib" - codesign --force --options runtime --entitlements "../CI/scripts/macos/app/entitlements.plist" --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libswiftshader_libGLESv2.dylib" - if ! [ "${{ env.MACOS_CEF_BUILD_VERSION }}" -le 3770 ]; then - codesign --force --options runtime --entitlements "../CI/scripts/macos/app/entitlements.plist" --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libvk_swiftshader.dylib" - fi - - if ! [ "${{ env.MACOS_CEF_BUILD_VERSION }}" -le 3770 ]; then - codesign --force --options runtime --entitlements "../CI/scripts/macos/helpers/helper-entitlements.plist" --sign "${SIGN_IDENTITY:--}" --deep "./OBS.app/Contents/Frameworks/OBS Helper.app" - codesign --force --options runtime --entitlements "../CI/scripts/macos/helpers/helper-gpu-entitlements.plist" --sign "${SIGN_IDENTITY:--}" --deep "./OBS.app/Contents/Frameworks/OBS Helper (GPU).app" - codesign --force --options runtime --entitlements "../CI/scripts/macos/helpers/helper-plugin-entitlements.plist" --sign "${SIGN_IDENTITY:--}" --deep "./OBS.app/Contents/Frameworks/OBS Helper (Plugin).app" - codesign --force --options runtime --entitlements "../CI/scripts/macos/helpers/helper-renderer-entitlements.plist" --sign "${SIGN_IDENTITY:--}" --deep "./OBS.app/Contents/Frameworks/OBS Helper (Renderer).app" - fi - - codesign --force --options runtime --deep --sign "${SIGN_IDENTITY:--}" "./OBS.app/Contents/Resources/data/obs-plugins/mac-virtualcam/obs-mac-virtualcam.plugin" - - codesign --force --options runtime --entitlements "../CI/scripts/macos/app/entitlements.plist" --sign "${SIGN_IDENTITY:--}" --deep ./OBS.app - - codesign -dvv ./OBS.app - - name: 'Package' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - working-directory: ${{ github.workspace }}/build - shell: bash - run: | - FILE_DATE=$(date +%Y-%m-%d) - FILE_NAME=$FILE_DATE-${{ env.OBS_GIT_HASH }}-${{ env.OBS_GIT_TAG }}-macOS.dmg - echo "FILE_NAME=${FILE_NAME}" >> $GITHUB_ENV - - cp ../CI/scripts/macos/package/settings.json.template ./settings.json - /usr/bin/sed -i '' 's#\$\$VERSION\$\$#${{ env.OBS_GIT_TAG }}#g' ./settings.json - /usr/bin/sed -i '' 's#\$\$CI_PATH\$\$#../CI/scripts/macos#g' ./settings.json - /usr/bin/sed -i '' 's#\$\$BUNDLE_PATH\$\$#${{ github.workspace }}/build#g' ./settings.json - - dmgbuild "OBS-Studio ${{ env.OBS_GIT_TAG }}" "${FILE_NAME}" -s ./settings.json - mkdir ../nightly - codesign --force --sign "${SIGN_IDENTITY:--}" ./"${FILE_NAME}" - codesign -dvv ./"${FILE_NAME}" - sudo cp ./${FILE_NAME} ../nightly/${FILE_NAME} - - name: 'Publish' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - uses: actions/upload-artifact@v2.2.0 + - name: 'Upload build Artifact' + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} + uses: actions/upload-artifact@v2 with: - name: '${{ env.FILE_NAME }}' - path: ./nightly/*.dmg - - name: 'Package Release' - if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' - working-directory: ${{ github.workspace }}/build + name: 'obs-macos-${{ matrix.arch }}' + path: '${{ github.workspace }}/obs-studio/build/${{ env.FILE_NAME }}' + + linux_build: + name: '02 - Linux' + runs-on: ${{ matrix.ubuntu }} + strategy: + matrix: + ubuntu: ['ubuntu-20.04', 'ubuntu-18.04'] + if: always() + needs: [clang_check] + defaults: + run: shell: bash - run: | - FILE_DATE=$(date +%Y-%m-%d) - FILE_NAME=$FILE_DATE-${{ env.OBS_GIT_HASH }}-${{ env.OBS_GIT_TAG }}-macOS.dmg - RELEASE_FILE_NAME=$FILE_DATE-${{ env.OBS_GIT_HASH }}-${{ env.OBS_GIT_TAG }}-rel-macOS.dmg - echo "RELEASE_FILE_NAME=${RELEASE_FILE_NAME}" >> $GITHUB_ENV - - xcrun altool --store-password-in-keychain-item "AC_PASSWORD" -u "${{ secrets.MACOS_NOTARIZATION_USERNAME }}" -p "${{ secrets.MACOS_NOTARIZATION_PASSWORD }}" - - xcnotary precheck "./OBS.app" - - if [ "$?" -eq 0 ]; then - xcnotary notarize "$FILE_NAME" --developer-account "${{ secrets.MACOS_NOTARIZATION_USERNAME }}" --developer-password-keychain-item "AC_PASSWORD" --provider "${{ secrets.ASC_PROVIDER_SHORTNAME }}" - else - return 1 - fi - - mkdir ../release - sudo mv ./$FILE_NAME ../release/$RELEASE_FILE_NAME - - name: 'Publish Release' - if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true' - uses: actions/upload-artifact@v2.2.0 - with: - name: '${{ env.RELEASE_FILE_NAME }}' - path: ./release/*.dmg - ubuntu64: - name: 'Linux/Ubuntu 64-bit' - runs-on: [ubuntu-18.04] + working-directory: 'obs-studio' + env: + BUILD_FOR_DISTRIBUTION: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }} steps: - name: 'Checkout' uses: actions/checkout@v2.3.3 with: submodules: 'recursive' - - name: 'Fetch Git Tags' - run: | - git fetch --prune --unshallow - echo "OBS_GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_TAG=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV + path: 'obs-studio' + fetch-depth: 0 + - name: 'Check for Github Labels' if: github.event_name == 'pull_request' run: | - LABELS_URL="$(echo ${{ github.event.pull_request.url }} | sed s'/pulls/issues/')" - LABEL_FOUND="$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "${LABELS_URL}/labels" | sed -n 's/.*"name": "\(.*\)",/\1/p' | grep 'Seeking Testers' || true)" - if [ "${LABEL_FOUND}" = "Seeking Testers" ]; then + if test -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')"; then echo "SEEKING_TESTERS=1" >> $GITHUB_ENV else echo "SEEKING_TESTERS=0" >> $GITHUB_ENV fi - - name: Install prerequisites (Apt) - shell: bash - run: | - echo "NPROC=$(($(nproc)+1))" >> $GITHUB_ENV - sudo dpkg --add-architecture amd64 - sudo apt-get -qq update - sudo apt-get install -y \ - build-essential \ - checkinstall \ - cmake \ - libasound2-dev \ - libavcodec-dev \ - libavdevice-dev \ - libavfilter-dev \ - libavformat-dev \ - libavutil-dev \ - libcurl4-openssl-dev \ - libfdk-aac-dev \ - libfontconfig-dev \ - libfreetype6-dev \ - libgl1-mesa-dev \ - libjack-jackd2-dev \ - libjansson-dev \ - libluajit-5.1-dev \ - libpulse-dev \ - libqt5x11extras5-dev \ - libsndio-dev \ - libspeexdsp-dev \ - libswresample-dev \ - libswscale-dev \ - libudev-dev \ - libv4l-dev \ - libva-dev \ - libvlc-dev \ - libx11-dev \ - libx264-dev \ - libxcb-randr0-dev \ - libxcb-shm0-dev \ - libxcb-xinerama0-dev \ - libxcomposite-dev \ - libxinerama-dev \ - libmbedtls-dev \ - pkg-config \ - python3-dev \ - qtbase5-dev \ - qtbase5-private-dev \ - libqt5svg5-dev \ - swig \ - libcmocka-dev \ - libpci-dev + + echo "CACHE_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV + + - name: 'Restore ccache from cache' + id: ccache-cache + uses: actions/cache@v2.1.2 + env: + CACHE_NAME: 'ccache-cache' + with: + path: ${{ github.workspace }}/.ccache + key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ matrix.ubuntu }}-${{ env.CACHE_DATE }} + - name: 'Restore Chromium Embedded Framework from cache' id: cef-cache uses: actions/cache@v2.1.2 env: CACHE_NAME: 'cef-cache' with: - path: ${{ github.workspace }}/cmbuild/cef_binary_${{ env.LINUX_CEF_BUILD_VERSION }}_linux64 - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.LINUX_CEF_BUILD_VERSION }}-1 - - name: 'Install prerequisite: Chromium Embedded Framework' - if: steps.cef-cache.outputs.cache-hit != 'true' - shell: bash + path: ${{ github.workspace }}/obs-build-dependencies/cef_binary_${{ env.CEF_BUILD_VERSION_LINUX }}_linux64 + key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.CEF_BUILD_VERSION_LINUX }} + + - name: 'Install dependencies' + env: + RESTORED_CEF: ${{ steps.cef-cache.outputs.cache-hit }} + run: CI/linux/01_install_dependencies.sh --disable-pipewire + + - name: 'Build OBS' + run: CI/linux/02_build_obs.sh --disable-pipewire + + - name: 'Run tests' + if: success() + run: cmake --build build -t test + + - name: 'Create build artifact' + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} run: | - curl -kL https://cdn-fastly.obsproject.com/downloads/cef_binary_${{ env.LINUX_CEF_BUILD_VERSION }}_linux64.tar.bz2 -f --retry 5 -o cef.tar.bz2 - if [ ! -d "${{ github.workspace }}/cmbuild" ]; then mkdir "${{ github.workspace }}/cmbuild"; fi - tar -C"${{ github.workspace }}/cmbuild" -xjf cef.tar.bz2 - - name: 'Configure' - shell: bash - run: | - mkdir ./build - cd ./build - cmake -DENABLE_PIPEWIRE=OFF -DUNIX_STRUCTURE=0 -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/obs-studio-portable" -DENABLE_UNIT_TESTS=ON -DENABLE_VLC=ON -DWITH_RTMPS=ON -DBUILD_BROWSER=ON -DCEF_ROOT_DIR="${{ github.workspace }}/cmbuild/cef_binary_${{ env.LINUX_CEF_BUILD_VERSION }}_linux64" -DTWITCH_CLIENTID='${{ env.TWITCH_CLIENTID }}' -DTWITCH_HASH='${{ env.TWITCH_HASH }}' -DRESTREAM_CLIENTID='${{ env.RESTREAM_CLIENTID }}' -DRESTREAM_HASH='${{ env.RESTREAM_HASH }}' .. - - name: 'Build' - shell: bash - working-directory: ${{ github.workspace }}/build - run: make -j${NPROC:-4} - - name: 'Test' - shell: bash - working-directory: ${{ github.workspace }}/build - run: make CTEST_OUTPUT_ON_FAILURE=1 test - - name: 'Package' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - shell: bash - run: | - FILE_DATE=$(date +%Y-%m-%d) - FILE_NAME=$FILE_DATE-${{ env.OBS_GIT_HASH }}-${{ env.OBS_GIT_TAG }}-linux64.tar.gz - echo "FILE_NAME=${FILE_NAME}" >> $GITHUB_ENV - cd ./build - sudo checkinstall --default --install=no --pkgname=obs-studio --fstrans=yes --backup=no --pkgversion="$(date +%Y%m%d)-git" --deldoc=yes - mkdir ../nightly - tar -cvzf "${FILE_NAME}" *.deb - mv "${FILE_NAME}" ../nightly/ - cd - - - name: 'Publish' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - uses: actions/upload-artifact@v2.2.0 + CI/linux/03_package_obs.sh + ARTIFACT_NAME=$(basename $(/usr/bin/find build -maxdepth 1 -type f -name "obs-studio-*.deb" | sort -rn | head -1)) + echo "FILE_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV + + - name: 'Upload build Artifact' + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} + uses: actions/upload-artifact@v2 with: - name: '${{ env.FILE_NAME }}' - path: './nightly/*.tar.gz' - win64: - name: 'Windows 64-bit' + name: 'obs-linux-deb' + path: '${{ github.workspace }}/obs-studio/build/${{ env.FILE_NAME }}' + + windows_build: + name: '02 - Windows' runs-on: [windows-2019] + needs: [clang_check] + if: always() + strategy: + matrix: + arch: [64, 32] env: - QT_VERSION: '5.15.2' - CMAKE_GENERATOR: "Visual Studio 16 2019" - CMAKE_SYSTEM_VERSION: "10.0.18363.657" - WINDOWS_DEPS_VERSION: '2022-01-31' - WINDOWS_DEPS_CACHE_VERSION: '1' - VLC_VERSION: '3.0.0-git' - VIRTUALCAM-GUID: "A3FCE0F5-3493-419F-958A-ABA1250EC20B" + CMAKE_GENERATOR: 'Visual Studio 16 2019' + CMAKE_SYSTEM_VERSION: '10.0.18363.657' + VIRTUALCAM-GUID: 'A3FCE0F5-3493-419F-958A-ABA1250EC20B' + BUILD_FOR_DISTRIBUTION: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }} + defaults: + run: + working-directory: 'obs-studio' steps: - - name: 'Add msbuild to PATH' - uses: microsoft/setup-msbuild@v1.0.2 - name: 'Checkout' uses: actions/checkout@v2.3.3 with: submodules: 'recursive' - - name: 'Fetch Git Tags' - shell: bash - run: | - git fetch --prune --unshallow - echo "OBS_GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_TAG=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV - - name: 'Check for Github Labels' - if: github.event_name == 'pull_request' - shell: bash - run: | - LABELS_URL="$(echo ${{ github.event.pull_request.url }} | sed s'/pulls/issues/')" - LABEL_FOUND="$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "${LABELS_URL}/labels" | sed -n 's/.*"name": "\(.*\)",/\1/p' | grep 'Seeking Testers' || true)" - if [ "${LABEL_FOUND}" = "Seeking Testers" ]; then - echo "SEEKING_TESTERS=1" >> $GITHUB_ENV - else - echo "SEEKING_TESTERS=0" >> $GITHUB_ENV - fi - - name: 'Restore QT dependency from cache' - id: qt-cache - uses: actions/cache@v2.1.2 - env: - CACHE_NAME: 'windows-qt-cache' - with: - path: ${{ github.workspace }}/cmbuild/QT - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.QT_VERSION }} - - name: 'Restore pre-built dependencies from cache' - id: deps-cache - uses: actions/cache@v2.1.2 - env: - CACHE_NAME: 'windows-deps-cache' - with: - path: ${{ github.workspace }}/cmbuild/deps - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.WINDOWS_DEPS_VERSION }}-${{ env.WINDOWS_DEPS_CACHE_VERSION }} - - name: 'Restore VLC dependency from cache' - id: vlc-cache - uses: actions/cache@v2.1.2 - env: - CACHE_NAME: 'windows-vlc-cache' - with: - path: ${{ github.workspace }}/cmbuild/vlc - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.VLC_VERSION }} - - name: 'Restore CEF dependency from cache (64 bit)' - id: cef-cache - uses: actions/cache@v2.1.2 - env: - CACHE_NAME: 'windows-cef-64-cache' - with: - path: ${{ github.workspace }}/cmbuild/cef_binary_${{ env.WINDOWS_CEF_BUILD_VERSION }}_windows_x64 - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.WINDOWS_CEF_BUILD_VERSION }}-3 - - name: 'Install prerequisite: QT' - if: steps.qt-cache.outputs.cache-hit != 'true' - run: | - curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_${{ env.QT_VERSION }}.7z -f --retry 5 -C - - 7z x Qt_${{ env.QT_VERSION }}.7z -o"${{ github.workspace }}/cmbuild/QT" - - name: 'Install prerequisite: Pre-built dependencies' - if: steps.deps-cache.outputs.cache-hit != 'true' - run: | - curl -L -O https://github.com/obsproject/obs-deps/releases/download/win-${{ env.WINDOWS_DEPS_VERSION }}/windows-deps-${{ env.WINDOWS_DEPS_VERSION }}.zip --retry 5 -C - - 7z x windows-deps-${{ env.WINDOWS_DEPS_VERSION }}.zip -o"${{ github.workspace }}/cmbuild/deps" - - name: 'Install prerequisite: VLC' - if: steps.vlc-cache.outputs.cache-hit != 'true' - run: | - curl -kL https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -o vlc.zip - 7z x vlc.zip -o"${{ github.workspace }}/cmbuild/vlc" - - name: 'Install prerequisite: Chromium Embedded Framework' - if: steps.cef-cache.outputs.cache-hit != 'true' - run: | - curl -kL https://cdn-fastly.obsproject.com/downloads/cef_binary_${{ env.WINDOWS_CEF_BUILD_VERSION }}_windows_x64.zip -f --retry 5 -o cef.zip - 7z x cef.zip -o"${{ github.workspace }}/cmbuild" - - name: 'Configure' - run: | - mkdir ./build - mkdir ./build64 - cd ./build64 - cmake -G"${{ env.CMAKE_GENERATOR }}" -A"x64" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=true -DCOMPILE_D3D12_HOOK=true -DVLCPath="${{ github.workspace }}/cmbuild/vlc" -DDepsPath="${{ github.workspace }}/cmbuild/deps/win64" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2019_64" -DENABLE_VLC=ON -DCEF_ROOT_DIR="${{ github.workspace }}/cmbuild/cef_binary_${{ env.WINDOWS_CEF_BUILD_VERSION }}_windows_x64" -DTWITCH_CLIENTID='${{ env.TWITCH_CLIENTID }}' -DTWITCH_HASH='${{ env.TWITCH_HASH }}' -DRESTREAM_CLIENTID='${{ env.RESTREAM_CLIENTID }}' -DRESTREAM_HASH='${{ env.RESTREAM_HASH }}' -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE -DVIRTUALCAM_GUID=${{ env.VIRTUALCAM-GUID }} .. - - name: 'Build' - run: msbuild /m /p:Configuration=RelWithDebInfo .\build64\obs-studio.sln - - name: 'Package' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - run: | - $env:FILE_DATE=(Get-Date -UFormat "%F") - $env:FILE_NAME="${env:FILE_DATE}-${{ env.OBS_GIT_HASH }}-${{ env.OBS_GIT_TAG }}-win64" - echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV} - robocopy .\build64\rundir\RelWithDebInfo .\build\ /E /XF .gitignore - 7z - - name: 'Publish' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - uses: actions/upload-artifact@v2.2.0 - with: - name: '${{ env.FILE_NAME }}' - path: build/* - win32: - name: 'Windows 32-bit' - runs-on: [windows-2019] - env: - QT_VERSION: '5.15.2' - CMAKE_GENERATOR: "Visual Studio 16 2019" - CMAKE_SYSTEM_VERSION: "10.0.18363.657" - WINDOWS_DEPS_VERSION: '2022-01-31' - WINDOWS_DEPS_CACHE_VERSION: '1' - VIRTUALCAM-GUID: "A3FCE0F5-3493-419F-958A-ABA1250EC20B" - steps: + path: 'obs-studio' + fetch-depth: 0 + - name: 'Add msbuild to PATH' uses: microsoft/setup-msbuild@v1.0.2 - - name: 'Checkout' - uses: actions/checkout@v2.3.3 - with: - submodules: 'recursive' - - name: 'Fetch Git Tags' - shell: bash - run: | - git fetch --prune --unshallow - echo "OBS_GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "OBS_GIT_TAG=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV + - name: 'Check for Github Labels' if: github.event_name == 'pull_request' - shell: bash run: | - LABELS_URL="$(echo ${{ github.event.pull_request.url }} | sed s'/pulls/issues/')" - LABEL_FOUND="$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "${LABELS_URL}/labels" | sed -n 's/.*"name": "\(.*\)",/\1/p' | grep 'Seeking Testers' || true)" - if [ "${LABEL_FOUND}" = "Seeking Testers" ]; then - echo "SEEKING_TESTERS=1" >> $GITHUB_ENV - else - echo "SEEKING_TESTERS=0" >> $GITHUB_ENV - fi - - name: 'Restore QT dependency from cache' - id: qt-cache - uses: actions/cache@v2.1.2 - env: - CACHE_NAME: 'qt-cache' - with: - path: ${{ github.workspace }}/cmbuild/QT - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.QT_VERSION }} - - name: 'Restore pre-built dependencies from cache' - id: deps-cache - uses: actions/cache@v2.1.2 - env: - CACHE_NAME: 'deps-cache' - with: - path: ${{ github.workspace }}/cmbuild/deps - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.WINDOWS_DEPS_VERSION }}-${{ env.WINDOWS_DEPS_CACHE_VERSION }} + $LabelFound = try { (Invoke-RestMethod -Authentication 'Bearer' -Token (ConvertTo-SecureString '${{ secrets.GITHUB_TOKEN }}' -AsPlainText) -Uri "${{ github.event.pull_request.url }}" -UseBasicParsing).labels.name.contains("Seeking Testers") } catch { $false } + Write-Output "SEEKING_TESTERS=$(if( $LabelFound -eq $true ) { 1 } else { 0 })" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + - name: 'Restore VLC dependency from cache' id: vlc-cache uses: actions/cache@v2.1.2 env: CACHE_NAME: 'vlc-cache' with: - path: ${{ github.workspace }}/cmbuild/vlc - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.WINDOWS_VLC_VERSION }} - - name: 'Restore CEF dependency from cache (32 bit)' + path: ${{ github.workspace }}/obs-build-dependencies/vlc-${{ env.VLC_VERSION_WIN }} + key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.VLC_VERSION_WIN }} + + - name: 'Restore Chromium Embedded Framework from cache' id: cef-cache uses: actions/cache@v2.1.2 env: - CACHE_NAME: 'cef-32-cache' + CACHE_NAME: 'cef-cache' with: - path: ${{ github.workspace }}/cmbuild/cef_binary_${{ env.WINDOWS_CEF_BUILD_VERSION }}_windows_x86 - key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.WINDOWS_CEF_BUILD_VERSION }}-3 - - name: 'Install prerequisite: QT' - if: steps.qt-cache.outputs.cache-hit != 'true' + path: ${{ github.workspace }}/obs-build-dependencies/cef_binary_${{ env.CEF_BUILD_VERSION_WIN }}_windows${{ matrix.arch }}_minimal + key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.CEF_BUILD_VERSION_WIN }} + + - name: 'Install dependencies' + env: + RESTORED_VLC: ${{ steps.vlc-cache.outputs.cache-hit }} + RESTORED_CEF: ${{ steps.cef-cache.outputs.cache-hit }} + run: CI/windows/01_install_dependencies.ps1 -BuildArch ${{ matrix.arch }}-bit + + - name: 'Build OBS' + run: CI/windows/02_build_obs.ps1 -BuildArch ${{ matrix.arch }}-bit + + - name: 'Create build artifact' + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} run: | - curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_${{ env.QT_VERSION }}.7z -f --retry 5 -C - - 7z x Qt_${{ env.QT_VERSION }}.7z -o"${{ github.workspace }}/cmbuild/QT" - - name: 'Install prerequisite: Pre-built dependencies' - if: steps.deps-cache.outputs.cache-hit != 'true' - run: | - curl -L -O https://github.com/obsproject/obs-deps/releases/download/win-${{ env.WINDOWS_DEPS_VERSION }}/windows-deps-${{ env.WINDOWS_DEPS_VERSION }}.zip --retry 5 -C - - 7z x windows-deps-${{ env.WINDOWS_DEPS_VERSION }}.zip -o"${{ github.workspace }}/cmbuild/deps" - - name: 'Install prerequisite: VLC' - if: steps.vlc-cache.outputs.cache-hit != 'true' - run: | - curl -kL https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -o vlc.zip - 7z x vlc.zip -o"${{ github.workspace }}/cmbuild/vlc" - - name: 'Install prerequisite: Chromium Embedded Framework' - if: steps.cef-cache.outputs.cache-hit != 'true' - run: | - curl -kL https://cdn-fastly.obsproject.com/downloads/cef_binary_${{ env.WINDOWS_CEF_BUILD_VERSION }}_windows_x86.zip -f --retry 5 -o cef.zip - 7z x cef.zip -o"${{ github.workspace }}/cmbuild" - - name: 'Configure' - run: | - mkdir ./build - mkdir ./build32 - cd ./build32 - cmake -G"${{ env.CMAKE_GENERATOR }}" -A"Win32" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DENABLE_VLC=ON -DBUILD_BROWSER=true -DCOMPILE_D3D12_HOOK=true -DVLCPath="${{ github.workspace }}/cmbuild/vlc" -DDepsPath="${{ github.workspace }}/cmbuild/deps/win32" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2019" -DCEF_ROOT_DIR="${{ github.workspace }}/cmbuild/cef_binary_${{ env.WINDOWS_CEF_BUILD_VERSION }}_windows_x86" -DTWITCH_CLIENTID='${{ env.TWITCH_CLIENTID }}' -DTWITCH_HASH='${{ env.TWITCH_HASH }}' -DRESTREAM_CLIENTID='${{ env.RESTREAM_CLIENTID }}' -DRESTREAM_HASH='${{ env.RESTREAM_HASH }}' -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE -DVIRTUALCAM_GUID=${{ env.VIRTUALCAM-GUID }} .. - - name: 'Build' - run: msbuild /m /p:Configuration=RelWithDebInfo .\build32\obs-studio.sln - - name: 'Package' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - run: | - $env:FILE_DATE=(Get-Date -UFormat "%F") - $env:FILE_NAME="${env:FILE_DATE}-${{ env.OBS_GIT_HASH }}-${{ env.OBS_GIT_TAG }}-win32" - echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV} - robocopy .\build32\rundir\RelWithDebInfo .\build\ /E /XF .gitignore - 7z - - name: 'Publish' - if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') - uses: actions/upload-artifact@v2.2.0 + CI/windows/03_package_obs.ps1 -BuildArch ${{ matrix.arch }}-bit -Package + $ArtifactName = Get-ChildItem -filter "OBS-Studio-*-Win${{ matrix.arch }}.zip" -File + Write-Output "FILE_NAME=${ArtifactName}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + + - name: 'Upload build artifact' + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} + uses: actions/upload-artifact@v2 with: - name: '${{ env.FILE_NAME }}' - path: build/* + name: 'obs-win${{ matrix.arch }}' + path: '${{ env.FILE_NAME }}' + + linux_package: + name: '02 - Flatpak Bundle' + runs-on: [ubuntu-latest] + needs: [clang_check] + if: always() + defaults: + run: + shell: bash + container: + image: bilelmoussaoui/flatpak-github-actions:kde-5.15-21.08 + options: --privileged + steps: + - name: 'Check for Github Labels' + if: github.event_name == 'pull_request' + run: | + if ! /usr/bin/command -v "jq" >/dev/null 2>&1; then sudo dnf install -y -q jq; fi + if test -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')"; then + echo "SEEKING_TESTERS=1" >> $GITHUB_ENV + else + echo "SEEKING_TESTERS=0" >> $GITHUB_ENV + fi + + - name: 'Checkout' + uses: actions/checkout@v2.3.3 + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} + with: + submodules: 'recursive' + fetch-depth: 0 + + - name: 'Setup build environment' + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} + run: | + echo "OBS_GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV + echo "OBS_GIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + echo "OBS_GIT_TAG=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV + + - name: Build Flatpak Manifest + uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4 + if: ${{ success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1') }} + with: + bundle: obs-studio-${{ github.sha }}.flatpak + manifest-path: CI/flatpak/com.obsproject.Studio.json + cache-key: flatpak-builder-${{ github.sha }} + + windows_package: + name: '03 - Windows Installer' + runs-on: [windows-latest] + needs: [windows_build] + if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }} + env: + BUILD_FOR_DISTRIBUTION: 'ON' + steps: + - name: 'Checkout' + uses: actions/checkout@v2.3.3 + + - name: 'Add msbuild to PATH' + uses: microsoft/setup-msbuild@v1.0.2 + + - name: 'Download 64-bit artifact' + uses: actions/download-artifact@v2 + with: + name: 'obs-win64' + + - name: 'Download 32-bit artifact' + uses: actions/download-artifact@v2 + with: + name: 'obs-win32' + + - name: 'Unpack Windows build artifacts' + run: | + if (!(Test-Path install_temp)) { + $null = New-Item -ItemType Directory -Force -Path install_temp + } + + Expand-Archive -Path "$(Get-ChildItem -filter "OBS-Studio-*-Win32.zip" -File)" -DestinationPath install_temp + Expand-Archive -Path "$(Get-ChildItem -filter "OBS-Studio-*-Win64.zip" -File)" -Force -DestinationPath install_temp + + CI/windows/03_package_obs.ps1 -CombinedArchs -Package + + $ArtifactName = (Get-ChildItem -filter "OBS-Studio-*-Windows.zip" -File).Name + Write-Output "FILE_NAME=${ArtifactName}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + + - name: 'Upload build artifact' + uses: actions/upload-artifact@v2 + with: + name: 'obs-windows' + path: '${{ env.FILE_NAME }}' + + macos_release: + name: '03 - macOS notarized image' + runs-on: [macos-11] + needs: [macos_build] + env: + HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY != '' && secrets.MACOS_SIGNING_CERT != '' }} + BUILD_FOR_DISTRIBUTION: 'ON' + if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }} + strategy: + matrix: + arch: ['x86_64'] + defaults: + run: + shell: bash + steps: + - name: 'Checkout' + if: env.HAVE_CODESIGN_IDENTITY == 'true' + uses: actions/checkout@v2.3.3 + + - name: 'Download artifact' + if: env.HAVE_CODESIGN_IDENTITY == 'true' + uses: actions/download-artifact@v2 + with: + name: 'obs-macos-${{ matrix.arch }}' + + - name: 'Install Apple Developer Certificate' + if: env.HAVE_CODESIGN_IDENTITY == 'true' + uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071 + with: + p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }} + p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }} + + - name: 'Create disk image for distribution' + if: env.HAVE_CODESIGN_IDENTITY == 'true' + env: + CODESIGN_IDENT: ${{ secrets.MACOS_SIGNING_IDENTITY }} + CODESIGN_IDENT_USER: ${{ secrets.MACOS_NOTARIZATION_USERNAME }} + CODESIGN_IDENT_PASS: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }} + run: | + ARTIFACT_NAME=$(/usr/bin/find . -type f -name "obs-studio-*.dmg" -depth 1 | head -1) + CI/macos/03_package_obs.sh --notarize-image ${ARTIFACT_NAME} + + echo "FILE_NAME=$(basename ${ARTIFACT_NAME})" >> $GITHUB_ENV + + - name: 'Upload build Artifact' + if: env.HAVE_CODESIGN_IDENTITY == 'true' + uses: actions/upload-artifact@v2 + with: + name: 'obs-macos-${{ matrix.arch }}-notarized' + path: '${{ github.workspace }}/${{ env.FILE_NAME }}' diff --git a/.gitignore b/.gitignore index cf5e8c984..afcf382fc 100644 --- a/.gitignore +++ b/.gitignore @@ -21,9 +21,11 @@ *.ninja .ninja* .dirstamp +/cmake/.CMakeBuildNumber #xcode *.xcodeproj/ +/xcodebuild/ #clion .idea/ @@ -39,8 +41,7 @@ GeneratedFiles/ .moc/ /UI/obs.rc .vscode/ - - +/CI/include/*.lock.json /other/ diff --git a/CI/before-deploy-win.cmd b/CI/before-deploy-win.cmd deleted file mode 100644 index e9dcb48dd..000000000 --- a/CI/before-deploy-win.cmd +++ /dev/null @@ -1,3 +0,0 @@ -robocopy .\build32\rundir\RelWithDebInfo .\build\ /E /XF .gitignore -robocopy .\build64\rundir\RelWithDebInfo .\build\ /E /XC /XN /XO /XF .gitignore -7z a build.zip .\build\* \ No newline at end of file diff --git a/CI/before-script-linux.sh b/CI/before-script-linux.sh deleted file mode 100755 index 397810ef2..000000000 --- a/CI/before-script-linux.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -ex -ccache -s || echo "CCache is not available." -mkdir build && cd build -cmake -DENABLE_PIPEWIRE=OFF -DBUILD_BROWSER=ON -DCEF_ROOT_DIR="../cef_binary_${LINUX_CEF_BUILD_VERSION}_linux64" .. diff --git a/CI/build-freebsd.sh b/CI/build-freebsd.sh new file mode 100755 index 000000000..36b615a4c --- /dev/null +++ b/CI/build-freebsd.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +############################################################################## +# FreeBSD full build script +############################################################################## +# +# This script contains all steps necessary to: +# +# * Build OBS with all default plugins and dependencies +# * Package a FreeBSD package +# +# Parameters: +# -h, --help : Print usage help +# -q, --quiet : Suppress most build process output +# -v, --verbose : Enable more verbose build process output +# -d, --skip-dependency-checks : Skip dependency checks (default: off) +# -p, --portable : Create portable build (default: off) +# -pkg, --package : Create distributable archive +# (default: off) +# --build-dir : Specify alternative build directory +# (default: build)" +# +############################################################################## + +# Halt on errors +set -eE + +## SET UP ENVIRONMENT ## +_RUN_OBS_BUILD_SCRIPT=TRUE +PRODUCT_NAME="OBS-Studio" + +CHECKOUT_DIR="$(git rev-parse --show-toplevel)" +DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" +source "${CHECKOUT_DIR}/CI/include/build_support.sh" +source "${CHECKOUT_DIR}/CI/include/build_support_freebsd.sh" + +## DEPENDENCY INSTALLATION +source "${CHECKOUT_DIR}/CI/freebsd/01_install_dependencies.sh" + +## BUILD OBS ## +source "${CHECKOUT_DIR}/CI/freebsd/02_build_obs.sh" + +## PACKAGE OBS AND NOTARIZE ## +source "${CHECKOUT_DIR}/CI/freebsd/03_package_obs.sh" + +## MAIN SCRIPT FUNCTIONS ## +print_usage() { + echo "build-linux.sh - Build script for OBS-Studio\n" + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-d, --skip-dependency-checks : Skip dependency checks (default: off)\n" \ + "-p, --portable : Create portable build (default: off)\n" \ + "-pkg, --package : Create distributable disk image (default: off)\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +obs-build-main() { + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -d | --skip-dependency-checks ) SKIP_DEP_CHECKS=TRUE; shift ;; + -p | --portable ) PORTABLE=TRUE; shift ;; + -pkg | --package ) PACKAGE=TRUE; shift ;; + --disable-pipewire ) DISABLE_PIPEWIRE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + ensure_dir "${CHECKOUT_DIR}" + step "Fetching OBS tags..." + git fetch origin --tags + + GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + GIT_HASH=$(git rev-parse --short HEAD) + GIT_TAG=$(git describe --tags --abbrev=0) + + FILE_NAME="obs-studio-${GIT_TAG}-${GIT_HASH}-FreeBSD" + + if [ -z "${SKIP_DEP_CHECKS}" ]; then + install_dependencies + fi + + build_obs + + if [ "${PACKAGE}" ]; then + package_obs + fi + + cleanup +} + +obs-build-main $* diff --git a/CI/build-linux.sh b/CI/build-linux.sh new file mode 100755 index 000000000..dbeb15907 --- /dev/null +++ b/CI/build-linux.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +############################################################################## +# Linux full build script +############################################################################## +# +# This script contains all steps necessary to: +# +# * Build OBS with all default plugins and dependencies +# * Package a Linux deb package +# +# Parameters: +# -h, --help : Print usage help +# -q, --quiet : Suppress most build process output +# -v, --verbose : Enable more verbose build process output +# -d, --skip-dependency-checks : Skip dependency checks (default: off) +# -p, --portable : Create portable build (default: off) +# -pkg, --package : Create distributable disk image +# (default: off) +# --build-dir : Specify alternative build directory +# (default: build)" +# +############################################################################## + +# Halt on errors +set -eE + +## SET UP ENVIRONMENT ## +_RUN_OBS_BUILD_SCRIPT=TRUE +PRODUCT_NAME="OBS-Studio" + +CHECKOUT_DIR="$(git rev-parse --show-toplevel)" +DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" +source "${CHECKOUT_DIR}/CI/include/build_support.sh" +source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh" + +## DEPENDENCY INSTALLATION +source "${CHECKOUT_DIR}/CI/linux/01_install_dependencies.sh" + +## BUILD OBS ## +source "${CHECKOUT_DIR}/CI/linux/02_build_obs.sh" + +## PACKAGE OBS AND NOTARIZE ## +source "${CHECKOUT_DIR}/CI/linux/03_package_obs.sh" + +## MAIN SCRIPT FUNCTIONS ## +print_usage() { + echo "build-linux.sh - Build script for OBS-Studio\n" + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-d, --skip-dependency-checks : Skip dependency checks (default: off)\n" \ + "-p, --portable : Create portable build (default: off)\n" \ + "-pkg, --package : Create distributable disk image (default: off)\n" \ + "--disable-pipewire : Disable building with Pipewire support (default: off)\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +obs-build-main() { + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -d | --skip-dependency-checks ) SKIP_DEP_CHECKS=TRUE; shift ;; + -p | --portable ) PORTABLE=TRUE; shift ;; + -pkg | --package ) PACKAGE=TRUE; shift ;; + --disable-pipewire ) DISABLE_PIPEWIRE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + ensure_dir "${CHECKOUT_DIR}" + step "Fetching OBS tags..." + git fetch origin --tags + + GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + GIT_HASH=$(git rev-parse --short HEAD) + GIT_TAG=$(git describe --tags --abbrev=0) + + if [ "${BUILD_FOR_DISTRIBUTION}" ]; then + VERSION_STRING="${GIT_TAG}" + else + VERSION_STRING="${GIT_TAG}-${GIT_HASH}" + fi + + FILE_NAME="obs-studio-${VERSION_STRING}-Linux.deb" + + if [ -z "${SKIP_DEP_CHECKS}" ]; then + install_dependencies + fi + + build_obs + + if [ "${PACKAGE}" ]; then + package_obs + fi + + cleanup +} + +obs-build-main $* diff --git a/CI/build-macos.sh b/CI/build-macos.sh new file mode 100755 index 000000000..6c2b1ec54 --- /dev/null +++ b/CI/build-macos.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +############################################################################## +# macOS build script +############################################################################## +# +# This script contains all steps necessary to: +# +# * Build OBS with all default plugins and dependencies +# * Create a macOS application bundle +# * Codesign the macOS application bundle +# * Package a macOS installation image +# * Notarize macOS application bundle and/or installation image +# +# Parameters: +# -h, --help : Print usage help +# -q, --quiet : Suppress most build process output +# -v, --verbose : Enable more verbose build process output +# -d, --skip-dependency-checks : Skip dependency checks (default: off) +# -b, --bundle : Create relocatable application bundle +# (default: off) +# -p, --package : Create distributable disk image +# (default: off) +# -c, --codesign : Codesign OBS and all libraries +# (default: ad-hoc only) +# -n, --notarize : Notarize OBS (default: off) +# --xcode : Create Xcode build environment instead +# of Ninja +# --build-dir : Specify alternative build directory +# (default: build)" +# Environment Variables (optional): +# +# MACOS_DEPS_VERSION : Precompiled macOS dependencies version +# MACOS_CEF_BUILD_VERSION : Chromium Embedded Framework version +# VLC_VERSION : VLC version +# SPARKLE_VERSION : Sparkle Framework version +# +############################################################################## + +# Halt on errors +set -eE + +## SET UP ENVIRONMENT ## +_RUN_OBS_BUILD_SCRIPT=TRUE +PRODUCT_NAME="OBS-Studio" + +CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)" +DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" +source "${CHECKOUT_DIR}/CI/include/build_support.sh" +source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh" + +## INSTALL DEPENDENCIES ## +source "${CHECKOUT_DIR}/CI/macos/01_install_dependencies.sh" + +## BUILD OBS ## +source "${CHECKOUT_DIR}/CI/macos/02_build_obs.sh" + +## PACKAGE OBS AND NOTARIZE ## +source "${CHECKOUT_DIR}/CI/macos/03_package_obs.sh" + +## MAIN SCRIPT FUNCTIONS ## +print_usage() { + echo "build-macos.sh - Build script for OBS-Studio" + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-d, --skip-dependency-checks : Skip dependency checks (default: off)\n" \ + "-b, --bundle : Create relocatable application bundle (default: off)\n" \ + "-p, --package : Create distributable disk image (default: off)\n" \ + "-c, --codesign : Codesign OBS and all libraries (default: ad-hoc only)\n" \ + "-n, --notarize : Notarize OBS (default: off)\n" \ + "--xcode : Create Xcode build environment instead of Ninja\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +print_deprecation() { + echo -e "DEPRECATION ERROR:\n" \ + "The '${1}' switch has been deprecated!\n" + + if [ "${1}" = "-s" ]; then + echo -e "The macOS build script system has changed:\n" \ + " - To configure and build OBS, run the script 'CI/macos/02_build_obs.sh'\n" \ + " - To bundle OBS into a relocatable application bundle, run the script 'CI/macos/02_build_obs.sh --bundle\n" \ + " - To package OBS, run the script 'CI/macos/03_package_obs.sh'\n" \ + " - To notarize OBS, run the script 'CI/macos/03_package_obs.sh --notarize'\n" + fi + +} + +obs-build-main() { + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -d | --skip-dependency-checks ) SKIP_DEP_CHECKS=TRUE; shift ;; + -p | --package ) PACKAGE=TRUE; shift ;; + -c | --codesign ) CODESIGN=TRUE; shift ;; + -n | --notarize ) NOTARIZE=TRUE; PACKAGE=TRUE CODESIGN=TRUE; shift ;; + -b | --bundle ) BUNDLE=TRUE; shift ;; + --xcode ) XCODE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -s ) print_deprecation ${1}; exit 1 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + ensure_dir "${CHECKOUT_DIR}" + check_archs + check_macos_version + step "Fetching OBS tags..." + /usr/bin/git fetch origin --tags + + GIT_BRANCH=$(/usr/bin/git rev-parse --abbrev-ref HEAD) + GIT_HASH=$(/usr/bin/git rev-parse --short HEAD) + GIT_TAG=$(/usr/bin/git describe --tags --abbrev=0) + + if [ "${BUILD_FOR_DISTRIBUTION}" ]; then + VERSION_STRING="${GIT_TAG}" + else + VERSION_STRING="${GIT_TAG}-${GIT_HASH}" + fi + + if [ "${ARCH}" = "arm64" ]; then + FILE_NAME="obs-studio-${VERSION_STRING}-macOS-Apple.dmg" + elif [ "${ARCH}" = "universal" ]; then + FILE_NAME="obs-studio-${VERSION_STRING}-macOS.dmg" + else + FILE_NAME="obs-studio-${VERSION_STRING}-macOS-Intel.dmg" + fi + + if [ -z "${SKIP_DEP_CHECKS}" ]; then + install_dependencies + fi + + build_obs + + if [ "${BUNDLE}" ]; then + bundle_obs + fi + + if [ "${PACKAGE}" ]; then + package_obs + fi + + if [ "${NOTARIZE}" ]; then + notarize_obs + fi + + cleanup +} + +obs-build-main $* diff --git a/CI/build-windows.ps1 b/CI/build-windows.ps1 new file mode 100644 index 000000000..b4e882871 --- /dev/null +++ b/CI/build-windows.ps1 @@ -0,0 +1,137 @@ +Param( + [Switch]$Help, + [Switch]$Quiet, + [Switch]$Verbose, + [Switch]$Package, + [Switch]$SkipDependencyChecks, + [Switch]$BuildInstaller, + [Switch]$CombinedArchs, + [String]$BuildDirectory = "build", + [ValidateSet("32-bit", "64-bit")] + [String]$BuildArch = (Get-CimInstance CIM_OperatingSystem).OSArchitecture, + [ValidateSet("Release", "RelWithDebInfo", "MinSizeRel", "Debug")] + [String]$BuildConfiguration = "RelWithDebInfo" +) + +############################################################################## +# Windows OBS build script +############################################################################## +# +# This script contains all steps necessary to: +# +# * Build OBS with all required dependencies +# * Create 64-bit and 32-bit variants +# +# Parameters: +# -Help : Print usage help +# -Quiet : Suppress most build process output +# -Verbose : Enable more verbose build process output +# -SkipDependencyChecks : Skip dependency checks +# -BuildDirectory : Directory to use for builds +# Default: build64 on 64-bit systems +# build32 on 32-bit systems +# -BuildArch : Build architecture to use ("32-bit" or "64-bit") +# -BuildConfiguration : Build configuration to use +# Default: RelWithDebInfo +# -CombinedArchs : Create combined packages and installer +# (64-bit and 32-bit) - Default: off +# -Package : Prepare folder structure for installer creation +# +# Environment Variables (optional): +# WindowsDepsVersion : Pre-compiled Windows dependencies version +# WindowsQtVersion : Pre-compiled Qt version +# +############################################################################## + +$ErrorActionPreference = "Stop" + +$_RunObsBuildScript = $true +$ProductName = "OBS-Studio" + +$CheckoutDir = Resolve-Path -Path "$PSScriptRoot\.." +$DepsBuildDir = "${CheckoutDir}/../obs-build-dependencies" +$ObsBuildDir = "${CheckoutDir}/../obs-studio" + +. ${CheckoutDir}/CI/include/build_support_windows.ps1 + +# Handle installation of build system components and build dependencies +. ${CheckoutDir}/CI/windows/01_install_dependencies.ps1 + +# Handle OBS build configuration +. ${CheckoutDir}/CI/windows/02_build_obs.ps1 + +# Handle packaging +. ${CheckoutDir}/CI/windows/03_package_obs.ps1 + +function Build-OBS-Main { + Ensure-Directory ${CheckoutDir} + Write-Step "Fetching version tags..." + $null = git fetch origin --tags + $GitBranch = git rev-parse --abbrev-ref HEAD + $GitHash = git rev-parse --short HEAD + $ErrorActionPreference = "SilentlyContinue" + $GitTag = git describe --tags --abbrev=0 + $ErrorActionPreference = "Stop" + + if(Test-Path variable:BUILD_FOR_DISTRIBUTION) { + $VersionString = "${GitTag}" + } else { + $VersionString = "${GitTag}-${GitHash}" + } + + $FileName = "${ProductName}-${VersionString}" + + if($CombinedArchs.isPresent) { + if (!(Test-Path env:obsInstallerTempDir)) { + $Env:obsInstallerTempDir = "${CheckoutDir}/install_temp" + } + + if(!($SkipDependencyChecks.isPresent)) { + Install-Dependencies -BuildArch 64-bit + } + + Build-OBS -BuildArch 64-bit + + if(!($SkipDependencyChecks.isPresent)) { + Install-Dependencies -BuildArch 32-bit + } + + Build-OBS -BuildArch 32-bit + } else { + if(!($SkipDependencyChecks.isPresent)) { + Install-Dependencies + } + + Build-OBS + } + + if($Package.isPresent) { + Package-OBS -CombinedArchs:$CombinedArchs + } +} + +## MAIN SCRIPT FUNCTIONS ## +function Print-Usage { + Write-Host "build-windows.ps1 - Build script for ${ProductName}" + $Lines = @( + "Usage: ${_ScriptName}", + "-Help : Print this help", + "-Quiet : Suppress most build process output" + "-Verbose : Enable more verbose build process output" + "-SkipDependencyChecks : Skip dependency checks - Default: off", + "-BuildDirectory : Directory to use for builds - Default: build64 on 64-bit systems, build32 on 32-bit systems", + "-BuildArch : Build architecture to use ('32-bit' or '64-bit') - Default: local architecture", + "-BuildConfiguration : Build configuration to use - Default: RelWithDebInfo", + "-CombinedArchs : Create combined packages and installer (64-bit and 32-bit) - Default: off" + "-Package : Prepare folder structure for installer creation" + ) + $Lines | Write-Host +} + +$_ScriptName = "$($MyInvocation.MyCommand.Name)" +if($Help.isPresent) { + Print-Usage + exit 0 +} + +Build-OBS-Main diff --git a/CI/check-changes.sh b/CI/check-changes.sh new file mode 100755 index 000000000..7642c190a --- /dev/null +++ b/CI/check-changes.sh @@ -0,0 +1,11 @@ +#!/bin/bash +dirty=$(git ls-files --modified) + +set +x +if [[ $dirty ]]; then + echo "=================================" + echo "Files were not formatted properly" + echo "$dirty" + echo "=================================" + exit 1 +fi \ No newline at end of file diff --git a/CI/check-cmake.sh b/CI/check-cmake.sh new file mode 100755 index 000000000..8879ea91e --- /dev/null +++ b/CI/check-cmake.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +set -o errexit +set -o pipefail + +if [ ${#} -eq 1 -a "${1}" = "VERBOSE" ]; then + VERBOSITY="-l debug" +else + VERBOSITY="" +fi + +if [ "${CI}" ]; then + MODE="--check" +else + MODE="-i" +fi + +# Runs the formatter in parallel on the code base. +# Return codes: +# - 1 there are files to be formatted +# - 0 everything looks fine + +# Get CPU count +OS=$(uname) +NPROC=1 +if [[ ${OS} = "Linux" ]] ; then + NPROC=$(nproc) +elif [[ ${OS} = "Darwin" ]] ; then + NPROC=$(sysctl -n hw.physicalcpu) +fi + +# Discover clang-format +if ! type cmake-format 2> /dev/null ; then + echo "Required cmake-format not found" + exit 1 +fi + +find . -type d \( \ + -path ./\*build -o \ + -path ./deps/jansson -o \ + -path ./plugins/decklink/\*/decklink-sdk -o \ + -path ./plugins/enc-amf -o \ + -path ./plugins/mac-syphon/syphon-framework -o \ + -path ./plugins/obs-outputs/ftl-sdk -o \ + -path ./plugins/obs-vst -o \ + -path ./plugins/obs-browser -o \ + -path ./plugins/win-dshow/libdshowcapture \ +\) -prune -false -type f -o \ + -name 'CMakeLists.txt' -or \ + -name '*.cmake' \ + | xargs -L10 -P ${NPROC} cmake-format ${MODE} ${VERBOSITY} diff --git a/CI/check-format.sh b/CI/check-format.sh index 7642c190a..50d542558 100755 --- a/CI/check-format.sh +++ b/CI/check-format.sh @@ -1,11 +1,60 @@ -#!/bin/bash -dirty=$(git ls-files --modified) +#!/usr/bin/env bash +# Original source https://github.com/Project-OSRM/osrm-backend/blob/master/scripts/format.sh -set +x -if [[ $dirty ]]; then - echo "=================================" - echo "Files were not formatted properly" - echo "$dirty" - echo "=================================" +set -o errexit +set -o pipefail +set -o nounset + +if [ ${#} -eq 1 ]; then + VERBOSITY="--verbose" +else + VERBOSITY="" +fi + +# Runs the Clang Formatter in parallel on the code base. +# Return codes: +# - 1 there are files to be formatted +# - 0 everything looks fine + +# Get CPU count +OS=$(uname) +NPROC=1 +if [[ ${OS} = "Linux" ]] ; then + NPROC=$(nproc) +elif [[ ${OS} = "Darwin" ]] ; then + NPROC=$(sysctl -n hw.physicalcpu) +fi + +# Discover clang-format +if type clang-format-12 2> /dev/null ; then + CLANG_FORMAT=clang-format-12 +elif type clang-format 2> /dev/null ; then + # Clang format found, but need to check version + CLANG_FORMAT=clang-format + V=$(clang-format --version) + if [[ $V != *"version 12.0"* ]]; then + echo "clang-format is not 12.0 (returned ${V})" + exit 1 + fi +else + echo "No appropriate clang-format found (expected clang-format-12.0.0, or clang-format)" exit 1 -fi \ No newline at end of file +fi + +find . -type d \( \ + -path ./\*build -o \ + -path ./cmake -o \ + -path ./deps -o \ + -path ./plugins/decklink/\*/decklink-sdk -o \ + -path ./plugins/enc-amf -o \ + -path ./plugins/mac-syphon/syphon-framework -o \ + -path ./plugins/obs-outputs/ftl-sdk -o \ + -path ./plugins/obs-vst \ +\) -prune -false -type f -o \ + -name '*.h' -or \ + -name '*.hpp' -or \ + -name '*.m' -or \ + -name '*.m,' -or \ + -name '*.c' -or \ + -name '*.cpp' \ + | xargs -L100 -P ${NPROC} ${CLANG_FORMAT} ${VERBOSITY} -i -style=file -fallback-style=none diff --git a/CI/flatpak/com.obsproject.Studio.json b/CI/flatpak/com.obsproject.Studio.json index 3cb6dded8..d989b1cc1 100644 --- a/CI/flatpak/com.obsproject.Studio.json +++ b/CI/flatpak/com.obsproject.Studio.json @@ -416,13 +416,14 @@ "config-opts": [ "-DCMAKE_BUILD_TYPE=Release", "-DENABLE_WAYLAND=ON", - "-DBUILD_BROWSER=ON", + "-DENABLE_BROWSER_SOURCE=ON", "-DCEF_ROOT_DIR=/app/cef", - "-DUNIX_STRUCTURE=ON", "-DUSE_XDG=ON", - "-DDISABLE_ALSA=ON", + "-DENABLE_ALSA=OFF", "-DENABLE_PULSEAUDIO=ON", - "-DWITH_RTMPS=ON" + "-DENABLE_RTMPS=ON", + "-DENABLE_VLC=OFF", + "-DENABLE_AJA=OFF" ], "secret-opts": [ "-DRESTREAM_CLIENTID=$RESTREAM_CLIENTID", diff --git a/CI/freebsd/01_install_dependencies.sh b/CI/freebsd/01_install_dependencies.sh new file mode 100644 index 000000000..203ebbea5 --- /dev/null +++ b/CI/freebsd/01_install_dependencies.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +############################################################################## +# FreeBSD dependency management function +############################################################################## +# +# This script file can be included in build scripts or run directly +# +############################################################################## + +# Halt on errors +set -eE + +install_build-deps() { + shift + status "Install OBS build dependencies" + trap "caught_error 'install_build-deps'" ERR + + sudo pkg install -U -y $@ +} + +install_obs-deps() { + shift + status "Install OBS dependencies" + trap "caught_error 'install_obs-deps'" ERR + + sudo pkg install -U -y $@ +} + +install_qt-deps() { + shift + status "Install Qt dependencies" + trap "caught_error 'install_qt-deps'" ERR + + sudo pkg install -U -y $@ +} + +install_plugin-deps() { + shift + status "Install plugin dependencies" + trap "caught_error 'install_plugin-deps'" ERR + + sudo pkg install -U -y $@ +} + +install_dependencies() { + status "Set up apt" + trap "caught_error 'install_dependencies'" ERR + + BUILD_DEPS=( + "build-deps cmake ninja pkgconf curl ccache" + "obs-deps ffmpeg libx264 mbedtls mesa-libs jansson lua52 luajit python37 libX11 xorgproto libxcb \ + libXcomposite libXext libXfixes libXinerama libXrandr swig dbus jansson libICE libSM libsysinfo" + "qt-deps qt5-buildtools qt5-qmake qt5-imageformats qt5-core qt5-gui qt5-svg qt5-widgets qt5-xml" + "plugin-deps v4l_compat fdk-aac fontconfig freetype2 speexdsp libudev-devd libv4l vlc audio/jack pulseaudio sndio" + ) + + for DEPENDENCY in "${BUILD_DEPS[@]}"; do + set -- ${DEPENDENCY} + trap "caught_error ${DEPENDENCY}" ERR + FUNC_NAME="install_${1}" + ${FUNC_NAME} ${@} + done +} + +install-dependencies-standalone() { + CHECKOUT_DIR="$(git rev-parse --show-toplevel)" + PRODUCT_NAME="OBS-Studio" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_freebsd.sh" + + status "Setup of OBS build dependencies" + install_dependencies +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" +} + +install-dependencies-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + install-dependencies-standalone + fi +} + +install-dependencies-main $* diff --git a/CI/freebsd/02_build_obs.sh b/CI/freebsd/02_build_obs.sh new file mode 100644 index 000000000..d2d5e4723 --- /dev/null +++ b/CI/freebsd/02_build_obs.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +############################################################################## +# FreeBSD build function +############################################################################## +# +# This script file can be included in build scripts for FreeBSD or run +# directly +# +############################################################################## + +# Halt on errors +set -eE + +build_obs() { + status "Build OBS" + if [ -z "${CI}" ]; then + _backup_artifacts + fi + + step "Configure OBS..." + _configure_obs + + ensure_dir "${CHECKOUT_DIR}/" + step "Build OBS targets..." + cmake --build ${BUILD_DIR} +} + +# Function to configure OBS build +_configure_obs() { + ensure_dir "${CHECKOUT_DIR}" + status "Configuration of OBS build system..." + check_ccache + + if [ "${TWITCH_CLIENTID}" -a "${TWICH_HASH}" ]; then + TWITCH_OPTIONS="-DTWITCH_CLIENTID=\"${TWITCH_CLIENTID}\" -DTWITCH_HASH=\"${TWITCH_HASH}\"" + fi + + if [ "${RESTREAM_CLIENTID}" -a "${RESTREAM_HASH}" ]; then + RESTREAM_OPTIONS="-DRESTREAM_CLIENTID=\"${RESTREAM_CLIENTID}\" -DRESTREAM_HASH=\"${RESTREAM_HASH}\"" + fi + + if [ "${YOUTUBE_CLIENTID}" -a "${YOUTUBE_CLIENTID_HASH}" -a "${YOUTUBE_SECRET}" -a "{YOUTUBE_SECRET_HASH}" ]; then + YOUTUBE_OPTIONS="-DYOUTUBE_CLIENTID=\"${YOUTUBE_CLIENTID}\" -DYOUTUBE_CLIENTID_HASH=\"${YOUTUBE_CLIENTID_HASH}\" -DYOUTUBE_SECRET=\"${YOUTUBE_SECRET}\" -DYOUTUBE_SECRET_HASH=\"${YOUTUBE_SECRET_HASH}\"" + fi + + if [ "${PORTABLE}" ]; then + PORTABLE_BUILD="ON" + fi + + cmake -S . -B ${BUILD_DIR} -G Ninja \ + -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \ + -DLINUX_PORTABLE=${PORTABLE_BUILD:-OFF} \ + -DENABLE_PIPEWIRE=OFF \ + ${CCACHE_OPTIONS} \ + ${TWITCH_OPTIONS} \ + ${YOUTUBE_OPTIONS} \ + ${RESTREAM_OPTIONS} \ + ${CI:+-DENABLE_UNIT_TESTS=ON -DBUILD_FOR_DISTRIBUTION=${BUILD_FOR_DISTRIBUTION} -DOBS_BUILD_NUMBER=${GITHUB_RUN_ID}} \ + ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR} +} + +# Function to backup previous build artifacts +_backup_artifacts() { + ensure_dir "${CHECKOUT_DIR}" + if [ -d "${BUILD_DIR}" ]; then + status "Backup of old OBS build artifacts" + + CUR_DATE=$(/bin/date +"%Y-%m-%d@%H%M%S") + NIGHTLY_DIR="${CHECKOUT_DIR}/nightly-${CUR_DATE}" + PACKAGE_NAME=$(/usr/bin/find ${BUILD_DIR} -maxdepth 1 -name "*.tar.gz" | sort -rn | head -1) + + if [ "${PACKAGE_NAME}" ]; then + step "Back up $(basename "${PACKAGE_NAME}")..." + ensure_dir "${NIGHTLY_DIR}" + ensure_dir "${CHECKOUT_DIR}" + /usr/bin/find "${BUILD_DIR}" -maxdepth 1 \( -name "obs-studio-*.sh" -o -name "obs-studio-*.tar.gz" -o -name "obs-studio-*.tar.Z" \) -print0 | /usr/bin/xargs -0 -I {} /bin/mv {} ${NIGHTLY_DIR}/ + info "You can find $(basename "${PACKAGE_NAME}") in ${NIGHTLY_DIR}" + fi + fi +} + +build-obs-standalone() { + CHECKOUT_DIR="$(git rev-parse --show-toplevel)" + PRODUCT_NAME="OBS-Studio" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_freebsd.sh" + + build_obs +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-p, --portable : Create portable build (default: off)\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +build-obs-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -p | --portable ) export PORTABLE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + build-obs-standalone + fi +} + +build-obs-main $* diff --git a/CI/freebsd/03_package_obs.sh b/CI/freebsd/03_package_obs.sh new file mode 100644 index 000000000..351a0623a --- /dev/null +++ b/CI/freebsd/03_package_obs.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +############################################################################## +# FreeBSD OBS package function +############################################################################## +# +# This script file can be included in build scripts for FreeBSD or run directly +# +############################################################################## + +# Halt on errors +set -eE + +package_obs() { + status "Create FreeBSD debian package" + trap "caught_error 'package app'" ERR + + ensure_dir "${CHECKOUT_DIR}" + + step "Package OBS..." + cmake --build ${BUILD_DIR} -t package + + ZIP_NAME="$(/usr/bin/find "${BUILD_DIR}" -maxdepth 1 -type f -name "obs-studio-*.sh" | sort -rn | head -1)" + + if [ "${ZIP_NAME}" ]; then + mv "${ZIP_NAME%.*}.sh" "${BUILD_DIR}/${FILE_NAME}.sh" + mv "${ZIP_NAME%.*}.tar.gz" "${BUILD_DIR}/${FILE_NAME}.tar.gz" + mv "${ZIP_NAME%.*}.tar.Z" "${BUILD_DIR}/${FILE_NAME}.tar.Z" + else + error "ERROR No suitable OBS debian package generated" + fi +} + +package-obs-standalone() { + PRODUCT_NAME="OBS-Studio" + + CHECKOUT_DIR="$(git rev-parse --show-toplevel)" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source ${CHECKOUT_DIR}/CI/include/build_support.sh + source ${CHECKOUT_DIR}/CI/include/build_support_freebsd.sh + + step "Fetch OBS tags..." + git fetch origin --tags + + GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + GIT_HASH=$(git rev-parse --short HEAD) + GIT_TAG=$(git describe --tags --abbrev=0) + + FILE_NAME="obs-studio-${GIT_TAG}-${GIT_HASH}-FreeBSD" + package_obs +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +package-obs-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + package-obs-standalone + fi +} + +package-obs-main $* diff --git a/CI/full-build-macos.sh b/CI/full-build-macos.sh deleted file mode 100755 index a0c0e6973..000000000 --- a/CI/full-build-macos.sh +++ /dev/null @@ -1,726 +0,0 @@ -#!/bin/bash - -############################################################################## -# macOS full build script -############################################################################## -# -# This script contains all steps necessary to: -# -# * Build OBS with all default plugins and dependencies -# * Create a macOS application bundle -# * Code-sign the macOS application-bundle -# * Package a macOS installation image -# * Notarize macOS application-bundle and/or installation image -# -# Parameters: -# -b: Create macOS bundle -# -d: Skip dependency checks -# -p: Create macOS distribution image -# -n: Notarize macOS app and disk image (implies bundling) -# -s: Skip the build process (useful for bundling/packaging only) -# -h: Print usage help -# -# Environment Variables (optional): -# MACOS_DEPS_VERSION : Pre-compiled macOS dependencies version -# MACOS_CEF_BUILD_VERSION : Chromium Embedded Framework version -# VLC_VERISON : VLC version -# SPARKLE_VERSION : Sparke Framework version -# BUILD_DIR : Alternative directory to build OBS in -# -############################################################################## - -# Halt on errors -set -eE - -## SET UP ENVIRONMENT ## -PRODUCT_NAME="OBS-Studio" - -CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)" -DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" -BUILD_DIR="${BUILD_DIR:-build}" -BUILD_CONFIG=${BUILD_CONFIG:-RelWithDebInfo} -CI_SCRIPTS="${CHECKOUT_DIR}/CI/scripts/macos" -CI_WORKFLOW="${CHECKOUT_DIR}/.github/workflows/main.yml" -CI_MACOS_CEF_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+MACOS_CEF_BUILD_VERSION: '([0-9]+)'/\1/p") -CI_DEPS_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+MACOS_DEPS_VERSION: '([0-9\-]+)'/\1/p") -CI_VLC_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+VLC_VERSION: '([0-9\.]+)'/\1/p") -CI_SPARKLE_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+SPARKLE_VERSION: '([0-9\.]+)'/\1/p") -CI_QT_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+QT_VERSION: '([0-9\.]+)'/\1/p" | /usr/bin/head -1) -CI_MIN_MACOS_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+MIN_MACOS_VERSION: '([0-9\.]+)'/\1/p") -NPROC="${NPROC:-$(sysctl -n hw.ncpu)}" -CURRENT_ARCH=$(uname -m) - -BUILD_DEPS=( - "obs-deps ${MACOS_DEPS_VERSION:-${CI_DEPS_VERSION}}" - "qt-deps ${QT_VERSION:-${CI_QT_VERSION}} ${MACOS_DEPS_VERSION:-${CI_DEPS_VERSION}}" - "cef ${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" - "vlc ${VLC_VERSION:-${CI_VLC_VERSION}}" - "sparkle ${SPARKLE_VERSION:-${CI_SPARKLE_VERSION}}" -) - -if [ -n "${TERM-}" ]; then - COLOR_RED=$(/usr/bin/tput setaf 1) - COLOR_GREEN=$(/usr/bin/tput setaf 2) - COLOR_BLUE=$(/usr/bin/tput setaf 4) - COLOR_ORANGE=$(/usr/bin/tput setaf 3) - COLOR_RESET=$(/usr/bin/tput sgr0) -else - COLOR_RED="" - COLOR_GREEN="" - COLOR_BLUE="" - COLOR_ORANGE="" - COLOR_RESET="" -fi - - -MACOS_VERSION="$(/usr/bin/sw_vers -productVersion)" -MACOS_MAJOR="$(/bin/echo ${MACOS_VERSION} | /usr/bin/cut -d '.' -f 1)" -MACOS_MINOR="$(/bin/echo ${MACOS_VERSION} | /usr/bin/cut -d '.' -f 2)" - -## DEFINE UTILITIES ## - -hr() { - /bin/echo "${COLOR_BLUE}[${PRODUCT_NAME}] ${1}${COLOR_RESET}" -} - -step() { - /bin/echo "${COLOR_GREEN} + ${1}${COLOR_RESET}" -} - -info() { - /bin/echo "${COLOR_ORANGE} + ${1}${COLOR_RESET}" -} - -error() { - /bin/echo "${COLOR_RED} + ${1}${COLOR_RESET}" -} - -exists() { - /usr/bin/command -v "$1" >/dev/null 2>&1 -} - -ensure_dir() { - [[ -n "${1}" ]] && /bin/mkdir -p "${1}" && builtin cd "${1}" -} - -cleanup() { - /bin/rm -rf "${CHECKOUT_DIR}/${BUILD_DIR}/settings.json" - unset CODESIGN_IDENT - unset CODESIGN_IDENT_USER - unset CODESIGN_IDENT_PASS -} - -caught_error() { - error "ERROR during build step: ${1}" - cleanup - exit 1 -} - -## CHECK AND INSTALL DEPENDENCIES ## -check_macos_version() { - MIN_VERSION=${MIN_MACOS_VERSION:-${CI_MIN_MACOS_VERSION}} - MIN_MAJOR=$(/bin/echo ${MIN_VERSION} | /usr/bin/cut -d '.' -f 1) - MIN_MINOR=$(/bin/echo ${MIN_VERSION} | /usr/bin/cut -d '.' -f 2) - - if [ "${MACOS_MAJOR}" -lt "11" ] && [ "${MACOS_MINOR}" -lt "${MIN_MINOR}" ]; then - error "WARNING: Minimum required macOS version is ${MIN_VERSION}, but running on ${MACOS_VERSION}" - fi -} - -install_homebrew_deps() { - if ! exists brew; then - error "Homebrew not found - please install homebrew (https://brew.sh)" - exit 1 - fi - - if [ -d /usr/local/opt/openssl@1.0.2t ]; then - brew uninstall openssl@1.0.2t - brew untap local/openssl - fi - - if [ -d /usr/local/opt/python@2.7.17 ]; then - brew uninstall python@2.7.17 - brew untap local/python2 - fi - - brew bundle --file "${CI_SCRIPTS}/Brewfile" - - check_curl -} - -check_curl() { - if [ "${MACOS_MAJOR}" -lt "11" ] && [ "${MACOS_MINOR}" -lt "15" ]; then - if [ ! -d /usr/local/opt/curl ]; then - step "Installing Homebrew curl.." - brew install curl - fi - export CURLCMD="/usr/local/opt/curl/bin/curl" - else - export CURLCMD="curl" - fi -} - -check_ccache() { - export PATH="/usr/local/opt/ccache/libexec:${PATH}" - CCACHE_STATUS=$(ccache -s >/dev/null 2>&1 && /bin/echo "CCache available." || /bin/echo "CCache is not available.") - info "${CCACHE_STATUS}" -} - -install_obs-deps() { - hr "Setting up pre-built macOS OBS dependencies v${1}" - ensure_dir "${DEPS_BUILD_DIR}" - step "Download..." - ${CURLCMD} --progress-bar -L -C - -O https://github.com/obsproject/obs-deps/releases/download/${1}/macos-deps-${1}-${CURRENT_ARCH}.tar.xz - step "Unpack..." - mkdir -p /tmp/obsdeps - /usr/bin/tar -xf "./macos-deps-${1}-${CURRENT_ARCH}.tar.xz" -C /tmp/obsdeps - /usr/bin/xattr -r -d com.apple.quarantine /tmp/obsdeps -} - -install_qt-deps() { - hr "Setting up pre-built dependency QT v${1}" - ensure_dir "${DEPS_BUILD_DIR}" - step "Download..." - ${CURLCMD} --progress-bar -L -C - -O https://github.com/obsproject/obs-deps/releases/download/${2}/macos-deps-qt-${2}-${CURRENT_ARCH}.tar.xz - step "Unpack..." - mkdir -p /tmp/obsdeps - /usr/bin/tar -xf ./macos-deps-qt-${2}-${CURRENT_ARCH}.tar.xz -C /tmp/obsdeps - /usr/bin/xattr -r -d com.apple.quarantine /tmp/obsdeps -} - -install_vlc() { - hr "Setting up dependency VLC v${1}" - ensure_dir "${DEPS_BUILD_DIR}" - step "Download..." - ${CURLCMD} --progress-bar -L -C - -O https://downloads.videolan.org/vlc/${1}/vlc-${1}.tar.xz - step "Unpack ..." - /usr/bin/tar -xf vlc-${1}.tar.xz -} - -install_sparkle() { - hr "Setting up dependency Sparkle v${1} (might prompt for password)" - ensure_dir "${DEPS_BUILD_DIR}/sparkle" - step "Download..." - ${CURLCMD} --progress-bar -L -C - -o sparkle.tar.bz2 https://github.com/sparkle-project/Sparkle/releases/download/${1}/Sparkle-${1}.tar.bz2 - step "Unpack..." - /usr/bin/tar -xf ./sparkle.tar.bz2 - step "Copy to destination..." - if [ -d /Library/Frameworks/Sparkle.framework/ ]; then - info "Warning - Sparkle framework already found in /Library/Frameworks" - else - sudo /bin/cp -R ./Sparkle.framework/ /Library/Frameworks/Sparkle.framework/ - fi -} - -install_cef() { - hr "Building dependency CEF v${1}" - ensure_dir "${DEPS_BUILD_DIR}" - step "Download..." - ${CURLCMD} --progress-bar -L -C - -O https://cdn-fastly.obsproject.com/downloads/cef_binary_${1}_macos_x86_64.tar.xz - step "Unpack..." - /usr/bin/tar -xf ./cef_binary_${1}_macos_x86_64.tar.xz - cd ./cef_binary_${1}_macos_x86_64 - step "Fix tests..." - /usr/bin/sed -i '.orig' '/add_subdirectory(tests\/ceftests)/d' ./CMakeLists.txt - /usr/bin/sed -i '.orig' 's/"'$(test "${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" -le 3770 && echo "10.9" || echo "10.10")'"/"'${MIN_MACOS_VERSION:-${CI_MIN_MACOS_VERSION}}'"/' ./cmake/cef_variables.cmake - ensure_dir ./build - step "Run CMAKE..." - cmake \ - -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++ -Wno-deprecated-declarations"\ - -DCMAKE_EXE_LINKER_FLAGS="-std=c++11 -stdlib=libc++"\ - -DCMAKE_OSX_DEPLOYMENT_TARGET=${MIN_MACOS_VERSION:-${CI_MIN_MACOS_VERSION}} \ - .. - step "Build..." - /usr/bin/make -j${NPROC} - if [ ! -d libcef_dll ]; then /bin/mkdir libcef_dll; fi -} - -## CHECK AND INSTALL PACKAGING DEPENDENCIES ## -install_dmgbuild() { - if ! exists dmgbuild; then - if exists "pip3"; then - PIPCMD="pip3" - elif exists "pip"; then - PIPCMD="pip" - else - error "Pip not found - please install pip via 'python -m ensurepip'" - exit 1 - fi - - ${PIPCMD} install dmgbuild - fi -} - -## OBS BUILD FROM SOURCE ## -configure_obs_build() { - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - - CUR_DATE=$(/bin/date +"%Y-%m-%d@%H%M%S") - NIGHTLY_DIR="${CHECKOUT_DIR}/nightly-${CUR_DATE}" - PACKAGE_NAME=$(/usr/bin/find . -name "*.dmg") - - if [ -d ./OBS.app ]; then - ensure_dir "${NIGHTLY_DIR}" - /bin/mv "../${BUILD_DIR}/OBS.app" . - info "You can find OBS.app in ${NIGHTLY_DIR}" - fi - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - if ([ -n "${PACKAGE_NAME}" ] && [ -f ${PACKAGE_NAME} ]); then - ensure_dir "${NIGHTLY_DIR}" - /bin/mv "../${BUILD_DIR}/$(basename "${PACKAGE_NAME}")" . - info "You can find ${PACKAGE_NAME} in ${NIGHTLY_DIR}" - fi - - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - - hr "Run CMAKE for OBS..." - cmake -DENABLE_SPARKLE_UPDATER=ON \ - -DCMAKE_OSX_DEPLOYMENT_TARGET=${MIN_MACOS_VERSION:-${CI_MIN_MACOS_VERSION}} \ - -DQTDIR="/tmp/obsdeps" \ - -DSWIGDIR="/tmp/obsdeps" \ - -DDepsPath="/tmp/obsdeps" \ - -DVLCPath="${DEPS_BUILD_DIR}/vlc-${VLC_VERSION:-${CI_VLC_VERSION}}" \ - -DBUILD_BROWSER=ON \ - -DBROWSER_LEGACY="$(test "${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" -le 3770 && echo "ON" || echo "OFF")" \ - -DWITH_RTMPS=ON \ - -DCEF_ROOT_DIR="${DEPS_BUILD_DIR}/cef_binary_${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}_macos_x86_64" \ - -DCMAKE_BUILD_TYPE="${BUILD_CONFIG}" \ - .. - -} - -run_obs_build() { - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - hr "Build OBS..." - /usr/bin/make -j${NPROC} -} - -## OBS BUNDLE AS MACOS APPLICATION ## -bundle_dylibs() { - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - - if [ ! -d ./OBS.app ]; then - error "No OBS.app bundle found" - exit 1 - fi - - hr "Bundle dylibs for macOS application" - - step "Run dylibBundler.." - - BUNDLE_PLUGINS=( - ./OBS.app/Contents/PlugIns/coreaudio-encoder.so - ./OBS.app/Contents/PlugIns/decklink-ouput-ui.so - ./OBS.app/Contents/PlugIns/decklink-captions.so - ./OBS.app/Contents/PlugIns/frontend-tools.so - ./OBS.app/Contents/PlugIns/image-source.so - ./OBS.app/Contents/PlugIns/mac-avcapture.so - ./OBS.app/Contents/PlugIns/mac-capture.so - ./OBS.app/Contents/PlugIns/mac-decklink.so - ./OBS.app/Contents/PlugIns/mac-syphon.so - ./OBS.app/Contents/PlugIns/mac-vth264.so - ./OBS.app/Contents/PlugIns/mac-virtualcam.so - ./OBS.app/Contents/PlugIns/obs-browser.so - ./OBS.app/Contents/PlugIns/obs-ffmpeg.so - ./OBS.app/Contents/PlugIns/obs-filters.so - ./OBS.app/Contents/PlugIns/obs-transitions.so - ./OBS.app/Contents/PlugIns/obs-vst.so - ./OBS.app/Contents/PlugIns/rtmp-services.so - ./OBS.app/Contents/MacOS/obs-ffmpeg-mux - ./OBS.app/Contents/MacOS/obslua.so - ./OBS.app/Contents/MacOS/_obspython.so - ./OBS.app/Contents/PlugIns/obs-x264.so - ./OBS.app/Contents/PlugIns/text-freetype2.so - ./OBS.app/Contents/PlugIns/obs-outputs.so - ./OBS.app/Contents/PlugIns/aja.so - ./OBS.app/Contents/PlugIns/aja-output-ui.so - ) - - SEARCH_PATHS=( - /tmp/obsdeps/lib - /tmp/obsdeps/lib/QtSvg.framework - /tmp/obsdeps/lib/QtXml.framework - /tmp/obsdeps/lib/QtNetwork.framework - /tmp/obsdeps/lib/QtCore.framework - /tmp/obsdeps/lib/QtGui.framework - /tmp/obsdeps/lib/QtWidgets.framework - /tmp/obsdeps/lib/QtDBus.framework - /tmp/obsdeps/lib/QtPrintSupport.framework - ) - if ! [ "${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" -le 3770 ]; then - "${CI_SCRIPTS}/app/dylibbundler" -cd -of -a ./OBS.app -q -f \ - -s ./OBS.app/Contents/MacOS \ - -s "${DEPS_BUILD_DIR}/sparkle/Sparkle.framework" \ - -s ./rundir/${BUILD_CONFIG}/bin/ \ - $(echo "${SEARCH_PATHS[@]/#/-s }") \ - $(echo "${BUNDLE_PLUGINS[@]/#/-x }") - else - "${CI_SCRIPTS}/app/dylibbundler" -cd -of -a ./OBS.app -q -f \ - -s ./OBS.app/Contents/MacOS \ - -s "${DEPS_BUILD_DIR}/sparkle/Sparkle.framework" \ - -s ./rundir/${BUILD_CONFIG}/bin/ \ - $(echo "${SEARCH_PATHS[@]/#/-s }") \ - $(echo "${BUNDLE_PLUGINS[@]/#/-x }") \ - -x ./OBS.app/Contents/PlugIns/obs-browser-page - fi - - step "Move libobs-opengl to final destination" - if [ -f "./libobs-opengl/libobs-opengl.so" ]; then - /bin/cp ./libobs-opengl/libobs-opengl.so ./OBS.app/Contents/Frameworks - else - /bin/cp ./libobs-opengl/${BUILD_CONFIG}/libobs-opengl.so ./OBS.app/Contents/Frameworks - fi -} - -install_frameworks() { - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - - if [ ! -d ./OBS.app ]; then - error "No OBS.app bundle found" - exit 1 - fi - - hr "Adding Chromium Embedded Framework" - step "Copy Framework..." - /bin/cp -R "${DEPS_BUILD_DIR}/cef_binary_${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}_macos_x86_64/Release/Chromium Embedded Framework.framework" ./OBS.app/Contents/Frameworks/ -} - -prepare_macos_bundle() { - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - - if [ ! -d ./rundir/${BUILD_CONFIG}/bin ]; then - error "No OBS build found" - return - fi - - if [ -d ./OBS.app ]; then /bin/rm -rf ./OBS.app; fi - - hr "Preparing OBS.app bundle" - step "Copy binary and plugins..." - /bin/mkdir -p OBS.app/Contents/MacOS - /bin/mkdir OBS.app/Contents/PlugIns - /bin/mkdir OBS.app/Contents/Resources - /bin/mkdir OBS.app/Contents/Frameworks - - /bin/cp rundir/${BUILD_CONFIG}/bin/obs ./OBS.app/Contents/MacOS - /bin/cp rundir/${BUILD_CONFIG}/bin/obs-ffmpeg-mux ./OBS.app/Contents/MacOS - /bin/cp rundir/${BUILD_CONFIG}/bin/libobsglad.0.dylib ./OBS.app/Contents/MacOS - if ! [ "${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" -le 3770 ]; then - /bin/cp -R "rundir/${BUILD_CONFIG}/bin/OBS Helper.app" "./OBS.app/Contents/Frameworks/OBS Helper.app" - /bin/cp -R "rundir/${BUILD_CONFIG}/bin/OBS Helper (GPU).app" "./OBS.app/Contents/Frameworks/OBS Helper (GPU).app" - /bin/cp -R "rundir/${BUILD_CONFIG}/bin/OBS Helper (Plugin).app" "./OBS.app/Contents/Frameworks/OBS Helper (Plugin).app" - /bin/cp -R "rundir/${BUILD_CONFIG}/bin/OBS Helper (Renderer).app" "./OBS.app/Contents/Frameworks/OBS Helper (Renderer).app" - fi - /bin/cp -R rundir/${BUILD_CONFIG}/data ./OBS.app/Contents/Resources - /bin/cp "${CI_SCRIPTS}/app/AppIcon.icns" ./OBS.app/Contents/Resources - /bin/cp -R rundir/${BUILD_CONFIG}/obs-plugins/ ./OBS.app/Contents/PlugIns - /bin/cp "${CI_SCRIPTS}/app/Info.plist" ./OBS.app/Contents - # Scripting plugins are required to be placed in same directory as binary - if [ -d ./OBS.app/Contents/Resources/data/obs-scripting ]; then - /bin/mv ./OBS.app/Contents/Resources/data/obs-scripting/obslua.so ./OBS.app/Contents/MacOS/ - /bin/mv ./OBS.app/Contents/Resources/data/obs-scripting/_obspython.so ./OBS.app/Contents/MacOS/ - /bin/mv ./OBS.app/Contents/Resources/data/obs-scripting/obspython.py ./OBS.app/Contents/MacOS/ - /bin/rm -rf ./OBS.app/Contents/Resources/data/obs-scripting/ - fi - # dylibbundler will only copy actually linked files into bundle, but not symlinks - /bin/cp -cpR /tmp/obsdeps/lib/*.dylib ./OBS.app/Contents/Frameworks - - bundle_dylibs - install_frameworks - - /bin/cp "${CI_SCRIPTS}/app/OBSPublicDSAKey.pem" ./OBS.app/Contents/Resources - - step "Set bundle meta information..." - /usr/bin/plutil -insert CFBundleVersion -string ${GIT_TAG}-${GIT_HASH} ./OBS.app/Contents/Info.plist - /usr/bin/plutil -insert CFBundleShortVersionString -string ${GIT_TAG}-${GIT_HASH} ./OBS.app/Contents/Info.plist - /usr/bin/plutil -insert OBSFeedsURL -string https://obsproject.com/osx_update/feeds.xml ./OBS.app/Contents/Info.plist - /usr/bin/plutil -insert SUFeedURL -string https://obsproject.com/osx_update/stable/updates.xml ./OBS.app/Contents/Info.plist - /usr/bin/plutil -insert SUPublicDSAKeyFile -string OBSPublicDSAKey.pem ./OBS.app/Contents/Info.plist -} - -## CREATE MACOS DISTRIBUTION AND INSTALLER IMAGE ## -prepare_macos_image() { - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - - if [ ! -d ./OBS.app ]; then - error "No OBS.app bundle found" - return - fi - - hr "Preparing macOS installation image" - - if [ -f "${FILE_NAME}" ]; then - /bin/rm "${FILE_NAME}" - fi - - step "Run dmgbuild..." - /bin/cp "${CI_SCRIPTS}/package/settings.json.template" ./settings.json - /usr/bin/sed -i '' 's#\$\$VERSION\$\$#'"${GIT_TAG}"'#g' ./settings.json - /usr/bin/sed -i '' 's#\$\$CI_PATH\$\$#'"${CI_SCRIPTS}"'#g' ./settings.json - /usr/bin/sed -i '' 's#\$\$BUNDLE_PATH\$\$#'"${CHECKOUT_DIR}"'/build#g' ./settings.json - /bin/echo -n "${COLOR_ORANGE}" - dmgbuild "OBS-Studio ${GIT_TAG}" "${FILE_NAME}" -s ./settings.json - /bin/echo -n "${COLOR_RESET}" - - if [ -n "${CODESIGN_OBS}" ]; then - codesign_image - fi -} - -## SET UP CODE SIGNING AND NOTARIZATION CREDENTIALS ## -############################################################################## -# Apple Developer Identity needed: -# -# + Signing the code requires a developer identity in the system's keychain -# + codesign will look up and find the identity automatically -# -############################################################################## -read_codesign_ident() { - if [ ! -n "${CODESIGN_IDENT}" ]; then - step "Code-signing Setup" - /usr/bin/read -p "${COLOR_ORANGE} + Apple developer identity: ${COLOR_RESET}" CODESIGN_IDENT - fi -} - -############################################################################## -# Apple Developer credentials necessary: -# -# + Signing for distribution and notarization require an active Apple -# Developer membership -# + An Apple Development identity is needed for code signing -# (i.e. 'Apple Development: YOUR APPLE ID (PROVIDER)') -# + Your Apple developer ID is needed for notarization -# + An app-specific password is necessary for notarization from CLI -# + This password will be stored in your macOS keychain under the identifier -# 'OBS-Codesign-Password'with access Apple's 'altool' only. -############################################################################## - -read_codesign_pass() { - if [ ! -n "${CODESIGN_IDENT_PASS}" ]; then - step "Notarization Setup" - /usr/bin/read -p "${COLOR_ORANGE} + Apple account id: ${COLOR_RESET}" CODESIGN_IDENT_USER - CODESIGN_IDENT_PASS=$(stty -echo; /usr/bin/read -p "${COLOR_ORANGE} + Apple developer password: ${COLOR_RESET}" pwd; stty echo; /bin/echo $pwd) - /bin/echo -n "${COLOR_ORANGE}" - /usr/bin/xcrun altool --store-password-in-keychain-item "OBS-Codesign-Password" -u "${CODESIGN_IDENT_USER}" -p "${CODESIGN_IDENT_PASS}" - /bin/echo -n "${COLOR_RESET}" - CODESIGN_IDENT_SHORT=$(/bin/echo "${CODESIGN_IDENT}" | /usr/bin/sed -En "s/.+\((.+)\)/\1/p") - fi -} - -codesign_bundle() { - if [ ! -n "${CODESIGN_OBS}" ]; then step "Skipping application bundle code signing"; return; fi - - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - trap "caught_error 'code-signing app'" ERR - - if [ ! -d ./OBS.app ]; then - error "No OBS.app bundle found" - return - fi - - hr "Code-signing application bundle" - - /usr/bin/xattr -crs ./OBS.app - - read_codesign_ident - step "Code-sign Sparkle framework..." - /bin/echo -n "${COLOR_ORANGE}" - /usr/bin/codesign --force --options runtime --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/fileop" - /usr/bin/codesign --force --options runtime --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate" - /usr/bin/codesign --force --options runtime --sign "${CODESIGN_IDENT}" --deep ./OBS.app/Contents/Frameworks/Sparkle.framework - /bin/echo -n "${COLOR_RESET}" - - step "Code-sign CEF framework..." - /bin/echo -n "${COLOR_ORANGE}" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/app/entitlements.plist" --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libEGL.dylib" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/app/entitlements.plist" --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libswiftshader_libEGL.dylib" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/app/entitlements.plist" --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libGLESv2.dylib" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/app/entitlements.plist" --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libswiftshader_libGLESv2.dylib" - if ! [ "${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" -le 3770 ]; then - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/app/entitlements.plist" --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/libvk_swiftshader.dylib" - fi - - /bin/echo -n "${COLOR_RESET}" - - if ! [ "${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" -le 3770 ]; then - step "Code-sign CEF helper apps..." - /bin/echo -n "${COLOR_ORANGE}" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/helpers/helper-entitlements.plist" --sign "${CODESIGN_IDENT}" --deep "./OBS.app/Contents/Frameworks/OBS Helper.app" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/helpers/helper-gpu-entitlements.plist" --sign "${CODESIGN_IDENT}" --deep "./OBS.app/Contents/Frameworks/OBS Helper (GPU).app" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/helpers/helper-plugin-entitlements.plist" --sign "${CODESIGN_IDENT}" --deep "./OBS.app/Contents/Frameworks/OBS Helper (Plugin).app" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/helpers/helper-renderer-entitlements.plist" --sign "${CODESIGN_IDENT}" --deep "./OBS.app/Contents/Frameworks/OBS Helper (Renderer).app" - /bin/echo -n "${COLOR_RESET}" - fi - - step "Code-sign DAL Plugin..." - /bin/echo -n "${COLOR_ORANGE}" - /usr/bin/codesign --force --options runtime --deep --sign "${CODESIGN_IDENT}" "./OBS.app/Contents/Resources/data/obs-plugins/mac-virtualcam/obs-mac-virtualcam.plugin" - /bin/echo -n "${COLOR_RESET}" - - step "Code-sign OBS code..." - /bin/echo -n "${COLOR_ORANGE}" - /usr/bin/codesign --force --options runtime --entitlements "${CI_SCRIPTS}/app/entitlements.plist" --sign "${CODESIGN_IDENT}" --deep ./OBS.app - /bin/echo -n "${COLOR_RESET}" - - step "Check code-sign result..." - /usr/bin/codesign -dvv ./OBS.app -} - -codesign_image() { - if [ ! -n "${CODESIGN_OBS}" ]; then step "Skipping installer image code signing"; return; fi - - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - trap "caught_error 'code-signing image'" ERR - - if [ ! -f "${FILE_NAME}" ]; then - error "No OBS disk image found" - return - fi - - hr "Code-signing installation image" - - read_codesign_ident - - step "Code-sign OBS installer image..." - /bin/echo -n "${COLOR_ORANGE}"; - /usr/bin/codesign --force --sign "${CODESIGN_IDENT}" "${FILE_NAME}" - /bin/echo -n "${COLOR_RESET}" - step "Check code-sign result..." - /usr/bin/codesign -dvv "${FILE_NAME}" -} - -## BUILD FROM SOURCE META FUNCTION ## -full-build-macos() { - if [ -n "${SKIP_BUILD}" ]; then step "Skipping full build"; return; fi - - if [ ! -n "${SKIP_DEPS}" ]; then - - hr "Installing Homebrew dependencies" - install_homebrew_deps - - for DEPENDENCY in "${BUILD_DEPS[@]}"; do - set -- ${DEPENDENCY} - trap "caught_error ${DEPENDENCY}" ERR - FUNC_NAME="install_${1}" - ${FUNC_NAME} ${2} ${3} - done - - check_ccache - trap "caught_error 'cmake'" ERR - fi - - configure_obs_build - run_obs_build -} - -## BUNDLE MACOS APPLICATION META FUNCTION ## -bundle_macos() { - if [ ! -n "${BUNDLE_OBS}" ]; then step "Skipping application bundle creation"; return; fi - - hr "Creating macOS app bundle" - trap "caught_error 'bundle app'" ERR - ensure_dir ${CHECKOUT_DIR} - prepare_macos_bundle -} - -## PACKAGE MACOS DISTRIBUTION IMAGE META FUNCTION ## -package_macos() { - if [ ! -n "${PACKAGE_OBS}" ]; then step "Skipping installer image creation"; return; fi - - hr "Creating macOS .dmg image" - trap "caught_error 'package app'" ERR - - install_dmgbuild - prepare_macos_image -} - -## NOTARIZATION META FUNCTION ## -notarize_macos() { - if [ ! -n "${NOTARIZE_OBS}" ]; then step "Skipping macOS notarization"; return; fi; - - hr "Notarizing OBS for macOS" - trap "caught_error 'notarizing app'" ERR - - ensure_dir "${CHECKOUT_DIR}/${BUILD_DIR}" - - if [ -f "${FILE_NAME}" ]; then - NOTARIZE_TARGET="${FILE_NAME}" - xcnotary precheck "./OBS.app" - elif [ -d "OBS.app" ]; then - NOTARIZE_TARGET="./OBS.app" - else - error "No notarization app bundle ('OBS.app') or disk image ('${FILE_NAME}') found" - return - fi - - if [ "$?" -eq 0 ]; then - read_codesign_ident - read_codesign_pass - - step "Run xcnotary with ${NOTARIZE_TARGET}..." - xcnotary notarize "${NOTARIZE_TARGET}" --developer-account "${CODESIGN_IDENT_USER}" --developer-password-keychain-item "OBS-Codesign-Password" --provider "${CODESIGN_IDENT_SHORT}" - fi -} - -## MAIN SCRIPT FUNCTIONS ## -print_usage() { - /bin/echo "full-build-macos.sh - Build helper script for OBS-Studio\n" - /bin/echo "Usage: ${0}\n" \ - "-d: Skip dependency checks\n" \ - "-b: Create macOS app bundle\n" \ - "-c: Codesign macOS app bundle\n" \ - "-p: Package macOS app into disk image\n" \ - "-n: Notarize macOS app and disk image (implies -b)\n" \ - "-s: Skip build process (useful for bundling/packaging only)\n" \ - "-h: Print this help" - exit 0 -} - -obs-build-main() { - ensure_dir ${CHECKOUT_DIR} - check_macos_version - step "Fetching OBS tags..." - /usr/bin/git fetch origin --tags - GIT_BRANCH=$(/usr/bin/git rev-parse --abbrev-ref HEAD) - GIT_HASH=$(/usr/bin/git rev-parse --short HEAD) - GIT_TAG=$(/usr/bin/git describe --tags --abbrev=0) - FILE_NAME="obs-studio-${GIT_TAG}-${GIT_HASH}-macOS.dmg" - - ########################################################################## - # IMPORTANT: - # - # Be careful when choosing to notarize and code-sign. The script will try - # to sign any pre-existing bundle but also pre-existing images. - # - # This could lead to a package containing a non-signed bundle, which - # will then fail notarization. - # - # To avoid this, run this script with -b -c first, then -p -c or -p -n - # after to make sure that a code-signed bundle will be packaged. - # - ########################################################################## - - while getopts ":hdsbnpc" OPTION; do - case ${OPTION} in - h) print_usage ;; - d) SKIP_DEPS=1 ;; - s) SKIP_BUILD=1 ;; - b) BUNDLE_OBS=1 ;; - n) CODESIGN_OBS=1; NOTARIZE_OBS=1 ;; - p) PACKAGE_OBS=1 ;; - c) CODESIGN_OBS=1 ;; - \?) ;; - esac - done - - full-build-macos - bundle_macos - codesign_bundle - package_macos - codesign_image - notarize_macos - - cleanup -} - -obs-build-main $* diff --git a/CI/include/Brewfile b/CI/include/Brewfile new file mode 100644 index 000000000..e5428721e --- /dev/null +++ b/CI/include/Brewfile @@ -0,0 +1,5 @@ +brew "cmake" +brew "ccache" +brew "ninja" +brew "freetype" +brew "cmocka" diff --git a/CI/include/Wingetfile b/CI/include/Wingetfile new file mode 100644 index 000000000..3b8f56963 --- /dev/null +++ b/CI/include/Wingetfile @@ -0,0 +1,2 @@ +package '7zip.7zip', path: '7-zip', bin: '7z' +package 'cmake', path: 'Cmake\bin', bin: 'cmake' diff --git a/CI/include/build_support.sh b/CI/include/build_support.sh new file mode 100644 index 000000000..06465c846 --- /dev/null +++ b/CI/include/build_support.sh @@ -0,0 +1,217 @@ +#!/bin/bash + +############################################################################## +# Unix support functions +############################################################################## +# +# This script file can be included in build scripts for UNIX-compatible +# shells to compose build scripts. +# +############################################################################## + +## DEFINE UTILITIES ## + +if [ -z "${QUIET}" ]; then + status() { + echo -e "${COLOR_BLUE}[${PRODUCT_NAME}] ${1}${COLOR_RESET}" + } + + step() { + echo -e "${COLOR_GREEN} + ${1}${COLOR_RESET}" + } + + info() { + echo -e "${COLOR_ORANGE} + ${1}${COLOR_RESET}" + } + + error() { + echo -e "${COLOR_RED} + ${1}${COLOR_RESET}" + } +else + status() { + : + } + + step() { + : + } + + info() { + : + } + + error() { + echo -e "${COLOR_RED} + ${1}${COLOR_RESET}" + } +fi + +exists() { + /usr/bin/command -v "$1" >/dev/null 2>&1 +} + +ensure_dir() { + [ -n "${1}" ] && /bin/mkdir -p "${1}" && builtin cd "${1}" +} + +cleanup() { + : +} + +caught_error() { + error "ERROR during build step: ${1}" + cleanup + exit 1 +} + +# Setup build environment +BUILD_DIR="${BUILD_DIR:-build}" +BUILD_CONFIG="${BUILD_CONFIG:-RelWithDebInfo}" +CI_WORKFLOW="${CHECKOUT_DIR}/.github/workflows/main.yml" +CURRENT_ARCH="$(uname -m)" +CURRENT_DATE="$(date +"%Y-%m-%d")" + +## Utility functions ## + +check_ccache() { + step "Check CCache..." + if ccache -V >/dev/null 2>&1; then + info "CCache available" + CMAKE_CCACHE_OPTIONS="-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache" + + if [ "${CI}" ]; then + ccache --set-config=cache_dir=${GITHUB_WORKSPACE:-${HOME}}/.ccache + ccache --set-config=max_size=${CCACHE_SIZE:-500M} + ccache --set-config=compression=true + ccache -z + fi + else + info "CCache not available" + fi +} + +safe_fetch() { + if [ $# -lt 2 ]; then + error "Usage: safe_fetch URL HASH" + return 1 + fi + + while true; do + case "${1}" in + -n | --nocontinue ) NOCONTINUE=TRUE; shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + DOWNLOAD_URL="${1}" + DOWNLOAD_HASH="${2}" + DOWNLOAD_FILE="$(basename ${DOWNLOAD_URL})" + CURLCMD=${CURLCMD:-curl} + + if [ "${NOCONTINUE}" ]; then + ${CURLCMD/--continue-at -/} "${DOWNLOAD_URL}" + else + ${CURLCMD} "${DOWNLOAD_URL}" + fi + + if [ "${DOWNLOAD_HASH}" = "$(sha256sum "${DOWNLOAD_FILE}" | cut -d " " -f 1)" ]; then + info "${DOWNLOAD_FILE} downloaded successfully and passed hash check" + return 0 + else + error "${DOWNLOAD_FILE} downloaded successfully and failed hash check" + return 1 + fi +} + +check_and_fetch() { + if [ $# -lt 2 ]; then + caught_error "Usage: check_and_fetch URL HASH" + fi + + while true; do + case "${1}" in + -n | --nocontinue ) NOCONTINUE=TRUE; shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + DOWNLOAD_URL="${1}" + DOWNLOAD_HASH="${2}" + DOWNLOAD_FILE="$(basename "${DOWNLOAD_URL}")" + + if [ -f "${DOWNLOAD_FILE}" ] && [ "${DOWNLOAD_HASH}" = "$(sha256sum "${DOWNLOAD_FILE}" | cut -d " " -f 1)" ]; then + info "${DOWNLOAD_FILE} exists and passed hash check" + return 0 + else + safe_fetch "${DOWNLOAD_URL}" "${DOWNLOAD_HASH}" + fi +} + +github_fetch() { + if [ $# -ne 3 ]; then + error "Usage: github_fetch GITHUB_USER GITHUB_REPOSITORY GITHUB_COMMIT_HASH" + return 1 + fi + + GH_USER="${1}" + GH_REPO="${2}" + GH_REF="${3}" + + if [ -d "./.git" ]; then + info "Repository ${GH_USER}/${GH_REPO} already exists, updating..." + git config advice.detachedHead false + git config remote.origin.url "https://github.com/${GH_USER}/${GH_REPO}.git" + git config remote.origin.fetch "+refs/heads/master:refs/remotes/origin/master" + git config remote.origin.tapOpt --no-tags + + if ! git rev-parse -q --verify "${GH_COMMIT}^{commit}"; then + git fetch origin + fi + + git checkout -f "${GH_REF}" -- + git reset --hard "${GH_REF}" -- + if [ -d "./.gitmodules" ]; then + git submodule foreach --recursive git submodule sync + git submodule update --init --recursive + fi + + else + git clone "https://github.com/${GH_USER}/${GH_REPO}.git" "$(pwd)" + git config advice.detachedHead false + info "Checking out commit ${GH_REF}..." + git checkout -f "${GH_REF}" -- + + if [ -d "./.gitmodules" ]; then + git submodule foreach --recursive git submodule sync + git submodule update --init --recursive + fi + fi +} + +apply_patch() { + if [ $# -ne 2 ]; then + error "Usage: apply_patch PATCH_URL PATCH_HASH" + return 1 + fi + + COMMIT_URL="${1}" + COMMIT_HASH="${2}" + PATCH_FILE="$(basename ${COMMIT_URL})" + + if [ "${COMMIT_URL:0:5}" = "https" ]; then + ${CURLCMD:-curl} "${COMMIT_URL}" + if [ "${COMMIT_HASH}" = "$(sha256sum ${PATCH_FILE} | cut -d " " -f 1)" ]; then + info "${PATCH_FILE} downloaded successfully and passed hash check" + else + error "${PATCH_FILE} downloaded successfully and failed hash check" + return 1 + fi + + info "Applying patch ${COMMIT_URL}" + else + PATCH_FILE="${COMMIT_URL}" + fi + + patch -g 0 -f -p1 -i "${PATCH_FILE}" +} diff --git a/CI/include/build_support_freebsd.sh b/CI/include/build_support_freebsd.sh new file mode 100644 index 000000000..67209416b --- /dev/null +++ b/CI/include/build_support_freebsd.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +############################################################################## +# FreeBSD support functions +############################################################################## +# +# This script file can be included in build scripts for FreeBSD. +# +############################################################################## + +# Setup build environment + +if [ "${TERM-}" -a -x /usr/local/bin/tput ]; then + COLOR_RED=$(/usr/local/bin/tput setaf 1) + COLOR_GREEN=$(/usr/local/bin/tput setaf 2) + COLOR_BLUE=$(/usr/local/bin/tput setaf 4) + COLOR_ORANGE=$(/usr/local/bin/tput setaf 3) + COLOR_RESET=$(/usr/local/bin/tput sgr0) +else + COLOR_RED="" + COLOR_GREEN="" + COLOR_BLUE="" + COLOR_ORANGE="" + COLOR_RESET="" +fi + +if [ "${CI}" -o "${QUIET}" ]; then + export CURLCMD="curl --silent --show-error --location -O" +else + export CURLCMD="curl --progress-bar --location --continue-at - -O" +fi + +_add_ccache_to_path() { + if [ "${CMAKE_CCACHE_OPTIONS}" ]; then + PATH="/usr/local/opt/ccache/libexec:${PATH}" + status "Compiler Info:" + local IFS=$'\n' + for COMPILER_INFO in $(type cc c++ gcc g++ clang clang++ || true); do + info "${COMPILER_INFO}" + done + fi +} diff --git a/CI/include/build_support_linux.sh b/CI/include/build_support_linux.sh new file mode 100644 index 000000000..23a9ffd1c --- /dev/null +++ b/CI/include/build_support_linux.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +############################################################################## +# Linux support functions +############################################################################## +# +# This script file can be included in build scripts for Linux. +# +############################################################################## + +# Setup build environment + +CI_LINUX_CEF_VERSION=$(cat "${CI_WORKFLOW}" | sed -En "s/[ ]+CEF_BUILD_VERSION_LINUX: '([0-9]+)'/\1/p") + +if [ "${TERM-}" -a -z "${CI}" ]; then + COLOR_RED=$(tput setaf 1) + COLOR_GREEN=$(tput setaf 2) + COLOR_BLUE=$(tput setaf 4) + COLOR_ORANGE=$(tput setaf 3) + COLOR_RESET=$(tput sgr0) +else + COLOR_RED="" + COLOR_GREEN="" + COLOR_BLUE="" + COLOR_ORANGE="" + COLOR_RESET="" +fi + +if [ "${CI}" -o "${QUIET}" ]; then + export CURLCMD="curl --silent --show-error --location -O" +else + export CURLCMD="curl --progress-bar --location --continue-at - -O" +fi + +_add_ccache_to_path() { + if [ "${CMAKE_CCACHE_OPTIONS}" ]; then + PATH="/usr/local/opt/ccache/libexec:${PATH}" + status "Compiler Info:" + local IFS=$'\n' + for COMPILER_INFO in $(type cc c++ gcc g++ clang clang++ || true); do + info "${COMPILER_INFO}" + done + fi +} diff --git a/CI/include/build_support_macos.sh b/CI/include/build_support_macos.sh new file mode 100644 index 000000000..1cb35b01c --- /dev/null +++ b/CI/include/build_support_macos.sh @@ -0,0 +1,156 @@ +#!/bin/bash + +############################################################################## +# macOS support functions +############################################################################## +# +# This script file can be included in build scripts for macOS. +# +############################################################################## + +# Setup build environment +WORKFLOW_CONTENT=$(/bin/cat "${CI_WORKFLOW}") +CI_DEPS_VERSION=$(echo "${WORKFLOW_CONTENT}" | /usr/bin/sed -En "s/[ ]+DEPS_VERSION_MAC: '([0-9\-]+)'/\1/p") +CI_VLC_VERSION=$(echo "${WORKFLOW_CONTENT}" | /usr/bin/sed -En "s/[ ]+VLC_VERSION_MAC: '([0-9\.]+)'/\1/p") +CI_SPARKLE_VERSION=$(echo "${WORKFLOW_CONTENT}" | /usr/bin/sed -En "s/[ ]+SPARKLE_VERSION: '([0-9\.]+)'/\1/p") +CI_QT_VERSION=$(echo "${WORKFLOW_CONTENT}" | /usr/bin/sed -En "s/[ ]+QT_VERSION_MAC: '([0-9\.]+)'/\1/p" | /usr/bin/head -1) +CI_MACOSX_DEPLOYMENT_TARGET=$(echo "${WORKFLOW_CONTENT}" | /usr/bin/sed -En "s/[ ]+MACOSX_DEPLOYMENT_TARGET: '([0-9\.]+)'/\1/p") +CI_MACOS_CEF_VERSION=$(echo "${WORKFLOW_CONTENT}" | /usr/bin/sed -En "s/[ ]+CEF_BUILD_VERSION_MAC: '([0-9]+)'/\1/p") + +MACOS_VERSION="$(/usr/bin/sw_vers -productVersion)" +MACOS_MAJOR="$(echo ${MACOS_VERSION} | /usr/bin/cut -d '.' -f 1)" +MACOS_MINOR="$(echo ${MACOS_VERSION} | /usr/bin/cut -d '.' -f 2)" + +if [ "${TERM-}" -a -z "${CI}" ]; then + COLOR_RED=$(/usr/bin/tput setaf 1) + COLOR_GREEN=$(/usr/bin/tput setaf 2) + COLOR_BLUE=$(/usr/bin/tput setaf 4) + COLOR_ORANGE=$(/usr/bin/tput setaf 3) + COLOR_RESET=$(/usr/bin/tput sgr0) +else + COLOR_RED="" + COLOR_GREEN="" + COLOR_BLUE="" + COLOR_ORANGE="" + COLOR_RESET="" +fi + +## DEFINE UTILITIES ## +check_macos_version() { + step "Check macOS version..." + MIN_VERSION=${MACOSX_DEPLOYMENT_TARGET:-${CI_MACOSX_DEPLOYMENT_TARGET}} + MIN_MAJOR=$(echo ${MIN_VERSION} | /usr/bin/cut -d '.' -f 1) + MIN_MINOR=$(echo ${MIN_VERSION} | /usr/bin/cut -d '.' -f 2) + + if [ "${MACOS_MAJOR}" -lt "11" -a "${MACOS_MINOR}" -lt "${MIN_MINOR}" ]; then + error "ERROR: Minimum required macOS version is ${MIN_VERSION}, but running on ${MACOS_VERSION}" + fi + + if [ "${MACOS_MAJOR}" -ge "11" ]; then + export CODESIGN_LINKER="ON" + fi +} + +install_homebrew_deps() { + if ! exists brew; then + caught_error "Homebrew not found - please install Homebrew (https://brew.sh)" + fi + + brew bundle --file "${CHECKOUT_DIR}/CI/include/Brewfile" ${QUIET:+--quiet} + + check_curl +} + +check_curl() { + if [ "${MACOS_MAJOR}" -lt "11" -a "${MACOS_MINOR}" -lt "15" ]; then + if [ ! -d /usr/local/opt/curl ]; then + step "Install Homebrew curl..." + brew install curl + fi + + CURLCMD="/usr/local/opt/curl/bin/curl" + else + CURLCMD="curl" + fi + + if [ "${CI}" -o "${QUIET}" ]; then + export CURLCMD="${CURLCMD} --silent --show-error --location -O" + else + export CURLCMD="${CURLCMD} --progress-bar --location --continue-at - -O" + fi +} + +check_archs() { + step "Check Architecture..." + ARCH="${ARCH:-${CURRENT_ARCH}}" + if [ "${ARCH}" = "universal" ]; then + CMAKE_ARCHS="x86_64;arm64" + elif [ "${ARCH}" != "x86_64" -a "${ARCH}" != "arm64" ]; then + caught_error "Unsupported architecture '${ARCH}' provided" + else + CMAKE_ARCHS="${ARCH}" + fi +} + +_add_ccache_to_path() { + if [ "${CMAKE_CCACHE_OPTIONS}" ]; then + if [ "${CURRENT_ARCH}" == "arm64" ]; then + PATH="/opt/homebrew/opt/ccache/libexec:${PATH}" + else + PATH="/usr/local/opt/ccache/libexec:${PATH}" + fi + status "Compiler Info:" + local IFS=$'\n' + for COMPILER_INFO in $(type cc c++ gcc g++ clang clang++ || true); do + info "${COMPILER_INFO}" + done + fi +} + +## SET UP CODE SIGNING AND NOTARIZATION CREDENTIALS ## +############################################################################## +# Apple Developer Identity needed: +# +# + Signing the code requires a developer identity in the system's keychain +# + codesign will look up and find the identity automatically +# +############################################################################## +read_codesign_ident() { + if [ -z "${CODESIGN_IDENT}" ]; then + step "Set up code signing..." + read -p "${COLOR_ORANGE} + Apple developer identity: ${COLOR_RESET}" CODESIGN_IDENT + fi +} + +############################################################################## +# Apple Developer credentials necessary: +# +# + Signing for distribution and notarization require an active Apple +# Developer membership +# + An Apple Development identity is needed for code signing +# (i.e. 'Apple Development: YOUR APPLE ID (PROVIDER)') +# + Your Apple developer ID is needed for notarization +# + An app-specific password is necessary for notarization from CLI +# + This password will be stored in your macOS keychain under the identifier +# 'OBS-Codesign-Password' with access Apple's 'altool' only. +############################################################################## + +read_codesign_pass() { + step "Set up notarization..." + + if [ -z "${CODESIGN_IDENT_USER}" ]; then + read -p "${COLOR_ORANGE} + Apple account id: ${COLOR_RESET}" CODESIGN_IDENT_USER + fi + + if [ -z "${CODESIGN_IDENT_PASS}" ]; then + CODESIGN_IDENT_PASS=$(stty -echo; read -p "${COLOR_ORANGE} + Apple developer password: ${COLOR_RESET}" secret; stty echo; echo $secret) + echo "" + fi + + step "Update notarization keychain..." + + echo -n "${COLOR_ORANGE}" + /usr/bin/xcrun altool --store-password-in-keychain-item "OBS-Codesign-Password" -u "${CODESIGN_IDENT_USER}" -p "${CODESIGN_IDENT_PASS}" + echo -n "${COLOR_RESET}" + CODESIGN_IDENT_SHORT=$(echo "${CODESIGN_IDENT}" | /usr/bin/sed -En "s/.+\((.+)\)/\1/p") +} diff --git a/CI/include/build_support_windows.ps1 b/CI/include/build_support_windows.ps1 new file mode 100644 index 000000000..96c9bd891 --- /dev/null +++ b/CI/include/build_support_windows.ps1 @@ -0,0 +1,156 @@ +$CIWorkflow = "${CheckoutDir}/.github/workflows/main.yml" +$WorkflowContent = Get-Content ${CIWorkflow} + +$CIDepsVersion = ${WorkflowContent} | Select-String "[ ]+DEPS_VERSION_WIN: '([0-9\-]+)'" | ForEach-Object{$_.Matches.Groups[1].Value} +$CIQtVersion = ${WorkflowContent} | Select-String "[ ]+QT_VERSION_WIN: '([0-9\.]+)'" | ForEach-Object{$_.Matches.Groups[1].Value} +$CIVlcVersion = ${WorkflowContent} | Select-String "[ ]+VLC_VERSION_WIN: '(.+)'" | ForEach-Object{$_.Matches.Groups[1].Value} +$CICefVersion = ${WorkflowContent} | Select-String "[ ]+CEF_BUILD_VERSION_WIN: '([0-9\.]+)'" | ForEach-Object{$_.Matches.Groups[1].Value} +$CIGenerator = ${WorkflowContent} | Select-String "[ ]+CMAKE_GENERATOR: '(.+)'" | ForEach-Object{$_.Matches.Groups[1].Value} + +function Write-Status { + Param( + [Parameter(Mandatory=$true)] + [String] $Output + ) + + if (!($Quiet.isPresent)) { + if (Test-Path Env:CI) { + Write-Host "[${ProductName}] ${Output}" + } else { + Write-Host -ForegroundColor blue "[${ProductName}] ${Output}" + } + } +} + +function Write-Info { + Param( + [Parameter(Mandatory=$true)] + [String] $Output + ) + + if (!($Quiet.isPresent)) { + if (Test-Path Env:CI) { + Write-Host " + ${Output}" + } else { + Write-Host -ForegroundColor DarkYellow " + ${Output}" + } + } +} + +function Write-Step { + Param( + [Parameter(Mandatory=$true)] + [String] $Output + ) + + if (!($Quiet.isPresent)) { + if (Test-Path Env:CI) { + Write-Host " + ${Output}" + } else { + Write-Host -ForegroundColor green " + ${Output}" + } + } +} + +function Write-Failure { + Param( + [Parameter(Mandatory=$true)] + [String] $Output + ) + + if (Test-Path Env:CI) { + Write-Host " + ${Output}" + } else { + Write-Host -ForegroundColor red " + ${Output}" + } +} + +function Test-CommandExists { + Param( + [Parameter(Mandatory=$true)] + [String] $Command + ) + + $CommandExists = $false + $OldActionPref = $ErrorActionPreference + $ErrorActionPreference = "stop" + + try { + if (Get-Command $Command) { + $CommandExists = $true + } + } Catch { + $CommandExists = $false + } Finally { + $ErrorActionPreference = $OldActionPref + } + + return $CommandExists +} + +function Ensure-Directory { + Param( + [Parameter(Mandatory=$true)] + [String] $Directory + ) + + if (!(Test-Path $Directory)) { + $null = New-Item -ItemType Directory -Force -Path $Directory + } + + Set-Location -Path $Directory +} + +$BuildDirectory = "$(if (Test-Path Env:BuildDirectory) { $env:BuildDirectory } else { $BuildDirectory })" +$BuildConfiguration = "$(if (Test-Path Env:BuildConfiguration) { $env:BuildConfiguration } else { $BuildConfiguration })" +$BuildArch = "$(if (Test-Path Env:BuildArch) { $env:BuildArch } else { $BuildArch })" +$WindowsDepsVersion = "$(if (Test-Path Env:WindowsDepsVersion ) { $env:WindowsDepsVersion } else { $CIDepsVersion })" +$WindowsQtVersion = "$(if (Test-Path Env:WindowsQtVersion ) { $env:WindowsQtVersion } else { $CIQtVersion })" +$WindowsVlcVersion = "$(if (Test-Path Env:WindowsVlcVersion ) { $env:WindowsVlcVersion } else { $CIVlcVersion })" +$WindowsCefVersion = "$(if (Test-Path Env:WindowsCefVersion ) { $env:WindowsCefVersion } else { $CICefVersion })" +$CmakeSystemVersion = "$(if (Test-Path Env:CMAKE_SYSTEM_VERSION) { $Env:CMAKE_SYSTEM_VERSION } else { "10.0.18363.657" })" +$CmakeGenerator = "$(if (Test-Path Env:CmakeGenerator) { $Env:CmakeGenerator } else { $CIGenerator })" + + +function Install-Windows-Dependencies { + $WingetFile = "$PSScriptRoot/Wingetfile" + + $Host64Bit = [System.Environment]::Is64BitOperatingSystem + + $Prefix = (${Env:ProgramFiles(x86)}, $Env:ProgramFiles)[$Host64Bit] + + $Paths = $Env:Path -split [System.IO.Path]::PathSeparator + + $WingetOptions = @('install', '--accept-package-agreements', '--accept-source-agreements') + + if ( $script:Quiet ) { + $WingetOptions += '--silent' + } + + Get-Content $WingetFile | ForEach-Object { + $_, $Package, $_, $Path, $_, $Binary = $_ -replace ',','' -replace "'", '' -split ' ' + + $FullPath = "${Prefix}\${Path}" + if ( ( Test-Path $FullPath ) -and ! ( $Paths -contains $FullPath ) ) { + $Paths += $FullPath + $Env:Path = $Paths -join [System.IO.Path]::PathSeparator + } + + Write-Step "Checking for command ${Binary}" + $Found = Get-Command -ErrorAction SilentlyContinue $Binary + + if ( $Found ) { + Write-Info "Found dependency ${Binary} as $($Found.Source)" + } else { + Write-Info "Installing package ${Package}" + + try { + $Params = $WingetOptions + $Package + + winget @Params + } catch { + throw "Error while installing winget package ${Package}: $_" + } + } + } +} diff --git a/CI/install-dependencies-linux.sh b/CI/install-dependencies-linux.sh deleted file mode 100755 index f432544ab..000000000 --- a/CI/install-dependencies-linux.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -set -ex - -curl -L https://packagecloud.io/github/git-lfs/gpgkey | sudo apt-key add - - -sudo apt-get -qq update -sudo apt-get install -y \ - build-essential \ - checkinstall \ - cmake \ - libasound2-dev \ - libavcodec-dev \ - libavdevice-dev \ - libavfilter-dev \ - libavformat-dev \ - libavutil-dev \ - libcurl4-openssl-dev \ - libfdk-aac-dev \ - libfontconfig-dev \ - libfreetype6-dev \ - libgl1-mesa-dev \ - libjack-jackd2-dev \ - libjansson-dev \ - libluajit-5.1-dev \ - libpulse-dev \ - libqt5x11extras5-dev \ - libspeexdsp-dev \ - libswresample-dev \ - libswscale-dev \ - libudev-dev \ - libv4l-dev \ - libva-dev \ - libvlc-dev \ - libx11-dev \ - libx264-dev \ - libxkbcommon-dev \ - libxcb-randr0-dev \ - libxcb-shm0-dev \ - libxcb-xinerama0-dev \ - libxcomposite-dev \ - libxinerama-dev \ - libmbedtls-dev \ - pkg-config \ - python3-dev \ - qtbase5-dev \ - qtbase5-private-dev \ - libqt5svg5-dev \ - swig - -# build cef -wget --quiet --retry-connrefused --waitretry=1 https://cdn-fastly.obsproject.com/downloads/cef_binary_${LINUX_CEF_BUILD_VERSION}_linux64.tar.bz2 -tar -xjf ./cef_binary_${LINUX_CEF_BUILD_VERSION}_linux64.tar.bz2 diff --git a/CI/install-qt-win.cmd b/CI/install-qt-win.cmd deleted file mode 100644 index 147784e28..000000000 --- a/CI/install-qt-win.cmd +++ /dev/null @@ -1,4 +0,0 @@ -if exist Qt_5.15.2.7z (curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.15.2.7z -f --retry 5 -z Qt_5.15.2.7z) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.15.2.7z -f --retry 5 -C -) -7z x Qt_5.15.2.7z -oQt -mv Qt C:\QtDep -dir C:\QtDep diff --git a/CI/install-script-linux.sh b/CI/install-script-linux.sh deleted file mode 100755 index abbfbf00c..000000000 --- a/CI/install-script-linux.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -set -ex - -build_config=RelWithDebInfo diff --git a/CI/install-script-win.cmd b/CI/install-script-win.cmd deleted file mode 100644 index dd3852d19..000000000 --- a/CI/install-script-win.cmd +++ /dev/null @@ -1,30 +0,0 @@ -if exist dependencies2019.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2019.zip -f --retry 5 -z dependencies2019.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2019.zip -f --retry 5 -C -) -if exist vlc.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -z vlc.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -C -) -if exist cef_binary_%CEF_VERSION%_windows32_minimal.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32_minimal.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows32_minimal.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32_minimal.zip -f --retry 5 -C -) -if exist cef_binary_%CEF_VERSION%_windows64_minimal.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64_minimal.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows64_minimal.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64_minimal.zip -f --retry 5 -C -) -7z x dependencies2019.zip -odependencies2019 -7z x vlc.zip -ovlc -7z x cef_binary_%CEF_VERSION%_windows32_minimal.zip -oCEF_32 -7z x cef_binary_%CEF_VERSION%_windows64_minimal.zip -oCEF_64 -set DepsPath32=%CD%\dependencies2019\win32 -set DepsPath64=%CD%\dependencies2019\win64 -set VLCPath=%CD%\vlc -set QTDIR32=C:\QtDep\5.15.2\msvc2019 -set QTDIR64=C:\QtDep\5.15.2\msvc2019_64 -set CEF_32=%CD%\CEF_32\cef_binary_%CEF_VERSION%_windows32_minimal -set CEF_64=%CD%\CEF_64\cef_binary_%CEF_VERSION%_windows64_minimal -set build_config=RelWithDebInfo -set VIRTUALCAM-GUID=A3FCE0F5-3493-419F-958A-ABA1250EC20B -mkdir build build32 build64 -if "%TWITCH-CLIENTID%"=="$(twitch_clientid)" ( -cd ./build32 -cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_SYSTEM_VERSION=10.0 -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DENABLE_VLC=ON -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_32% -DVIRTUALCAM_GUID="%VIRTUALCAM-GUID%" .. -cd ../build64 -cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_SYSTEM_VERSION=10.0 -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DENABLE_VLC=ON -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_64% -DVIRTUALCAM_GUID="%VIRTUALCAM-GUID%" .. -) else ( -cd ./build32 -cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_SYSTEM_VERSION=10.0 -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DENABLE_VLC=ON -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_32% -DTWITCH_CLIENTID="%TWITCH-CLIENTID%" -DTWITCH_HASH="%TWITCH-HASH%" -DRESTREAM_CLIENTID="%RESTREAM-CLIENTID%" -DRESTREAM_HASH="%RESTREAM-HASH%" -DVIRTUALCAM_GUID="%VIRTUALCAM-GUID%" .. -cd ../build64 -cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_SYSTEM_VERSION=10.0 -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DENABLE_VLC=ON -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_64% -DTWITCH_CLIENTID="%TWITCH-CLIENTID%" -DTWITCH_HASH="%TWITCH-HASH%" -DRESTREAM_CLIENTID="%RESTREAM-CLIENTID%" -DRESTREAM_HASH="%RESTREAM-HASH%" -DVIRTUALCAM_GUID="%VIRTUALCAM-GUID%" .. -) -cd .. diff --git a/CI/linux/01_install_dependencies.sh b/CI/linux/01_install_dependencies.sh new file mode 100755 index 000000000..dc8a9594c --- /dev/null +++ b/CI/linux/01_install_dependencies.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +############################################################################## +# Linux dependency management function +############################################################################## +# +# This script file can be included in build scripts for Linux or run directly +# with the -s/--standalone switch +# +############################################################################## + +# Halt on errors +set -eE + +install_build-deps() { + shift + status "Install OBS build dependencies" + trap "caught_error 'install_build-deps'" ERR + + sudo apt-get install -y $@ +} + +install_obs-deps() { + shift + status "Install OBS dependencies" + trap "caught_error 'install_obs-deps'" ERR + + if [ -z "${DISABLE_PIPEWIRE}" ]; then + sudo apt-get install -y $@ libpipewire-0.3-dev + else + sudo apt-get install -y $@ + fi +} + +install_qt-deps() { + shift + status "Install Qt dependencies" + trap "caught_error 'install_qt-deps'" ERR + + sudo apt-get install -y $@ +} + +install_cef() { + shift + status "Setup for dependency CEF v${1}" + ensure_dir "${DEPS_BUILD_DIR}" + + if [ "${CI}" -a "${RESTORED_CEF}" ]; then + _SKIP=TRUE + elif [ -d "${DEPS_BUILD_DIR}/cef_binary_${1}_linux64" -a -f "${DEPS_BUILD_DIR}/cef_binary_${1}_linux64/build/libcef_dll_wrapper/libcef_dll_wrapper.a" ]; then + _SKIP=TRUE + fi + + if [ -z "${_SKIP}" ]; then + step "Download..." + ${CURLCMD:-curl -O} https://cdn-fastly.obsproject.com/downloads/cef_binary_${1}_linux64.tar.bz2 + step "Unpack..." + tar -xf cef_binary_${1}_linux64.tar.bz2 + else + step "Found existing Chromium Embedded Framework and loader library..." + fi +} + +install_plugin-deps() { + shift + status "Install plugin dependencies" + trap "caught_error 'install_plugin-deps'" ERR + + sudo apt-get install -y $@ +} + +install_dependencies() { + status "Set up apt" + trap "caught_error 'install_dependencies'" ERR + + BUILD_DEPS=( + "build-deps cmake ninja-build pkg-config clang clang-format build-essential curl ccache" + "obs-deps libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev \ + libswscale-dev libx264-dev libcurl4-openssl-dev libmbedtls-dev libgl1-mesa-dev libjansson-dev \ + libluajit-5.1-dev python3-dev libx11-dev libxcb-randr0-dev libxcb-shm0-dev libxcb-xinerama0-dev \ + libxcomposite-dev libxinerama-dev libxcb1-dev libx11-xcb-dev libxcb-xfixes0-dev swig libcmocka-dev \ + libpci-dev libxss-dev libglvnd-dev libgles2-mesa libgles2-mesa-dev libwayland-dev libxkbcommon-dev" + "qt-deps qtbase5-dev qtbase5-private-dev libqt5svg5-dev qtwayland5" + "cef ${LINUX_CEF_BUILD_VERSION:-${CI_LINUX_CEF_VERSION}}" + "plugin-deps libasound2-dev libfdk-aac-dev libfontconfig-dev libfreetype6-dev libjack-jackd2-dev \ + libpulse-dev libsndio-dev libspeexdsp-dev libudev-dev libv4l-dev libva-dev libvlc-dev libdrm-dev" + ) + + sudo dpkg --add-architecture amd64 + sudo apt-get -qq update + + for DEPENDENCY in "${BUILD_DEPS[@]}"; do + set -- ${DEPENDENCY} + trap "caught_error ${DEPENDENCY}" ERR + FUNC_NAME="install_${1}" + ${FUNC_NAME} ${@} + done +} + +install-dependencies-standalone() { + CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)" + PRODUCT_NAME="OBS-Studio" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh" + + status "Setup of OBS build dependencies" + install_dependencies +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "--disable-pipewire : Disable building with Pipewire support (default: off)\n" +} + +install-dependencies-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + --disable-pipewire ) DISABLE_PIPEWIRE=TRUE; shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + install-dependencies-standalone + fi +} + +install-dependencies-main $* diff --git a/CI/linux/02_build_obs.sh b/CI/linux/02_build_obs.sh new file mode 100755 index 000000000..b7006609a --- /dev/null +++ b/CI/linux/02_build_obs.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +############################################################################## +# Linux build function +############################################################################## +# +# This script file can be included in build scripts for Linux or run directly +# +############################################################################## + +# Halt on errors +set -eE + +build_obs() { + status "Build OBS" + trap "caught_error 'build app'" ERR + if [ -z "${CI}" ]; then + _backup_artifacts + fi + + step "Configure OBS..." + _configure_obs + + ensure_dir "${CHECKOUT_DIR}/" + step "Build OBS targets..." + cmake --build ${BUILD_DIR} +} + +# Function to configure OBS build +_configure_obs() { + ensure_dir "${CHECKOUT_DIR}" + status "Configuration of OBS build system..." + trap "caught_error 'configure build'" ERR + check_ccache + + if [ "${TWITCH_CLIENTID}" -a "${TWICH_HASH}" ]; then + TWITCH_OPTIONS="-DTWITCH_CLIENTID=\"${TWITCH_CLIENTID}\" -DTWITCH_HASH=\"${TWITCH_HASH}\"" + fi + + if [ "${RESTREAM_CLIENTID}" -a "${RESTREAM_HASH}" ]; then + RESTREAM_OPTIONS="-DRESTREAM_CLIENTID=\"${RESTREAM_CLIENTID}\" -DRESTREAM_HASH=\"${RESTREAM_HASH}\"" + fi + + if [ "${YOUTUBE_CLIENTID}" -a "${YOUTUBE_CLIENTID_HASH}" -a "${YOUTUBE_SECRET}" -a "{YOUTUBE_SECRET_HASH}" ]; then + YOUTUBE_OPTIONS="-DYOUTUBE_CLIENTID=\"${YOUTUBE_CLIENTID}\" -DYOUTUBE_CLIENTID_HASH=\"${YOUTUBE_CLIENTID_HASH}\" -DYOUTUBE_SECRET=\"${YOUTUBE_SECRET}\" -DYOUTUBE_SECRET_HASH=\"${YOUTUBE_SECRET_HASH}\"" + fi + + if [ "${PORTABLE}" ]; then + PORTABLE_BUILD="ON" + fi + + if [ "${DISABLE_PIPEWIRE}" ]; then + PIPEWIRE_OPTION="-DENABLE_PIPEWIRE=OFF" + fi + + cmake -S . -B ${BUILD_DIR} -G Ninja \ + -DCEF_ROOT_DIR="${DEPS_BUILD_DIR}/cef_binary_${LINUX_CEF_BUILD_VERSION:-${CI_LINUX_CEF_VERSION}}_linux64" \ + -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \ + -DLINUX_PORTABLE=${PORTABLE_BUILD:-OFF} \ + -DENABLE_AJA=OFF \ + ${PIPEWIRE_OPTION} \ + ${YOUTUBE_OPTIONS} \ + ${TWITCH_OPTIONS} \ + ${RESTREAM_OPTIONS} \ + ${CI:+-DENABLE_UNIT_TESTS=ON -DBUILD_FOR_DISTRIBUTION=${BUILD_FOR_DISTRIBUTION} -DOBS_BUILD_NUMBER=${GITHUB_RUN_ID}} \ + ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR} +} + +# Function to backup previous build artifacts +_backup_artifacts() { + ensure_dir "${CHECKOUT_DIR}" + if [ -d ${BUILD_DIR} ]; then + status "Backup of old OBS build artifacts" + + CUR_DATE=$(date +"%Y-%m-%d@%H%M%S") + NIGHTLY_DIR="${CHECKOUT_DIR}/nightly-${CUR_DATE}" + PACKAGE_NAME=$(find ${BUILD_DIR} -maxdepth 1 -name "*.deb" | sort -rn | head -1) + + if [ "${PACKAGE_NAME}" ]; then + step "Back up $(basename "${PACKAGE_NAME}")..." + ensure_dir "${NIGHTLY_DIR}" + mv "../${BUILD_DIR}/$(basename "${PACKAGE_NAME}")" ${NIGHTLY_DIR}/ + info "You can find ${PACKAGE_NAME} in ${NIGHTLY_DIR}" + fi + fi +} + +build-obs-standalone() { + CHECKOUT_DIR="$(git rev-parse --show-toplevel)" + PRODUCT_NAME="OBS-Studio" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh" + + build_obs +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-p, --portable : Create portable build (default: off)\n" \ + "--disable-pipewire : Disable building with PipeWire support (default: off)\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +build-obs-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -p | --portable ) export PORTABLE=TRUE; shift ;; + --disable-pipewire ) DISABLE_PIPEWIRE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + build-obs-standalone + fi +} + +build-obs-main $* diff --git a/CI/linux/03_package_obs.sh b/CI/linux/03_package_obs.sh new file mode 100755 index 000000000..170fba216 --- /dev/null +++ b/CI/linux/03_package_obs.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +############################################################################## +# Linux libobs plugin package function +############################################################################## +# +# This script file can be included in build scripts for Linux or run directly +# +############################################################################## + +# Halt on errors +set -eE + +package_obs() { + status "Create Linux debian package" + trap "caught_error 'package app'" ERR + + ensure_dir "${CHECKOUT_DIR}" + + step "Package OBS..." + cmake --build ${BUILD_DIR} -t package + + DEB_NAME=$(find ${BUILD_DIR} -maxdepth 1 -type f -name "obs*.deb" | sort -rn | head -1) + + if [ "${DEB_NAME}" ]; then + mv ${DEB_NAME} ${BUILD_DIR}/${FILE_NAME} + else + error "ERROR No suitable OBS debian package generated" + fi +} + +package-obs-standalone() { + PRODUCT_NAME="OBS-Studio" + + CHECKOUT_DIR="$(git rev-parse --show-toplevel)" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh" + + step "Fetch OBS tags..." + git fetch origin --tags + + GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + GIT_HASH=$(git rev-parse --short HEAD) + GIT_TAG=$(git describe --tags --abbrev=0) + + if [ "${BUILD_FOR_DISTRIBUTION}" ]; then + VERSION_STRING="${GIT_TAG}" + else + VERSION_STRING="${GIT_TAG}-${GIT_HASH}" + fi + + FILE_NAME="obs-studio-${VERSION_STRING}-Linux.deb" + package_obs +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +package-obs-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + package-obs-standalone + fi +} + +package-obs-main $* diff --git a/CI/macos/01_install_dependencies.sh b/CI/macos/01_install_dependencies.sh new file mode 100755 index 000000000..40cb2157b --- /dev/null +++ b/CI/macos/01_install_dependencies.sh @@ -0,0 +1,178 @@ +#!/bin/bash + +############################################################################## +# macOS dependency management function +############################################################################## +# +# This script file can be included in build scripts for macOS or run directly. +# +############################################################################## + +# Halt on errors +set -eE + +install_obs-deps() { + status "Set up precompiled macOS OBS dependencies v${1}" + ensure_dir "${DEPS_BUILD_DIR}" + step "Download..." + ${CURLCMD:-curl} https://github.com/obsproject/obs-deps/releases/download/${1}/macos-deps-${1}.tar.gz + step "Unpack..." + /usr/bin/tar -xf "./macos-deps-${1}.tar.gz" -C /tmp +} + +install_qt-deps() { + status "Set up precompiled dependency Qt v${1}" + ensure_dir "${DEPS_BUILD_DIR}" + step "Download..." + ${CURLCMD:-curl} https://github.com/obsproject/obs-deps/releases/download/${2}/macos-qt-${1}-${2}.tar.gz + step "Unpack..." + /usr/bin/tar -xf ./macos-qt-${1}-${2}.tar.gz -C /tmp + /usr/bin/xattr -r -d com.apple.quarantine /tmp/obsdeps +} + +install_vlc() { + status "Set up dependency VLC v${1}" + ensure_dir "${DEPS_BUILD_DIR}" + unset _SKIP + + if [ "${CI}" -a "${RESTORED_VLC}" ]; then + _SKIP=TRUE + elif [ -d "${DEPS_BUILD_DIR}/vlc-${1}" -a -f "${DEPS_BUILD_DIR}/vlc-${1}/include/vlc/vlc.h" ]; then + _SKIP=TRUE + fi + + if [ -z "${_SKIP}" ]; then + step "Download..." + check_and_fetch "https://downloads.videolan.org/vlc/${1}/vlc-${1}.tar.xz" "${2}" + step "Unpack..." + /usr/bin/tar -xf vlc-${1}.tar.xz + else + step "Found existing VLC..." + fi +} + +install_sparkle() { + status "Set up dependency Sparkle v${1}" + ensure_dir "${DEPS_BUILD_DIR}" + unset _SKIP + + if [ "${CI}" -a "${RESTORED_SPARKLE}" ]; then + _SKIP=TRUE + elif [ -d "${DEPS_BUILD_DIR}/sparkle/Sparkle.framework" -a -f "${DEPS_BUILD_DIR}/sparkle/Sparkle.framework/Sparkle" ]; then + _SKIP=TRUE + fi + + if [ -z "${_SKIP}" ]; then + step "Download..." + ${CURLCMD:-curl} https://github.com/sparkle-project/Sparkle/releases/download/${1}/Sparkle-${1}.tar.xz + step "Unpack..." + ensure_dir "${DEPS_BUILD_DIR}/sparkle" + /usr/bin/tar -xf ../Sparkle-${1}.tar.xz + else + step "Found existing Sparkle Framework..." + fi +} + +install_cef() { + status "Set up dependency CEF v${1}" + ensure_dir "${DEPS_BUILD_DIR}" + unset _SKIP + + if [ "${CI}" -a "${RESTORED_CEF}" ]; then + _SKIP=TRUE + elif [ -d "${DEPS_BUILD_DIR}/cef_binary_${1}_macos_${ARCH:-x86_64}" -a -f "${DEPS_BUILD_DIR}/cef_binary_${1}_macos_${ARCH:-x86_64}/build/libcef_dll_wrapper/libcef_dll_wrapper.a" ]; then + _SKIP=TRUE + fi + + if [ -z "${_SKIP}" ]; then + step "Download..." + ${CURLCMD:-curl} https://cdn-fastly.obsproject.com/downloads/cef_binary_${1}_macos_${ARCH:-x86_64}.tar.xz + step "Unpack..." + /usr/bin/tar -xf cef_binary_${1}_macos_${ARCH:-x86_64}.tar.xz + cd cef_binary_${1}_macos_${ARCH:-x86_64} + step "Fix tests..." + + /usr/bin/sed -i '.orig' '/add_subdirectory(tests\/ceftests)/d' ./CMakeLists.txt + /usr/bin/sed -E -i '' 's/"10.(9|10)"/"'${MACOSX_DEPLOYMENT_TARGET:-${CI_MACOSX_DEPLOYMENT_TARGET}}'"/' ./cmake/cef_variables.cmake + + step "Run CMake..." + check_ccache + cmake ${CCACHE_OPTIONS} ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR} \ + -S . -B build \ + -G Ninja \ + -DPROJECT_ARCH=${CMAKE_ARCHS:-x86_64} \ + -DCEF_COMPILER_FLAGS="-Wno-deprecated-copy" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++ -Wno-deprecated-declarations -Wno-unknown-warning-option" \ + -DCMAKE_EXE_LINKER_FLAGS="-std=c++11 -stdlib=libc++" \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-${CI_MACOSX_DEPLOYMENT_TARGET}} + + step "Build CEF v${1}..." + cmake --build build + mkdir -p build/libcef_dll + else + step "Found existing Chromium Embedded Framework and loader library..." + fi +} + +install_dependencies() { + status "Install Homebrew dependencies" + trap "caught_error 'install_dependencies'" ERR + + BUILD_DEPS=( + "obs-deps ${MACOS_DEPS_VERSION:-${CI_DEPS_VERSION}}" + "qt-deps ${QT_VERSION:-${CI_QT_VERSION}} ${MACOS_DEPS_VERSION:-${CI_DEPS_VERSION}}" + "cef ${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" + "vlc ${VLC_VERSION:-${CI_VLC_VERSION}}" + "sparkle ${SPARKLE_VERSION:-${CI_SPARKLE_VERSION}}" + ) + + install_homebrew_deps + + for DEPENDENCY in "${BUILD_DEPS[@]}"; do + set -- ${DEPENDENCY} + trap "caught_error ${DEPENDENCY}" ERR + FUNC_NAME="install_${1}" + ${FUNC_NAME} ${2} ${3} + done +} + +install-dependencies-standalone() { + CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)" + PRODUCT_NAME="OBS-Studio" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh" + + status "Setup of OBS build dependencies" + check_macos_version + check_archs + install_dependencies +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-a, --architecture : Specify build architecture (default: x86_64, alternative: arm64)\n" +} + +install-dependencies-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -a | --architecture ) ARCH="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + install-dependencies-standalone + fi +} + +install-dependencies-main $* diff --git a/CI/macos/02_build_obs.sh b/CI/macos/02_build_obs.sh new file mode 100755 index 000000000..36c644f9c --- /dev/null +++ b/CI/macos/02_build_obs.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +############################################################################## +# macOS build function +############################################################################## +# +# This script file can be included in build scripts for macOS or run directly +# +############################################################################## + +# Halt on errors +set -eE + +build_obs() { + status "Build OBS" + trap "caught_error 'build app'" ERR + + if [ -z "${CI}" ]; then + _backup_artifacts + fi + step "Configure OBS..." + _configure_obs + + ensure_dir "${CHECKOUT_DIR}/" + step "Build OBS targets..." + cmake --build ${BUILD_DIR} +} + +bundle_obs() { + status "Create relocatable macOS application bundle" + trap "caught_error 'package app'" ERR + + ensure_dir "${CHECKOUT_DIR}" + + step "Install OBS application bundle..." + cmake --install ${BUILD_DIR} +} + +# Function to configure OBS build +_configure_obs() { + if [ "${CODESIGN}" ]; then + read_codesign_ident + fi + + ensure_dir "${CHECKOUT_DIR}" + status "Configure OBS build system..." + trap "caught_error 'configure build'" ERR + check_ccache + + if [ "${TWITCH_CLIENTID}" -a "${TWICH_HASH}" ]; then + TWITCH_OPTIONS="-DTWITCH_CLIENTID=\"${TWITCH_CLIENTID}\" -DTWITCH_HASH=\"${TWITCH_HASH}\"" + fi + + if [ "${RESTREAM_CLIENTID}" -a "${RESTREAM_HASH}" ]; then + RESTREAM_OPTIONS="-DRESTREAM_CLIENTID=\"${RESTREAM_CLIENTID}\" -DRESTREAM_HASH=\"${RESTREAM_HASH}\"" + fi + + if [ "${YOUTUBE_CLIENTID}" -a "${YOUTUBE_CLIENTID_HASH}" -a "${YOUTUBE_SECRET}" -a "{YOUTUBE_SECRET_HASH}" ]; then + YOUTUBE_OPTIONS="-DYOUTUBE_CLIENTID=\"${YOUTUBE_CLIENTID}\" -DYOUTUBE_CLIENTID_HASH=\"${YOUTUBE_CLIENTID_HASH}\" -DYOUTUBE_SECRET=\"${YOUTUBE_SECRET}\" -DYOUTUBE_SECRET_HASH=\"${YOUTUBE_SECRET_HASH}\"" + fi + + if [ "${XCODE}" ]; then + GENERATOR="Xcode" + else + GENERATOR="Ninja" + fi + + cmake -S . -B ${BUILD_DIR} -G ${GENERATOR} \ + -DCEF_ROOT_DIR="${DEPS_BUILD_DIR}/cef_binary_${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}_macos_${ARCH:-x86_64}" \ + -DVLC_PATH="${DEPS_BUILD_DIR}/vlc-${VLC_VERSION:-${CI_VLC_VERSION}}" \ + -DCMAKE_PREFIX_PATH="/tmp/obsdeps;${DEPS_BUILD_DIR}/sparkle" \ + -DBROWSER_LEGACY=$(test "${MACOS_CEF_BUILD_VERSION:-${CI_MACOS_CEF_VERSION}}" -le 3770 && echo "ON" || echo "OFF") \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-${CI_MACOSX_DEPLOYMENT_TARGET}} \ + -DCMAKE_OSX_ARCHITECTURES=${CMAKE_ARCHS} \ + -DOBS_CODESIGN_LINKER=${CODESIGN_LINKER:-OFF} \ + -DCMAKE_INSTALL_PREFIX=${BUILD_DIR}/install \ + -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \ + -DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}" \ + ${YOUTUBE_OPTIONS} \ + ${TWITCH_OPTIONS} \ + ${RESTREAM_OPTIONS} \ + ${CI:+-DENABLE_UNIT_TESTS=ON -DBUILD_FOR_DISTRIBUTION=${BUILD_FOR_DISTRIBUTION} -DOBS_BUILD_NUMBER=${GITHUB_RUN_ID}} \ + ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR} +} + +# Function to backup previous build artifacts +_backup_artifacts() { + ensure_dir "${CHECKOUT_DIR}" + if [ -d "${BUILD_DIR}" ]; then + status "Backup old OBS build artifacts" + + CUR_DATE=$(/bin/date +"%Y-%m-%d@%H%M%S") + NIGHTLY_DIR="${CHECKOUT_DIR}/nightly-${CUR_DATE}" + PACKAGE_NAME=$(/usr/bin/find "${BUILD_DIR}" -name "*.dmg" -depth 1 | sort -rn | head -1) + + if [ -d "${BUILD_DIR}/install/OBS.app" ]; then + step "Back up OBS.app..." + ensure_dir "${NIGHTLY_DIR}" + /bin/mv "${CHECKOUT_DIR}/${BUILD_DIR}/install/OBS.app" "${NIGHTLY_DIR}/" + info "You can find OBS.app in ${NIGHTLY_DIR}" + fi + + if [ "${PACKAGE_NAME}" ]; then + step "Back up $(basename "${PACKAGE_NAME}")..." + ensure_dir "${NIGHTLY_DIR}" + /bin/mv "../${BUILD_DIR}/$(basename "${PACKAGE_NAME}")" "${NIGHTLY_DIR}/" + info "You can find ${PACKAGE_NAME} in ${NIGHTLY_DIR}" + fi + fi +} + +build-obs-standalone() { + CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)" + PRODUCT_NAME="OBS-Studio" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh" + + check_archs + check_macos_version + build_obs + + if [ "${BUNDLE}" ]; then + bundle_obs + fi +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-a, --architecture : Specify build architecture (default: x86_64, alternative: arm64)\n" \ + "-c, --codesign : Codesign OBS and all libraries (default: ad-hoc only)\n" \ + "-b, --bundle : Create relocatable OBS application bundle in build directory (default: build/install/OBS.app)\n" \ + "--xcode : Create Xcode build environment instead of Ninja\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +build-obs-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -a | --architecture ) ARCH="${2}"; shift 2 ;; + -c | --codesign ) CODESIGN=TRUE; shift ;; + -b | --bundle ) BUNDLE=TRUE; shift ;; + --xcode ) XCODE=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + build-obs-standalone + fi +} + +build-obs-main $* diff --git a/CI/macos/03_package_obs.sh b/CI/macos/03_package_obs.sh new file mode 100755 index 000000000..f678e242a --- /dev/null +++ b/CI/macos/03_package_obs.sh @@ -0,0 +1,185 @@ +#!/bin/bash + +############################################################################## +# macOS libobs plugin package function +############################################################################## +# +# This script file can be included in build scripts for macOS or run directly +# +############################################################################## + +# Halt on errors +set -eE + +package_obs() { + if [ "${CODESIGN}" ]; then + read_codesign_ident + fi + + status "Create macOS disk image" + trap "caught_error 'package app'" ERR + + info "/!\\ CPack will use an AppleScript to create the disk image, this will lead to a Finder window opening to adjust window settings. /!\\" + + ensure_dir "${CHECKOUT_DIR}" + + step "Package OBS..." + cmake --build ${BUILD_DIR} -t package + + DMG_NAME=$(/usr/bin/find "${BUILD_DIR}" -type f -name "OBS-*.dmg" -depth 1 | sort -rn | head -1) + + if [ "${DMG_NAME}" ]; then + mv "${DMG_NAME}" "${BUILD_DIR}/${FILE_NAME}" + + step "Codesign OBS disk image..." + /usr/bin/codesign --force --sign "${CODESIGN_IDENT:--}" "${BUILD_DIR}/${FILE_NAME}" + else + error "ERROR No suitable OBS disk image generated" + fi +} + +notarize_obs() { + status "Notarize OBS" + trap "caught_error 'notarizing app'" ERR + + if ! exists brew; then + error "ERROR Homebrew not found - please install homebrew (https://brew.sh)" + exit 1 + fi + + if ! exists xcnotary; then + step "Install notarization dependency 'xcnotary'" + brew install akeru-inc/tap/xcnotary + fi + + ensure_dir "${CHECKOUT_DIR}" + + if [ "${NOTARIZE_IMAGE}" ]; then + trap "_caught_error_xcnotary '${NOTARIZE_IMAGE}'" ERR + + step "Attach OBS disk image ${NOTARIZE_IMAGE}..." + hdiutil attach -readonly -noverify -noautoopen -quiet "${NOTARIZE_IMAGE}" + + VOLUME_NAME=$(hdiutil info -plist | grep "/Volumes/OBS-" | sed 's/\/Volumes\/\([^<]*\)<\/string>/\1/' | sed -e 's/^[[:space:]]*//') + PRECHECK="/Volumes/${VOLUME_NAME}/OBS.app" + NOTARIZE_TARGET="${NOTARIZE_IMAGE}" + elif [ "${NOTARIZE_BUNDLE}" ]; then + PRECHECK="${NOTARIZE_BUNDLE}" + NOTARIZE_TARGET="${NOTARIZE_BUNDLE}" + else + OBS_IMAGE="${BUILD_DIR}/${FILE_NAME}" + + if [ -f "${OBS_IMAGE}" ]; then + OBS_BUNDLE=$(/usr/bin/find "${BUILD_DIR}/_CPack_Packages" -type d -name "OBS.app") + PRECHECK="${OBS_BUNDLE}" + NOTARIZE_TARGET="${OBS_IMAGE}" + else + error "No notarization application bundle ('OBS.app') or disk image ('${NOTARIZE_IMAGE:-${FILE_NAME}}') found" + return + fi + fi + + step "Run notarization pre-checks on OBS.app..." + xcnotary precheck "${PRECHECK}" + + if [ "$?" -eq 0 ]; then + read_codesign_ident + read_codesign_pass + + step "Run xcnotary with ${NOTARIZE_TARGET}..." + xcnotary notarize "${NOTARIZE_TARGET}" --developer-account "${CODESIGN_IDENT_USER}" --developer-password-keychain-item "OBS-Codesign-Password" --provider "${CODESIGN_IDENT_SHORT}" + fi + + if [ "${NOTARIZE_IMAGE}" -a -d "/Volumes/${VOLUME_NAME}" ]; then + step "Detach OBS disk image ${NOTARIZE_IMAGE}..." + hdiutil detach "/Volumes/${VOLUME_NAME}" -quiet + fi +} + +_caught_error_xcnotary() { + error "ERROR during notarization of image '${1}'" + + if [ -d "/Volumes/${1}" ]; then + step "Detach OBS disk image ${1}..." + hdiutil detach "/Volumes/${1}" -quiet + fi + + cleanup + exit 1 +} + +package-obs-standalone() { + PRODUCT_NAME="OBS-Studio" + + CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)" + DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies" + source "${CHECKOUT_DIR}/CI/include/build_support.sh" + source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh" + + check_macos_version + check_archs + + step "Fetch OBS tags..." + /usr/bin/git fetch origin --tags + + GIT_BRANCH=$(/usr/bin/git rev-parse --abbrev-ref HEAD) + GIT_HASH=$(/usr/bin/git rev-parse --short HEAD) + GIT_TAG=$(/usr/bin/git describe --tags --abbrev=0) + + if [ "${BUILD_FOR_DISTRIBUTION}" ]; then + VERSION_STRING="${GIT_TAG}" + else + VERSION_STRING="${GIT_TAG}-${GIT_HASH}" + fi + + if [ -z "${NOTARIZE_IMAGE}" -a -z "${NOTARIZE_BUNDLE}" ]; then + if [ "${ARCH}" = "arm64" ]; then + FILE_NAME="obs-studio-${VERSION_STRING}-macOS-Apple.dmg" + elif [ "${ARCH}" = "universal" ]; then + FILE_NAME="obs-studio-${VERSION_STRING}-macOS.dmg" + else + FILE_NAME="obs-studio-${VERSION_STRING}-macOS-Intel.dmg" + fi + + package_obs + fi + + if [ "${NOTARIZE}" ]; then + notarize_obs + fi +} + +print_usage() { + echo -e "Usage: ${0}\n" \ + "-h, --help : Print this help\n" \ + "-q, --quiet : Suppress most build process output\n" \ + "-v, --verbose : Enable more verbose build process output\n" \ + "-c, --codesign : Codesign OBS and all libraries (default: ad-hoc only)\n" \ + "-n, --notarize : Notarize OBS (default: off)\n" \ + "--notarize-image [IMAGE] : Specify existing OBS disk image for notarization\n" \ + "--notarize-bundle [BUNDLE] : Specify existing OBS application bundle for notarization\n" \ + "--build-dir : Specify alternative build directory (default: build)\n" +} + +package-obs-main() { + if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then + while true; do + case "${1}" in + -h | --help ) print_usage; exit 0 ;; + -q | --quiet ) export QUIET=TRUE; shift ;; + -v | --verbose ) export VERBOSE=TRUE; shift ;; + -c | --codesign ) CODESIGN=TRUE; shift ;; + -n | --notarize ) NOTARIZE=TRUE; CODESIGN=TRUE; shift ;; + --build-dir ) BUILD_DIR="${2}"; shift 2 ;; + --notarize-image ) NOTARIZE_IMAGE="${2}"; NOTARIZE=TRUE; CODESIGN=TRUE; shift 2 ;; + --notarize-bundle ) NOTARIZE_BUNDLE="${2}"; NOTARIZE=TRUE; CODESIGN=TRUE; shift 2 ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + package-obs-standalone + fi +} + +package-obs-main $* diff --git a/CI/scripts/macos/Brewfile b/CI/scripts/macos/Brewfile deleted file mode 100644 index eff533552..000000000 --- a/CI/scripts/macos/Brewfile +++ /dev/null @@ -1,5 +0,0 @@ -tap "akeru-inc/tap" -brew "cmake" -brew "freetype" -brew "cmocka" -brew "akeru-inc/tap/xcnotary" \ No newline at end of file diff --git a/CI/scripts/macos/app/AppIcon.icns b/CI/scripts/macos/app/AppIcon.icns deleted file mode 100644 index b4cf117ed..000000000 Binary files a/CI/scripts/macos/app/AppIcon.icns and /dev/null differ diff --git a/CI/scripts/macos/app/OBSPublicDSAKey.pem b/CI/scripts/macos/app/OBSPublicDSAKey.pem deleted file mode 100644 index 91adb402f..000000000 --- a/CI/scripts/macos/app/OBSPublicDSAKey.pem +++ /dev/null @@ -1,36 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIGPDCCBC4GByqGSM44BAEwggQhAoICAQCZZZ2y7H2GJmMfP4KQihJTJOoiGNUw -mue6sqMbH+utRykRnSKBZux6R665eRFMpNgrgFO1TLLGbdD2U31KiGtCvFJOmOl3 -+QP055BuXjEG36NU7AWEFLAlbDlr/2D3oumq3Ib3iMnnr9RrVztJ2VFOvVio1eWr -ZxboVwKPK8D6BqsWiv15vbYlJnTC4Fls6ySmdjVBxwoPlTaMu1ysi5DfbIZ93s5u -aQt1FvXuWtPBWjyVUORcNbcWf49E5R2pV0OSBK95Hw2/wXz4vmj+w92dTePGnVaW -Me4CoF5PIeZILwp6DCLStX4eW2WG1NChJTC8zeQ/3bMMoGyKM/MadyvrDqMywsKY -caxkIwHrDKOEdXXGo80dIwZMMLipPA8DKhx5ojphfkeXjIhKSx+49knXT3ED5okE -Wai7tGUXj/8D8sGh+7b+AVsdujvr4v8WQaZiKUOZ2IIHOg3VLz9T9v0zet1Yt987 -KNymFcp2CHeJ6KnDP/ZGQ6Nl0HsPxUgscsXV+R2FEc8Q1j0Ukkuxnopa0E4/huUu -gjyRzpXD734qFMDf7LcXca6qNjBor6gVj5sRyRKCpZ+KQfMUlr8jp506ztYSyeJu -dxJV30tQgztwkbrs02CqOt4Z3Peo6sdht7hWKSPVwmja3tq8/TfUSSoo6wKYN9/w -Mf3dVeRF8hCzJQIVAJnzuzmzQhCKPiQnl3jh5qGII2XfAoICAQCCVATAff89ceHj -ROHEbHTQFpVxJ/kRZPfxnU46DSw79Tih7tthV68oakPSOTP3cx/Tga0GwogarZ9N -F2VVan5w9OQSSewXsr5UDT5bnmJF+h+JB7TMy+sXZBYobUqjlUd5VtKc8RsN86P4 -s7xbK0mA+hfe+27r18JT81/eH3xUfh7UOUGSdMN2Ch9f7RFSMZIgUAZUzu2K3ODp -hPgtc2QJ8QVAp7GLvQgw8ZUME/ChZslyBIyJvYgUIxfxlgRWYro5pQT7/ngkgdXo -wlghHKkldwMuY3zaFdhPnFNuEUEtc18ILsbz0+AnagCUd6n+3safskCRqLIHMOY6 -iLBSZPX9hJQhVCqSqz1VNDDww8FNa/fojJ1Lr/TI0I+0Ib2pCiY2LChXUqGY5SLZ -2KNs5qFsyZP+I0L8YsGwqvUYyFwk7Ok224n0NtaOwqpLCrtXd/i6DaDNiaoJuwJC -1ELCfaZivorgkC5rhBt2H7qWUAR+EtrFE/gb0k/G5EIhjYql7onGbX+G2re38vQA -fg1pzguhig2dafP/BxMLZrn1Gg61xzmEYPuS9gclktaf675srv8GVb46VkOxXL+D -YvTmpJPP7UUOVlmAMCo4j4y09MW3jq9TDp42VTLeZVubyjslGnavlnq1O+ZyXUye -1FMeby65sIbSHHHwoFnRv3hLSEXI5gOCAgYAAoICAQCUkYnZkPfHfOJZI403xUYP -CE/bLpkza074Xo6EXElsWRnpQgNTx+JFOvItgj3v0OkIqDin9UredKOwfkiftslV -jxUVKA6I5kwnGvCpvTpQMLyLjq+VQr+J2D6eId6tV/iajhdu5r4JThU8KllT7Ywb -NAur34ftLNCVAMRUaDNeEoHfePgderW384e+lbvpmtifmBluammGSxxRtUsdjvJZ -BFkhaJu86CKxcU7D1lbPVOtV/jaxz6d16VdGcfBdi2LzXZzZtYpT9XGPX3NF+xii -spAURWsoe11LTRXF+eJhgCm5iIDN3kh1HEQKYKAVpmrcM0aFzk/NpS+tFyU72vaq -IRSSJw/aa1oELOAakG5oPldc4RcYWl32sbnVwXHO7TZvgTrBSC10o65MAC5CHP/s -b07heDYAIt7re7szvOYq+c/9zAMAlu3pcO8MqaXYMmybdHBXHQ2b+DdJWHmIUWcX -CbUzr09vzGkJAvqsXqbmJPr8aixrO75DhT0iDTILLWe/GWK51nf+Tg0pNxVgGyAl -BqvRqqo7SSDu9FMkwQesFFHhuoHLyEHwVPJ+sMQTNwQcm9c6YuW8EYDRSkeKLWYk -3fkjG+Pe9uVE8a1taDg3FjSY0UqjUT6XMw+i0Lajyus2L6wFBwrrGM6E4xa6x1CC -MGjmuSOlPA1umQsToIcO4g== ------END PUBLIC KEY----- diff --git a/CI/scripts/macos/app/big_sur_icon_template.psd b/CI/scripts/macos/app/big_sur_icon_template.psd deleted file mode 100644 index 71af91dd1..000000000 Binary files a/CI/scripts/macos/app/big_sur_icon_template.psd and /dev/null differ diff --git a/CI/scripts/macos/app/dylibbundler b/CI/scripts/macos/app/dylibbundler deleted file mode 100755 index 2634e6396..000000000 Binary files a/CI/scripts/macos/app/dylibbundler and /dev/null differ diff --git a/CI/scripts/macos/app/entitlements.plist b/CI/scripts/macos/app/entitlements.plist deleted file mode 100644 index 516d0d521..000000000 --- a/CI/scripts/macos/app/entitlements.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.device.camera - - com.apple.security.device.audio-input - - com.apple.security.cs.disable-library-validation - - - com.apple.security.cs.allow-dyld-environment-variables - - - diff --git a/CI/scripts/macos/app/obs.icns b/CI/scripts/macos/app/obs.icns deleted file mode 100644 index 6f878d6a3..000000000 Binary files a/CI/scripts/macos/app/obs.icns and /dev/null differ diff --git a/CI/scripts/macos/helpers/helper-entitlements.plist b/CI/scripts/macos/helpers/helper-entitlements.plist deleted file mode 100644 index 22d3b9cc5..000000000 --- a/CI/scripts/macos/helpers/helper-entitlements.plist +++ /dev/null @@ -1,12 +0,0 @@ - - - - - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.cs.disable-library-validation - - com.apple.security.cs.allow-jit - - - \ No newline at end of file diff --git a/CI/scripts/macos/helpers/helper-gpu-entitlements.plist b/CI/scripts/macos/helpers/helper-gpu-entitlements.plist deleted file mode 100644 index ac08c81b7..000000000 --- a/CI/scripts/macos/helpers/helper-gpu-entitlements.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.cs.allow-jit - - - \ No newline at end of file diff --git a/CI/scripts/macos/helpers/helper-plugin-entitlements.plist b/CI/scripts/macos/helpers/helper-plugin-entitlements.plist deleted file mode 100644 index d56643431..000000000 --- a/CI/scripts/macos/helpers/helper-plugin-entitlements.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.cs.disable-library-validation - - - \ No newline at end of file diff --git a/CI/scripts/macos/helpers/helper-renderer-entitlements.plist b/CI/scripts/macos/helpers/helper-renderer-entitlements.plist deleted file mode 100644 index ac08c81b7..000000000 --- a/CI/scripts/macos/helpers/helper-renderer-entitlements.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.cs.allow-jit - - - \ No newline at end of file diff --git a/CI/scripts/macos/package/background.tiff b/CI/scripts/macos/package/background.tiff deleted file mode 100644 index 454874005..000000000 Binary files a/CI/scripts/macos/package/background.tiff and /dev/null differ diff --git a/CI/scripts/macos/package/settings.json.template b/CI/scripts/macos/package/settings.json.template deleted file mode 100644 index de39e030f..000000000 --- a/CI/scripts/macos/package/settings.json.template +++ /dev/null @@ -1,28 +0,0 @@ -{ - "title": "OBS-Studio $$VERSION$$", - "background": "$$CI_PATH$$/package/background.tiff", - "icon": "$$CI_PATH$$/app/AppIcon.icns", - "format": "ULFO", - "icon-size": 96, - "window": { - "position": { - "x": 100, - "y": 100 - }, - "size": { - "width": 540, - "height": 380 - } - }, - "contents": [{ - "x": 124, - "y": 180, - "type": "file", - "path": "$$BUNDLE_PATH$$/OBS.app" - }, { - "x": 416, - "y": 180, - "type": "link", - "path": "/Applications" - }] -} \ No newline at end of file diff --git a/CI/scripts/macos/package/src/background.png b/CI/scripts/macos/package/src/background.png deleted file mode 100644 index 02c4d5501..000000000 Binary files a/CI/scripts/macos/package/src/background.png and /dev/null differ diff --git a/CI/scripts/macos/package/src/background@2x.png b/CI/scripts/macos/package/src/background@2x.png deleted file mode 100644 index a001edf36..000000000 Binary files a/CI/scripts/macos/package/src/background@2x.png and /dev/null differ diff --git a/CI/scripts/macos/package/src/makeRetinaBG b/CI/scripts/macos/package/src/makeRetinaBG deleted file mode 100755 index 5d7f309b5..000000000 --- a/CI/scripts/macos/package/src/makeRetinaBG +++ /dev/null @@ -1 +0,0 @@ -tiffutil -cathidpicheck background.png background@2x.png -out background.tiff diff --git a/CI/windows/01_install_dependencies.ps1 b/CI/windows/01_install_dependencies.ps1 new file mode 100644 index 000000000..cddc2f820 --- /dev/null +++ b/CI/windows/01_install_dependencies.ps1 @@ -0,0 +1,177 @@ +Param( + [Switch]$Help = $(if (Test-Path variable:Help) { $Help }), + [Switch]$Quiet = $(if (Test-Path variable:Quiet) { $Quiet }), + [Switch]$Verbose = $(if (Test-Path variable:Verbose) { $Verbose }), + [ValidateSet("32-bit", "64-bit")] + [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" } else { (Get-CimInstance CIM_OperatingSystem).OSArchitecture }) +) + +############################################################################## +# Windows dependency management function +############################################################################## +# +# This script file can be included in build scripts for Windows or run +# directly +# +############################################################################## + +$ErrorActionPreference = "Stop" + +Function Install-obs-deps { + Param( + [Parameter(Mandatory=$true)] + [String]$Version + ) + + Write-Status "Setup for pre-built Windows OBS dependencies v${Version}" + Ensure-Directory $DepsBuildDir + + if (!(Test-Path "$DepsBuildDir/dependencies${Version}")) { + + Write-Step "Download..." + $ProgressPreference = $(if ($Quiet.isPresent) { "SilentlyContinue" } else { "Continue" }) + Invoke-WebRequest -Uri "https://cdn-fastly.obsproject.com/downloads/dependencies${Version}.zip" -UseBasicParsing -OutFile "dependencies${Version}.zip" + $ProgressPreference = "Continue" + + Write-Step "Unpack..." + + Expand-Archive -Path "dependencies${Version}.zip" + } else { + Write-Step "Found existing pre-built dependencies..." + } +} + +function Install-qt-deps { + Param( + [Parameter(Mandatory=$true)] + [String]$Version + ) + + Write-Status "Setup for pre-built dependency Qt v${Version}" + Ensure-Directory $DepsBuildDir + + if (!(Test-Path "$DepsBuildDir/Qt_${Version}")) { + + Write-Step "Download..." + $ProgressPreference = $(if ($Quiet.isPresent) { 'SilentlyContinue' } else { 'Continue' }) + Invoke-WebRequest -Uri "https://cdn-fastly.obsproject.com/downloads/Qt_${Version}.7z" -UseBasicParsing -OutFile "Qt_${Version}.7z" + $ProgressPreference = "Continue" + + Write-Step "Unpack..." + + # TODO: Replace with zip and properly package Qt to share directory with other deps + Invoke-Expression "7z x Qt_${Version}.7z" + Move-Item -Path "${Version}" -Destination "Qt_${Version}" + } else { + Write-Step "Found existing pre-built Qt..." + } +} + +function Install-vlc { + Param( + [Parameter(Mandatory=$true)] + [String]$Version + ) + + Write-Status "Setup for dependency VLC v${Version}" + Ensure-Directory $DepsBuildDir + + if (!((Test-Path "$DepsBuildDir/vlc-${Version}") -and (Test-Path "$DepsBuildDir/vlc-${Version}/include/vlc/vlc.h"))) { + Write-Step "Download..." + $ProgressPreference = $(if ($Quiet.isPresent) { 'SilentlyContinue' } else { 'Continue' }) + Invoke-WebRequest -Uri "https://cdn-fastly.obsproject.com/downloads/vlc.zip" -UseBasicParsing -OutFile "vlc_${Version}.zip" + $ProgressPreference = "Continue" + + Write-Step "Unpack..." + # Expand-Archive -Path "vlc_${Version}.zip" + Invoke-Expression "7z x vlc_${Version}.zip -ovlc" + Move-Item -Path vlc -Destination "vlc-${Version}" + } else { + Write-Step "Found existing VLC..." + } +} + +function Install-cef { + Param( + [Parameter(Mandatory=$true)] + [String]$Version + ) + Write-Status "Setup for dependency CEF v${Version} - ${BuildArch}" + + Ensure-Directory $DepsBuildDir + $ArchSuffix = "$(if ($BuildArch -eq "64-bit") { "x64" } else { "x86" })" + + if (!((Test-Path "${DepsBuildDir}/cef_binary_${Version}_windows_${ArchSuffix}") -and (Test-Path "${DepsBuildDir}/cef_binary_${Version}_windows_${ArchSuffix}/build/libcef_dll_wrapper/Release/libcef_dll_wrapper.lib"))) { + Write-Step "Download..." + $ProgressPreference = $(if ($Quiet.isPresent) { 'SilentlyContinue' } else { 'Continue' }) + Invoke-WebRequest -Uri "https://cdn-fastly.obsproject.com/downloads/cef_binary_${Version}_windows_${ArchSuffix}.zip" -UseBasicParsing -OutFile "cef_binary_${Version}_windows_${ArchSuffix}.zip" + $ProgressPreference = "Continue" + + Write-Step "Unpack..." + Invoke-Expression "7z x cef_binary_${Version}_windows_${ArchSuffix}.zip" + } else { + Write-Step "Found existing CEF framework and loader library..." + } +} + +function Install-Dependencies { + Param( + [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" }) + ) + + if($Choco.isPresent) { + Install-Windows-Dependencies + } + + $BuildDependencies = @( + @('obs-deps', $WindowsDepsVersion), + @('qt-deps', $WindowsQtVersion), + @('vlc', $WindowsVlcVersion), + @('cef', $WindowsCefVersion) + ) + + Foreach($Dependency in ${BuildDependencies}) { + $DependencyName = $Dependency[0] + $DependencyVersion = $Dependency[1] + + $FunctionName = "Install-${DependencyName}" + Invoke-Expression "${FunctionName} -Version ${DependencyVersion}" + } + + Ensure-Directory ${CheckoutDir} +} + +function Install-Dependencies-Standalone { + $ProductName = "OBS-Studio" + $CheckoutDir = Resolve-Path -Path "$PSScriptRoot\..\.." + $DepsBuildDir = "${CheckoutDir}/../obs-build-dependencies" + $ObsBuildDir = "${CheckoutDir}/../obs-studio" + + . ${CheckoutDir}/CI/include/build_support_windows.ps1 + + Write-Status "Setup of OBS build dependencies" + Install-Dependencies +} + +function Print-Usage { + $Lines = @( + "Usage: ${_ScriptName}", + "-Help : Print this help", + "-Quiet : Suppress most build process output", + "-Verbose : Enable more verbose build process output", + "-Choco : Enable automatic dependency installation via Chocolatey - Default: off" + "-BuildArch : Build architecture to use (32-bit or 64-bit) - Default: local architecture" + ) + + $Lines | Write-Host +} + +if(!(Test-Path variable:_RunObsBuildScript)) { + $_ScriptName = "$($MyInvocation.MyCommand.Name)" + if($Help.isPresent) { + Print-Usage + exit 0 + } + + Install-Dependencies-Standalone +} diff --git a/CI/windows/02_build_obs.ps1 b/CI/windows/02_build_obs.ps1 new file mode 100644 index 000000000..fb3f899ee --- /dev/null +++ b/CI/windows/02_build_obs.ps1 @@ -0,0 +1,116 @@ +Param( + [Switch]$Help = $(if (Test-Path variable:Help) { $Help }), + [Switch]$Quiet = $(if (Test-Path variable:Quiet) { $Quiet }), + [Switch]$Verbose = $(if (Test-Path variable:Verbose) { $Verbose }), + [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" } else { "build" }), + [ValidateSet("32-bit", "64-bit")] + [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" } else { (Get-CimInstance CIM_OperatingSystem).OSArchitecture }), + [ValidateSet("Release", "RelWithDebInfo", "MinSizeRel", "Debug")] + [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" } else { "RelWithDebInfo" }) +) + +############################################################################## +# Windows libobs library build function +############################################################################## +# +# This script file can be included in build scripts for Windows or run +# directly +# +############################################################################## + +$ErrorActionPreference = "Stop" + +function Build-OBS { + Param( + [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" }), + [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" }), + [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" }) + ) + + Write-Status "Build OBS" + + Configure-OBS + + Ensure-Directory ${CheckoutDir} + Write-Step "Build OBS targets..." + + Invoke-Expression "cmake --build $(if($BuildArch -eq "64-bit") { "build64" } else { "build32" }) --config ${BuildConfiguration}" +} + +function Configure-OBS { + Ensure-Directory ${CheckoutDir} + Write-Status "Configuration of OBS build system..." + + # TODO: Clean up archive and directory naming across dependencies + $QtDirectory = "${CheckoutDir}/../obs-build-dependencies/Qt_${WindowsQtVersion}/msvc2019$(if (${BuildArch} -eq "64-bit") { "_64" })" + $DepsDirectory = "${CheckoutDir}/../obs-build-dependencies/dependencies${WindowsDepsVersion}/win$(if (${BuildArch} -eq "64-bit") { "64" } else { "32" })" + $CefDirectory = "${CheckoutDir}/../obs-build-dependencies/cef_binary_${WindowsCefVersion}_windows_$(if (${BuildArch} -eq "64-bit") { "x64" } else { "x86" })" + $CmakePrefixPath = "${QtDirectory};${DepsDirectory}/bin;${DepsDirectory}" + $BuildDirectoryActual = "${BuildDirectory}$(if (${BuildArch} -eq "64-bit") { "64" } else { "32" })" + $GeneratorPlatform = "$(if (${BuildArch} -eq "64-bit") { "x64" } else { "Win32" })" + + $CmakeCommand = @( + "-S . -B `"${BuildDirectoryActual}`"", + "-G `"${CmakeGenerator}`"", + "-DCMAKE_GENERATOR_PLATFORM=`"${GeneratorPlatform}`"", + "-DCMAKE_SYSTEM_VERSION=`"${CmakeSystemVersion}`"", + "-DCMAKE_PREFIX_PATH=`"${CmakePrefixPath}`"", + "-DCEF_ROOT_DIR=`"${CefDirectory}`"", + "-DVLC_PATH=`"${CheckoutDir}/../obs-build-dependencies/vlc-${WindowsVlcVersion}`"", + "-DCMAKE_INSTALL_PREFIX=`"${BuildDirectoryActual}/install`"", + "-DVIRTUALCAM_GUID=`"${Env:VIRTUALCAM-GUID}`"", + "-DTWITCH_CLIENTID=`"${Env:TWITCH_CLIENTID}`"", + "-DTWITCH_HASH=`"${Env:TWITCH_HASH}`"", + "-DRESTREAM_CLIENTID=`"${Env:RESTREAM_CLIENTID}`"", + "-DRESTREAM_HASH=`"${Env:RESTREAM_HASH}`"", + "-DYOUTUBE_CLIENTID=`"${Env:YOUTUBE_CLIENTID}`"", + "-DYOUTUBE_CLIENTID_HASH=`"${Env:YOUTUBE_CLIENTID_HASH}`"", + "-DYOUTUBE_SECRET=`"${Env:YOUTUBE_SECRET}`"", + "-DYOUTUBE_SECRET_HASH=`"${Env:YOUTUBE_SECRET_HASH}`"", + "-DCOPIED_DEPENDENCIES=OFF", + "-DCOPY_DEPENDENCIES=ON", + "-DBUILD_FOR_DISTRIBUTION=`"$(if (Test-Path Env:BUILD_FOR_DISTRIBUTION) { "ON" } else { "OFF" })`"", + "$(if (Test-Path Env:CI) { "-DOBS_BUILD_NUMBER=${Env:GITHUB_RUN_ID}" })", + "$(if (Test-Path Variable:$Quiet) { "-Wno-deprecated -Wno-dev --log-level=ERROR" })" + ) + + Invoke-Expression "cmake ${CmakeCommand}" + + Ensure-Directory ${CheckoutDir} +} + +function Build-OBS-Standalone { + $ProductName = "OBS-Studio" + + $CheckoutDir = Resolve-Path -Path "$PSScriptRoot\..\.." + $DepsBuildDir = "${CheckoutDir}/../obs-build-dependencies" + $ObsBuildDir = "${CheckoutDir}/../obs-studio" + + . ${CheckoutDir}/CI/include/build_support_windows.ps1 + + Build-OBS +} + +function Print-Usage { + $Lines = @( + "Usage: ${_ScriptName}", + "-Help : Print this help", + "-Quiet : Suppress most build process output", + "-Verbose : Enable more verbose build process output", + "-BuildDirectory : Directory to use for builds - Default: build64 on 64-bit systems, build32 on 32-bit systems", + "-BuildArch : Build architecture to use (32-bit or 64-bit) - Default: local architecture", + "-BuildConfiguration : Build configuration to use - Default: RelWithDebInfo" + ) + + $Lines | Write-Host +} + +if(!(Test-Path variable:_RunObsBuildScript)) { + $_ScriptName = "$($MyInvocation.MyCommand.Name)" + if($Help.isPresent) { + Print-Usage + exit 0 + } + + Build-OBS-Standalone +} diff --git a/CI/windows/03_package_obs.ps1 b/CI/windows/03_package_obs.ps1 new file mode 100644 index 000000000..7e4aa96af --- /dev/null +++ b/CI/windows/03_package_obs.ps1 @@ -0,0 +1,155 @@ +Param( + [Switch]$Help = $(if (Test-Path variable:Help) { $Help }), + [Switch]$Quiet = $(if (Test-Path variable:Quiet) { $Quiet }), + [Switch]$Verbose = $(if (Test-Path variable:Verbose) { $Verbose }), + [Switch]$BuildInstaller = $(if ($BuildInstaller.isPresent) { $BuildInstaller }), + [Switch]$CombinedArchs = $(if ($CombinedArchs.isPresent) { $CombinedArchs }), + [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" } else { "build" }), + [ValidateSet("32-bit", "64-bit")] + [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" } else { (Get-CimInstance CIM_OperatingSystem).OSArchitecture }), + [ValidateSet("Release", "RelWithDebInfo", "MinSizeRel", "Debug")] + [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" } else { "RelWithDebInfo" }) +) + +############################################################################## +# Windows OBS package function +############################################################################## +# +# This script file can be included in build scripts for Windows or run +# directly +# +############################################################################## + +$ErrorActionPreference = "Stop" + +function Package-OBS { + Param( + [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" }), + [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" }), + [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" }) + ) + + Write-Status "Package plugin ${ProductName}" + Ensure-Directory ${CheckoutDir} + + if ($CombinedArchs.isPresent) { + if (!(Test-Path env:obsInstallerTempDir)) { + $Env:obsInstallerTempDir = "${CheckoutDir}/install_temp" + } + + if (!(Test-Path ${CheckoutDir}/install_temp/bin/64bit)) { + Write-Step "Build 64-bit OBS..." + Invoke-Expression "cmake -S . -B `"${BuildDirectory}64`" -DCOPIED_DEPENDENCIES=OFF -DCOPY_DEPENDENCIES=ON" + Invoke-Expression "cmake --build `"${BuildDirectory}64`" --config `"${BuildConfiguration}`"" + } + + if (!(Test-Path ${CheckoutDir}/install_temp/bin/32bit)) { + Write-Step "Build 32-bit OBS..." + Invoke-Expression "cmake -S . -B `"${BuildDirectory}32`" -DCOPIED_DEPENDENCIES=OFF -DCOPY_DEPENDENCIES=ON" + Invoke-Expression "cmake --build `"${BuildDirectory}32`" --config `"${BuildConfiguration}`"" + } + + Write-Step "Prepare Installer run..." + Invoke-Expression "cmake -S . -B build -DINSTALLER_RUN=ON -DCMAKE_INSTALL_PREFIX=`"${CheckoutDir}/build/install`"" + Write-Step "Execute Installer run..." + Invoke-Expression "cmake --build build --config `"${BuildConfiguration}`" -t install" + + $CompressVars = @{ + Path = "${CheckoutDir}/build/install/*" + CompressionLevel = "Optimal" + DestinationPath = "${FileName}-Windows.zip" + } + + Write-Step "Creating zip archive..." + + $ProgressPreference = $(if ($Quiet.isPresent) { 'SilentlyContinue' } else { 'Continue' }) + Compress-Archive -Force @CompressVars + $ProgressPreference = 'Continue' + + } elseif ($BuildArch -eq "64-bit") { + Write-Step "Install 64-bit OBS..." + Invoke-Expression "cmake --build `"${BuildDirectory}64`" --config ${BuildConfiguration} -t install" + + $CompressVars = @{ + Path = "${CheckoutDir}/build64/install/bin", "${CheckoutDir}/build64/install/data", "${CheckoutDir}/build64/install/obs-plugins" + CompressionLevel = "Optimal" + DestinationPath = "${FileName}-Win64.zip" + } + + Write-Step "Creating zip archive..." + + $ProgressPreference = $(if ($Quiet.isPresent) { 'SilentlyContinue' } else { 'Continue' }) + Compress-Archive -Force @CompressVars + $ProgressPreference = 'Continue' + + } elseif ($BuildArch -eq "32-bit") { + Write-Step "Install 32-bit OBS..." + Invoke-Expression "cmake --build `"${BuildDirectory}32`" --config ${BuildConfiguration} -t install" + + $CompressVars = @{ + Path = "${CheckoutDir}/build32/install/bin", "${CheckoutDir}/build32/install/data", "${CheckoutDir}/build32/install/obs-plugins" + CompressionLevel = "Optimal" + DestinationPath = "${FileName}-Win32.zip" + } + + Write-Step "Creating zip archive..." + + $ProgressPreference = $(if ($Quiet.isPresent) { 'SilentlyContinue' } else { 'Continue' }) + Compress-Archive -Force @CompressVars + $ProgressPreference = 'Continue' + + } +} + +function Package-OBS-Standalone { + $ProductName = "OBS-Studio" + $CheckoutDir = Resolve-Path -Path "$PSScriptRoot\..\.." + + . ${CheckoutDir}/CI/include/build_support_windows.ps1 + + Write-Step "Fetch OBS tags..." + $null = git fetch origin --tags + + Ensure-Directory ${CheckoutDir} + $GitBranch = git rev-parse --abbrev-ref HEAD + $GitHash = git rev-parse --short HEAD + $ErrorActionPreference = "SilentlyContinue" + $GitTag = git describe --tags --abbrev=0 + $ErrorActionPreference = "Stop" + + if(Test-Path variable:BUILD_FOR_DISTRIBUTION) { + $VersionString = "${GitTag}" + } else { + $VersionString = "${GitTag}-${GitHash}" + } + + $FileName = "${ProductName}-${VersionString}" + + Package-OBS +} + +function Print-Usage { + $Lines = @( + "Usage: ${_ScriptName}", + "-Help : Print this help", + "-Quiet : Suppress most build process output", + "-Verbose : Enable more verbose build process output", + "-CombinedArchs : Create combined architecture package", + "-BuildDirectory : Directory to use for builds - Default: build64 on 64-bit systems, build32 on 32-bit systems", + "-BuildArch : Build architecture to use (32-bit or 64-bit) - Default: local architecture", + "-BuildConfiguration : Build configuration to use - Default: RelWithDebInfo" + ) + + $Lines | Write-Host +} + + +if(!(Test-Path variable:_RunObsBuildScript)) { + $_ScriptName = "$($MyInvocation.MyCommand.Name)" + if($Help.isPresent) { + Print-Usage + exit 0 + } + + Package-OBS-Standalone +} diff --git a/CMakeLists.txt b/CMakeLists.txt index f5aaea626..e1ec9107d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,309 +1,92 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.16...3.21) -if (UNIX AND POLICY CMP0072) - # In case of both legacy and glvnd OpenGL libraries found. Prefer GLVND - cmake_policy(SET CMP0072 NEW) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") +include(VersionConfig) + +# Prohibit in-source builds +if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + message( + FATAL_ERROR + "OBS: You cannot build in a source directory (or any directory with " + "CMakeLists.txt file). Please make a build subdirectory. Feel free to " + "remove CMakeCache.txt and CMakeFiles.") endif() -project(obs-studio) - -option(DEBUG_FFMPEG_MUX "Debug FFmpeg muxer subprocess" FALSE) - +project(obs-studio VERSION ${OBS_VERSION_CANONICAL}) set_property(GLOBAL PROPERTY USE_FOLDERS ON) -if(WIN32) - cmake_minimum_required(VERSION 3.16) - - # Check for Win SDK version 10.0.20348 or above - if(MSVC) - message(STATUS "Windows API version is ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") - string(REPLACE "." ";" WINAPI_VER "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") - - list(GET WINAPI_VER 0 WINAPI_VER_MAJOR) - list(GET WINAPI_VER 1 WINAPI_VER_MINOR) - list(GET WINAPI_VER 2 WINAPI_VER_BUILD) - - set(WINAPI_COMPATIBLE FALSE) - if(WINAPI_VER_MAJOR EQUAL 10) - if (WINAPI_VER_MINOR EQUAL 0) - if (WINAPI_VER_BUILD GREATER_EQUAL 20348) - set(WINAPI_COMPATIBLE TRUE) - endif() - else() - set(WINAPI_COMPATIBLE TRUE) - endif() - elseif(WINAPI_VER_MAJOR GREATER 10) - set(WINAPI_COMPATIBLE TRUE) - endif() - - if(NOT WINAPI_COMPATIBLE) - message(FATAL_ERROR "OBS requires Windows 10 SDK version 10.0.20348.0 and above to compile.\nPlease download the most recent Windows 10 SDK in order to compile.") - endif() - endif() - - if (QTDIR OR DEFINED ENV{QTDIR} OR DEFINED ENV{QTDIR32} OR DEFINED ENV{QTDIR64}) - # Qt path set by user or env var - else() - set(QTDIR "" CACHE PATH "Path to Qt (e.g. C:/Qt/5.7/msvc2015_64)") - message(WARNING "QTDIR variable is missing. Please set this variable to specify path to Qt (e.g. C:/Qt/5.7/msvc2015_64)") - endif() - if (DepsPath OR DEFINED ENV{DepsPath} OR DEFINED ENV{DepsPath32} OR DEFINED ENV{DepsPath64}) - # Dependencies path set by user or env var - else() - set(DepsPath "" CACHE PATH "Path to compiled dependencies (e.g. D:/dependencies/win64)") - message(WARNING "DepsPath variable is missing. Please set this variable to specify path to compiled dependencies (e.g. D:/dependencies/win64)") - endif() -endif() - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") -set(ENABLE_SCRIPTING TRUE CACHE BOOL "Enables scripting") -set(SCRIPTING_ENABLED OFF CACHE BOOL "Internal global cmake variable" FORCE) - +# Use target folders for MSVC/Xcode/etc. +include(DeprecationHelpers) include(ObsHelpers) -include(ObsCpack) -include(GNUInstallDirs) -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) - -set(OBS_RELEASE_CANDIDATE_MAJOR 0) -set(OBS_RELEASE_CANDIDATE_MINOR 0) -set(OBS_RELEASE_CANDIDATE_PATCH 0) -set(OBS_RELEASE_CANDIDATE 0) -set(OBS_BETA_MAJOR 0) -set(OBS_BETA_MINOR 0) -set(OBS_BETA_PATCH 0) -set(OBS_BETA 0) - -# Must be a string in the format of "x.x.x-rcx" or "x.x.x-betax" -if(DEFINED RELEASE_CANDIDATE) - set(OBS_VERSION "${RELEASE_CANDIDATE}") - string(REPLACE "-rc" "." RC_SPLIT ${RELEASE_CANDIDATE}) - string(REPLACE "." ";" RC_SPLIT ${RC_SPLIT}) - message(WARNING "******************************************************************************\nRelease candidate detected, OBS_VERSION is now: ${OBS_VERSION}\n******************************************************************************") - list(GET RC_SPLIT 0 OBS_RELEASE_CANDIDATE_MAJOR) - list(GET RC_SPLIT 1 OBS_RELEASE_CANDIDATE_MINOR) - list(GET RC_SPLIT 2 OBS_RELEASE_CANDIDATE_PATCH) - list(GET RC_SPLIT 3 OBS_RELEASE_CANDIDATE) -elseif(DEFINED BETA) - set(OBS_VERSION "${BETA}") - string(REPLACE "-beta" "." BETA_SPLIT ${BETA}) - string(REPLACE "." ";" BETA_SPLIT ${BETA_SPLIT}) - message(WARNING "******************************************************************************\nBeta detected, OBS_VERSION is now: ${OBS_VERSION}\n******************************************************************************") - list(GET BETA_SPLIT 0 OBS_BETA_MAJOR) - list(GET BETA_SPLIT 1 OBS_BETA_MINOR) - list(GET BETA_SPLIT 2 OBS_BETA_PATCH) - list(GET BETA_SPLIT 3 OBS_BETA) -endif() - -# Binary Versioning for Windows -if(WIN32) - string(REPLACE "-" ";" UI_VERSION_SPLIT ${OBS_VERSION}) - list(GET UI_VERSION_SPLIT 0 UI_VERSION) - string(REPLACE "." ";" UI_VERSION_SEMANTIC ${UI_VERSION}) - list(GET UI_VERSION_SEMANTIC 0 UI_VERSION_MAJOR) - list(GET UI_VERSION_SEMANTIC 1 UI_VERSION_MINOR) - list(GET UI_VERSION_SEMANTIC 2 UI_VERSION_PATCH) - set(OBS_COMPANY_NAME "OBS") - set(OBS_PRODUCT_NAME "OBS Studio") - set(OBS_COMMENTS "Free and open source software for video recording and live streaming") - set(OBS_LEGAL_COPYRIGHT "(C) Hugh Bailey") - set(MODULE_DESCRIPTION "OBS Studio") - configure_file(UI/obs.rc.in ${PROJECT_BINARY_DIR}/obs.rc) -endif() - -if(MSVC AND NOT EXISTS "${CMAKE_BINARY_DIR}/ALL_BUILD.vcxproj.user") - file(GENERATE - OUTPUT "${CMAKE_BINARY_DIR}/ALL_BUILD.vcxproj.user" - INPUT "${CMAKE_SOURCE_DIR}/cmake/ALL_BUILD.vcxproj.user.in") -endif() +# Set default compiler flags +include(CompilerConfig) +# Allow selection of common build types via UI if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE RelWithDebInfo) + set(CMAKE_BUILD_TYPE + "RelWithDebInfo" + CACHE STRING + "OBS build type [Release, RelWithDebInfo, Debug, MinSizeRel]" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Release RelWithDebInfo + Debug MinSizeRel) endif() -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED YES) -set(CMAKE_CXX_EXTENSIONS NO) +# Global project options +option(BUILD_FOR_DISTRIBUTION "Build for distribution (enables optimisations)" + OFF) +option(ENABLE_UI "Enable building with UI (requires Qt)" ON) +option(ENABLE_SCRIPTING "Enable scripting support" ON) +option(USE_LIBCXX "Use libc++ instead of libstdc++" ${APPLE}) +option( + BUILD_TESTS + "Build test directory (includes test sources and possibly a platform test executable)" + OFF) -if(${CMAKE_C_COMPILER_ID} MATCHES "Clang" OR ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") - set(CMAKE_COMPILER_IS_CLANG TRUE) +if(OS_WINDOWS) + option( + INSTALLER_RUN + "Build a multiarch installer (needs to run independently after both archs have compiled) (Windows)" + OFF) + +elseif(OS_MACOS) + option(ENABLE_SPARKLE_UPDATER "Enable Sparkle framework for updates (macOS)" + OFF) + +elseif(OS_POSIX) + option(LINUX_PORTABLE "Build portable version (Linux)" OFF) + option(USE_XDG "Utilize XDG Base Directory Specification (Linux)" ON) + if(OS_LINUX) + option(ENABLE_WAYLAND "Enable building with support for Wayland (Linux)" ON) + option(BUILD_FOR_PPA "Build for PPA distribution" OFF) + endif() endif() -if (MSVC_CXX_ARCHITECTURE_ID) - string(TOLOWER ${MSVC_CXX_ARCHITECTURE_ID} LOWERCASE_CMAKE_SYSTEM_PROCESSOR) -else () - string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} LOWERCASE_CMAKE_SYSTEM_PROCESSOR) -endif () +setup_obs_project() +mark_as_advanced(BUILD_TESTS USE_LIBCXX) -if(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(i[3-6]86|x86|x64|x86_64|amd64|e2k)") - if(NOT MSVC) - set(ARCH_SIMD_FLAGS "-mmmx" "-msse" "-msse2") - endif() -elseif(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64(le)?") - set(ARCH_SIMD_DEFINES "-DNO_WARN_X86_INTRINSICS") - set(ARCH_SIMD_FLAGS "-mvsx") - add_compile_definitions(NO_WARN_X86_INTRINSICS) -else() - if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSIMDE_ENABLE_OPENMP") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSIMDE_ENABLE_OPENMP") - CHECK_C_COMPILER_FLAG("-fopenmp-simd" C_COMPILER_SUPPORTS_OPENMP_SIMD) - if(C_COMPILER_SUPPORTS_OPENMP_SIMD) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp-simd") - endif() - CHECK_CXX_COMPILER_FLAG("-fopenmp-simd" CXX_COMPILER_SUPPORTS_OPENMP_SIMD) - if(CXX_COMPILER_SUPPORTS_OPENMP_SIMD) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp-simd") - endif() - endif() - set(ARCH_SIMD_FLAGS "") - message(STATUS "No Native SSE2 SIMD Support - Using SIMDE") +if(INSTALLER_RUN) + generate_multiarch_installer() + return() endif() -if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) - set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wvla -Wno-unused-function -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS} -fno-strict-aliasing") - set(CMAKE_C_FLAGS "-Wall -Wextra -Wvla -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-braces -Wno-missing-field-initializers ${CMAKE_C_FLAGS} -std=gnu99 -fno-strict-aliasing") +# OBS sources and plugins +add_subdirectory(deps) +add_subdirectory(libobs-opengl) +if(OS_WINDOWS) + add_subdirectory(libobs-d3d11) + add_subdirectory(libobs-winrt) +endif() +add_subdirectory(libobs) +add_subdirectory(plugins) - option(USE_LIBC++ "Use libc++ instead of libstdc++" ${APPLE}) - if(USE_LIBC++) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - endif() -elseif(MSVC) - if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") - endif() +# OBS main app +add_subdirectory(UI) - # Disable pointless constant condition warnings - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4127 /wd4201 /wd4456 /wd4457 /wd4458 /wd4459 /wd4595") +# Tests +if(ENABLE_UNIT_TESTS) + enable_testing() endif() -if(WIN32) - add_definitions(-DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS) +if(BUILD_TESTS OR ENABLE_UNIT_TESTS) + add_subdirectory(test) endif() - -if(MSVC) - add_compile_options("/MP") - set(CMAKE_C_FLAGS_DEBUG "/DDEBUG=1 /D_DEBUG=1 ${CMAKE_C_FLAGS_DEBUG}") - set(CMAKE_CXX_FLAGS_DEBUG "/DDEBUG=1 /D_DEBUG=1 ${CMAKE_C_FLAGS_DEBUG}") - - # https://gitlab.kitware.com/cmake/cmake/-/issues/20812 - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Ob2") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ob2") - - if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO") - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO") - endif() - - foreach(t EXE SHARED MODULE) - set(CMAKE_${t}_LINKER_FLAGS "${CMAKE_${t}_LINKER_FLAGS} /OPT:REF") - set(CMAKE_${t}_LINKER_FLAGS_DEBUG "${CMAKE_${t}_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO") - set(CMAKE_${t}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${t}_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO /OPT:ICF") - endforeach() -else() - if(MINGW) - set(CMAKE_WIDL "widl" CACHE STRING "wine IDL header file generation program") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WIN32_WINNT=0x0600 -DWINVER=0x0600") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=0x0600 -DWINVER=0x0600") - endif() - set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=1 -D_DEBUG=1 ${CMAKE_C_FLAGS_DEBUG}") - set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=1 -D_DEBUG=1 ${CMAKE_C_FLAGS_DEBUG}") -endif() - -if(APPLE) - set(CMAKE_MACOSX_RPATH TRUE) - set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) - list(APPEND CMAKE_INSTALL_RPATH "@loader_path/" "@executable_path/") -elseif(UNIX) - option(USE_XDG "Utilize XDG Base Directory Specification" ON) - option(ENABLE_WAYLAND "Build support for Wayland" ON) - if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) - option(ENABLE_DARRAY_TYPE_TEST "Test types of darray argument" ON) - else() - option(ENABLE_DARRAY_TYPE_TEST "Test types of darray argument" OFF) - endif() - - if(USE_XDG) - add_definitions(-DUSE_XDG) - endif() - - if(NOT UNIX_STRUCTURE) - list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN") - endif() - - if(ENABLE_DARRAY_TYPE_TEST) - add_definitions(-DENABLE_DARRAY_TYPE_TEST) - endif() -endif() - -if(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "e2k") - foreach(TEST_C_FLAG "-Wno-unused-parameter" "-Wno-ignored-qualifiers" "-Wno-pointer-sign" "-Wno-unused-variable" "-Wno-sign-compare" "-Wno-bad-return-value-type" "-Wno-maybe-uninitialized") - CHECK_C_COMPILER_FLAG(${TEST_C_FLAG} C_COMPILER_SUPPORTS_FLAG_${TEST_C_FLAG}) - if(C_COMPILER_SUPPORTS_FLAG_${TEST_C_FLAG}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_C_FLAG}") - endif() - endforeach() - foreach(TEST_CXX_FLAG "-Wno-invalid-offsetof" "-Wno-maybe-uninitialized") - CHECK_CXX_COMPILER_FLAG(${TEST_CXX_FLAG} CXX_COMPILER_SUPPORTS_FLAG_${TEST_CXX_FLAG}) - if(CXX_COMPILER_SUPPORTS_FLAG_${TEST_CXX_FLAG}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEST_CXX_FLAG}") - endif() - endforeach() -endif() - -option(BUILD_TESTS "Build test directory (includes test sources and possibly a platform test executable)" FALSE) -mark_as_advanced(BUILD_TESTS) - -if(NOT INSTALLER_RUN) - option(ENABLE_UI "Enables the OBS user interfaces" ON) - if(DISABLE_UI OR NOT ENABLE_UI) - set(UI_ENABLED FALSE) - else() - set(UI_ENABLED TRUE) - - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_lib_suffix 64) - else() - set(_lib_suffix 32) - endif() - - if(DEFINED QTDIR${_lib_suffix}) - list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}") - elseif(DEFINED QTDIR) - list(APPEND CMAKE_PREFIX_PATH "${QTDIR}") - elseif(DEFINED ENV{QTDIR${_lib_suffix}}) - list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}") - elseif(DEFINED ENV{QTDIR}) - list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}") - endif() - - find_package(Qt5Widgets REQUIRED) - endif() - - add_subdirectory(deps) - - if(WIN32) - add_subdirectory(libobs-d3d11) - add_subdirectory(libobs-winrt) - endif() - - add_subdirectory(libobs-opengl) - add_subdirectory(libobs) - add_subdirectory(plugins) - add_subdirectory(UI) - - if (ENABLE_UNIT_TESTS) - enable_testing() - endif() - - if (BUILD_TESTS OR ENABLE_UNIT_TESTS) - add_subdirectory(test) - endif() -else() - obs_generate_multiarch_installer() -endif() - -include(CopyMSVCBins) diff --git a/cmake/Modules/CompilerConfig.cmake b/cmake/Modules/CompilerConfig.cmake index 8d2f84e6b..5c99daca8 100644 --- a/cmake/Modules/CompilerConfig.cmake +++ b/cmake/Modules/CompilerConfig.cmake @@ -16,38 +16,36 @@ if(OS_WINDOWS AND MSVC) endif() # Check for Win SDK version 10.0.20348 or above - if(MSVC_VERSION LESS 1920) - message( - INFO - " + OBS-Studio - Windows API version is ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" - ) - string(REPLACE "." ";" WINAPI_VER - "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") + message( + INFO + " + OBS-Studio - Windows API version is ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" + ) + string(REPLACE "." ";" WINAPI_VER + "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") - list(GET WINAPI_VER 0 WINAPI_VER_MAJOR) - list(GET WINAPI_VER 1 WINAPI_VER_MINOR) - list(GET WINAPI_VER 2 WINAPI_VER_BUILD) + list(GET WINAPI_VER 0 WINAPI_VER_MAJOR) + list(GET WINAPI_VER 1 WINAPI_VER_MINOR) + list(GET WINAPI_VER 2 WINAPI_VER_BUILD) - set(WINAPI_COMPATIBLE FALSE) - if(WINAPI_VER_MAJOR EQUAL 10) - if(WINAPI_VER_MINOR EQUAL 0) - if(WINAPI_VER_BUILD GREATER_EQUAL 20348) - set(WINAPI_COMPATIBLE TRUE) - endif() - else() + set(WINAPI_COMPATIBLE FALSE) + if(WINAPI_VER_MAJOR EQUAL 10) + if(WINAPI_VER_MINOR EQUAL 0) + if(WINAPI_VER_BUILD GREATER_EQUAL 20348) set(WINAPI_COMPATIBLE TRUE) endif() - elseif(WINAPI_VER_MAJOR GREATER 10) + else() set(WINAPI_COMPATIBLE TRUE) endif() + elseif(WINAPI_VER_MAJOR GREATER 10) + set(WINAPI_COMPATIBLE TRUE) + endif() - if(NOT WINAPI_COMPATIBLE) - message( - FATAL_ERROR - "OBS: OBS requires Windows 10 SDK version 10.0.20348.0 and above to compile.\n" - " Please download the most recent Windows 10 SDK in order to compile (or update to Visual Studio 2019)." - ) - endif() + if(NOT WINAPI_COMPATIBLE) + message( + FATAL_ERROR + "OBS: OBS requires Windows 10 SDK version 10.0.20348.0 and above to compile.\n" + " Please download the most recent Windows 10 SDK in order to compile." + ) endif() add_compile_options( diff --git a/formatcode.sh b/formatcode.sh deleted file mode 100755 index 5bb867fbc..000000000 --- a/formatcode.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -# Original source https://github.com/Project-OSRM/osrm-backend/blob/master/scripts/format.sh - -set +x -set -o errexit -set -o pipefail -set -o nounset - -# Runs the Clang Formatter in parallel on the code base. -# Return codes: -# - 1 there are files to be formatted -# - 0 everything looks fine - -# Get CPU count -OS=$(uname) -NPROC=1 -if [[ $OS = "Linux" || $OS = "Darwin" ]] ; then - NPROC=$(getconf _NPROCESSORS_ONLN) -fi - -# Discover clang-format -if type clang-format-12 2> /dev/null ; then - CLANG_FORMAT=clang-format-12 -elif type clang-format-10 2> /dev/null ; then - CLANG_FORMAT=clang-format-10 -elif type clang-format-8 2> /dev/null ; then - CLANG_FORMAT=clang-format-8 -else - CLANG_FORMAT=clang-format -fi - -find . -type d \( -path ./deps \ --o -path ./cmake \ --o -path ./plugins/decklink/win/decklink-sdk \ --o -path ./plugins/decklink/mac/decklink-sdk \ --o -path ./plugins/decklink/linux/decklink-sdk \ --o -path ./plugins/enc-amf \ --o -path ./plugins/mac-syphon/syphon-framework \ --o -path ./plugins/obs-outputs/ftl-sdk \ --o -path ./plugins/obs-vst \ --o -path ./plugins/aja/sdk \ --o -path ./build \) -prune -type f -o -name '*.h' -or -name '*.hpp' -or -name '*.m' -or -name '*.mm' -or -name '*.c' -or -name '*.cpp' \ -| xargs -L100 -P${NPROC} ${CLANG_FORMAT} -i -style=file -fallback-style=none diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 45a5543b9..8e5dd867b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,16 +1,15 @@ - if(BUILD_TESTS) - add_subdirectory(test-input) + add_subdirectory(test-input) - if(WIN32) - add_subdirectory(win) - endif() + if(OS_WINDOWS) + add_subdirectory(win) + endif() - if(APPLE AND UNIX) - add_subdirectory(osx) - endif() + if(OS_POSIX) + add_subdirectory(osx) + endif() endif() -if (ENABLE_UNIT_TESTS) - add_subdirectory(cmocka) +if(ENABLE_UNIT_TESTS) + add_subdirectory(cmocka) endif() diff --git a/test/cmocka/CMakeLists.txt b/test/cmocka/CMakeLists.txt index 775e1e88f..d31da02b3 100644 --- a/test/cmocka/CMakeLists.txt +++ b/test/cmocka/CMakeLists.txt @@ -1,50 +1,23 @@ project(obs-cmocka) -# Fix libobs path -macro(fixLink target_arg) - if(APPLE AND UNIX) - add_custom_command (TARGET ${target_arg} - POST_BUILD COMMAND "${CMAKE_INSTALL_NAME_TOOL}" - "-change" "@rpath/libobs.0.dylib" "@executable_path/../../libobs/libobs.0.dylib" - "$" VERBATIM) - add_custom_command (TARGET ${target_arg} - POST_BUILD COMMAND "${CMAKE_INSTALL_NAME_TOOL}" - "-add_rpath" /tmp/obsdeps/lib - "$" VERBATIM) - endif() -endmacro() - -set(CMAKE_MACOSX_RPATH TRUE) -set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) -list(APPEND CMAKE_INSTALL_RPATH "@loader_path/" "@executable_path/") - find_package(CMocka CONFIG REQUIRED) -include_directories(${CMOCKA_INCLUDE_DIR}) -include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs") - -# fix rpath on linux -if (UNIX AND NOT APPLE) - set(CMAKE_INSTALL_RPATH "$ORIGIN";../../libobs) -endif() # Serializer test add_executable(test_serializer test_serializer.c) -target_link_libraries(test_serializer ${CMOCKA_LIBRARIES} libobs) - +target_include_directories(test_serializer PRIVATE ${CMOCKA_INCLUDE_DIR}) +target_link_libraries(test_serializer PRIVATE OBS::libobs ${CMOCKA_LIBRARIES}) add_test(test_serializer ${CMAKE_CURRENT_BINARY_DIR}/test_serializer) -fixLink(test_serializer) - # darray test add_executable(test_darray test_darray.c) -target_link_libraries(test_darray ${CMOCKA_LIBRARIES} libobs) +target_include_directories(test_darray PRIVATE ${CMOCKA_INCLUDE_DIR}) +target_link_libraries(test_darray PRIVATE OBS::libobs ${CMOCKA_LIBRARIES}) add_test(test_darray ${CMAKE_CURRENT_BINARY_DIR}/test_darray) -fixLink(test_darray) # bitstream test add_executable(test_bitstream test_bitstream.c) -target_link_libraries(test_bitstream ${CMOCKA_LIBRARIES} libobs) +target_include_directories(test_bitstream PRIVATE ${CMOCKA_INCLUDE_DIR}) +target_link_libraries(test_bitstream PRIVATE OBS::libobs ${CMOCKA_LIBRARIES}) add_test(test_bitstream ${CMAKE_CURRENT_BINARY_DIR}/test_bitstream) -fixLink(test_bitstream) diff --git a/test/osx/CMakeLists.txt b/test/osx/CMakeLists.txt index 862acdc5e..cc6c1c8d7 100644 --- a/test/osx/CMakeLists.txt +++ b/test/osx/CMakeLists.txt @@ -1,19 +1,18 @@ project(osx-text) -include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs") - find_library(COCOA Cocoa) -include_directories(${COCOA}) +mark_as_advanced(COCOA) -add_definitions(-fobjc-arc) +add_executable(macOS_test) -set(osx-test_SOURCES - test.mm) +target_sources(macOS_test PRIVATE test.mm) -add_executable(osx_test - ${osx-test_SOURCES}) -set_target_properties(osx_test PROPERTIES FOLDER "tests and examples") -target_link_libraries(osx_test - libobs - ${COCOA}) -define_graphic_modules(osx_test) +target_link_libraries(macOS_test PRIVATE OBS::libobs ${COCOA}) + +target_compile_options(macOS_test PRIVATE -fobjc-arc) + +target_compile_features(macOS_test PRIVATE cxx_std_11) + +set_target_properties(macOS_test PROPERTIES FOLDER "tests and examples") + +define_graphic_modules(macOS_test) diff --git a/test/test-input/CMakeLists.txt b/test/test-input/CMakeLists.txt index 4de030ff8..24e75544b 100644 --- a/test/test-input/CMakeLists.txt +++ b/test/test-input/CMakeLists.txt @@ -1,29 +1,24 @@ project(test-input) -include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs") +add_library(test-input MODULE) + +target_sources( + test-input + PRIVATE test-filter.c + test-input.c + test-sinewave.c + sync-async-source.c + sync-audio-buffering.c + sync-pair-vid.c + sync-pair-aud.c + test-random.c) + +target_link_libraries(test-input PRIVATE OBS::libobs) if(MSVC) - set(test-input_PLATFORM_DEPS - w32-pthreads) + target_link_libraries(test-input PRIVATE OBS::w32-pthreads) endif() -set(test-input_SOURCES - ${test-input_PLATFORM_SOURCES} - test-filter.c - test-input.c - test-sinewave.c - sync-async-source.c - sync-audio-buffering.c - sync-pair-vid.c - sync-pair-aud.c - test-random.c) - -add_library(test-input MODULE - ${test-input_SOURCES}) - -target_link_libraries(test-input - ${test-input_PLATFORM_DEPS} - libobs) set_target_properties(test-input PROPERTIES FOLDER "tests and examples") -install_obs_plugin_with_data(test-input data) +setup_plugin_target(test-input) diff --git a/test/win/CMakeLists.txt b/test/win/CMakeLists.txt index fd7f6c324..8270f9b74 100644 --- a/test/win/CMakeLists.txt +++ b/test/win/CMakeLists.txt @@ -1,13 +1,11 @@ project(win-test) -include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs") +add_executable(win-test WIN32) -set(win-text_SOURCES - test.cpp) +target_sources(win-test PRIVATE test.cpp) + +target_link_libraries(win-test PRIVATE OBS::libobs) -add_executable(win-test WIN32 - ${win-text_SOURCES}) -target_link_libraries(win-test - libobs) set_target_properties(win-test PROPERTIES FOLDER "tests and examples") + define_graphic_modules(win-test)