教程 3 - 包装以便分发¶
到目前为止,我们一直在 "开发者模式 "下运行应用程序。这让我们可以轻松地在本地运行应用程序,但我们真正想要的是能将我们的应用程序提供给其他人。
但是,我们不想教用户如何安装 Python、创建虚拟环境、克隆 git 仓库并在开发者模式下运行 Briefcase。我们宁可只给他们一个安装程序,让应用程序能够正常运行。
公文包可用于打包您的应用程序,以便以这种方式发布。
创建应用程序脚手架¶
由于这是第一次打包应用程序,我们需要创建一些配置文件和其他脚手架来支持打包过程。在 helloworld
目录中,运行:
(beeware-venv) $ briefcase create
[helloworld] Generating application template...
Using app template: https://github.com/beeware/briefcase-macOS-app-template.git, branch v0.3.18
...
[helloworld] Installing support package...
...
[helloworld] Installing application code...
Installing src/helloworld... done
[helloworld] Installing requirements...
...
[helloworld] Installing application resources...
...
[helloworld] Removing unneeded app content...
Removing unneeded app bundle content... done
[helloworld] Created build/helloworld/macos/app
(beeware-venv) $ briefcase create
[helloworld] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.10
[helloworld] Generating application template...
Using app template: https://github.com/beeware/briefcase-linux-AppImage-template.git, branch v0.3.18
...
[helloworld] Installing support package...
No support package required.
[helloworld] Installing application code...
Installing src/helloworld... done
[helloworld] Installing requirements...
...
[helloworld] Installing application resources...
...
[helloworld] Removing unneeded app content...
Removing unneeded app bundle content... done
[helloworld] Created build/helloworld/linux/ubuntu/jammy
Errors about Python versions
If you receive an error that reads something like:
The version of Python being used to run Briefcase (3.12) is not the system python3 (3.10).
You will need to recreate your virtual environment using the system
python3
. Using the system Python is a requirement for packaging your
application.
(beeware-venv) C:\...>briefcase create
[helloworld] Generating application template...
Using app template: https://github.com/beeware/briefcase-windows-app-template.git, branch v0.3.18
...
[helloworld] Installing support package...
...
[helloworld] Installing application code...
Installing src/helloworld... done
[helloworld] Installing requirements...
...
[helloworld] Installing application resources...
...
[helloworld] Created build\helloworld\windows\app
您可能刚刚在终端上看到了几页内容......那么刚刚发生了什么?公文包做了以下工作:
它**生成一个应用程序模板**。除了实际应用程序的代码之外,构建本机安装程序还需要许多文件和配置。这些额外的脚手架对于同一平台上的每个应用程序几乎都是一样的,除了正在构建的实际应用程序的名称--因此,Briefcase 为其支持的每个平台提供了一个应用程序模板。这一步将推出模板,替换应用程序名称、捆绑 ID 和配置文件中的其他属性,以支持正在构建的平台。
如果您对 Briefcase 提供的模板不满意,可以提供自己的模板。不过,在使用 Briefcase 的默认模板获得更多经验之前,您可能不想这样做。
它**下载并安装了一个支持包**。公文包所采用的打包方法被描述为 "最简单可行的方法"--它将一个完整、独立的 Python 解释器作为其构建的每个应用程序的一部分。这种打包方式在空间利用上略显不足--如果有 5 个应用程序打包到 Briefcase 中,那么就会有 5 份 Python 解释器副本。但是,这种方法保证了每个应用程序都是完全独立的,使用的 Python 都是已知的能与应用程序一起工作的特定版本。
同样,Briefcase 为每个平台提供了默认的支持包;如果需要,您可以提供自己的支持包,并将其作为构建过程的一部分。如果您需要启用 Python 解释器中的特定选项,或者如果您想从标准库中剥离运行时不需要的模块,您可能需要这样做。
公文包维护支持包的本地缓存,因此一旦您下载了特定的支持包,该缓存副本将用于未来的构建。
As noted above, when Briefcase packages an app as a native Linux system package (the default package format for Linux), a support package is not included with the app. Instead, the app will use the Python that is provided by the distribution of Linux being targeted.
它**安装应用程序要求**。您的应用程序可以指定运行时所需的任何第三方模块。这些模块将使用
pip
安装到应用程序的安装程序中。它**安装你的应用程序代码**。您的应用程序将有自己的代码和资源(如运行时需要的图像);这些文件会被复制到安装程序中。
最后,它还会添加安装程序本身所需的其他资源。这包括需要附加到最终应用程序的图标和闪屏图像等。
完成上述操作后,如果查看项目目录,就会发现一个与平台("macOS"、"linux "或 "windows")相对应的目录,其中包含附加文件。这就是应用程序的特定平台打包配置。
构建您的应用程序¶
现在可以编译应用程序了。此步骤将执行二进制编译,这是应用程序在目标平台上可执行所必需的。
(beeware-venv) $ briefcase build
[helloworld] Adhoc signing app...
...
Signing build/helloworld/macos/app/Hello World.app
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 00:07
[helloworld] Built build/helloworld/macos/app/Hello World.app
在 macOS 上,"build``"命令不需要*编译*任何内容,但需要对二进制文件的内容进行签名,以便执行。这种签名是一种*临时*签名--它只能在*你*的机器上工作;如果你想将应用程序发布给其他人,就需要提供完整的签名。
(beeware-venv) $ briefcase build
[helloworld] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.10
[helloworld] Building application...
Build bootstrap binary...
make: Entering directory '/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/bootstrap'
...
make: Leaving directory '/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/bootstrap'
Building bootstrap binary... done
Installing license... done
Installing changelog... done
Installing man page... done
Updating file permissions... done
Stripping binary... done
[helloworld] Built build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/bin/helloworld
此步骤完成后,build`文件夹将包含一个`helloworld-0.0.1`文件夹,其中包含一个 Linux `/usr`` 文件系统的镜像。这个文件系统镜像将包含一个``bin``文件夹,里面有一个``helloworld``二进制文件,以及支持二进制文件所需的``lib``和``share``文件夹。
(beeware-venv) C:\...>briefcase build
Setting stub app details... done
[helloworld] Built build\helloworld\windows\app\src\Hello World.exe
在 Windows 上,build
命令不需要编译*任何东西,但它确实需要写入一些元数据,以便应用程序知道它的名称、版本等。
触发杀毒软件
由于这些元数据是在 create
命令中直接写入从模板推出的预编译二进制文件的,因此可能会触发机器上运行的杀毒软件,从而阻止元数据的写入。在这种情况下,请指示杀毒软件允许工具(名为 rcedit-x64.exe
)运行,并重新运行上述命令。
运行应用程序¶
现在您可以使用公文包运行应用程序了:
(beeware-venv) $ briefcase run
[helloworld] Starting app...
===========================================================================
Configuring isolated Python...
Pre-initializing Python runtime...
PythonHome: /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
PYTHONPATH:
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python311.zip
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib/lib-dynload
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app_packages
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app
Configure argc/argv...
Initializing Python runtime...
Installing Python NSLog handler...
Running app module: helloworld
---------------------------------------------------------------------------
(beeware-venv) $ briefcase run
[helloworld] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.10
[helloworld] Starting app...
===========================================================================
Install path: /home/brutus/beeware-tutorial/helloworld/build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr
Pre-initializing Python runtime...
PYTHONPATH:
- /usr/lib/python3.10
- /usr/lib/python3.10/lib-dynload
- /home/brutus/beeware-tutorial/helloworld/build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/lib/helloworld/app
- /home/brutus/beeware-tutorial/helloworld/build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/lib/helloworld/app_packages
Configure argc/argv...
Initializing Python runtime...
Running app module: helloworld
---------------------------------------------------------------------------
(beeware-venv) C:\...>briefcase run
[helloworld] Starting app...
===========================================================================
Log started: 2023-04-23 04:47:45Z
PreInitializing Python runtime...
PythonHome: C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
PYTHONPATH:
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\python39.zip
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app_packages
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app
Configure argc/argv...
Initializing Python runtime...
Running app module: helloworld
---------------------------------------------------------------------------
这将使用 build
命令的输出开始运行本地应用程序。
你可能会注意到应用程序运行时的外观有一些细微差别。例如,操作系统显示的图标和名称可能与在开发者模式下运行时略有不同。这也是因为您使用的是打包的应用程序,而不仅仅是运行 Python 代码。从操作系统的角度来看,您现在运行的是 "一个应用程序",而不是 "一个 Python 程序",这也反映在应用程序的显示方式上。
创建安装程序¶
现在,您可以使用 package
命令打包应用程序,以便发布。打包命令会执行将脚手架项目转换为最终可发布产品所需的编译工作。根据平台的不同,这可能涉及编译安装程序、执行代码签名或执行其他发布前任务。
(beeware-venv) $ briefcase package --adhoc-sign
[helloworld] Signing app...
*************************************************************************
** WARNING: Signing with an ad-hoc identity **
*************************************************************************
This app is being signed with an ad-hoc identity. The resulting
app will run on this computer, but will not run on anyone else's
computer.
To generate an app that can be distributed to others, you must
obtain an application distribution certificate from Apple, and
select the developer identity associated with that certificate
when running 'briefcase package'.
*************************************************************************
Signing app with ad-hoc identity...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 00:07
[helloworld] Building DMG...
Building dist/Hello World-0.0.1.dmg
[helloworld] Packaged dist/Hello World-0.0.1.dmg
dist "文件夹将包含一个名为 "Hello World-0.0.1.dmg "的文件。如果在 Finder 中找到该文件,并双击其图标,就会加载 DMG,从而获得 Hello World 应用程序的副本,并链接到 "应用程序 "文件夹以方便安装。将应用程序文件拖入 "应用程序",就安装好了应用程序。将 DMG 文件发送给朋友,他们应该也能完成同样的操作。
在本例中,我们使用了"--adhoc-sign "选项--也就是说,我们使用*ad hoc* 凭据(仅在你的机器上有效的临时凭据)来签署我们的应用程序。我们这样做是为了让教程简单明了。设置代码签名身份有点麻烦,而且只有当你打算将应用程序发布给他人时才*需要。如果我们要发布一个真正的应用程序供他人使用,我们就需要指定真实的凭据。
当您准备发布真正的应用程序时,请查看关于 "设置 macOS 代码签名身份 <https://briefcase.readthedocs.io/en/latest/how-to/code-signing/macOS.html>`__" 的公文包操作指南。
软件包步骤的输出会因 Linux 发行版的不同而略有不同。如果你使用的是 Debian 衍生发行版,你会看到:
(beeware-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] Building .deb package...
Write Debian package control file... done
dpkg-deb: building package 'helloworld' in 'helloworld-0.0.1.deb'.
Building Debian package... done
[helloworld] Packaged dist/helloworld_0.0.1-1~ubuntu-jammy_amd64.deb
dist "文件夹将包含生成的".deb "文件。
如果你使用的是基于 RHEL 的发行版,你就会看到:
(beeware-venv) $ briefcase package
[helloworld] Finalizing application configuration...
Targeting fedora:40 (Vendor base rhel)
Determining glibc version... done
Targeting glibc 2.39
Targeting Python3.12
[helloworld] Building .rpm package...
Generating rpmbuild layout... done
Write RPM spec file... done
Building source archive... done
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Kav9H7
+ umask 022
...
+ exit 0
Building RPM package... done
[helloworld] Packaged dist/helloworld-0.0.1-1.fc40.x86_64.rpm
dist "文件夹将包含生成的".rpm "文件。
如果你使用的是基于 Arch 的发行版,你就会看到:
(beeware-venv) $ briefcase package
[helloworld] Finalizing application configuration...
Targeting arch:20240101 (Vendor base arch)
Determining glibc version... done
Targeting glibc 2.38
Targeting Python3.12
[helloworld] Building .pkg.tar.zst package...
...
Building Arch package... done
[helloworld] Packaged dist/helloworld-0.0.1-1-x86_64.pkg.tar.zst
dist "文件夹将包含生成的".pkg.tar.zst "文件。
目前不支持其他 Linux 发行版的打包。
如果你想为你正在使用的 Linux 发行版之外的其他发行版构建软件包,Briefcase 也能提供帮助,但你需要安装 Docker。
Docker Engine <https://docs.docker.com/engine/install>`__ 的官方安装程序适用于一系列 Unix 发行版。请按照您所在平台的说明进行操作;不过,请确保不要在 "无根 "模式下安装 Docker。
安装好 Docker 后,你就可以启动 Linux 容器了,例如:
$ docker run --rm -it ubuntu:22.04
将显示 Ubuntu 22.04 Docker 容器中的 Unix 提示(类似于 root@84444e31cff9:/#
)。键入 Ctrl-D 退出 Docker 并返回本地 shell。
一旦安装了 Docker,只要将 Docker 镜像作为参数传递,就可以使用 Briefcase 为 Briefcase 支持的任何 Linux 发行版构建软件包。例如,要为 Ubuntu 22.04 (Jammy) 构建一个 DEB 包,无论你使用的是哪种操作系统,你都可以运行:
$ briefcase package --target ubuntu:jammy
这将下载所选操作系统的 Docker 镜像,创建一个能够运行 Briefcase 构建的容器,并在镜像中构建应用程序软件包。完成后,dist` 文件夹将包含目标 Linux 发行版的软件包。
(beeware-venv) C:\...>briefcase package
*************************************************************************
** WARNING: No signing identity provided **
*************************************************************************
Briefcase will not sign the app. To provide a signing identity,
use the `--identity` option; or, to explicitly disable signing,
use `--adhoc-sign`.
*************************************************************************
[helloworld] Building MSI...
Compiling application manifest...
Compiling... done
Compiling application installer...
helloworld.wxs
helloworld-manifest.wxs
Compiling... done
Linking application installer...
Linking... done
[helloworld] Packaged dist\Hello_World-0.0.1.msi
在本例中,我们使用了"--adhoc-sign "选项--也就是说,我们使用*ad hoc* 凭据(仅在你的机器上有效的临时凭据)来签署我们的应用程序。我们这样做是为了让教程简单明了。设置代码签名身份有点麻烦,而且只有当你打算将应用程序发布给他人时才*需要。如果我们要发布一个真正的应用程序供他人使用,我们就需要指定真实的凭据。
当您准备发布真正的应用程序时,请查看关于 "设置 macOS 代码签名身份 <https://briefcase.readthedocs.io/en/latest/how-to/code-signing/macOS.html>`__" 的公文包操作指南。
此步骤完成后,"dist "文件夹中将包含一个名为 "Hello_World-0.0.1.msi "的文件。如果双击运行该安装程序,就会进入熟悉的 Windows 安装过程。安装完成后,开始菜单中将出现 "Hello World "条目。
下一步¶
现在,我们已将应用程序打包发布到桌面平台上。但是,当我们需要更新应用程序中的代码时该怎么办?如何将这些更新添加到打包的应用程序中?请访问 Tutorial 4 了解详情...