fune/python/mozbuild/mozpack/executables.py
Ricky Stewart 02a7b4ebdf Bug 1654103: Standardize on Black for Python code in mozilla-central.
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.

To produce this patch I did all of the following:

1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.

2. Run ./mach lint --linter black --fix

3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.

4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat.

5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).

# ignore-this-changeset

Differential Revision: https://phabricator.services.mozilla.com/D94045
2020-10-26 18:34:53 +00:00

182 lines
5.7 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
import os
import struct
import subprocess
from mozpack.errors import errors
MACHO_SIGNATURES = [
0xFEEDFACE, # mach-o 32-bits big endian
0xCEFAEDFE, # mach-o 32-bits little endian
0xFEEDFACF, # mach-o 64-bits big endian
0xCFFAEDFE, # mach-o 64-bits little endian
]
FAT_SIGNATURE = 0xCAFEBABE # mach-o FAT binary
ELF_SIGNATURE = 0x7F454C46 # Elf binary
UNKNOWN = 0
MACHO = 1
ELF = 2
def get_type(path):
"""
Check the signature of the give file and returns what kind of executable
matches.
"""
with open(path, "rb") as f:
signature = f.read(4)
if len(signature) < 4:
return UNKNOWN
signature = struct.unpack(">L", signature)[0]
if signature == ELF_SIGNATURE:
return ELF
if signature in MACHO_SIGNATURES:
return MACHO
if signature != FAT_SIGNATURE:
return UNKNOWN
# We have to sanity check the second four bytes, because Java class
# files use the same magic number as Mach-O fat binaries.
# This logic is adapted from file(1), which says that Mach-O uses
# these bytes to count the number of architectures within, while
# Java uses it for a version number. Conveniently, there are only
# 18 labelled Mach-O architectures, and Java's first released
# class format used the version 43.0.
num = f.read(4)
if len(num) < 4:
return UNKNOWN
num = struct.unpack(">L", num)[0]
if num < 20:
return MACHO
return UNKNOWN
def is_executable(path):
"""
Return whether a given file path points to an executable or a library,
where an executable or library is identified by:
- the file extension on OS/2 and WINNT
- the file signature on OS/X and ELF systems (GNU/Linux, Android, BSD,
Solaris)
As this function is intended for use to choose between the ExecutableFile
and File classes in FileFinder, and choosing ExecutableFile only matters
on OS/2, OS/X, ELF and WINNT (in GCC build) systems, we don't bother
detecting other kind of executables.
"""
from buildconfig import substs
if not os.path.exists(path):
return False
if substs["OS_ARCH"] == "WINNT":
return path.lower().endswith((substs["DLL_SUFFIX"], substs["BIN_SUFFIX"]))
return get_type(path) != UNKNOWN
def may_strip(path):
"""
Return whether strip() should be called
"""
from buildconfig import substs
# Bug 1658632: clang-11-based strip complains about d3dcompiler_47.dll.
# It's not clear why this happens, but as a quick fix just avoid stripping
# this DLL. It's not from our build anyway.
if "d3dcompiler" in path:
return False
return bool(substs.get("PKG_STRIP"))
def strip(path):
"""
Execute the STRIP command with STRIP_FLAGS on the given path.
"""
from buildconfig import substs
strip = substs["STRIP"]
flags = substs.get("STRIP_FLAGS", [])
cmd = [strip] + flags + [path]
if subprocess.call(cmd) != 0:
errors.fatal("Error executing " + " ".join(cmd))
def may_elfhack(path):
"""
Return whether elfhack() should be called
"""
# elfhack only supports libraries. We should check the ELF header for
# the right flag, but checking the file extension works too.
from buildconfig import substs
return (
"USE_ELF_HACK" in substs
and substs["USE_ELF_HACK"]
and path.endswith(substs["DLL_SUFFIX"])
and "COMPILE_ENVIRONMENT" in substs
and substs["COMPILE_ENVIRONMENT"]
)
def elfhack(path):
"""
Execute the elfhack command on the given path.
"""
from buildconfig import topobjdir
cmd = [os.path.join(topobjdir, "build/unix/elfhack/elfhack"), path]
if subprocess.call(cmd) != 0:
errors.fatal("Error executing " + " ".join(cmd))
def xz_compress(path):
"""
Execute xz to compress the given path.
"""
if open(path, "rb").read(5)[1:] == "7zXZ":
print("%s is already compressed" % path)
return
from buildconfig import substs
xz = substs.get("XZ")
cmd = [xz, "-zkf", path]
# For now, the mozglue XZStream ELF loader can only support xz files
# with a single stream that contains a single block. In xz, there is no
# explicit option to set the max block count. Instead, we force xz to use
# single thread mode, which results in a single block.
cmd.extend(["--threads=1"])
bcj = None
if substs.get("MOZ_THUMB2"):
bcj = "--armthumb"
elif substs.get("CPU_ARCH") == "arm":
bcj = "--arm"
elif substs.get("CPU_ARCH") == "x86":
bcj = "--x86"
if bcj:
cmd.extend([bcj])
# We need to explicitly specify the LZMA filter chain to ensure consistent builds
# across platforms. Note that the dict size must be less then 16MiB per the hardcoded
# value in mozglue/linker/XZStream.cpp. This is the default LZMA filter chain for for
# xz-utils version 5.0. See:
# https://github.com/xz-mirror/xz/blob/v5.0.0/src/liblzma/lzma/lzma_encoder_presets.c
# https://github.com/xz-mirror/xz/blob/v5.0.0/src/liblzma/api/lzma/container.h#L31
cmd.extend(["--lzma2=dict=8MiB,lc=3,lp=0,pb=2,mode=normal,nice=64,mf=bt4,depth=0"])
print("xz-compressing %s with %s" % (path, " ".join(cmd)))
if subprocess.call(cmd) != 0:
errors.fatal("Error executing " + " ".join(cmd))
return
os.rename(path + ".xz", path)