├── .github ├── FUNDING.yml └── workflows │ ├── CI-full.yml │ ├── CI.yml │ └── cronjob.yml ├── README.md ├── latest-release.txt ├── obs-full-junest.sh ├── obs-junest.sh └── templates └── obs-studio-ppa.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ivan-hc] 4 | custom: ["paypal.me/IvanAlexHC"] 5 | ko_fi: IvanAlexHC 6 | -------------------------------------------------------------------------------- /.github/workflows/CI-full.yml: -------------------------------------------------------------------------------- 1 | name: OBS Studio FULL Appimage 2 | concurrency: 3 | group: build-${{ github.ref }} 4 | cancel-in-progress: true 5 | 6 | on: 7 | schedule: 8 | - cron: "0 18 * * 0-6" 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - name: build 18 | if: always() 19 | run: | 20 | sudo apt update && sudo apt install desktop-file-utils 21 | sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0 22 | sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 23 | wget https://raw.githubusercontent.com/ivan-hc/OBS-Studio-appimage/main/obs-full-junest.sh 24 | chmod a+x ./obs-full-junest.sh 25 | ./obs-full-junest.sh 26 | mkdir dist 27 | mv *AppImage* dist/ 28 | 29 | - name: Upload artifact 30 | uses: actions/upload-artifact@v4.4.0 31 | with: 32 | name: OBS-Studio-FULL-x86_64.AppImage 33 | path: 'dist' 34 | 35 | release: 36 | needs: [build] 37 | permissions: write-all 38 | runs-on: ubuntu-latest 39 | 40 | steps: 41 | - uses: actions/download-artifact@v4.1.8 42 | with: 43 | name: OBS-Studio-FULL-x86_64.AppImage 44 | 45 | - name: release 46 | uses: marvinpinto/action-automatic-releases@latest 47 | with: 48 | title: Continuous-full build 49 | automatic_release_tag: continuous-full 50 | prerelease: true 51 | draft: false 52 | files: | 53 | *.AppImage* 54 | repo_token: ${{ secrets.GITHUB_TOKEN }} 55 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: OBS Studio Appimage 2 | concurrency: 3 | group: build-${{ github.ref }} 4 | cancel-in-progress: true 5 | 6 | on: 7 | schedule: 8 | - cron: "0 6 * * 0-6" 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - name: build 18 | if: always() 19 | run: | 20 | sudo apt update && sudo apt install desktop-file-utils 21 | sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0 22 | sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 23 | chmod a+x ./obs-junest.sh 24 | ./obs-junest.sh 25 | mkdir dist 26 | mv *AppImage* dist/ 27 | 28 | - name: Upload artifact 29 | uses: actions/upload-artifact@v4.4.0 30 | with: 31 | name: OBS-Studio-x86_64.AppImage 32 | path: 'dist' 33 | 34 | release: 35 | needs: [build] 36 | permissions: write-all 37 | runs-on: ubuntu-latest 38 | 39 | steps: 40 | - uses: actions/download-artifact@v4.1.8 41 | with: 42 | name: OBS-Studio-x86_64.AppImage 43 | 44 | - name: release 45 | uses: marvinpinto/action-automatic-releases@latest 46 | with: 47 | title: Continuous build 48 | automatic_release_tag: continuous 49 | prerelease: false 50 | draft: false 51 | files: | 52 | *.AppImage* 53 | repo_token: ${{ secrets.GITHUB_TOKEN }} 54 | -------------------------------------------------------------------------------- /.github/workflows/cronjob.yml: -------------------------------------------------------------------------------- 1 | name: Github Action with a cronjob trigger 2 | on: 3 | schedule: 4 | - cron: "0 0 * * *" 5 | 6 | workflow_dispatch: 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | permissions: 13 | contents: write 14 | 15 | jobs: 16 | sync-files: 17 | name: "Run sync" 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: "Checkout source repository" 21 | uses: actions/checkout@v4 22 | 23 | - name: "List releases" 24 | run: | 25 | curl -Ls https://api.github.com/repos/${GITHUB_REPOSITORY}/releases | sed 's/[()",{} ]/\n/g' | grep -oi "https.*mage$" > latest-release.txt 26 | 27 | - name: "Push to Source" 28 | run: | 29 | git config --global user.name "ivan-hc" 30 | git config --global user.email "noreply@github.com" 31 | git add latest-release.txt 32 | if git diff-index --quiet HEAD; then 33 | echo "No changes to commit." >> $GITHUB_STEP_SUMMARY 34 | else 35 | git commit -m "Sync files from source repository" 36 | git push && echo "Sync to Source succeeded" >> $GITHUB_STEP_SUMMARY 37 | fi 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository creates and distributes the unofficial Appimage of OBS Studio built on top of JuNest, the lightweight Arch Linux based distro that runs, without root privileges, on top of any other Linux distro. 2 | 3 | Versions available are: 4 | - `obs-studio`, the regular/lightweight version https://github.com/ivan-hc/OBS-Studio-appimage/releases/tag/continuous 5 | - `obs-studio-full`, with web browser support https://github.com/ivan-hc/OBS-Studio-appimage/releases/tag/continuous-full 6 | 7 | ## Credits 8 | - JuNest https://github.com/fsquillace/junest 9 | - ArchImage https://github.com/ivan-hc/ArchImage 10 | 11 | ------------------------------------------------------------------------ 12 | 13 | ## Install and update it with ease 14 | 15 | ### *"*AM*" Application Manager* 16 | #### *Package manager, database & solutions for all AppImages and portable apps for GNU/Linux!* 17 | 18 | [![Istantanea_2024-06-26_17-00-46 png](https://github.com/ivan-hc/AM/assets/88724353/671f5eb0-6fb6-4392-b45e-af0ea9271d9b)](https://github.com/ivan-hc/AM) 19 | 20 | [![Readme](https://img.shields.io/github/stars/ivan-hc/AM?label=%E2%AD%90&style=for-the-badge)](https://github.com/ivan-hc/AM/stargazers) [![Readme](https://img.shields.io/github/license/ivan-hc/AM?label=&style=for-the-badge)](https://github.com/ivan-hc/AM/blob/main/LICENSE) 21 | 22 | *"AM"/"AppMan" is a set of scripts and modules for installing, updating, and managing AppImage packages and other portable formats, in the same way that APT manages DEBs packages, DNF the RPMs, and so on... using a large database of Shell scripts inspired by the Arch User Repository, each dedicated to an app or set of applications.* 23 | 24 | *The engine of "AM"/"AppMan" is the "APP-MANAGER" script which, depending on how you install or rename it, allows you to install apps system-wide (for a single system administrator) or locally (for each user).* 25 | 26 | *"AM"/"AppMan" aims to be the default package manager for all AppImage packages, giving them a home to stay.* 27 | 28 | *You can consult the entire **list of managed apps** at [**portable-linux-apps.github.io/apps**](https://portable-linux-apps.github.io/apps).* 29 | 30 | ## *Go to *https://github.com/ivan-hc/AM* for more!* 31 | 32 | ------------------------------------------------------------------------ 33 | 34 | | [***Install "AM"***](https://github.com/ivan-hc/AM) | [***See all available apps***](https://portable-linux-apps.github.io) | [***Support me on ko-fi.com***](https://ko-fi.com/IvanAlexHC) | [***Support me on PayPal.me***](https://paypal.me/IvanAlexHC) | 35 | | - | - | - | - | 36 | 37 | ------------------------------------------------------------------------ 38 | -------------------------------------------------------------------------------- /latest-release.txt: -------------------------------------------------------------------------------- 1 | https://github.com/ivan-hc/OBS-Studio-appimage/releases/download/continuous/OBS-Studio_31.0.3-2-archimage4.3-x86_64.AppImage 2 | https://github.com/ivan-hc/OBS-Studio-appimage/releases/download/continuous-full/OBS-Studio-FULL_31.0.3-4-archimage4.3-x86_64.AppImage 3 | -------------------------------------------------------------------------------- /obs-full-junest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | APP=obs-studio-browser 4 | BIN="obs" #CHANGE THIS IF THE NAME OF THE BINARY IS DIFFERENT FROM "$APP" (for example, the binary of "obs-studio" is "obs") 5 | DEPENDENCES="python leancrypto" #SYNTAX: "APP1 APP2 APP3 APP4...", LEAVE BLANK IF NO OTHER DEPENDENCIES ARE NEEDED 6 | BASICSTUFF="binutils debugedit gzip" 7 | COMPILERS="base-devel asio-git" 8 | 9 | ############################################################################# 10 | # KEYWORDS TO FIND AND SAVE WHEN COMPILING THE APPIMAGE 11 | ############################################################################# 12 | 13 | BINSAVED="v4l" 14 | SHARESAVED="glvnd" 15 | lib_audio_keywords="alsa jack pipewire pulse" 16 | lib_browser_launcher="gio-launch-desktop libasound.so libatk-bridge libatspi libcloudproviders libdb- libdl.so libedit libepoxy libgtk-3.so.0 libjson-glib libnssutil libpthread.so librt.so libtinysparql libwayland-cursor libX11-xcb.so libxapp-gtk3-module.so libXcursor libXdamage libXi.so libxkbfile.so libXrandr p11 pk" 17 | LIBSAVED="EGL libDeckLinkAPI libdrm libedit libfdk libFLAC.so libglslang-default-resource-limits.so libLLVM libluajit libpxbackend libsensors \ 18 | libSM.so libsodium.so libsoxr.so libva libwayland libxcb libuuid libxshmfence qt v4l libSDL \ 19 | libleancrypto libcjson libxkbcommon $lib_audio_keywords $lib_browser_launcher" 20 | 21 | [ -n "$lib_browser_launcher" ] && DEPENDENCES="$DEPENDENCES xapp hicolor-icon-theme" 22 | 23 | ############################################################################# 24 | # SETUP THE ENVIRONMENT 25 | ############################################################################# 26 | 27 | # Download appimagetool 28 | if [ ! -f ./appimagetool ]; then 29 | echo "-----------------------------------------------------------------------------" 30 | echo "◆ Downloading \"appimagetool\" from https://github.com/AppImage/appimagetool" 31 | echo "-----------------------------------------------------------------------------" 32 | curl -#Lo appimagetool https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage && chmod a+x appimagetool 33 | fi 34 | 35 | # Create and enter the AppDir 36 | mkdir -p "$APP".AppDir archlinux && cd archlinux || exit 1 37 | 38 | # Set archlinux as a temporary $HOME directory 39 | HOME="$(dirname "$(readlink -f "$0")")" 40 | 41 | ############################################################################# 42 | # DOWNLOAD, INSTALL AND CONFIGURE JUNEST 43 | ############################################################################# 44 | 45 | _enable_multilib() { 46 | printf "\n[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> ./.junest/etc/pacman.conf 47 | } 48 | 49 | _enable_chaoticaur() { 50 | # This function is ment to be used during the installation of JuNest, see "_pacman_patches" 51 | ./.local/share/junest/bin/junest -- sudo pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com 52 | ./.local/share/junest/bin/junest -- sudo pacman-key --lsign-key 3056513887B78AEB 53 | ./.local/share/junest/bin/junest -- sudo pacman-key --populate chaotic 54 | ./.local/share/junest/bin/junest -- sudo pacman --noconfirm -U 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst' 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst' 55 | printf "\n[chaotic-aur]\nInclude = /etc/pacman.d/chaotic-mirrorlist" >> ./.junest/etc/pacman.conf 56 | } 57 | 58 | _custom_mirrorlist() { 59 | COUNTRY=$(curl -i ipinfo.io 2>/dev/null | grep country | cut -c 15- | cut -c -2) 60 | if [ -n "$GITHUB_REPOSITORY_OWNER" ] || ! curl --output /dev/null --silent --head --fail "https://archlinux.org/mirrorlist/?country=$COUNTRY" 1>/dev/null; then 61 | curl -Ls https://archlinux.org/mirrorlist/all | awk NR==2 RS= | sed 's/#Server/Server/g' > ./.junest/etc/pacman.d/mirrorlist 62 | else 63 | curl -Ls "https://archlinux.org/mirrorlist/?country=$COUNTRY" | sed 's/#Server/Server/g' > ./.junest/etc/pacman.d/mirrorlist 64 | fi 65 | } 66 | 67 | _bypass_signature_check_level() { 68 | sed -i 's/#SigLevel/SigLevel/g; s/Required DatabaseOptional/Never/g' ./.junest/etc/pacman.conf 69 | } 70 | 71 | _install_junest() { 72 | echo "-----------------------------------------------------------------------------" 73 | echo "◆ Clone JuNest from https://github.com/fsquillace/junest" 74 | echo "-----------------------------------------------------------------------------" 75 | git clone https://github.com/fsquillace/junest.git ./.local/share/junest 76 | echo "-----------------------------------------------------------------------------" 77 | echo "◆ Downloading JuNest archive from https://github.com/ivan-hc/junest" 78 | echo "-----------------------------------------------------------------------------" 79 | curl -#Lo junest-x86_64.tar.gz https://github.com/ivan-hc/junest/releases/download/continuous/junest-x86_64.tar.gz 80 | ./.local/share/junest/bin/junest setup -i junest-x86_64.tar.gz 81 | rm -f junest-x86_64.tar.gz 82 | echo " Apply patches to PacMan..." 83 | #_enable_multilib 84 | _enable_chaoticaur 85 | _custom_mirrorlist 86 | _bypass_signature_check_level 87 | 88 | # Update arch linux in junest 89 | ./.local/share/junest/bin/junest -- sudo pacman -Syy 90 | ./.local/share/junest/bin/junest -- sudo pacman --noconfirm -Syu 91 | } 92 | 93 | if ! test -d "$HOME/.local/share/junest"; then 94 | echo "-----------------------------------------------------------------------------" 95 | echo " DOWNLOAD, INSTALL AND CONFIGURE JUNEST" 96 | echo "-----------------------------------------------------------------------------" 97 | _install_junest 98 | else 99 | echo "-----------------------------------------------------------------------------" 100 | echo " RESTART JUNEST" 101 | echo "-----------------------------------------------------------------------------" 102 | fi 103 | 104 | ############################################################################# 105 | # INSTALL PROGRAMS USING YAY 106 | ############################################################################# 107 | 108 | ./.local/share/junest/bin/junest -- yay -Syy 109 | #./.local/share/junest/bin/junest -- gpg --keyserver keyserver.ubuntu.com --recv-key C01E1CAD5EA2C4F0B8E3571504C367C218ADD4FF # UNCOMMENT IF YOU USE THE AUR 110 | if [ -n "$BASICSTUFF" ]; then 111 | ./.local/share/junest/bin/junest -- yay --noconfirm -S $BASICSTUFF 112 | fi 113 | if [ -n "$COMPILERS" ]; then 114 | ./.local/share/junest/bin/junest -- yay --noconfirm -S $COMPILERS 115 | fi 116 | if [ -n "$DEPENDENCES" ]; then 117 | ./.local/share/junest/bin/junest -- yay --noconfirm -S $DEPENDENCES 118 | fi 119 | if [ -n "$APP" ]; then 120 | ./.local/share/junest/bin/junest -- yay --noconfirm -S alsa-lib gtk3 xapp 121 | ./.local/share/junest/bin/junest -- yay --noconfirm -S "$(./.local/share/junest/bin/junest -- yay -Si "$APP" | grep -i 'depends on' | cut -d ':' -f 2)" 122 | ./.local/share/junest/bin/junest -- yay --noconfirm -Sa "$APP" 123 | ./.local/share/junest/bin/junest -- glib-compile-schemas /usr/share/glib-2.0/schemas/ 124 | else 125 | echo "No app found, exiting"; exit 1 126 | fi 127 | 128 | cd .. 129 | 130 | echo "" 131 | echo "-----------------------------------------------------------------------------" 132 | echo " CREATING THE APPDIR" 133 | echo "-----------------------------------------------------------------------------" 134 | echo "" 135 | 136 | # Set locale 137 | rm -f archlinux/.junest/etc/locale.conf 138 | sed -i 's/LANG=${LANG:-C}/LANG=$LANG/g' archlinux/.junest/etc/profile.d/locale.sh 139 | 140 | # Add launcher and icon 141 | rm -f ./*.desktop 142 | LAUNCHER=$(grep -iRl "$BIN" archlinux/.junest/usr/share/applications/* | grep ".desktop" | head -1) 143 | cp -r "$LAUNCHER" "$APP".AppDir/ 144 | ICON=$(cat "$LAUNCHER" | grep "Icon=" | cut -c 6-) 145 | [ -z "$ICON" ] && ICON="$BIN" 146 | cp -r archlinux/.junest/usr/share/icons/*"$ICON"* "$APP".AppDir/ 2>/dev/null 147 | cp -r archlinux/.junest/usr/share/icons/hicolor/22x22/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 148 | cp -r archlinux/.junest/usr/share/icons/hicolor/24x24/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 149 | cp -r archlinux/.junest/usr/share/icons/hicolor/32x32/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 150 | cp -r archlinux/.junest/usr/share/icons/hicolor/48x48/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 151 | cp -r archlinux/.junest/usr/share/icons/hicolor/64x64/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 152 | cp -r archlinux/.junest/usr/share/icons/hicolor/128x128/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 153 | cp -r archlinux/.junest/usr/share/icons/hicolor/192x192/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 154 | cp -r archlinux/.junest/usr/share/icons/hicolor/256x256/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 155 | cp -r archlinux/.junest/usr/share/icons/hicolor/512x512/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 156 | cp -r archlinux/.junest/usr/share/icons/hicolor/scalable/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 157 | cp -r archlinux/.junest/usr/share/pixmaps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 158 | 159 | # Test if the desktop file and the icon are in the root of the future appimage (./*appdir/*) 160 | if test -f "$APP".AppDir/*.desktop; then 161 | echo "◆ The .desktop file is available in $APP.AppDir/" 162 | elif test -f archlinux/.junest/usr/bin/"$BIN"; then 163 | echo "◆ No .desktop file available for $APP, creating a new one" 164 | cat <<-HEREDOC >> "$APP".AppDir/"$APP".desktop 165 | [Desktop Entry] 166 | Version=1.0 167 | Type=Application 168 | Name=$(echo "$APP" | tr '[:lower:]' '[:upper:]') 169 | Comment= 170 | Exec=$BIN 171 | Icon=tux 172 | Categories=Utility; 173 | Terminal=true 174 | StartupNotify=true 175 | HEREDOC 176 | curl -Lo "$APP".AppDir/tux.png https://raw.githubusercontent.com/Portable-Linux-Apps/Portable-Linux-Apps.github.io/main/favicon.ico 2>/dev/null 177 | else 178 | echo "No binary in path... aborting all the processes." 179 | exit 0 180 | fi 181 | 182 | if [ ! -d "$APP".AppDir/.local ]; then 183 | mkdir -p "$APP".AppDir/.local 184 | rsync -av archlinux/.local/ "$APP".AppDir/.local/ | echo "◆ Rsync .local directory to the AppDir" 185 | # Made JuNest a portable app and remove "read-only file system" errors 186 | sed -i 's#${JUNEST_HOME}/usr/bin/junest_wrapper#${HOME}/.cache/junest_wrapper.old#g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 187 | sed -i 's/rm -f "${JUNEST_HOME}${bin_path}_wrappers/#rm -f "${JUNEST_HOME}${bin_path}_wrappers/g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 188 | sed -i 's/ln/#ln/g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 189 | sed -i 's/rm -f "$file"/test -f "$file"/g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 190 | sed -i 's#--bind "$HOME" "$HOME"#--bind-try /home /home --bind-try /run/user /run/user#g' "$APP".AppDir/.local/share/junest/lib/core/namespace.sh 191 | fi 192 | 193 | echo "◆ Rsync .junest directories structure to the AppDir" 194 | rm -Rf "$APP".AppDir/.junest/* 195 | archdirs=$(find archlinux/.junest -type d | sed 's/^archlinux\///g') 196 | for d in $archdirs; do 197 | mkdir -p "$APP".AppDir/"$d" 198 | done 199 | symlink_dirs=" bin sbin lib lib64 usr/sbin usr/lib64" 200 | for l in $symlink_dirs; do 201 | cp -r archlinux/.junest/"$l" "$APP".AppDir/.junest/"$l" 202 | done 203 | 204 | rsync -av archlinux/.junest/usr/bin_wrappers/ "$APP".AppDir/.junest/usr/bin_wrappers/ | echo "◆ Rsync bin_wrappers to the AppDir" 205 | rsync -av archlinux/.junest/etc/* "$APP".AppDir/.junest/etc/ | echo "◆ Rsync /etc" 206 | 207 | ############################################################################# 208 | # APPRUN 209 | ############################################################################# 210 | 211 | rm -f "$APP".AppDir/AppRun 212 | cat <<-'HEREDOC' >> "$APP".AppDir/AppRun 213 | #!/bin/sh 214 | HERE="$(dirname "$(readlink -f "$0")")" 215 | export UNION_PRELOAD="$HERE" 216 | export JUNEST_HOME="$HERE"/.junest 217 | 218 | if command -v unshare >/dev/null 2>&1 && ! unshare --user -p /bin/true >/dev/null 2>&1; then 219 | PROOT_ON=1 220 | export PATH="$HERE"/.local/share/junest/bin/:"$PATH" 221 | mkdir -p "$HOME"/.cache 222 | else 223 | export PATH="$PATH":"$HERE"/.local/share/junest/bin 224 | fi 225 | 226 | [ -z "$NVIDIA_ON" ] && NVIDIA_ON=1 227 | if [ "$NVIDIA_ON" = 1 ]; then 228 | DATADIR="${XDG_DATA_HOME:-$HOME/.local/share}" 229 | CONTY_DIR="${DATADIR}/Conty/overlayfs_shared" 230 | [ -f /sys/module/nvidia/version ] && nvidia_driver_version="$(cat /sys/module/nvidia/version)" 231 | if [ -n "$nvidia_driver_version" ]; then 232 | mkdir -p "${CONTY_DIR}"/nvidia "${CONTY_DIR}"/up/usr/lib "${CONTY_DIR}"/up/usr/share 233 | nvidia_data_dirs="egl glvnd nvidia vulkan" 234 | for d in $nvidia_data_dirs; do [ ! -d "${CONTY_DIR}"/up/usr/share/"$d" ] && ln -s /usr/share/"$d" "${CONTY_DIR}"/up/usr/share/ 2>/dev/null; done 235 | [ ! -f "${CONTY_DIR}"/nvidia/current-nvidia-version ] && echo "${nvidia_driver_version}" > "${CONTY_DIR}"/nvidia/current-nvidia-version 236 | [ -f "${CONTY_DIR}"/nvidia/current-nvidia-version ] && nvidia_driver_conty=$(cat "${CONTY_DIR}"/nvidia/current-nvidia-version) 237 | if [ "${nvidia_driver_version}" != "${nvidia_driver_conty}" ]; then 238 | rm -f "${CONTY_DIR}"/up/usr/lib/*; echo "${nvidia_driver_version}" > "${CONTY_DIR}"/nvidia/current-nvidia-version 239 | fi 240 | /sbin/ldconfig -p > "${CONTY_DIR}"/nvidia/host_libs 241 | grep -i "nvidia\|libcuda" "${CONTY_DIR}"/nvidia/host_libs | cut -d ">" -f 2 > "${CONTY_DIR}"/nvidia/host_nvidia_libs 242 | libnv_paths=$(grep "libnv" "${CONTY_DIR}"/nvidia/host_libs | cut -d ">" -f 2) 243 | for f in $libnv_paths; do strings "${f}" | grep -qi -m 1 "nvidia" && echo "${f}" >> "${CONTY_DIR}"/nvidia/host_nvidia_libs; done 244 | nvidia_libs=$(cat "${CONTY_DIR}"/nvidia/host_nvidia_libs) 245 | for n in $nvidia_libs; do libname=$(echo "$n" | sed 's:.*/::') && [ ! -f "${CONTY_DIR}"/up/usr/lib/"$libname" ] && cp "$n" "${CONTY_DIR}"/up/usr/lib/; done 246 | libvdpau_nvidia="${CONTY_DIR}/up/usr/lib/libvdpau_nvidia.so" 247 | if ! test -f "${libvdpau_nvidia}*"; then cp "$(find /usr/lib -type f -name 'libvdpau_nvidia.so*' -print -quit 2>/dev/null | head -1)" "${CONTY_DIR}"/up/usr/lib/; fi 248 | [ -f "${libvdpau_nvidia}"."${nvidia_driver_version}" ] && [ ! -f "${libvdpau_nvidia}" ] && ln -s "${libvdpau_nvidia}"."${nvidia_driver_version}" "${libvdpau_nvidia}" 249 | [ -d "${CONTY_DIR}"/up/usr/lib ] && export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}":"${CONTY_DIR}"/up/usr/lib:"${LD_LIBRARY_PATH}" 250 | [ -d "${CONTY_DIR}"/up/usr/share ] && export XDG_DATA_DIRS="${XDG_DATA_DIRS}":"${CONTY_DIR}"/up/usr/share:"${XDG_DATA_DIRS}" 251 | fi 252 | fi 253 | 254 | PROOT_BINDINGS="" 255 | BWRAP_BINDINGS="" 256 | 257 | bind_files="/etc/resolv.conf /etc/hosts /etc/nsswitch.conf /etc/passwd /etc/group /etc/machine-id /etc/asound.conf /etc/localtime " 258 | for f in $bind_files; do [ -f "$f" ] && PROOT_BINDINGS=" $PROOT_BINDINGS --bind=$f" && BWRAP_BINDINGS=" $BWRAP_BINDINGS --ro-bind-try $f $f"; done 259 | 260 | bind_dirs=" /media /mnt /opt /run/media /usr/lib/locale /usr/share/fonts /usr/share/themes /var" 261 | for d in $bind_dirs; do [ -d "$d" ] && PROOT_BINDINGS=" $PROOT_BINDINGS --bind=$d" && BWRAP_BINDINGS=" $BWRAP_BINDINGS --bind-try $d $d"; done 262 | 263 | PROOT_BINDS=" --bind=/dev --bind=/sys --bind=/tmp --bind=/proc $PROOT_BINDINGS --bind=/home --bind=/home/$USER " 264 | BWRAP_BINDS=" --dev-bind /dev /dev --ro-bind /sys /sys --bind-try /tmp /tmp --proc /proc $BWRAP_BINDINGS " 265 | 266 | _JUNEST_CMD() { 267 | if [ "$PROOT_ON" = 1 ]; then 268 | "$HERE"/.local/share/junest/bin/junest proot -n -b "$PROOT_BINDS" "$@" 269 | else 270 | "$HERE"/.local/share/junest/bin/junest -n -b "$BWRAP_BINDS" "$@" 271 | fi 272 | } 273 | 274 | EXEC=$(grep -e '^Exec=.*' "${HERE}"/*.desktop | head -n 1 | cut -d "=" -f 2- | sed -e 's|%.||g') 275 | 276 | _JUNEST_CMD -- /usr/bin/obs "$@" 277 | 278 | HEREDOC 279 | chmod a+x "$APP".AppDir/AppRun 280 | 281 | ############################################################################# 282 | # EXTRACT PACKAGES 283 | ############################################################################# 284 | 285 | [ -z "$extraction_count" ] && extraction_count=0 286 | [ ! -f ./autodeps ] && echo "$extraction_count" > ./autodeps 287 | [ -f ./autodeps ] && autodeps=$(cat ./autodeps) 288 | [ "$autodeps" != "$extraction_count" ] && rm -Rf ./deps ./packages && echo "$extraction_count" > ./autodeps 289 | 290 | [ ! -f ./userdeps ] && echo "$DEPENDENCES" > ./userdeps 291 | [ -f ./userdeps ] && userdeps=$(cat ./userdeps) 292 | [ "$userdeps" != "$DEPENDENCES" ] && rm -Rf ./deps ./packages && echo "$DEPENDENCES" > ./userdeps 293 | 294 | _extract_main_package() { 295 | mkdir -p base 296 | rm -Rf ./base/* 297 | pkg_full_path=$(find ./archlinux -type f -name "$APP-*zst") 298 | if [ "$(echo "$pkg_full_path" | wc -l)" = 1 ]; then 299 | pkg_full_path=$(find ./archlinux -type f -name "$APP-*zst") 300 | else 301 | for p in $pkg_full_path; do 302 | if tar fx "$p" .PKGINFO -O | grep -q "pkgname = $APP$"; then 303 | pkg_full_path="$p" 304 | fi 305 | done 306 | fi 307 | [ -z "$pkg_full_path" ] && echo "💀 ERROR: no package found for \"$APP\", operation aborted!" && exit 0 308 | tar fx "$pkg_full_path" -C ./base/ 309 | VERSION=$(cat ./base/.PKGINFO | grep pkgver | cut -c 10- | sed 's@.*:@@') 310 | mkdir -p deps 311 | } 312 | 313 | _download_missing_packages() { 314 | localpackage=$(find ./archlinux -name "$arg-[0-9]*zst") 315 | if ! test -f "$localpackage"; then 316 | ./archlinux/.local/share/junest/bin/junest -- yay --noconfirm -Sw "$arg" 317 | fi 318 | } 319 | 320 | _extract_package() { 321 | _download_missing_packages &> /dev/null 322 | pkg_full_path=$(find ./archlinux -name "$arg-[0-9]*zst") 323 | pkgname=$(echo "$pkg_full_path" | sed 's:.*/::') 324 | [ ! -f ./packages ] && rm -Rf ./deps/* && touch ./packages 325 | if [ -z "$( ls -A './deps' )" ]; then 326 | rm -f ./packages 327 | echo "" 328 | echo "-----------------------------------------------------------------------------" 329 | echo " EXTRACTING PACKAGES" 330 | echo "-----------------------------------------------------------------------------" 331 | echo "" 332 | fi 333 | if test -f "$pkg_full_path"; then 334 | if ! grep -q "$pkgname" ./packages 2>/dev/null;then 335 | echo "◆ Extracting $pkgname" 336 | tar fx "$pkg_full_path" -C ./deps/ --warning=no-unknown-keyword 337 | echo "$pkgname" >> ./packages 338 | fi 339 | [ -n "$lib_browser_launcher" ] && [[ "$arg" =~ (hicolor-icon-theme|xapp) ]] && tar fx "$pkg_full_path" -C ./base/ --warning=no-unknown-keyword --exclude='.PKGINFO' 340 | fi 341 | } 342 | 343 | _determine_packages_and_libraries() { 344 | if echo "$arg" | grep -q "\.so"; then 345 | LIBSAVED="$LIBSAVED $arg" 346 | elif [ "$arg" != autoconf ] && [ "$arg" != autoconf ] && [ "$arg" != automake ] && [ "$arg" != bison ] && [ "$arg" != debugedit ] && [ "$arg" != dkms ] && [ "$arg" != fakeroot ] && [ "$arg" != flatpak ] && [ "$arg" != linux ] && [ "$arg" != gcc ] && [ "$arg" != make ] && [ "$arg" != pacman ] && [ "$arg" != patch ] && [ "$arg" != systemd ]; then 347 | _extract_package 348 | cat ./deps/.PKGINFO 2>/dev/null | grep "^depend = " | cut -c 10- | sed 's/=.*//' >> depdeps 349 | rm -f ./deps/.* 350 | fi 351 | } 352 | 353 | _extract_deps() { 354 | DEPS=$(sort -u ./depdeps) 355 | for arg in $DEPS; do 356 | _determine_packages_and_libraries 357 | done 358 | } 359 | 360 | _extract_all_dependences() { 361 | rm -f ./depdeps 362 | 363 | OPTDEPS=$(cat ./base/.PKGINFO 2>/dev/null | grep "^optdepend = " | sed 's/optdepend = //g' | sed 's/=.*//' | sed 's/:.*//') 364 | for arg in $OPTDEPS; do 365 | _determine_packages_and_libraries 366 | done 367 | [ -f ./depdeps ] && _extract_deps 368 | rm -f ./depdeps 369 | 370 | ARGS=$(echo "$DEPENDENCES" | tr " " "\n") 371 | for arg in $ARGS; do 372 | _determine_packages_and_libraries 373 | done 374 | 375 | DEPS=$(cat ./base/.PKGINFO 2>/dev/null | grep "^depend = " | sed 's/depend = //g' | sed 's/=.*//') 376 | for arg in $DEPS; do 377 | _determine_packages_and_libraries 378 | done 379 | 380 | # Set the level of sub-dependencies extraction, the higher the number, the bigger the AppImage will be 381 | if [ "$extraction_count" != 0 ]; then 382 | for e in $(seq "$extraction_count"); do _extract_deps; done 383 | fi 384 | } 385 | 386 | _extract_main_package 387 | _extract_all_dependences 388 | 389 | echo "" 390 | echo "-----------------------------------------------------------------------------" 391 | echo " IMPLEMENTING NECESSARY LIBRARIES (MAY TAKE SEVERAL MINUTES)" 392 | echo "-----------------------------------------------------------------------------" 393 | echo "" 394 | 395 | # Save files in /usr/bin 396 | _savebins() { 397 | echo "◆ Saving files in /usr/bin" 398 | cp -r ./archlinux/.junest/usr/bin/bwrap ./"$APP".AppDir/.junest/usr/bin/ 399 | cp -r ./archlinux/.junest/usr/bin/proot* ./"$APP".AppDir/.junest/usr/bin/ 400 | cp -r ./archlinux/.junest/usr/bin/*$BIN* ./"$APP".AppDir/.junest/usr/bin/ 401 | coreutils="[ basename cat chmod chown cp cut dir dirname du echo env expand expr fold head id ln ls mkdir mv readlink realpath rm rmdir seq sleep sort stty sum sync tac tail tee test timeout touch tr true tty uname uniq wc who whoami yes" 402 | utils_bin="awk bash $coreutils gawk gio grep ld ldd sed sh strings xdg-open" 403 | for b in $utils_bin; do 404 | cp -r ./archlinux/.junest/usr/bin/"$b" ./"$APP".AppDir/.junest/usr/bin/ 405 | done 406 | for arg in $BINSAVED; do 407 | cp -r ./archlinux/.junest/usr/bin/*"$arg"* ./"$APP".AppDir/.junest/usr/bin/ 408 | done 409 | } 410 | 411 | # Save files in /usr/lib 412 | _savelibs() { 413 | echo "◆ Detect libraries related to /usr/bin files" 414 | libs4bin=$(readelf -d ./"$APP".AppDir/.junest/usr/bin/* 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so") 415 | 416 | echo "◆ Saving JuNest core libraries" 417 | cp -r ./archlinux/.junest/usr/lib/ld-linux-x86-64.so* ./"$APP".AppDir/.junest/usr/lib/ 418 | lib_preset="$APP $BIN gconv libdw libelf libresolv.so libtinfo.so $libs4bin" 419 | LIBSAVED="$lib_preset $LIBSAVED $SHARESAVED" 420 | for arg in $LIBSAVED; do 421 | LIBPATHS="$LIBPATHS $(find ./archlinux/.junest/usr/lib -maxdepth 20 -wholename "*$arg*" | sed 's/\.\/archlinux\///g')" 422 | done 423 | for arg in $LIBPATHS; do 424 | [ ! -d "$APP".AppDir/"$arg" ] && cp -r ./archlinux/"$arg" "$APP".AppDir/"$arg" & 425 | done 426 | wait 427 | core_libs=$(find ./"$APP".AppDir -type f) 428 | lib_core=$(for c in $core_libs; do readelf -d "$c" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 429 | 430 | echo "◆ Detect libraries of the main package" 431 | base_libs=$(find ./base -type f | uniq) 432 | lib_base_0=$(for b in $base_libs; do readelf -d "$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 433 | 434 | echo "◆ Detect libraries of the dependencies" 435 | dep_libs=$(find ./deps -executable -name "*.so*") 436 | lib_deps=$(for d in $dep_libs; do readelf -d "$d" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 437 | 438 | echo "◆ Detect and copy base libs" 439 | basebin_libs=$(find ./base -executable -name "*.so*") 440 | lib_base_1=$(for b in $basebin_libs; do readelf -d "$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 441 | lib_base_1=$(echo "$lib_base_1" | tr ' ' '\n' | sort -u | xargs) 442 | lib_base_2=$(for b in $lib_base_1; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 443 | lib_base_2=$(echo "$lib_base_2" | tr ' ' '\n' | sort -u | xargs) 444 | lib_base_3=$(for b in $lib_base_2; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 445 | lib_base_3=$(echo "$lib_base_3" | tr ' ' '\n' | sort -u | xargs) 446 | lib_base_4=$(for b in $lib_base_3; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 447 | lib_base_4=$(echo "$lib_base_4" | tr ' ' '\n' | sort -u | xargs) 448 | lib_base_5=$(for b in $lib_base_4; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 449 | lib_base_5=$(echo "$lib_base_5" | tr ' ' '\n' | sort -u | xargs) 450 | lib_base_6=$(for b in $lib_base_5; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 451 | lib_base_6=$(echo "$lib_base_6" | tr ' ' '\n' | sort -u | xargs) 452 | lib_base_7=$(for b in $lib_base_6; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 453 | lib_base_7=$(echo "$lib_base_7" | tr ' ' '\n' | sort -u | xargs) 454 | lib_base_8=$(for b in $lib_base_7; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 455 | lib_base_8=$(echo "$lib_base_8" | tr ' ' '\n' | sort -u | xargs) 456 | lib_base_9=$(for b in $lib_base_8; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 457 | lib_base_9=$(echo "$lib_base_9" | tr ' ' '\n' | sort -u | xargs) 458 | lib_base_libs="$lib_core $lib_base_0 $lib_base_1 $lib_base_2 $lib_base_3 $lib_base_4 $lib_base_5 $lib_base_6 $lib_base_7 $lib_base_8 $lib_base_9 $lib_deps" 459 | lib_base_libs=$(echo "$lib_base_libs" | tr ' ' '\n' | sort -u | sed 's/.so.*/.so/' | xargs) 460 | for l in $lib_base_libs; do 461 | rsync -av ./archlinux/.junest/usr/lib/"$l"* ./"$APP".AppDir/.junest/usr/lib/ & 462 | done 463 | wait 464 | for l in $lib_base_libs; do 465 | rsync -av ./deps/usr/lib/"$l"* ./"$APP".AppDir/.junest/usr/lib/ & 466 | done 467 | wait 468 | } 469 | 470 | # Save files in /usr/share 471 | _saveshare() { 472 | echo "◆ Saving directories in /usr/share" 473 | SHARESAVED="$SHARESAVED $APP $BIN fontconfig glib- locale mime wayland X11" 474 | for arg in $SHARESAVED; do 475 | cp -r ./archlinux/.junest/usr/share/*"$arg"* ./"$APP".AppDir/.junest/usr/share/ 476 | done 477 | } 478 | 479 | _savebins 2>/dev/null 480 | _savelibs 2>/dev/null 481 | _saveshare 2>/dev/null 482 | 483 | echo "" 484 | echo "-----------------------------------------------------------------------------" 485 | echo " ASSEMBLING THE APPIMAGE" 486 | echo "-----------------------------------------------------------------------------" 487 | echo "" 488 | 489 | _rsync_main_package() { 490 | rm -Rf ./base/.* 491 | rsync -av ./base/ ./"$APP".AppDir/.junest/ | echo "◆ Rsync the content of the \"$APP\" package" 492 | } 493 | 494 | _rsync_dependences() { 495 | rm -Rf ./deps/.* 496 | chmod -R 777 ./deps/* 497 | rsync -av ./deps/ ./"$APP".AppDir/.junest/ | echo "◆ Rsync all dependencies, please wait" 498 | } 499 | 500 | _rsync_main_package 501 | _rsync_dependences 502 | 503 | ############################################################################# 504 | # REMOVE BLOATWARES, ENABLE MOUNTPOINTS 505 | ############################################################################# 506 | 507 | _remove_more_bloatwares() { 508 | etc_remove="makepkg.conf pacman" 509 | for r in $etc_remove; do 510 | rm -Rf ./"$APP".AppDir/.junest/etc/"$r"* 511 | done 512 | bin_remove="gcc" 513 | for r in $bin_remove; do 514 | rm -Rf ./"$APP".AppDir/.junest/usr/bin/"$r"* 515 | done 516 | lib_remove="cmake d3d gcc gconv libgphobos libOSMesa libxatracker" 517 | for r in $lib_remove; do 518 | rm -Rf ./"$APP".AppDir/.junest/usr/lib/"$r"* 519 | done 520 | share_remove="gcc gir hwdata i18n terminfo vulkan z" 521 | for r in $share_remove; do 522 | rm -Rf ./"$APP".AppDir/.junest/usr/share/"$r"* 523 | done 524 | echo Y | rm -Rf ./"$APP".AppDir/.cache/yay/* 525 | find ./"$APP".AppDir/.junest/usr/share/doc/* -not -iname "*$BIN*" -a -not -name "." -delete 2> /dev/null #REMOVE ALL DOCUMENTATION NOT RELATED TO THE APP 526 | find ./"$APP".AppDir/.junest/usr/share/locale/*/*/* -not -iname "*$BIN*" -a -not -name "." -delete 2> /dev/null #REMOVE ALL ADDITIONAL LOCALE FILES 527 | rm -Rf ./"$APP".AppDir/.junest/home # remove the inbuilt home 528 | rm -Rf ./"$APP".AppDir/.junest/usr/include # files related to the compiler 529 | rm -Rf ./"$APP".AppDir/.junest/usr/share/man # AppImages are not ment to have man command 530 | rm -Rf ./"$APP".AppDir/.junest/usr/lib/python*/__pycache__/* # if python is installed, removing this directory can save several megabytes 531 | #rm -Rf ./"$APP".AppDir/.junest/usr/lib/libgallium* 532 | rm -Rf ./"$APP".AppDir/.junest/usr/lib/libgo.so* 533 | #rm -Rf ./"$APP".AppDir/.junest/usr/lib/libLLVM* # included in the compilation phase, can sometimes be excluded for daily use 534 | rm -Rf ./"$APP".AppDir/.junest/var/* # remove all packages downloaded with the package manager 535 | } 536 | 537 | _enable_mountpoints_for_the_inbuilt_bubblewrap() { 538 | mkdir -p ./"$APP".AppDir/.junest/home 539 | mkdir -p ./"$APP".AppDir/.junest/media 540 | mkdir -p ./"$APP".AppDir/.junest/usr/lib/locale 541 | mkdir -p ./"$APP".AppDir/.junest/usr/share/fonts 542 | mkdir -p ./"$APP".AppDir/.junest/usr/share/themes 543 | mkdir -p ./"$APP".AppDir/.junest/run/media 544 | mkdir -p ./"$APP".AppDir/.junest/run/user 545 | rm -f ./"$APP".AppDir/.junest/etc/localtime && touch ./"$APP".AppDir/.junest/etc/localtime 546 | [ ! -f ./"$APP".AppDir/.junest/etc/asound.conf ] && touch ./"$APP".AppDir/.junest/etc/asound.conf 547 | } 548 | 549 | # Fix libcurl 550 | rm -f ./"$APP".AppDir/.junest/usr/lib/libcurl* && cp -r ./archlinux/.junest/usr/lib/libcurl* ./"$APP".AppDir/.junest/usr/lib/ 551 | 552 | _remove_more_bloatwares 553 | find ./"$APP".AppDir/.junest/usr/lib ./"$APP".AppDir/.junest/usr/lib32 -type f -regex '.*\.a' -exec rm -f {} \; 2>/dev/null 554 | find ./"$APP".AppDir/.junest/usr -type f -regex '.*\.so.*' -exec strip --strip-debug {} \; 555 | find ./"$APP".AppDir/.junest/usr/bin -type f ! -regex '.*\.so.*' -exec strip --strip-unneeded {} \; 556 | find ./"$APP".AppDir/.junest/usr -type d -empty -delete 557 | _enable_mountpoints_for_the_inbuilt_bubblewrap 558 | 559 | ############################################################################# 560 | # CREATE THE APPIMAGE 561 | ############################################################################# 562 | 563 | if test -f ./*.AppImage; then rm -Rf ./*archimage*.AppImage; fi 564 | 565 | APPNAME=$(cat ./"$APP".AppDir/*.desktop | grep 'Name=' | head -1 | cut -c 6- | sed 's/ /-/g') 566 | REPO="OBS-Studio-appimage" 567 | TAG="continuous-full" 568 | VERSION="$VERSION" 569 | UPINFO="gh-releases-zsync|$GITHUB_REPOSITORY_OWNER|$REPO|$TAG|*x86_64.AppImage.zsync" 570 | 571 | ARCH=x86_64 ./appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 20 \ 572 | -u "$UPINFO" \ 573 | ./"$APP".AppDir "$APPNAME"-FULL_"$VERSION"-archimage4.3-x86_64.AppImage 574 | -------------------------------------------------------------------------------- /obs-junest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | APP=obs-studio 4 | BIN="obs" #CHANGE THIS IF THE NAME OF THE BINARY IS DIFFERENT FROM "$APP" (for example, the binary of "obs-studio" is "obs") 5 | DEPENDENCES="" #SYNTAX: "APP1 APP2 APP3 APP4...", LEAVE BLANK IF NO OTHER DEPENDENCIES ARE NEEDED 6 | #BASICSTUFF="binutils debugedit gzip" 7 | #COMPILERS="base-devel" 8 | 9 | ############################################################################# 10 | # KEYWORDS TO FIND AND SAVE WHEN COMPILING THE APPIMAGE 11 | ############################################################################# 12 | 13 | BINSAVED="v4l" 14 | SHARESAVED="glvnd" 15 | lib_audio_keywords="alsa jack pipewire pulse" 16 | lib_browser_launcher="gio-launch-desktop libasound.so libatk-bridge libatspi libcloudproviders libdb- libdl.so libedit libepoxy libgtk-3.so.0 libjson-glib libnssutil libpthread.so librt.so libtinysparql libwayland-cursor libX11-xcb.so libxapp-gtk3-module.so libXcursor libXdamage libXi.so libxkbfile.so libXrandr p11 pk" 17 | LIBSAVED="EGL libDeckLinkAPI libdrm libedit libfdk libFLAC.so libglslang-default-resource-limits.so libLLVM libluajit libpxbackend libsensors \ 18 | libSM.so libsodium.so libsoxr.so libva libwayland libxcb libxshmfence qt v4l libSDL $lib_audio_keywords $lib_browser_launcher" 19 | 20 | [ -n "$lib_browser_launcher" ] && DEPENDENCES="$DEPENDENCES xapp hicolor-icon-theme" 21 | 22 | ############################################################################# 23 | # SETUP THE ENVIRONMENT 24 | ############################################################################# 25 | 26 | # Download appimagetool 27 | if [ ! -f ./appimagetool ]; then 28 | echo "-----------------------------------------------------------------------------" 29 | echo "◆ Downloading \"appimagetool\" from https://github.com/AppImage/appimagetool" 30 | echo "-----------------------------------------------------------------------------" 31 | curl -#Lo appimagetool https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage && chmod a+x appimagetool 32 | fi 33 | 34 | # Create and enter the AppDir 35 | mkdir -p "$APP".AppDir archlinux && cd archlinux || exit 1 36 | 37 | # Set archlinux as a temporary $HOME directory 38 | HOME="$(dirname "$(readlink -f "$0")")" 39 | 40 | ############################################################################# 41 | # DOWNLOAD, INSTALL AND CONFIGURE JUNEST 42 | ############################################################################# 43 | 44 | _enable_multilib() { 45 | printf "\n[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> ./.junest/etc/pacman.conf 46 | } 47 | 48 | _enable_chaoticaur() { 49 | # This function is ment to be used during the installation of JuNest, see "_pacman_patches" 50 | ./.local/share/junest/bin/junest -- sudo pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com 51 | ./.local/share/junest/bin/junest -- sudo pacman-key --lsign-key 3056513887B78AEB 52 | ./.local/share/junest/bin/junest -- sudo pacman-key --populate chaotic 53 | ./.local/share/junest/bin/junest -- sudo pacman --noconfirm -U 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst' 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst' 54 | printf "\n[chaotic-aur]\nInclude = /etc/pacman.d/chaotic-mirrorlist" >> ./.junest/etc/pacman.conf 55 | } 56 | 57 | _custom_mirrorlist() { 58 | COUNTRY=$(curl -i ipinfo.io 2>/dev/null | grep country | cut -c 15- | cut -c -2) 59 | if [ -n "$GITHUB_REPOSITORY_OWNER" ] || ! curl --output /dev/null --silent --head --fail "https://archlinux.org/mirrorlist/?country=$COUNTRY" 1>/dev/null; then 60 | curl -Ls https://archlinux.org/mirrorlist/all | awk NR==2 RS= | sed 's/#Server/Server/g' > ./.junest/etc/pacman.d/mirrorlist 61 | else 62 | curl -Ls "https://archlinux.org/mirrorlist/?country=$COUNTRY" | sed 's/#Server/Server/g' > ./.junest/etc/pacman.d/mirrorlist 63 | fi 64 | } 65 | 66 | _bypass_signature_check_level() { 67 | sed -i 's/#SigLevel/SigLevel/g; s/Required DatabaseOptional/Never/g' ./.junest/etc/pacman.conf 68 | } 69 | 70 | _install_junest() { 71 | echo "-----------------------------------------------------------------------------" 72 | echo "◆ Clone JuNest from https://github.com/fsquillace/junest" 73 | echo "-----------------------------------------------------------------------------" 74 | git clone https://github.com/fsquillace/junest.git ./.local/share/junest 75 | echo "-----------------------------------------------------------------------------" 76 | echo "◆ Downloading JuNest archive from https://github.com/ivan-hc/junest" 77 | echo "-----------------------------------------------------------------------------" 78 | curl -#Lo junest-x86_64.tar.gz https://github.com/ivan-hc/junest/releases/download/continuous/junest-x86_64.tar.gz 79 | ./.local/share/junest/bin/junest setup -i junest-x86_64.tar.gz 80 | rm -f junest-x86_64.tar.gz 81 | echo " Apply patches to PacMan..." 82 | #_enable_multilib 83 | #_enable_chaoticaur 84 | _custom_mirrorlist 85 | _bypass_signature_check_level 86 | 87 | # Update arch linux in junest 88 | ./.local/share/junest/bin/junest -- sudo pacman -Syy 89 | ./.local/share/junest/bin/junest -- sudo pacman --noconfirm -Syu 90 | } 91 | 92 | if ! test -d "$HOME/.local/share/junest"; then 93 | echo "-----------------------------------------------------------------------------" 94 | echo " DOWNLOAD, INSTALL AND CONFIGURE JUNEST" 95 | echo "-----------------------------------------------------------------------------" 96 | _install_junest 97 | else 98 | echo "-----------------------------------------------------------------------------" 99 | echo " RESTART JUNEST" 100 | echo "-----------------------------------------------------------------------------" 101 | fi 102 | 103 | ############################################################################# 104 | # INSTALL PROGRAMS USING YAY 105 | ############################################################################# 106 | 107 | ./.local/share/junest/bin/junest -- yay -Syy 108 | #./.local/share/junest/bin/junest -- gpg --keyserver keyserver.ubuntu.com --recv-key C01E1CAD5EA2C4F0B8E3571504C367C218ADD4FF # UNCOMMENT IF YOU USE THE AUR 109 | if [ -n "$BASICSTUFF" ]; then 110 | ./.local/share/junest/bin/junest -- yay --noconfirm -S "$BASICSTUFF" 111 | fi 112 | if [ -n "$COMPILERS" ]; then 113 | ./.local/share/junest/bin/junest -- yay --noconfirm -S "$COMPILERS" 114 | fi 115 | if [ -n "$DEPENDENCES" ]; then 116 | ./.local/share/junest/bin/junest -- yay --noconfirm -S "$DEPENDENCES" 117 | fi 118 | if [ -n "$APP" ]; then 119 | ./.local/share/junest/bin/junest -- yay --noconfirm -S alsa-lib gtk3 xapp 120 | ./.local/share/junest/bin/junest -- yay --noconfirm -S "$APP" 121 | ./.local/share/junest/bin/junest -- glib-compile-schemas /usr/share/glib-2.0/schemas/ 122 | else 123 | echo "No app found, exiting"; exit 1 124 | fi 125 | 126 | cd .. 127 | 128 | echo "" 129 | echo "-----------------------------------------------------------------------------" 130 | echo " CREATING THE APPDIR" 131 | echo "-----------------------------------------------------------------------------" 132 | echo "" 133 | 134 | # Set locale 135 | rm -f archlinux/.junest/etc/locale.conf 136 | sed -i 's/LANG=${LANG:-C}/LANG=$LANG/g' archlinux/.junest/etc/profile.d/locale.sh 137 | 138 | # Add launcher and icon 139 | rm -f ./*.desktop 140 | LAUNCHER=$(grep -iRl "$BIN" archlinux/.junest/usr/share/applications/* | grep ".desktop" | head -1) 141 | cp -r "$LAUNCHER" "$APP".AppDir/ 142 | ICON=$(cat "$LAUNCHER" | grep "Icon=" | cut -c 6-) 143 | [ -z "$ICON" ] && ICON="$BIN" 144 | cp -r archlinux/.junest/usr/share/icons/*"$ICON"* "$APP".AppDir/ 2>/dev/null 145 | cp -r archlinux/.junest/usr/share/icons/hicolor/22x22/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 146 | cp -r archlinux/.junest/usr/share/icons/hicolor/24x24/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 147 | cp -r archlinux/.junest/usr/share/icons/hicolor/32x32/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 148 | cp -r archlinux/.junest/usr/share/icons/hicolor/48x48/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 149 | cp -r archlinux/.junest/usr/share/icons/hicolor/64x64/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 150 | cp -r archlinux/.junest/usr/share/icons/hicolor/128x128/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 151 | cp -r archlinux/.junest/usr/share/icons/hicolor/192x192/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 152 | cp -r archlinux/.junest/usr/share/icons/hicolor/256x256/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 153 | cp -r archlinux/.junest/usr/share/icons/hicolor/512x512/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 154 | cp -r archlinux/.junest/usr/share/icons/hicolor/scalable/apps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 155 | cp -r archlinux/.junest/usr/share/pixmaps/*"$ICON"* "$APP".AppDir/ 2>/dev/null 156 | 157 | # Test if the desktop file and the icon are in the root of the future appimage (./*appdir/*) 158 | if test -f "$APP".AppDir/*.desktop; then 159 | echo "◆ The .desktop file is available in $APP.AppDir/" 160 | elif test -f archlinux/.junest/usr/bin/"$BIN"; then 161 | echo "◆ No .desktop file available for $APP, creating a new one" 162 | cat <<-HEREDOC >> "$APP".AppDir/"$APP".desktop 163 | [Desktop Entry] 164 | Version=1.0 165 | Type=Application 166 | Name=$(echo "$APP" | tr '[:lower:]' '[:upper:]') 167 | Comment= 168 | Exec=$BIN 169 | Icon=tux 170 | Categories=Utility; 171 | Terminal=true 172 | StartupNotify=true 173 | HEREDOC 174 | curl -Lo "$APP".AppDir/tux.png https://raw.githubusercontent.com/Portable-Linux-Apps/Portable-Linux-Apps.github.io/main/favicon.ico 2>/dev/null 175 | else 176 | echo "No binary in path... aborting all the processes." 177 | exit 0 178 | fi 179 | 180 | if [ ! -d "$APP".AppDir/.local ]; then 181 | mkdir -p "$APP".AppDir/.local 182 | rsync -av archlinux/.local/ "$APP".AppDir/.local/ | echo "◆ Rsync .local directory to the AppDir" 183 | # Made JuNest a portable app and remove "read-only file system" errors 184 | sed -i 's#${JUNEST_HOME}/usr/bin/junest_wrapper#${HOME}/.cache/junest_wrapper.old#g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 185 | sed -i 's/rm -f "${JUNEST_HOME}${bin_path}_wrappers/#rm -f "${JUNEST_HOME}${bin_path}_wrappers/g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 186 | sed -i 's/ln/#ln/g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 187 | sed -i 's/rm -f "$file"/test -f "$file"/g' "$APP".AppDir/.local/share/junest/lib/core/wrappers.sh 188 | sed -i 's#--bind "$HOME" "$HOME"#--bind-try /home /home --bind-try /run/user /run/user#g' "$APP".AppDir/.local/share/junest/lib/core/namespace.sh 189 | fi 190 | 191 | echo "◆ Rsync .junest directories structure to the AppDir" 192 | rm -Rf "$APP".AppDir/.junest/* 193 | archdirs=$(find archlinux/.junest -type d | sed 's/^archlinux\///g') 194 | for d in $archdirs; do 195 | mkdir -p "$APP".AppDir/"$d" 196 | done 197 | symlink_dirs=" bin sbin lib lib64 usr/sbin usr/lib64" 198 | for l in $symlink_dirs; do 199 | cp -r archlinux/.junest/"$l" "$APP".AppDir/.junest/"$l" 200 | done 201 | 202 | rsync -av archlinux/.junest/usr/bin_wrappers/ "$APP".AppDir/.junest/usr/bin_wrappers/ | echo "◆ Rsync bin_wrappers to the AppDir" 203 | rsync -av archlinux/.junest/etc/* "$APP".AppDir/.junest/etc/ | echo "◆ Rsync /etc" 204 | 205 | ############################################################################# 206 | # APPRUN 207 | ############################################################################# 208 | 209 | rm -f "$APP".AppDir/AppRun 210 | cat <<-'HEREDOC' >> "$APP".AppDir/AppRun 211 | #!/bin/sh 212 | HERE="$(dirname "$(readlink -f "$0")")" 213 | export UNION_PRELOAD="$HERE" 214 | export JUNEST_HOME="$HERE"/.junest 215 | 216 | if command -v unshare >/dev/null 2>&1 && ! unshare --user -p /bin/true >/dev/null 2>&1; then 217 | PROOT_ON=1 218 | export PATH="$HERE"/.local/share/junest/bin/:"$PATH" 219 | mkdir -p "$HOME"/.cache 220 | else 221 | export PATH="$PATH":"$HERE"/.local/share/junest/bin 222 | fi 223 | 224 | [ -z "$NVIDIA_ON" ] && NVIDIA_ON=1 225 | if [ "$NVIDIA_ON" = 1 ]; then 226 | DATADIR="${XDG_DATA_HOME:-$HOME/.local/share}" 227 | CONTY_DIR="${DATADIR}/Conty/overlayfs_shared" 228 | [ -f /sys/module/nvidia/version ] && nvidia_driver_version="$(cat /sys/module/nvidia/version)" 229 | if [ -n "$nvidia_driver_version" ]; then 230 | mkdir -p "${CONTY_DIR}"/nvidia "${CONTY_DIR}"/up/usr/lib "${CONTY_DIR}"/up/usr/share 231 | nvidia_data_dirs="egl glvnd nvidia vulkan" 232 | for d in $nvidia_data_dirs; do [ ! -d "${CONTY_DIR}"/up/usr/share/"$d" ] && ln -s /usr/share/"$d" "${CONTY_DIR}"/up/usr/share/ 2>/dev/null; done 233 | [ ! -f "${CONTY_DIR}"/nvidia/current-nvidia-version ] && echo "${nvidia_driver_version}" > "${CONTY_DIR}"/nvidia/current-nvidia-version 234 | [ -f "${CONTY_DIR}"/nvidia/current-nvidia-version ] && nvidia_driver_conty=$(cat "${CONTY_DIR}"/nvidia/current-nvidia-version) 235 | if [ "${nvidia_driver_version}" != "${nvidia_driver_conty}" ]; then 236 | rm -f "${CONTY_DIR}"/up/usr/lib/*; echo "${nvidia_driver_version}" > "${CONTY_DIR}"/nvidia/current-nvidia-version 237 | fi 238 | /sbin/ldconfig -p > "${CONTY_DIR}"/nvidia/host_libs 239 | grep -i "nvidia\|libcuda" "${CONTY_DIR}"/nvidia/host_libs | cut -d ">" -f 2 > "${CONTY_DIR}"/nvidia/host_nvidia_libs 240 | libnv_paths=$(grep "libnv" "${CONTY_DIR}"/nvidia/host_libs | cut -d ">" -f 2) 241 | for f in $libnv_paths; do strings "${f}" | grep -qi -m 1 "nvidia" && echo "${f}" >> "${CONTY_DIR}"/nvidia/host_nvidia_libs; done 242 | nvidia_libs=$(cat "${CONTY_DIR}"/nvidia/host_nvidia_libs) 243 | for n in $nvidia_libs; do libname=$(echo "$n" | sed 's:.*/::') && [ ! -f "${CONTY_DIR}"/up/usr/lib/"$libname" ] && cp "$n" "${CONTY_DIR}"/up/usr/lib/; done 244 | libvdpau_nvidia="${CONTY_DIR}/up/usr/lib/libvdpau_nvidia.so" 245 | if ! test -f "${libvdpau_nvidia}*"; then cp "$(find /usr/lib -type f -name 'libvdpau_nvidia.so*' -print -quit 2>/dev/null | head -1)" "${CONTY_DIR}"/up/usr/lib/; fi 246 | [ -f "${libvdpau_nvidia}"."${nvidia_driver_version}" ] && [ ! -f "${libvdpau_nvidia}" ] && ln -s "${libvdpau_nvidia}"."${nvidia_driver_version}" "${libvdpau_nvidia}" 247 | [ -d "${CONTY_DIR}"/up/usr/lib ] && export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}":"${CONTY_DIR}"/up/usr/lib:"${LD_LIBRARY_PATH}" 248 | [ -d "${CONTY_DIR}"/up/usr/share ] && export XDG_DATA_DIRS="${XDG_DATA_DIRS}":"${CONTY_DIR}"/up/usr/share:"${XDG_DATA_DIRS}" 249 | fi 250 | fi 251 | 252 | PROOT_BINDINGS="" 253 | BWRAP_BINDINGS="" 254 | 255 | bind_files="/etc/resolv.conf /etc/hosts /etc/nsswitch.conf /etc/passwd /etc/group /etc/machine-id /etc/asound.conf /etc/localtime " 256 | for f in $bind_files; do [ -f "$f" ] && PROOT_BINDINGS=" $PROOT_BINDINGS --bind=$f" && BWRAP_BINDINGS=" $BWRAP_BINDINGS --ro-bind-try $f $f"; done 257 | 258 | bind_dirs=" /media /mnt /opt /run/media /usr/lib/locale /usr/share/fonts /usr/share/themes /var" 259 | for d in $bind_dirs; do [ -d "$d" ] && PROOT_BINDINGS=" $PROOT_BINDINGS --bind=$d" && BWRAP_BINDINGS=" $BWRAP_BINDINGS --bind-try $d $d"; done 260 | 261 | PROOT_BINDS=" --bind=/dev --bind=/sys --bind=/tmp --bind=/proc $PROOT_BINDINGS --bind=/home --bind=/home/$USER " 262 | BWRAP_BINDS=" --dev-bind /dev /dev --ro-bind /sys /sys --bind-try /tmp /tmp --proc /proc $BWRAP_BINDINGS " 263 | 264 | _JUNEST_CMD() { 265 | if [ "$PROOT_ON" = 1 ]; then 266 | "$HERE"/.local/share/junest/bin/junest proot -n -b "$PROOT_BINDS" "$@" 267 | else 268 | "$HERE"/.local/share/junest/bin/junest -n -b "$BWRAP_BINDS" "$@" 269 | fi 270 | } 271 | 272 | EXEC=$(grep -e '^Exec=.*' "${HERE}"/*.desktop | head -n 1 | cut -d "=" -f 2- | sed -e 's|%.||g') 273 | 274 | _JUNEST_CMD -- /usr/bin/obs "$@" 275 | 276 | HEREDOC 277 | chmod a+x "$APP".AppDir/AppRun 278 | 279 | ############################################################################# 280 | # EXTRACT PACKAGES 281 | ############################################################################# 282 | 283 | [ -z "$extraction_count" ] && extraction_count=0 284 | [ ! -f ./autodeps ] && echo "$extraction_count" > ./autodeps 285 | [ -f ./autodeps ] && autodeps=$(cat ./autodeps) 286 | [ "$autodeps" != "$extraction_count" ] && rm -Rf ./deps ./packages && echo "$extraction_count" > ./autodeps 287 | 288 | [ ! -f ./userdeps ] && echo "$DEPENDENCES" > ./userdeps 289 | [ -f ./userdeps ] && userdeps=$(cat ./userdeps) 290 | [ "$userdeps" != "$DEPENDENCES" ] && rm -Rf ./deps ./packages && echo "$DEPENDENCES" > ./userdeps 291 | 292 | _extract_main_package() { 293 | mkdir -p base 294 | rm -Rf ./base/* 295 | pkg_full_path=$(find ./archlinux -type f -name "$APP-*zst") 296 | if [ "$(echo "$pkg_full_path" | wc -l)" = 1 ]; then 297 | pkg_full_path=$(find ./archlinux -type f -name "$APP-*zst") 298 | else 299 | for p in $pkg_full_path; do 300 | if tar fx "$p" .PKGINFO -O | grep -q "pkgname = $APP$"; then 301 | pkg_full_path="$p" 302 | fi 303 | done 304 | fi 305 | [ -z "$pkg_full_path" ] && echo "💀 ERROR: no package found for \"$APP\", operation aborted!" && exit 0 306 | tar fx "$pkg_full_path" -C ./base/ 307 | VERSION=$(cat ./base/.PKGINFO | grep pkgver | cut -c 10- | sed 's@.*:@@') 308 | mkdir -p deps 309 | } 310 | 311 | _download_missing_packages() { 312 | localpackage=$(find ./archlinux -name "$arg-[0-9]*zst") 313 | if ! test -f "$localpackage"; then 314 | ./archlinux/.local/share/junest/bin/junest -- yay --noconfirm -Sw "$arg" 315 | fi 316 | } 317 | 318 | _extract_package() { 319 | _download_missing_packages &> /dev/null 320 | pkg_full_path=$(find ./archlinux -name "$arg-[0-9]*zst") 321 | pkgname=$(echo "$pkg_full_path" | sed 's:.*/::') 322 | [ ! -f ./packages ] && rm -Rf ./deps/* && touch ./packages 323 | if [ -z "$( ls -A './deps' )" ]; then 324 | rm -f ./packages 325 | echo "" 326 | echo "-----------------------------------------------------------------------------" 327 | echo " EXTRACTING PACKAGES" 328 | echo "-----------------------------------------------------------------------------" 329 | echo "" 330 | fi 331 | if test -f "$pkg_full_path"; then 332 | if ! grep -q "$pkgname" ./packages 2>/dev/null;then 333 | echo "◆ Extracting $pkgname" 334 | tar fx "$pkg_full_path" -C ./deps/ --warning=no-unknown-keyword 335 | echo "$pkgname" >> ./packages 336 | fi 337 | [ -n "$lib_browser_launcher" ] && [[ "$arg" =~ (hicolor-icon-theme|xapp) ]] && tar fx "$pkg_full_path" -C ./base/ --warning=no-unknown-keyword --exclude='.PKGINFO' 338 | fi 339 | } 340 | 341 | _determine_packages_and_libraries() { 342 | if echo "$arg" | grep -q "\.so"; then 343 | LIBSAVED="$LIBSAVED $arg" 344 | elif [ "$arg" != autoconf ] && [ "$arg" != autoconf ] && [ "$arg" != automake ] && [ "$arg" != bison ] && [ "$arg" != debugedit ] && [ "$arg" != dkms ] && [ "$arg" != fakeroot ] && [ "$arg" != flatpak ] && [ "$arg" != linux ] && [ "$arg" != gcc ] && [ "$arg" != make ] && [ "$arg" != pacman ] && [ "$arg" != patch ] && [ "$arg" != systemd ]; then 345 | _extract_package 346 | cat ./deps/.PKGINFO 2>/dev/null | grep "^depend = " | cut -c 10- | sed 's/=.*//' >> depdeps 347 | rm -f ./deps/.* 348 | fi 349 | } 350 | 351 | _extract_deps() { 352 | DEPS=$(sort -u ./depdeps) 353 | for arg in $DEPS; do 354 | _determine_packages_and_libraries 355 | done 356 | } 357 | 358 | _extract_all_dependences() { 359 | rm -f ./depdeps 360 | 361 | OPTDEPS=$(cat ./base/.PKGINFO 2>/dev/null | grep "^optdepend = " | sed 's/optdepend = //g' | sed 's/=.*//' | sed 's/:.*//') 362 | for arg in $OPTDEPS; do 363 | _determine_packages_and_libraries 364 | done 365 | [ -f ./depdeps ] && _extract_deps 366 | rm -f ./depdeps 367 | 368 | ARGS=$(echo "$DEPENDENCES" | tr " " "\n") 369 | for arg in $ARGS; do 370 | _determine_packages_and_libraries 371 | done 372 | 373 | DEPS=$(cat ./base/.PKGINFO 2>/dev/null | grep "^depend = " | sed 's/depend = //g' | sed 's/=.*//') 374 | for arg in $DEPS; do 375 | _determine_packages_and_libraries 376 | done 377 | 378 | # Set the level of sub-dependencies extraction, the higher the number, the bigger the AppImage will be 379 | if [ "$extraction_count" != 0 ]; then 380 | for e in $(seq "$extraction_count"); do _extract_deps; done 381 | fi 382 | } 383 | 384 | _extract_main_package 385 | _extract_all_dependences 386 | 387 | echo "" 388 | echo "-----------------------------------------------------------------------------" 389 | echo " IMPLEMENTING NECESSARY LIBRARIES (MAY TAKE SEVERAL MINUTES)" 390 | echo "-----------------------------------------------------------------------------" 391 | echo "" 392 | 393 | # Save files in /usr/bin 394 | _savebins() { 395 | echo "◆ Saving files in /usr/bin" 396 | cp -r ./archlinux/.junest/usr/bin/bwrap ./"$APP".AppDir/.junest/usr/bin/ 397 | cp -r ./archlinux/.junest/usr/bin/proot* ./"$APP".AppDir/.junest/usr/bin/ 398 | cp -r ./archlinux/.junest/usr/bin/*$BIN* ./"$APP".AppDir/.junest/usr/bin/ 399 | coreutils="[ basename cat chmod chown cp cut dir dirname du echo env expand expr fold head id ln ls mkdir mv readlink realpath rm rmdir seq sleep sort stty sum sync tac tail tee test timeout touch tr true tty uname uniq wc who whoami yes" 400 | utils_bin="awk bash $coreutils gawk gio grep ld ldd sed sh strings xdg-open" 401 | for b in $utils_bin; do 402 | cp -r ./archlinux/.junest/usr/bin/"$b" ./"$APP".AppDir/.junest/usr/bin/ 403 | done 404 | for arg in $BINSAVED; do 405 | cp -r ./archlinux/.junest/usr/bin/*"$arg"* ./"$APP".AppDir/.junest/usr/bin/ 406 | done 407 | } 408 | 409 | # Save files in /usr/lib 410 | _savelibs() { 411 | echo "◆ Detect libraries related to /usr/bin files" 412 | libs4bin=$(readelf -d ./"$APP".AppDir/.junest/usr/bin/* 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so") 413 | 414 | echo "◆ Saving JuNest core libraries" 415 | cp -r ./archlinux/.junest/usr/lib/ld-linux-x86-64.so* ./"$APP".AppDir/.junest/usr/lib/ 416 | lib_preset="$APP $BIN gconv libdw libelf libresolv.so libtinfo.so $libs4bin" 417 | LIBSAVED="$lib_preset $LIBSAVED $SHARESAVED" 418 | for arg in $LIBSAVED; do 419 | LIBPATHS="$LIBPATHS $(find ./archlinux/.junest/usr/lib -maxdepth 20 -wholename "*$arg*" | sed 's/\.\/archlinux\///g')" 420 | done 421 | for arg in $LIBPATHS; do 422 | [ ! -d "$APP".AppDir/"$arg" ] && cp -r ./archlinux/"$arg" "$APP".AppDir/"$arg" & 423 | done 424 | wait 425 | core_libs=$(find ./"$APP".AppDir -type f) 426 | lib_core=$(for c in $core_libs; do readelf -d "$c" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 427 | 428 | echo "◆ Detect libraries of the main package" 429 | base_libs=$(find ./base -type f | uniq) 430 | lib_base_0=$(for b in $base_libs; do readelf -d "$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 431 | 432 | echo "◆ Detect libraries of the dependencies" 433 | dep_libs=$(find ./deps -executable -name "*.so*") 434 | lib_deps=$(for d in $dep_libs; do readelf -d "$d" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 435 | 436 | echo "◆ Detect and copy base libs" 437 | basebin_libs=$(find ./base -executable -name "*.so*") 438 | lib_base_1=$(for b in $basebin_libs; do readelf -d "$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 439 | lib_base_1=$(echo "$lib_base_1" | tr ' ' '\n' | sort -u | xargs) 440 | lib_base_2=$(for b in $lib_base_1; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 441 | lib_base_2=$(echo "$lib_base_2" | tr ' ' '\n' | sort -u | xargs) 442 | lib_base_3=$(for b in $lib_base_2; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 443 | lib_base_3=$(echo "$lib_base_3" | tr ' ' '\n' | sort -u | xargs) 444 | lib_base_4=$(for b in $lib_base_3; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 445 | lib_base_4=$(echo "$lib_base_4" | tr ' ' '\n' | sort -u | xargs) 446 | lib_base_5=$(for b in $lib_base_4; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 447 | lib_base_5=$(echo "$lib_base_5" | tr ' ' '\n' | sort -u | xargs) 448 | lib_base_6=$(for b in $lib_base_5; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 449 | lib_base_6=$(echo "$lib_base_6" | tr ' ' '\n' | sort -u | xargs) 450 | lib_base_7=$(for b in $lib_base_6; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 451 | lib_base_7=$(echo "$lib_base_7" | tr ' ' '\n' | sort -u | xargs) 452 | lib_base_8=$(for b in $lib_base_7; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 453 | lib_base_8=$(echo "$lib_base_8" | tr ' ' '\n' | sort -u | xargs) 454 | lib_base_9=$(for b in $lib_base_8; do readelf -d ./archlinux/.junest/usr/lib/"$b" 2>/dev/null | grep NEEDED | tr '[] ' '\n' | grep ".so"; done) 455 | lib_base_9=$(echo "$lib_base_9" | tr ' ' '\n' | sort -u | xargs) 456 | lib_base_libs="$lib_core $lib_base_0 $lib_base_1 $lib_base_2 $lib_base_3 $lib_base_4 $lib_base_5 $lib_base_6 $lib_base_7 $lib_base_8 $lib_base_9 $lib_deps" 457 | lib_base_libs=$(echo "$lib_base_libs" | tr ' ' '\n' | sort -u | sed 's/.so.*/.so/' | xargs) 458 | for l in $lib_base_libs; do 459 | rsync -av ./archlinux/.junest/usr/lib/"$l"* ./"$APP".AppDir/.junest/usr/lib/ & 460 | done 461 | wait 462 | for l in $lib_base_libs; do 463 | rsync -av ./deps/usr/lib/"$l"* ./"$APP".AppDir/.junest/usr/lib/ & 464 | done 465 | wait 466 | } 467 | 468 | # Save files in /usr/share 469 | _saveshare() { 470 | echo "◆ Saving directories in /usr/share" 471 | SHARESAVED="$SHARESAVED $APP $BIN fontconfig glib- locale mime wayland X11" 472 | for arg in $SHARESAVED; do 473 | cp -r ./archlinux/.junest/usr/share/*"$arg"* ./"$APP".AppDir/.junest/usr/share/ 474 | done 475 | } 476 | 477 | _savebins 2>/dev/null 478 | _savelibs 2>/dev/null 479 | _saveshare 2>/dev/null 480 | 481 | echo "" 482 | echo "-----------------------------------------------------------------------------" 483 | echo " ASSEMBLING THE APPIMAGE" 484 | echo "-----------------------------------------------------------------------------" 485 | echo "" 486 | 487 | _rsync_main_package() { 488 | rm -Rf ./base/.* 489 | rsync -av ./base/ ./"$APP".AppDir/.junest/ | echo "◆ Rsync the content of the \"$APP\" package" 490 | } 491 | 492 | _rsync_dependences() { 493 | rm -Rf ./deps/.* 494 | chmod -R 777 ./deps/* 495 | rsync -av ./deps/ ./"$APP".AppDir/.junest/ | echo "◆ Rsync all dependencies, please wait" 496 | } 497 | 498 | _rsync_main_package 499 | _rsync_dependences 500 | 501 | ############################################################################# 502 | # REMOVE BLOATWARES, ENABLE MOUNTPOINTS 503 | ############################################################################# 504 | 505 | _remove_more_bloatwares() { 506 | etc_remove="makepkg.conf pacman" 507 | for r in $etc_remove; do 508 | rm -Rf ./"$APP".AppDir/.junest/etc/"$r"* 509 | done 510 | bin_remove="gcc" 511 | for r in $bin_remove; do 512 | rm -Rf ./"$APP".AppDir/.junest/usr/bin/"$r"* 513 | done 514 | lib_remove="cmake d3d gcc gconv libgphobos libOSMesa libxatracker" 515 | for r in $lib_remove; do 516 | rm -Rf ./"$APP".AppDir/.junest/usr/lib/"$r"* 517 | done 518 | share_remove="gcc gir hwdata i18n terminfo vulkan z" 519 | for r in $share_remove; do 520 | rm -Rf ./"$APP".AppDir/.junest/usr/share/"$r"* 521 | done 522 | echo Y | rm -Rf ./"$APP".AppDir/.cache/yay/* 523 | find ./"$APP".AppDir/.junest/usr/share/doc/* -not -iname "*$BIN*" -a -not -name "." -delete 2> /dev/null #REMOVE ALL DOCUMENTATION NOT RELATED TO THE APP 524 | find ./"$APP".AppDir/.junest/usr/share/locale/*/*/* -not -iname "*$BIN*" -a -not -name "." -delete 2> /dev/null #REMOVE ALL ADDITIONAL LOCALE FILES 525 | rm -Rf ./"$APP".AppDir/.junest/home # remove the inbuilt home 526 | rm -Rf ./"$APP".AppDir/.junest/usr/include # files related to the compiler 527 | rm -Rf ./"$APP".AppDir/.junest/usr/share/man # AppImages are not ment to have man command 528 | rm -Rf ./"$APP".AppDir/.junest/usr/lib/python*/__pycache__/* # if python is installed, removing this directory can save several megabytes 529 | #rm -Rf ./"$APP".AppDir/.junest/usr/lib/libgallium* 530 | rm -Rf ./"$APP".AppDir/.junest/usr/lib/libgo.so* 531 | #rm -Rf ./"$APP".AppDir/.junest/usr/lib/libLLVM* # included in the compilation phase, can sometimes be excluded for daily use 532 | rm -Rf ./"$APP".AppDir/.junest/var/* # remove all packages downloaded with the package manager 533 | } 534 | 535 | _enable_mountpoints_for_the_inbuilt_bubblewrap() { 536 | mkdir -p ./"$APP".AppDir/.junest/home 537 | mkdir -p ./"$APP".AppDir/.junest/media 538 | mkdir -p ./"$APP".AppDir/.junest/usr/lib/locale 539 | mkdir -p ./"$APP".AppDir/.junest/usr/share/fonts 540 | mkdir -p ./"$APP".AppDir/.junest/usr/share/themes 541 | mkdir -p ./"$APP".AppDir/.junest/run/media 542 | mkdir -p ./"$APP".AppDir/.junest/run/user 543 | rm -f ./"$APP".AppDir/.junest/etc/localtime && touch ./"$APP".AppDir/.junest/etc/localtime 544 | [ ! -f ./"$APP".AppDir/.junest/etc/asound.conf ] && touch ./"$APP".AppDir/.junest/etc/asound.conf 545 | } 546 | 547 | # Fix libcurl 548 | rm -f ./"$APP".AppDir/.junest/usr/lib/libcurl* && cp -r ./archlinux/.junest/usr/lib/libcurl* ./"$APP".AppDir/.junest/usr/lib/ 549 | 550 | _remove_more_bloatwares 551 | find ./"$APP".AppDir/.junest/usr/lib ./"$APP".AppDir/.junest/usr/lib32 -type f -regex '.*\.a' -exec rm -f {} \; 2>/dev/null 552 | find ./"$APP".AppDir/.junest/usr -type f -regex '.*\.so.*' -exec strip --strip-debug {} \; 553 | find ./"$APP".AppDir/.junest/usr/bin -type f ! -regex '.*\.so.*' -exec strip --strip-unneeded {} \; 554 | find ./"$APP".AppDir/.junest/usr -type d -empty -delete 555 | _enable_mountpoints_for_the_inbuilt_bubblewrap 556 | 557 | ############################################################################# 558 | # CREATE THE APPIMAGE 559 | ############################################################################# 560 | 561 | if test -f ./*.AppImage; then rm -Rf ./*archimage*.AppImage; fi 562 | 563 | APPNAME=$(cat ./"$APP".AppDir/*.desktop | grep 'Name=' | head -1 | cut -c 6- | sed 's/ /-/g') 564 | REPO="OBS-Studio-appimage" 565 | TAG="latest" 566 | VERSION="$VERSION" 567 | UPINFO="gh-releases-zsync|$GITHUB_REPOSITORY_OWNER|$REPO|$TAG|*x86_64.AppImage.zsync" 568 | 569 | ARCH=x86_64 ./appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 20 \ 570 | -u "$UPINFO" \ 571 | ./"$APP".AppDir "$APPNAME"_"$VERSION"-archimage4.3-x86_64.AppImage 572 | -------------------------------------------------------------------------------- /templates/obs-studio-ppa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | APP=obs-studio 4 | 5 | mkdir -p tmp 6 | cd tmp 7 | 8 | # DOWNLOADING THE DEPENDENCIES 9 | if test -f ./appimagetool; then 10 | echo " appimagetool already exists" 1> /dev/null 11 | else 12 | echo " Downloading appimagetool..." 13 | wget -q https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O appimagetool 14 | fi 15 | if test -f ./pkg2appimage; then 16 | echo " pkg2appimage already exists" 1> /dev/null 17 | else 18 | echo " Downloading pkg2appimage..." 19 | wget -q https://raw.githubusercontent.com/ivan-hc/AM-application-manager/main/tools/pkg2appimage 20 | fi 21 | chmod a+x ./appimagetool ./pkg2appimage 22 | 23 | # CREATING THE APPIMAGE: APPDIR FROM A RECIPE... 24 | 25 | PREVIOUSLTS=$(wget -q https://releases.ubuntu.com/ -O - | grep class | grep LTS | grep -m2 href | tail -n1 | sed -n 's/.*href="\([^"]*\).*/\1/p' | rev| cut -c 2- | rev) 26 | DEB=$(wget -q https://ppa.launchpadcontent.net/obsproject/obs-studio/ubuntu/pool/main/o/obs-studio/ -O - | grep $PREVIOUSLTS | grep amd64.deb | grep -o -P '(?<=href=").*(?=">obs)') 27 | wget https://ppa.launchpadcontent.net/obsproject/obs-studio/ubuntu/pool/main/o/obs-studio/$DEB 28 | ar x ./*.deb 29 | tar fx ./control.tar.xz 30 | 31 | mkdir -p $APP 32 | mv ./$DEB ./$APP/ 33 | 34 | # ...COMPILE THE RECIPE... 35 | rm -f ./recipe.yml 36 | echo "app: $APP 37 | binpatch: true 38 | ingredients: 39 | dist: $PREVIOUSLTS 40 | sources: 41 | - deb http://archive.ubuntu.com/ubuntu/ $PREVIOUSLTS main universe restricted multiverse 42 | - deb http://archive.ubuntu.com/ubuntu $PREVIOUSLTS-security main universe restricted multiverse 43 | - deb http://archive.ubuntu.com/ubuntu/ $PREVIOUSLTS-updates main universe restricted multiverse 44 | ppas: 45 | - obsproject/obs-studio 46 | packages: 47 | - obs-studio 48 | - ffmpeg 49 | - libvlc5 50 | - libnss-mdns 51 | - libxdmcp6 52 | - libxau6 53 | - libxdamage1 54 | - libpciaccess0 55 | - libxcb-randr0 56 | - libpangocairo-1.0-0 57 | - libpangoft2-1.0-0 58 | - libqt5x11extras5 59 | - libqt5x11extras5-dev 60 | - libssl-dev 61 | - libxcb-glx0-dev 62 | - v4l2loopback-dkms 63 | - xcb" >> recipe.yml 64 | 65 | echo "" >> deps 66 | cat control | grep -e "Depends:" | tr ' ' '\n' | grep -w -v '(' | grep -w -v ',' | grep -w -v '|' | grep -w -v ')' | tr ',' '\n' | grep -w -v "" >> deps 67 | ARGS=$(sed '1d' ./deps) 68 | for arg in $ARGS; do echo " - $arg" >> ./recipe.yml; done 69 | 70 | # ...RUN PKG2APPIMAGE... 71 | ./pkg2appimage ./recipe.yml 72 | 73 | # ...DOWNLOADING LIBUNIONPRELOAD... 74 | wget https://github.com/project-portable/libunionpreload/releases/download/amd64/libunionpreload.so 75 | chmod a+x libunionpreload.so 76 | mv ./libunionpreload.so ./$APP/$APP.AppDir/ 77 | 78 | # ...REPLACING THE EXISTING APPRUN WITH A CUSTOM ONE... 79 | rm -R -f ./$APP/$APP.AppDir/AppRun 80 | cat >> ./$APP/$APP.AppDir/AppRun << 'EOF' 81 | #!/bin/sh 82 | HERE="$(dirname "$(readlink -f $0)")" 83 | export UNION_PRELOAD=$HERE 84 | export LD_PRELOAD=$HERE/libunionpreload.so 85 | export PATH=$HERE/usr/bin/:$HERE/usr/sbin/:$HERE/bin/:$HERE/sbin/:$PATH 86 | export LD_LIBRARY_PATH=/lib/:/lib64/:/usr/lib/:/usr/lib/x86_64-linux-gnu/:$HERE/usr/lib/x86_64-linux-gnu/obs-plugins/:$HERE/usr/lib/x86_64-linux-gnu/cmake/libobs/:$HERE/usr/lib/x86_64-linux-gnu/qt5/plugins/xcbglintegrations/:$HERE/usr/lib/x86_64-linux-gnu/cmake/obs-frontend-api/:$HERE/usr/lib/x86_64-linux-gnu/obs-scripting/:$HERE/usr/lib/:$HERE/usr/lib/x86_64-linux-gnu/:$HERE/lib/:$HERE/lib/x86_64-linux-gnu/:$HERE/usr/lib/gcc/x86_64-linux-gnu/9/:$HERE/usr/lib/python3.8/lib-dynload/:$LD_LIBRARY_PATH 87 | export PYTHONPATH=$HERE/usr/lib/python3.8/:$PYTHONPATH 88 | export PYTHONHOME=$HERE/usr/:$PYTHONHOME 89 | export XDG_DATA_DIRS=$HERE/usr/share/:$XDG_DATA_DIRS 90 | export PERL5LIB=$HERE/usr/share/perl5/:$HERE/usr/lib/perl5/:$PERLLIB 91 | export GSETTINGS_SCHEMA_DIR=$HERE/usr/share/glib-2.0/schemas/:$GSETTINGS_SCHEMA_DIR 92 | export QT_PLUGIN_PATH=$HERE/lib/:$HERE/usr/lib/:$HERE/usr/lib/x86_64-linux-gnu/qt5/plugins/:$HERE/usr/lib/x86_64-linux-gnu/obs-plugins/:$HERE/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/:$QT_PLUGIN_PATH 93 | 94 | 95 | export OBS_DATA_PATH=$HERE/usr/share/obs/obs-studio/ 96 | export OBS_PLUGINS_LIB_PATH=$HERE/usr/lib/x86_64-linux-gnu/obs-plugins/ 97 | export OBS_PLUGINS_DATA_PATH=$HERE/usr/share/obs/obs-plugins/ 98 | export LIBOBS_DATA_PATH=$HERE/usr/share/obs/libobs/ 99 | export QT_QPA_PLATFORM_PLUGIN_PATH=$HERE/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/ 100 | export OBS_INCLUDE_PATH=$HERE/usr/include/obs/ 101 | 102 | export INCLUDE_PATH=$HERE/usr/include/ 103 | 104 | export QT_DEBUG_PLUGINS=1 105 | exec $HERE/usr/bin/obs "$@" 106 | EOF 107 | chmod a+x ./$APP/$APP.AppDir/AppRun 108 | 109 | # ...IMPORT THE LAUNCHER AND THE ICON TO THE APPDIR (uncomment if not available)... 110 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/22x22/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 111 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/24x24/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 112 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/32x32/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 113 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/48x48/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 114 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/64x64/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 115 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/128x128/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 116 | cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/256x256/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 117 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/512x512/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 118 | #cp ./$APP/$APP.AppDir/usr/share/icons/hicolor/scalable/apps/* ./$APP/$APP.AppDir/ 2>/dev/null 119 | cp ./$APP/$APP.AppDir/usr/share/applications/* ./$APP/$APP.AppDir/ 2>/dev/null 120 | 121 | # ...EXPORT THE APPDIR TO AN APPIMAGE! 122 | ARCH=x86_64 ./appimagetool -n ./$APP/$APP.AppDir; 123 | mkdir version 124 | mv ./$APP/$APP$underscore*.deb ./version/ 125 | version=$(ls ./version | cut -c 12- | rev | cut -c 11- | rev) 126 | 127 | cd .. 128 | mv ./tmp/*.AppImage ./OBS-Studio-$version-x86_64.AppImage 129 | --------------------------------------------------------------------------------