diff --git a/src/briefcase/platforms/linux/system.py b/src/briefcase/platforms/linux/system.py index 2adb63cc6..bc5f8ce21 100644 --- a/src/briefcase/platforms/linux/system.py +++ b/src/briefcase/platforms/linux/system.py @@ -54,16 +54,6 @@ def parse_options(self, extra): return options - @property - def linux_arch(self): - # Linux uses different architecture identifiers for some platforms - return { - "x86_64": "amd64", - "aarch64": "arm64", - "armv6l": "armhf", - "i686": "i386", - }.get(self.tools.host_arch, self.tools.host_arch) - def build_path(self, app): # Override the default build path to use the vendor name, # rather than "linux" @@ -86,31 +76,6 @@ def rpm_tag(self, app): else: return f"el{app.target_codename}" - def distribution_filename(self, app): - if app.packaging_format == "deb": - return ( - f"{app.app_name}_{app.version}-{getattr(app, 'revision', 1)}" - f"~{app.target_vendor}-{app.target_codename}_{self.linux_arch}.deb" - ) - elif app.packaging_format == "rpm": - return ( - f"{app.app_name}-{app.version}-{getattr(app, 'revision', 1)}" - f".{self.rpm_tag(app)}.{self.tools.host_arch}.rpm" - ) - elif app.packaging_format == "pkg": - return ( - f"{app.app_name}-{app.version}-{getattr(app, 'revision', 1)}" - f"-{self.tools.host_arch}.pkg.tar.zst" - ) - else: - raise BriefcaseCommandError( - "Briefcase doesn't currently know how to build system packages in " - f"{app.packaging_format.upper()} format." - ) - - def distribution_path(self, app): - return self.dist_path / self.distribution_filename(app) - def target_glibc_version(self, app): target_glibc = self.tools.os.confstr("CS_GNU_LIBC_VERSION").split()[1] return target_glibc @@ -236,7 +201,7 @@ def use_docker(self): # what "use docker" means in terms of target_image. return bool(self.target_image) - def app_python_version_tag(self, app): + def app_python_version_tag(self, app: AppConfig): if self.use_docker: # If we're running in Docker, we can't know the Python3 version # before rolling out the template; so we fall back to "3". Later, @@ -248,6 +213,62 @@ def app_python_version_tag(self, app): python_version_tag = super().app_python_version_tag(app) return python_version_tag + def deb_abi(self, app: AppConfig): + try: + return self._deb_abi + except AttributeError: + self._deb_abi = ( + self.tools[app] + .app_context.check_output(["dpkg", "--print-architecture"]) + .strip() + ) + return self._deb_abi + + def rpm_abi(self, app: AppConfig): + try: + return self._rpm_abi + except AttributeError: + self._rpm_abi = ( + self.tools[app] + .app_context.check_output(["rpm", "--eval", "%_target_cpu"]) + .strip() + ) + return self._rpm_abi + + def pkg_abi(self, app: AppConfig): + try: + return self._pkg_abi + except AttributeError: + self._pkg_abi = ( + self.tools[app].app_context.check_output(["uname", "-m"]).strip() + ) + return self._pkg_abi + + def distribution_filename(self, app: AppConfig): + if app.packaging_format == "deb": + return ( + f"{app.app_name}_{app.version}-{getattr(app, 'revision', 1)}" + f"~{app.target_vendor}-{app.target_codename}_{self.deb_abi(app)}.deb" + ) + elif app.packaging_format == "rpm": + return ( + f"{app.app_name}-{app.version}-{getattr(app, 'revision', 1)}" + f".{self.rpm_tag(app)}.{self.rpm_abi(app)}.rpm" + ) + elif app.packaging_format == "pkg": + return ( + f"{app.app_name}-{app.version}-{getattr(app, 'revision', 1)}" + f"-{self.pkg_abi(app)}.pkg.tar.zst" + ) + else: + raise BriefcaseCommandError( + "Briefcase doesn't currently know how to build system packages in " + f"{app.packaging_format.upper()} format." + ) + + def distribution_path(self, app: AppConfig): + return self.dist_path / self.distribution_filename(app) + def target_glibc_version(self, app): """Determine the glibc version. @@ -290,7 +311,7 @@ def target_glibc_version(self, app): return target_glibc - def platform_freedesktop_info(self, app): + def platform_freedesktop_info(self, app: AppConfig): if self.use_docker: # Preserve the target image on the command line as the app's target app.target_image = self.target_image @@ -309,7 +330,7 @@ def platform_freedesktop_info(self, app): return freedesktop_info - def docker_image_tag(self, app): + def docker_image_tag(self, app: AppConfig): """The Docker image tag for an app.""" return f"briefcase/{app.bundle_identifier.lower()}:{app.target_vendor}-{app.target_codename}" @@ -340,7 +361,7 @@ def clone_options(self, command): super().clone_options(command) self.target_image = command.target_image - def verify_python(self, app): + def verify_python(self, app: AppConfig): """Verify that the version of Python being used to build the app in Docker is compatible with the version being used to run Briefcase. @@ -488,7 +509,7 @@ def verify_system_packages(self, app: AppConfig): ) return - # Run a check for each packages listed in the app's system_requires, + # Run a check for each package listed in the app's system_requires, # plus the baseline system packages that are required. missing = [] for package in base_system_packages + getattr(app, "system_requires", []): @@ -879,15 +900,15 @@ def _package_deb(self, app: AppConfig, **kwargs): f.write( "\n".join( [ - f"Package: { app.app_name }", - f"Version: { app.version }", - f"Architecture: { self.linux_arch }", - f"Maintainer: { app.author } <{ app.author_email }>", - f"Homepage: { app.url }", - f"Description: { app.description }", - f" { debian_multiline_description(app.long_description) }", - f"Depends: { system_runtime_requires }", - f"Section: { getattr(app, 'system_section', 'utils') }", + f"Package: {app.app_name}", + f"Version: {app.version}", + f"Architecture: {self.deb_abi(app)}", + f"Maintainer: {app.author } <{app.author_email}>", + f"Homepage: {app.url}", + f"Description: {app.description}", + f" {debian_multiline_description(app.long_description)}", + f"Depends: {system_runtime_requires}", + f"Section: {getattr(app, 'system_section', 'utils')}", "Priority: optional\n", ] ) @@ -993,7 +1014,7 @@ def _package_rpm(self, app: AppConfig, **kwargs): # pragma: no-cover-if-is-wind ] + [ "", - f"ExclusiveArch: {self.tools.host_arch}", + f"ExclusiveArch: {self.rpm_abi(app)}", "", "%description", app.long_description, @@ -1071,7 +1092,7 @@ def _package_rpm(self, app: AppConfig, **kwargs): # pragma: no-cover-if-is-wind self.tools.shutil.move( rpmbuild_path / "RPMS" - / self.tools.host_arch + / self.rpm_abi(app) / self.distribution_filename(app), self.distribution_path(app), ) @@ -1139,7 +1160,7 @@ def _package_pkg(self, app: AppConfig, **kwargs): # pragma: no-cover-if-is-wind f"pkgver={app.version}", f"pkgrel={getattr(app, 'revision', 1)}", f'pkgdesc="{app.description}"', - f"arch=('{self.tools.host_arch}')", + f"arch=('{self.pkg_abi(app)}')", f'url="{app.url}"', f"license=('{app.license}')", f"depends=({system_runtime_requires})",