Skip to content

# Packaging external apps

By default, Briefcase assumes that you will be using Briefcase to manage the full app packaging life cycle. In this mode, your Briefcase configuration defines all your app's source code, dependencies, and resources; and Briefcase generates a distributable artefact that is appropriate for the target platform.

However, Briefcase can also be used to package an application which has been constructed using another tool, such as PyInstaller or py2app. In this mode of operation, Briefcase can be used to convert the app generated by those tools into an installer artefact, performing signing and notarization where necessary.

Briefcase refers to this mode of Briefcase usage as packaging an "external app".

## Configuring an external app

The process of configuring an external app is mostly the same as a normal Briefcase app, with one important difference: you do not define a `sources` entry, but instead define an `external_package_path`. This should be the content produced by your build tool that you want to distribute to end users.

The following would be a minimal `pyproject.toml` configuration for an external app called "Hello World":

    [tool.briefcase]
    project_name = "Hello World"
    bundle = "com.example"

    [tool.briefcase.app.helloworld]
    formal_name = "Hello World"
    version = "0.0.1"

    [tool.briefcase.app.helloworld.macOS]
    external_package_path = "..."

    [tool.briefcase.app.helloworld.linux]
    external_package_path = "..."

    [tool.briefcase.app.helloworld.windows]
    external_package_path = "..."

The required format for `external_package_path` is different on each platform.

### macOS

On macOS, the `external_package_path` should be the location of the `.app` bundle that you want to distribute to users. The configured `formal_name` must match the name of the app bundle (e.g., `Hello World.app` should use a formal name of `Hello World`); the `app_name` will be used for the shortcut installed in `/usr/local/bin` when creating a console app.

Briefcase will sign and notarize the app bundle, as well as any DMG or PKG file that is produced.

External macOS apps must be full macOS app bundles. Briefcase cannot be used to package standalone binaries.

### Linux

On Linux, the `external_package_path` should be a path that contains the root of a installation tree to be packaged. If you define an `external_package_path` of `external`, it is assumed that `external/usr/bin/<app_name>` will be the executable for your application, which will be installed as `/usr/bin/<app_name>`. Any other content that should be installed as part of your app should be included in the tree contained under `external`.

Although it is not possible to specify `requires` for external applications, external Linux applications must define `system_runtime_requires`. These requirements are used to define system-level requirements in the generated system packages.

### Windows

On Windows, the `external_package_path` should be the directory that contains all the content to be installed into the end-user's Program Files directory. By default, it is assumed that the executable used to launch the app is named `<external_package_path>/<formal_name>.exe` (or `<external_package_path>/<app_name>.exe` for a console app). If this is not the name or path to your executable, you can define `external_package_executable_path` to define the path inside `external_package_path` to your executable binary. For example, an `external_package_path` value of `external`, and an `external_package_executable_path` value of `somewhere/myapp.exe`, would define that `external/somewhere/myapp.exe` is the executable that should be installed as the application shortcut.

## Customizing packaging metadata

In the process of packaging an external app, Briefcase will generate an application template. The template is used to populate packaging metadata, installer and signing configuration files. The template that is used is identical to the one used for a normal Briefcase application; however, the packaged app will be removed from the template, and no attempt will be made to install application dependencies, resources, or a support package.

The files generated by the template should not be modified by hand. If you need to customize the contents of these templated files, you should use Briefcase app configuration settings to define those changes. For example, on macOS if you need to add an entitlement for signing purposes, you should not modify the templated `Entitlements.plist` file by hand - you should use the `entitlement` setting in your `pyproject.toml`.

If Briefcase's configuration options are not sufficient for your requirements, you can either fork the template used by Briefcase and use the `template` option to point at your custom template; or you can submit a pull request to Briefcase to support your customization use case.

## Packaging an external app

Once you have configured your external app, you can call `briefcase package`. There is no need to invoke `briefcase create`, `briefcase build`, or any other Briefcase command:

macOS Linux Windows

    (venv) $ briefcase package

    [helloworld] Packaging external content from /Users/brutus/helloworld/output/Hello World.app

    [helloworld] Generating application template...
    ...
    [helloworld] Packaged dist/Hello World-0.0.1.dmg

The `dist` folder will contain the `.dmg` that that was created.

The output of the package step will be slightly different depending on your Linux distribution; however, it will follow the following general format:

    (venv) $ briefcase package

    [helloworld] Finalizing application configuration...
    Targeting ubuntu:jammy (Vendor base debian)
    Determining glibc version... done
    Targeting glibc 2.35
    Targeting Python3.10

    [helloworld] Packaging external content from /Users/brutus/helloworld/output/linux-app

    [helloworld] Generating application template...
    ...
    [helloworld] Packaged dist/helloworld_0.0.1-1~ubuntu-jammy_amd64.deb

The `dist` folder will contain the system package that was created.

Docker (and the `--target` option) cannot be used to package external apps for different operating systems.

    (venv) C:\...>briefcase package

    [helloworld] Packaging external content from Z:\projects\helloworld\output\windows-app

    [helloworld] Generating application template...
    ...
    [helloworld] Packaged dist\Hello_World-0.0.1.msi

The `dist` folder will contain the installer that was created.

Any arguments to `briefcase package` that are allowed for normal Briefcase apps will also be honored for external apps. See the documentation of the Package command for details.

Briefcase will re-generate the templated app content on every invocation of `briefcase package`. On a second invocation of `briefcase package` for the same project, you will be prompted to overwrite the application. This will only overwrite the templated packaging metadata, not the application itself.