diff --git a/ou_dedetai.spec b/ou_dedetai.spec index df0d1fc9..aa497ff7 100644 --- a/ou_dedetai.spec +++ b/ou_dedetai.spec @@ -6,7 +6,7 @@ a = Analysis( pathex=[], #binaries=[('/usr/bin/tclsh8.6', '.')], binaries=[], - datas=[('ou_dedetai/img/*icon.png', 'ou_dedetai/img'),('ou_dedetai/assets/LogosStubFailOK.mst', 'assets')], + datas=[('ou_dedetai/img/*icon.png', 'img'),('ou_dedetai/assets/LogosStubFailOK.mst', 'assets')], hiddenimports=[], hookspath=[], hooksconfig={}, diff --git a/ou_dedetai/config.py b/ou_dedetai/config.py index 8beed496..75561b06 100644 --- a/ou_dedetai/config.py +++ b/ou_dedetai/config.py @@ -496,6 +496,7 @@ class Config: # i.e. filesystem traversals _wine_user: Optional[str] = None _download_dir: Optional[str] = None + _user_download_dir: Optional[str] = None _wine_output_encoding: Optional[str] = None _installed_faithlife_product_release: Optional[str] = None _wine_binary_files: Optional[list[str]] = None @@ -999,9 +1000,15 @@ def skip_install_system_dependencies(self, val: bool): @property def download_dir(self) -> str: if self._download_dir is None: - self._download_dir = utils.get_user_downloads_dir() + self._download_dir = constants.DEFAULT_CACHE_DIR return self._download_dir + @property + def user_download_dir(self) -> str: + if self._user_download_dir is None: + self._user_download_dir = utils.get_user_downloads_dir() + return self._user_download_dir + @property def installed_faithlife_product_release(self) -> Optional[str]: if self._raw.install_dir is None: diff --git a/ou_dedetai/constants.py b/ou_dedetai/constants.py index 48aba6ce..6dc3eae2 100644 --- a/ou_dedetai/constants.py +++ b/ou_dedetai/constants.py @@ -1,21 +1,31 @@ import logging import os import sys - from pathlib import Path -# This is relative to this file itself -APP_IMAGE_DIR = Path(__file__).parent / "img" + +def get_runmode() -> str: + if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): + return 'binary' + elif os.environ.get('SNAP'): + return 'snap' + else: + return 'script' + + # Are we running from binary or src? -if getattr(sys, 'frozen', False): - # We are running inside a PyInstaller bundle +RUNMODE = get_runmode() +if RUNMODE == 'binary': BUNDLE_DIR = Path(sys._MEIPASS) +elif RUNMODE == 'snap': + BUNDLE_DIR = Path(os.environ.get('SNAP')) else: # We are running in normal development mode BUNDLE_DIR = Path(__file__).resolve().parent -# Now define an assets directory that works in both modes: +# Now define assets and img directories. +APP_IMAGE_DIR = BUNDLE_DIR / 'img' APP_ASSETS_DIR = BUNDLE_DIR / 'assets' # Define app name variables. @@ -31,11 +41,17 @@ CACHE_LIFETIME_HOURS = 12 """How long to wait before considering our version cache invalid""" +if RUNMODE == 'snap': + cache_dir = Path(os.getenv('SNAP_USER_COMMON')) / '.cache' +else: + cache_dir = Path(os.getenv('XDG_CACHE_HOME', Path.home() / '.cache')) + # Set other run-time variables not set in the env. DEFAULT_CONFIG_PATH = os.path.expanduser(f"~/.config/FaithLife-Community/{BINARY_NAME}.json") # noqa: E501 -DEFAULT_APP_WINE_LOG_PATH= os.path.expanduser("~/.local/state/FaithLife-Community/wine.log") # noqa: E501 -DEFAULT_APP_LOG_PATH= os.path.expanduser(f"~/.local/state/FaithLife-Community/{BINARY_NAME}.log") # noqa: E501 -NETWORK_CACHE_PATH = os.path.expanduser("~/.cache/FaithLife-Community/network.json") # noqa: E501 +DEFAULT_APP_WINE_LOG_PATH = os.path.expanduser("~/.local/state/FaithLife-Community/wine.log") # noqa: E501 +DEFAULT_APP_LOG_PATH = os.path.expanduser(f"~/.local/state/FaithLife-Community/{BINARY_NAME}.log") # noqa: E501 +DEFAULT_CACHE_DIR = str(cache_dir / 'FaithLife-Community') +NETWORK_CACHE_PATH = f"{DEFAULT_CACHE_DIR}/network.json" DEFAULT_WINEDEBUG = "fixme-all,err-all" LEGACY_CONFIG_FILES = [ os.path.expanduser("~/.config/FaithLife-Community/Logos_on_Linux.json"), diff --git a/ou_dedetai/gui_app.py b/ou_dedetai/gui_app.py index 247fe70b..a22dcb80 100644 --- a/ou_dedetai/gui_app.py +++ b/ou_dedetai/gui_app.py @@ -615,9 +615,9 @@ def update_app_button(self, evt=None): def update_latest_lli_release_button(self, evt=None): msg = None result = utils.compare_logos_linux_installer_version(self) - if system.get_runmode() != 'binary': + if constants.RUNMODE != 'binary': state = 'disabled' - msg = "This button is disabled. Can't run self-update from script." + msg = f"This button is disabled. Can't run self-update from {constants.RUNMODE}." # noqa: E501 elif result == utils.VersionComparison.OUT_OF_DATE: state = '!disabled' elif result == utils.VersionComparison.UP_TO_DATE: diff --git a/ou_dedetai/installer.py b/ou_dedetai/installer.py index 287ca235..c8c9e32f 100644 --- a/ou_dedetai/installer.py +++ b/ou_dedetai/installer.py @@ -259,8 +259,7 @@ def ensure_launcher_executable(app: App): app.installer_step_count += 1 ensure_config_file(app=app) app.installer_step += 1 - runmode = system.get_runmode() - if runmode == 'binary': + if constants.RUNMODE == 'binary': app.status(f"Copying launcher to {app.conf.install_dir}…") # Copy executable into install dir. @@ -282,14 +281,13 @@ def ensure_launcher_shortcuts(app: App): ensure_launcher_executable(app=app) app.installer_step += 1 app.status("Creating launcher shortcuts…") - runmode = system.get_runmode() - if runmode == 'binary': + if constants.RUNMODE == 'binary': app.status("Creating launcher shortcuts…") create_launcher_shortcuts(app) else: # This is done so devs can run this without it clobbering their install app.status( - "Running from source. Won't clobber your desktop shortcuts", + f"Runmode is '{constants.RUNMODE}'. Won't create desktop shortcuts", ) def install(app: App): @@ -349,8 +347,28 @@ def create_wine_appimage_symlinks(app: App): p.symlink_to(f"./{app.conf.wine_appimage_link_file_name}") -def create_desktop_file(name, contents): - launcher_path = Path(f"~/.local/share/applications/{name}").expanduser() +def create_desktop_file( + filename: str, + app_name: str, + exec_cmd: str, + icon_path: str, + wm_class: str, +): + contents = f"""[Desktop Entry] +Name={app_name} +GenericName=FaithLife Wine App Installer +Comment=Manages FaithLife Bible Software via Wine +Exec={exec_cmd} +Icon={icon_path} +Terminal=false +Type=Application +StartupWMClass={wm_class} +Categories=Education; +Keywords=Logos;Verbum;Bible;Control; +""" + local_share = Path.home() / '.local' / 'share' + xdg_data_home = Path(os.getenv('XDG_DATA_HOME', local_share)) + launcher_path = xdg_data_home / 'applications' / filename if launcher_path.is_file(): logging.info(f"Removing desktop launcher at {launcher_path}.") launcher_path.unlink() @@ -361,6 +379,7 @@ def create_desktop_file(name, contents): with launcher_path.open('w') as f: f.write(contents) os.chmod(launcher_path, 0o755) + return launcher_path def create_launcher_shortcuts(app: App): @@ -376,8 +395,10 @@ def create_launcher_shortcuts(app: App): logos_icon_path = app_dir / logos_icon_src.name app_icon_path = app_dir / app_icon_src.name - if system.get_runmode() == 'binary': + if constants.RUNMODE == 'binary': lli_executable = f"{installdir}/{constants.BINARY_NAME}" + elif constants.RUNMODE == 'snap': + lli_executable = f"{os.getenv('SNAP')}/bin/{constants.BINARY_NAME}" else: script = Path(sys.argv[0]).expanduser().resolve() repo_dir = None @@ -401,41 +422,21 @@ def create_launcher_shortcuts(app: App): else: logging.info(f"Icon found at {path}.") - # Set launcher file names and content. - desktop_files = [ - ( - f"{flproduct}Bible.desktop", - f"""[Desktop Entry] -Name={flproduct}Bible -Comment=A Bible Study Library with Built-In Tools -Exec={lli_executable} --run-installed-app -Icon={logos_icon_path} -Terminal=false -Type=Application -StartupWMClass={flproduct.lower()}.exe -Categories=Education; -Keywords={flproduct};Logos;Bible;Control; -""" - ), - ( - f"{constants.BINARY_NAME}.desktop", - f"""[Desktop Entry] -Name={constants.APP_NAME} -GenericName=FaithLife Wine App Installer -Comment=Manages FaithLife Bible Software via Wine -Exec={lli_executable} -Icon={app_icon_path} -Terminal=false -Type=Application -StartupWMClass={constants.BINARY_NAME} -Categories=Education; -Keywords={flproduct};Logos;Bible;Control; -""" - ), - ] - - # Create the files. - for file_name, content in desktop_files: - create_desktop_file(file_name, content) - fpath = Path.home() / '.local' / 'share' / 'applications' / file_name - logging.debug(f"> File exists?: {fpath}: {fpath.is_file()}") + # Create Logos/Verbum desktop file. + logos_path = create_desktop_file( + f"{flproduct}Bible.desktop", + f"{flproduct}Bible", + f"{lli_executable} --run-installed-app", + logos_icon_path, + f"{flproduct.lower()}.exe", + ) + logging.debug(f"> File exists?: {logos_path}: {logos_path.is_file()}") + # Create Ou Dedetai desktop file. + app_path = create_desktop_file( + f"{constants.BINARY_NAME}.desktop", + constants.APP_NAME, + lli_executable, + app_icon_path, + constants.BINARY_NAME, + ) + logging.debug(f"> File exists?: {app_path}: {app_path.is_file()}") diff --git a/ou_dedetai/main.py b/ou_dedetai/main.py index 0ed9779a..5ffbf638 100755 --- a/ou_dedetai/main.py +++ b/ou_dedetai/main.py @@ -215,7 +215,7 @@ def parse_args(args, parser) -> Tuple[EphemeralConfiguration, Callable[[Ephemera # if network.check_for_updates: # ephemeral_config.check_updates_now = True - if args.skip_dependencies: + if args.skip_dependencies or constants.RUNMODE == 'snap': ephemeral_config.install_dependencies_skip = True if args.force_root: diff --git a/ou_dedetai/network.py b/ou_dedetai/network.py index 50f33013..6de36015 100644 --- a/ou_dedetai/network.py +++ b/ou_dedetai/network.py @@ -177,7 +177,7 @@ def load(cls) -> "CachedRequests": def _write(self) -> None: """Writes the cache to disk. Done internally when there are changes""" path = Path(constants.NETWORK_CACHE_PATH) - path.parent.mkdir(exist_ok=True) + path.parent.mkdir(exist_ok=True, parents=True) with open(path, "w") as f: json.dump(self.__dict__, f, indent=4, sort_keys=True, default=vars) f.write("\n") @@ -305,8 +305,7 @@ def logos_reuse_download( status_messages: bool = True ): dirs = [ - app.conf.install_dir, - os.getcwd(), + app.conf.user_download_dir, app.conf.download_dir, ] found = 1 diff --git a/ou_dedetai/system.py b/ou_dedetai/system.py index 32247775..7db932d7 100644 --- a/ou_dedetai/system.py +++ b/ou_dedetai/system.py @@ -12,19 +12,10 @@ import sys import time +from ou_dedetai import constants from ou_dedetai.app import App -from . import constants - - -def get_runmode(): - if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): - return 'binary' - else: - return 'script' - - def fix_ld_library_path(env: Optional[MutableMapping[str, str]]) -> dict[str, str]: #noqa: E501 """Removes pyinstaller bundled dynamic linked libraries when executing commands @@ -42,7 +33,7 @@ def fix_ld_library_path(env: Optional[MutableMapping[str, str]]) -> dict[str, st # Only do this when running in binary mode # Since LD_LIBRARY_PATH is core to how binaries work, we don't want it # modified unless we know we need to. - if get_runmode() == 'binary': + if constants.RUNMODE == 'binary': # *BSD uses LD_LIBRARY_PATH, AIX uses LIBPATH for lp_key in ["LD_LIBRARY_PATH", "LIBPATH"]: lp_orig = env.pop(lp_key + '_ORIG', None) @@ -264,8 +255,7 @@ def get_dialog() -> str: dialog - tk (graphical), curses (terminal ui), or cli (command line) """ if not os.environ.get('DISPLAY'): - print("The installer does not work unless you are running a display", file=sys.stderr) # noqa: E501 - sys.exit(1) + logging.critical("The installer does not work unless you are running a display") # noqa: E501 dialog = os.getenv('DIALOG') # find dialog @@ -528,6 +518,7 @@ def get_package_manager() -> PackageManager | None: "libva mpg123 v4l-utils " # video "libxslt sqlite " # misc ) + logos_9_packages = "" incompatible_packages = "" # appimagelauncher handled separately else: # Add more conditions for other package managers as needed. @@ -544,7 +535,7 @@ def get_package_manager() -> PackageManager | None: logos_9_packages=logos_9_packages, query_prefix=query_prefix ) - logging.debug("Package Manager: {output}") + logging.debug(f"Package Manager: {output}") return output diff --git a/ou_dedetai/tui_app.py b/ou_dedetai/tui_app.py index 6c729d28..73d8d704 100644 --- a/ou_dedetai/tui_app.py +++ b/ou_dedetai/tui_app.py @@ -899,7 +899,7 @@ def which_dialog_options(self, labels: list[str]) -> list[Any]: #noqa: E501 def set_tui_menu_options(self): labels = [] - if system.get_runmode() == "binary": + if constants.RUNMODE == "binary": status = utils.compare_logos_linux_installer_version(self) if status == utils.VersionComparison.OUT_OF_DATE: labels.append(f"Update {constants.APP_NAME}") diff --git a/ou_dedetai/utils.py b/ou_dedetai/utils.py index 095b0039..19bc6e25 100644 --- a/ou_dedetai/utils.py +++ b/ou_dedetai/utils.py @@ -85,9 +85,10 @@ def clean_all(): def get_user_downloads_dir() -> str: home = Path.home() + downloads_path = str(home / 'Downloads') + xdg_config = Path(os.getenv('XDG_CONFIG_HOME', home / '.config')) user_dirs_file = xdg_config / 'user-dirs.dirs' - downloads_path = str(home / 'Downloads') if user_dirs_file.is_file(): with user_dirs_file.open() as f: for line in f.readlines(): @@ -540,8 +541,8 @@ def set_appimage_symlink(app: App): def update_to_latest_lli_release(app: App): result = compare_logos_linux_installer_version(app) - if system.get_runmode() != 'binary': - logging.error(f"Can't update {constants.APP_NAME} when run as a script.") + if constants.RUNMODE != 'binary': + logging.error(f"Can't update {constants.APP_NAME} when run as {constants.RUNMODE}.") # noqa: E501 elif result == VersionComparison.OUT_OF_DATE: network.update_lli_binary(app=app) elif result == VersionComparison.UP_TO_DATE: diff --git a/snap/bin/run.sh b/snap/bin/run.sh new file mode 100755 index 00000000..1d74a03a --- /dev/null +++ b/snap/bin/run.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Ensure correct environment. +if [[ $SNAP_NAME != oudedetai ]]; then + echo "ERROR: Not running in oudedetai snap environment." + exit 1 +fi + +export FLPRODUCT="$1" +shift +echo "Starting $FLPRODUCT" +export TARGETVERSION="10" + +# Ensure Faithlife app is installed. +app_exe="$(find "${INSTALLDIR}/wine64_bottle" -wholename "*${FLPRODUCT}/${FLPRODUCT}.exe" 2>/dev/null)" +if [[ -z $app_exe ]]; then + oudedetai --install-app --assume-yes $@ + ec=$? + if [[ $ec -ne 0 ]]; then + exit $ec + fi +fi + +# Run Faithlife app. +oudedetai --run-installed-app $@ diff --git a/snap/gui/logos.png b/snap/gui/logos.png new file mode 120000 index 00000000..15dddfc1 --- /dev/null +++ b/snap/gui/logos.png @@ -0,0 +1 @@ +../../ou_dedetai/img/Logos-128-icon.png \ No newline at end of file diff --git a/snap/gui/oudedetai.desktop b/snap/gui/oudedetai.desktop new file mode 100644 index 00000000..6b10e861 --- /dev/null +++ b/snap/gui/oudedetai.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Ou Dedetai +GenericName=FaithLife Wine App Installer +Comment=Manages FaithLife Bible Software via Wine +Exec=oudedetai +Icon=${SNAP}/meta/gui/oudedetai.png +Terminal=false +Type=Application +StartupWMClass=Ou Dedetai +Categories=Education; +Keywords=Logos;Verbum;Bible;Control; diff --git a/snap/gui/oudedetai.logos.desktop b/snap/gui/oudedetai.logos.desktop new file mode 100644 index 00000000..12077cba --- /dev/null +++ b/snap/gui/oudedetai.logos.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Logos Bible +GenericName=FaithLife Wine App Installer +Comment=Manages FaithLife Bible Software via Wine (snap) +Exec=oudedetai.logos +Icon=${SNAP}/meta/gui/logos.png +Terminal=false +Type=Application +StartupWMClass=logos.exe +Categories=Education; +Keywords=Logos;Bible; diff --git a/snap/gui/oudedetai.png b/snap/gui/oudedetai.png new file mode 120000 index 00000000..aebd7458 --- /dev/null +++ b/snap/gui/oudedetai.png @@ -0,0 +1 @@ +../../ou_dedetai/img/icon.png \ No newline at end of file diff --git a/snap/gui/oudedetai.verbum.desktop b/snap/gui/oudedetai.verbum.desktop new file mode 100644 index 00000000..f2684b85 --- /dev/null +++ b/snap/gui/oudedetai.verbum.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Verbum Bible +GenericName=FaithLife Wine App Installer +Comment=Manages FaithLife Bible Software via Wine (snap) +Exec=oudedetai.verbum +Icon=${SNAP}/meta/gui/verbum.png +Terminal=false +Type=Application +StartupWMClass=verbum.exe +Categories=Education; +Keywords=Verbum;Bible; diff --git a/snap/gui/verbum.png b/snap/gui/verbum.png new file mode 120000 index 00000000..4efd423b --- /dev/null +++ b/snap/gui/verbum.png @@ -0,0 +1 @@ +../../ou_dedetai/img/Verbum-128-icon.png \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 00000000..fbbc9732 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,139 @@ +name: oudedetai +base: core24 +adopt-info: oudedetai +summary: Install and maintain FaithLife's Logos Bible (Verbum) Software. +description: | + This repository contains a Python program for installing and maintaining + FaithLife's Logos Bible (Verbum) Software on Linux. + + This program is created and maintained by the FaithLife Community and is + licensed under the MIT License. +grade: stable +confinement: strict +icon: ou_dedetai/img/icon.svg # or post-build: snap/img/icon.svg + +platforms: + amd64: + +environment: + # Define config variables. + INSTALLDIR: "$SNAP_USER_COMMON" + WINE_EXE: "$SNAP/bin/wine64" + WINEBIN_CODE: "Custom" + # Define runtime variables. + # https://forum.snapcraft.io/t/modulenotfounderror-no-module-named-tkinter/28707/5?u=n8marti + TCL_LIBRARY: $SNAP/usr/share/tcltk/tcl8.6 + TK_LIBRARY: $SNAP/usr/share/tcltk/tk8.6 + TCLLIBPATH: $SNAP/usr/lib/tcltk/$CRAFT_ARCH_TRIPLET_BUILD_FOR/tk8.6 + PYTHON_SITE_PKGS: $SNAP/lib/python3.12/site-packages + PYTHON_APT_PKGS: $SNAP/usr/lib/python3.12 + PYTHON_LIB_DYNLD: $SNAP/usr/lib/python3.12/lib-dynload + PYTHONPATH: $PYTHON_SITE_PKGS:$PYTHON_APT_PKGS:$PYTHON_LIB_DYNLD + # https://forum.snapcraft.io/t/libpxbackend-1-0-so-cannot-open-shared-object-file-no-such-file-or-directory/44263/2 + LD_LIBRARY_PATH: $SNAP/usr/lib:$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR + +apps: + oudedetai: + extensions: [gnome] + command: bin/oudedetai + plugs: &allplugs + - audio-playback + - home + - network + - opengl + - removable-media + - system-observe + - system-trace + + logos: + extensions: [gnome] + command: bin/run.sh Logos + plugs: *allplugs + + verbum: + extensions: [gnome] + command: bin/run.sh Verbum + plugs: *allplugs + +parts: + bin: + source: ./snap/bin + plugin: dump + organize: + run.sh: bin/run.sh + # stage-packages: + # - jq + + assets: + source: ./ou_dedetai/assets + plugin: dump + organize: + '*': assets/ + + img: + source: ./ou_dedetai/img + plugin: dump + organize: + '*': img/ + + # wine-apt: # installs most recent devel version + # plugin: nil + # build-packages: [wget] + # override-stage: | + # dpkg --add-architecture i386 + # mkdir -pm755 /etc/apt/keyrings + # wget -qO /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key + # wget -qNP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/noble/winehq-noble.sources + # apt-get update + # apt-get -y install --install-recommends winehq-devel + # craftctl default + + wine-custom: + source: https://github.com/sil-car/wine-builds/releases/download/wine_10.0/wine_10.0+24.04.tar.xz + plugin: dump + organize: + 'wine_*/bin': bin + 'wine_*/lib': lib + 'wine_*/share': share + stage-packages: + - libavcodec60 + - libavformat60 + - libavutil58 + - libusb-1.0-0 + - libxkbregistry0 + + oudedetai: + source: https://github.com/FaithLife-Community/LogosLinuxInstaller.git + plugin: python + override-pull: | + craftctl default + craftctl set version=$(git describe --tag) + stage-packages: + - libncurses6 + - libncursesw6 + - python3-tk + + cleanup: + after: + - wine-custom + - oudedetai + plugin: nil + override-prime: | + # Remove libraries from snapcraft build lint warnings. + rm -f lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicudata.so* + rm -f usr/lib/libBLTlite.2.5.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libcjson_utils.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libform.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libformw.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libhwy_contrib.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libhwy_test.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicui18n.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicuio.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicutest.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicutu.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libmenu.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libmenuw.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libpanel.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libpanelw.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libtheora.so* + rm -f usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libzvbi-chains.so*