Skip to content

Commit 07592b9

Browse files
marc-hblgirdwood
authored andcommitted
xtensa-build-zephyr.py: install and checksum .elf, .lst and other files
Sample new output below. The sha256 is computed on the _uncompressed_ files and _not_ affected by gzip metadata. ``` build-sof-staging ├── sof │ ├── community │ │ ├── sof-imx8.ri sha256=50c5423d2355ef3ed91... │ │ └── sof-tgl.ri sha256=6b1d26c12a63de5dfc8... │ ├── sof-imx8.ldc sha256=520d365d188d5ef4e907d3dd8c9... │ └── sof-tgl.ldc sha256=cdce6ad340d4dc047e71e738eb0... ├── sof-info │ ├── imx8 │ │ ├── config.gz │ │ ├── zephyr.elf.gz │ │ ├── zephyr.lst.gz sha256=8c83c3fc92df0a871dd... │ │ ├── zephyr.map.gz │ │ └── zephyr.strip.gz sha256=d3ce3d3450c67bb3580... │ └── tgl │ ├── boot.mod.gz sha256=d9c9e82e75fa6d061bf... │ ├── config.gz │ ├── main.mod.gz │ ├── stripped-main.mod.gz sha256=c367dccca6d... │ ├── zephyr.elf.gz │ ├── zephyr.lst.gz sha256=5474bc5e58a5d000109... │ ├── zephyr.map.gz │ └── zephyr.strip.gz sha256=6285f41c0682b33b7e0... └── tools ├── cavstool.py ├── cavstool_client.py ├── cavstwist.sh ├── mtrace-reader.py ├── remote-fw-service.py └── sof-logger ``` Signed-off-by: Marc Herbert <[email protected]> (cherry picked from commit 9fa1a99)
1 parent 584eb1e commit 07592b9

File tree

1 file changed

+94
-1
lines changed

1 file changed

+94
-1
lines changed

scripts/xtensa-build-zephyr.py

+94-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
import shutil
3434
import os
3535
import warnings
36+
import fnmatch
37+
import hashlib
38+
import gzip
39+
from dataclasses import dataclass
40+
3641
# anytree module is defined in Zephyr build requirements
3742
from anytree import AnyNode, RenderTree
3843
from packaging import version
@@ -293,6 +298,7 @@ def execute_command(*run_args, **run_kwargs):
293298

294299
return subprocess.run(*run_args, **run_kwargs)
295300

301+
296302
def show_installed_files():
297303
"""[summary] Scans output directory building binary tree from files and folders
298304
then presents them in similar way to linux tree command."""
@@ -309,8 +315,37 @@ def show_installed_files():
309315
matches = [node for node in nodes if node.long_name == str(entry.parent)]
310316
assert len(matches) == 1, f'"{entry}" does not have exactly one parent'
311317
nodes.append(AnyNode(name=entry.name, long_name=str(entry), parent=matches[0]))
318+
312319
for pre, _, node in RenderTree(graph_root):
313-
print(f"{pre}{node.name}")
320+
fpath = STAGING_DIR / node.long_name
321+
stem = node.name[:-3] if node.name.endswith(".gz") else node.name
322+
323+
shasum_trailer = ""
324+
if checksum_wanted(stem) and fpath.is_file() and not fpath.is_symlink():
325+
shasum_trailer = "\tsha256=" + checksum(fpath)
326+
327+
print(f"{pre}{node.name} {shasum_trailer}")
328+
329+
330+
# TODO: among other things in this file it should be less SOF-specific;
331+
# try to move as much as possible to generic Zephyr code. See
332+
# discussions in https://github.com/zephyrproject-rtos/zephyr/pull/51954
333+
def checksum_wanted(stem):
334+
for pattern in CHECKSUM_WANTED:
335+
if fnmatch.fnmatch(stem, pattern):
336+
return True
337+
return False
338+
339+
340+
def checksum(fpath):
341+
if fpath.suffix == ".gz":
342+
inputf = gzip.GzipFile(fpath, "rb")
343+
else:
344+
inputf = open(fpath, "rb")
345+
chksum = hashlib.sha256(inputf.read()).hexdigest()
346+
inputf.close()
347+
return chksum
348+
314349

315350
def check_west_installation():
316351
west_path = shutil.which("west")
@@ -681,6 +716,64 @@ def install_platform(platform, sof_platform_output_dir):
681716
shutil.copy2(fw_file_to_copy, install_key_dir)
682717

683718

719+
# sof-info/ directory
720+
721+
@dataclass
722+
class InstFile:
723+
'How to install one file'
724+
name: str
725+
renameTo: str = None
726+
# TODO: upgrade this to 3 states: optional/warning/error
727+
optional: bool = False
728+
gzip: bool = True
729+
730+
installed_files = [
731+
# Fail if one of these is missing
732+
InstFile(".config", "config"),
733+
InstFile(BIN_NAME + ".elf"),
734+
InstFile(BIN_NAME + ".lst"),
735+
InstFile(BIN_NAME + ".map"),
736+
737+
# CONFIG_BUILD_OUTPUT_STRIPPED
738+
InstFile(BIN_NAME + '.strip', optional=True),
739+
740+
# Not every platform has intermediate rimage modules
741+
InstFile("main-stripped.mod", optional=True),
742+
InstFile("boot.mod", optional=True),
743+
InstFile("main.mod", optional=True),
744+
]
745+
746+
sof_info = pathlib.Path(STAGING_DIR) / "sof-info" / platform
747+
sof_info.mkdir(parents=True, exist_ok=True)
748+
for f in installed_files:
749+
if not pathlib.Path(abs_build_dir / f.name).is_file() and f.optional:
750+
continue
751+
dstname = f.renameTo or f.name
752+
shutil.copy2(abs_build_dir / f.name, sof_info / dstname)
753+
if f.gzip:
754+
gzip_compress(sof_info / dstname)
755+
756+
757+
# Zephyr's CONFIG_KERNEL_BIN_NAME default value
758+
BIN_NAME = 'zephyr'
759+
760+
CHECKSUM_WANTED = [
761+
'*.ri', # Some .ri files have a non-deterministic signature, others not
762+
'*.strip', '*stripped*', # stripped ELF files are reproducible
763+
'boot.mod', # no debug section -> no need to strip this ELF
764+
BIN_NAME + '.lst', # objdump --disassemble
765+
'*.ldc',
766+
]
767+
768+
def gzip_compress(fname, gzdst=None):
769+
gzdst = gzdst or pathlib.Path(f"{fname}.gz")
770+
with open(fname, 'rb') as inputf:
771+
# mtime=0 for recursive diff convenience
772+
with gzip.GzipFile(gzdst, 'wb', mtime=0) as gzf:
773+
shutil.copyfileobj(inputf, gzf)
774+
os.remove(fname)
775+
776+
684777
# As of October 2022, sof_ri_info.py expects .ri files to include a CSE manifest / signature.
685778
# Don't run sof_ri_info and ignore silently .ri files that don't have one.
686779
RI_INFO_UNSUPPORTED = []

0 commit comments

Comments
 (0)