=======================
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
<https://pyinstaller.org/>`_ or `py2app <https://py2app.readthedocs.io/en/latest/>`_. 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 :attr:`sources` entry, but instead
define an :attr:`external_package_path`. This should be the content
produced by your build tool that you want to distribute to end users.

macOS
~~~~~

On macOS, the :attr:`external_package_path` should be the location of the ``.app`` bundle
that you want to distribute to users. The configured :attr:`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 :doc:`console app </how-to/cli-apps>`.

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 :attr:`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 :attr:`requires` for external applications, external
Linux applications *must* define :attr:`system_runtime_requires`. These requirements are
used to define system-level requirements in the generated system packages.

Windows
~~~~~~~

On Windows, the :attr:`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 :doc:`console app </how-to/cli-apps>`).
If this is not the name or path to your executable, you can define
:attr:`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 :attr:`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 :attr:`template` option to point at
your custom template; or you can :doc:`submit a pull request to Briefcase
</how-to/contribute/code>` 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:

.. tabs::

  .. group-tab:: macOS

    .. code-block:: console

      (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.

  .. group-tab:: Linux

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

    .. code-block:: console

      (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.

  .. group-tab:: Windows

    .. code-block:: doscon

      (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 :doc:`documentation of the Package command
</reference/commands/package>` 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.
