From 24a0dd9a2164ff1f82d20342c75a8446db6c8a08 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 2 Dec 2024 17:22:31 +0100 Subject: [PATCH] llext: add support for library building Build libraries of modules, as specified in their cmake files. Signed-off-by: Guennadi Liakhovetski --- scripts/xtensa-build-zephyr.py | 102 ++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 35 deletions(-) diff --git a/scripts/xtensa-build-zephyr.py b/scripts/xtensa-build-zephyr.py index 465c87d6e896..62602e8f02d6 100755 --- a/scripts/xtensa-build-zephyr.py +++ b/scripts/xtensa-build-zephyr.py @@ -933,6 +933,11 @@ def install_lib(sof_lib_dir, abs_build_dir, platform_wconfig): global signing_key + libs = dict() + lib_uuids = dict() + rimage_cmd = shlex.split(platform_wconfig.get('rimage.path'))[0] + _ws_args = platform_wconfig.get("rimage.extra-args") + with os.scandir(str(abs_build_dir)) as iter: if args.key_type_subdir != "none": sof_lib_dir = sof_lib_dir / args.key_type_subdir @@ -955,45 +960,72 @@ def install_lib(sof_lib_dir, abs_build_dir, platform_wconfig): # eq_iir_llext/eq_iir.llext llext_base = entry.name[:-6] llext_file = llext_base + '.llext' - - dst = sof_lib_dir / llext_file - - rimage_cfg = entry_path / 'rimage_config.toml' - llext_input = entry_path / (llext_base + '.llext') - llext_output = entry_path / (llext_file + '.ri') - - # See why the shlex() parsing step is required at - # https://docs.zephyrproject.org/latest/develop/west/sign.html#rimage - # and in Zephyr commit 030b740bd1ec - rimage_cmd = shlex.split(platform_wconfig.get('rimage.path'))[0] - sign_cmd = [rimage_cmd, "-o", str(llext_output), - "-e", "-c", str(rimage_cfg), - "-k", str(signing_key), "-l", "-r"] - _ws_args = platform_wconfig.get("rimage.extra-args") - if _ws_args is not None: - sign_cmd.extend(shlex.split(_ws_args)) - sign_cmd.append(str(llext_input)) - execute_command(sign_cmd, cwd=west_top) - - # An intuitive way to make this multiline would be - # with (open(dst, 'wb') as fdst, open(llext_output, 'rb') as fllext, - # open(llext_output.with_suffix('.llext.xman'), 'rb') as fman): - # but a Python version, used on Windows errored out on this. - # Thus we're left with a choice between a 150-character - # long line and an illogical split like this - with open(dst, 'wb') as fdst, open(llext_output, 'rb') as fllext, open( - llext_output.with_suffix('.ri.xman'), 'rb') as fman: - # Concatenate the manifest and the llext - shutil.copyfileobj(fman, fdst) - shutil.copyfileobj(fllext, fdst) + lib_name = '' + + lib_fname = entry_path / 'lib_name.txt' + if os.path.exists(lib_fname): + with open(lib_fname, 'r') as libs_f: + lib_name = libs_f.read() + if lib_name not in libs.keys(): + libs[lib_name] = [] + libs[lib_name].append(str(entry_path / llext_file)) + else: + dst = sof_lib_dir / llext_file + + rimage_cfg = entry_path / 'rimage_config.toml' + llext_input = entry_path / (llext_base + '.llext') + llext_output = entry_path / (llext_file + '.ri') + + # See why the shlex() parsing step is required at + # https://docs.zephyrproject.org/latest/develop/west/sign.html#rimage + # and in Zephyr commit 030b740bd1ec + sign_cmd = [rimage_cmd, "-o", str(llext_output), + "-e", "-c", str(rimage_cfg), + "-k", str(signing_key), "-l", "-r"] + if _ws_args is not None: + sign_cmd.extend(shlex.split(_ws_args)) + sign_cmd.append(str(llext_input)) + execute_command(sign_cmd, cwd=west_top) + + # An intuitive way to make this multiline would be + # with (open(dst, 'wb') as fdst, open(llext_output, 'rb') as fllext, + # open(llext_output.with_suffix('.llext.xman'), 'rb') as fman): + # but a Python version, used on Windows errored out on this. + # Thus we're left with a choice between a 150-character + # long line and an illogical split like this + with open(dst, 'wb') as fdst, open(llext_output, 'rb') as fllext, open( + llext_output.with_suffix('.ri.xman'), 'rb') as fman: + # Concatenate the manifest and the llext + shutil.copyfileobj(fman, fdst) + shutil.copyfileobj(fllext, fdst) # Create symbolic links for all UUIDs with open(uuids, 'r') as uuids_f: for uuid in uuids_f: - linkname = uuid.strip() + '.bin' - symlink_or_copy(sof_lib_dir, llext_file, - sof_lib_dir, linkname) - + if os.path.exists(lib_fname): + if lib_name not in lib_uuids.keys(): + lib_uuids[lib_name] = [] + lib_uuids[lib_name].append(uuid.strip()) + else: + linkname = uuid.strip() + '.bin' + symlink_or_copy(sof_lib_dir, llext_file, + sof_lib_dir, linkname) + + for key in libs.keys(): + lib_path = abs_build_dir / ('lib' + key + '.ri') + sign_cmd = [rimage_cmd, "-o", str(lib_path), "-e", + "-c", str(abs_build_dir / 'misc' / 'generated' / 'rimage_config_full.toml'), + "-k", str(signing_key), "-l", "-r"] + if _ws_args is not None: + sign_cmd.extend(shlex.split(_ws_args)) + sign_cmd.extend(libs[key]) + execute_command(sign_cmd, cwd=west_top) + dst = abs_build_dir / ('lib' + key + '.bin') + with open(dst, 'wb') as fdst, open(lib_path, 'rb') as fllext, open( + lib_path.with_suffix('.ri.xman'), 'rb') as fman: + # Concatenate the manifest and the llext + shutil.copyfileobj(fman, fdst) + shutil.copyfileobj(fllext, fdst) def install_platform(platform, sof_output_dir, platf_build_environ, platform_wconfig):