# Buggy code
def build_app(self, app: BaseConfig, **kwargs):
    """
    Build an application.

    :param app: The application to build
    """
    print()
    print("[{app.app_name}] Building AppImage...".format(app=app))

    try:
        print()
        # Build the AppImage.
        # For some reason, the version has to be passed in as an
        # environment variable, *not* in the configuration...
        env = {"VERSION": app.version}
        appdir_path = self.bundle_path(app) / "{app.formal_name}.AppDir".format(app=app)
        with self.dockerize(app) as docker:
            docker.run(
                [
                    str(self.linuxdeploy_appimage),
                    "--appimage-extract-and-run",
                    "--appdir={appdir_path}".format(appdir_path=appdir_path),
                    "-d",
                    str(
                        appdir_path
                        / "{app.bundle}.{app.app_name}.desktop".format(
                            app=app,
                        )
                    ),
                    "-o",
                    "appimage",
                ],
                env=env,
                check=True,
                cwd=str(self.platform_path),
            )

        # Make the binary executable.
        self.os.chmod(str(self.binary_path(app)), 0o755)
    except subprocess.CalledProcessError:
        print()
        raise BriefcaseCommandError(
            "Error while building app {app.app_name}.".format(app=app)
        )


# Traceback (ImportError)
(beeware-dev) osboxes@osboxes:~/beeware-tutorial/helloworld$ briefcase run

[helloworld] Starting app...

Traceback (most recent call last):
File "/tmp/.mount_Hello_63m7qR/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/tmp/.mount_Hello_63m7qR/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/tmp/.mount_Hello_63m7qR/usr/app/helloworld/__main__.py", line 4, in <module>
main().main_loop()
File "/tmp/.mount_Hello_63m7qR/usr/app/helloworld/app.py", line 40, in main
return HelloWorld()
File "/tmp/.mount_Hello_63m7qR/usr/app_packages/toga/app.py", line 208, in __init__
self.factory = get_platform_factory(factory)
File "/tmp/.mount_Hello_63m7qR/usr/app_packages/toga/platform.py", line 39, in get_platform_factory
from toga_gtk import factory
File "/tmp/.mount_Hello_63m7qR/usr/app_packages/toga_gtk/factory.py", line 1, in <module>
from .app import App, DocumentApp, MainWindow
File "/tmp/.mount_Hello_63m7qR/usr/app_packages/toga_gtk/app.py", line 8, in <module>
import gbulb
File "/tmp/.mount_Hello_63m7qR/usr/app_packages/gbulb/__init__.py", line 1, in <module>
from .glib_events import *
File "/tmp/.mount_Hello_63m7qR/usr/app_packages/gbulb/glib_events.py", line 12, in <module>
from gi.repository import GLib, Gio
File "/tmp/.mount_Hello_63m7qR/usr/app_packages/gi/__init__.py", line 42, in <module>
from . import _gi
ImportError: libffi.so.6: cannot open shared object file: No such file or directory

Unable to start app helloworld.

# Fixed code
def build_app(self, app: BaseConfig, **kwargs):
    """
    Build an application.

    :param app: The application to build
    """
    print()
    print("[{app.app_name}] Building AppImage...".format(app=app))

    try:
        print()
        # Build the AppImage.
        # For some reason, the version has to be passed in as an
        # environment variable, *not* in the configuration...
        env = {"VERSION": app.version}

        # Find all the .so files in app and app_packages,
        # so they can be passed in to linuxdeploy to have their
        # dependencies added to the AppImage. Looks for any .so file
        # in the application, and make sure it is marked for deployment.
        so_folders = set()
        for so_file in self.appdir_path(app).glob("**/*.so"):
            so_folders.add(so_file.parent)

        deploy_deps_args = []
        for folder in sorted(so_folders):
            deploy_deps_args.extend(["--deploy-deps-only", str(folder)])

        # Build the app image. We use `--appimage-extract-and-run`
        # because AppImages won't run natively inside Docker.
        with self.dockerize(app) as docker:
            docker.run(
                [
                    str(self.linuxdeploy_appimage_path),
                    "--appimage-extract-and-run",
                    "--appdir={appdir_path}".format(appdir_path=self.appdir_path(app)),
                    "-d",
                    str(
                        self.appdir_path(app)
                        / "{app.bundle}.{app.app_name}.desktop".format(
                            app=app,
                        )
                    ),
                    "-o",
                    "appimage",
                ]
                + deploy_deps_args,
                env=env,
                check=True,
                cwd=str(self.platform_path),
            )

        # Make the binary executable.
        self.os.chmod(str(self.binary_path(app)), 0o755)
    except subprocess.CalledProcessError:
        print()
        raise BriefcaseCommandError(
            "Error while building app {app.app_name}.".format(app=app)
        )