Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

building modules: using python scripts #8828

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ build*/
cscope.*
ncscope.*

# headers pack
header_pack.zip
23 changes: 23 additions & 0 deletions lmdk/include/headers_manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[
["src", "include", "ipc4", "header.h"],
["src", "include", "module","audio","audio_stream.h"],
["src","include","module","audio","format.h"],
["src","include","module","audio","sink_api.h"],
["src","include","module","audio","source_api.h"],
["src","include","module","iadk","adsp_error_code.h"],
["src","include","module","ipc","stream.h"],
["src","include","module","ipc4","base-config.h"],
["src","include","module","module","api_ver.h"],
["src","include","module","module","base.h"],
["src","include","module","module","interface.h"],
["src","include","sof","audio","ipc-config.h"],
["src","include","sof","audio","module_adapter","library","native_system_service.h"],
["src","include","sof","audio","module_adapter","module","generic.h"],
["src","include","sof","audio","module_adapter","iadk","adsp_stddef.h"],
["posix","include","sof","compiler_attributes.h"],
["posix","include","sof","list.h"],
["posix","include","rtos","string.h"],
["src","include","user","trace.h"],
["src","module","audio","sink_api.c"],
["src","module","audio","source_api.c"]
]
15 changes: 15 additions & 0 deletions lmdk/modules/dummy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,18 @@ target_sources(dummy PRIVATE dummy.c)
set_target_properties(dummy PROPERTIES
HPSRAM_ADDR "0xa06a1000"
)

target_compile_definitions(dummy PRIVATE CONFIG_XTENSA=1
CONFIG_IPC_MAJOR_4=1
CONFIG_LIBRARY=1
XCHAL_HAVE_HIFI3=1
SOF_MODULE_API_PRIVATE=1)

set(LMDK_DIR_INCLUDE ../../../lmdk/include)

target_include_directories(dummy PRIVATE "${LMDK_DIR_INCLUDE}"
"${LMDK_DIR_INCLUDE}/src/include"
"${LMDK_DIR_INCLUDE}/src/include/sof/audio/module_adapter/iadk"
"${LMDK_DIR_INCLUDE}/posix/include"
"${LMDK_DIR_INCLUDE}/posix/include/sof"
)
56 changes: 56 additions & 0 deletions lmdk/scripts/header_pack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause


import json
import pathlib
import shutil


"""Headers for needs of lmdk are defined in
lmdk/include/headers_list.json"""


_SOF_TOP = pathlib.Path(__file__).parents[2].resolve()
LMDK_HEADERS = _SOF_TOP / "lmdk" / "include" / "headers_manifest.json"


def str_path_from_json(record):
"""parsing json record to string"""
src = ''
for i in record:
src += i
src += "/"
return src[:-1]


def create_separate_headers():
f = open(LMDK_HEADERS)
data = json.load(f)

for i in data:
src = str_path_from_json(i)
p = pathlib.Path(_SOF_TOP, "lmdk", "include", "sof", src)
p.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(_SOF_TOP / src, _SOF_TOP / "lmdk" /"include" / "sof" / src)
f.close()

""" -> to do
def validate_separate_headers():
return 0"""


def create_headers_pack():
"""Creates pack of lmdk headers"""
create_separate_headers()
shutil.make_archive(_SOF_TOP / "lmdk" /"include" / "header_pack", "zip", _SOF_TOP / "lmdk" /"include" / "sof")
shutil.rmtree(_SOF_TOP / "lmdk" /"include" / "sof", ignore_errors=True)
return 0


def main():
create_headers_pack()


if __name__ == "__main__":
main()
76 changes: 76 additions & 0 deletions lmdk/scripts/libraries_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause


import pathlib
import dataclasses
from tools.utils import rmtree_if_exists, execute_command
import argparse
import platform as py_platform
import sys
import os
import warnings

SOF_TOP = pathlib.Path(__file__).parents[3].resolve()
MIN_PYTHON_VERSION = 3, 8
assert sys.version_info >= MIN_PYTHON_VERSION, \
f"Python {MIN_PYTHON_VERSION} or above is required."

"""Constant value resolves SOF_TOP directory as: "this script directory/.." """
SOF_TOP = pathlib.Path(__file__).parents[1].resolve()
LMDK_BUILD_DIR = SOF_TOP / "../.." / "sof" / "lmdk"
RIMAGE_BUILD_DIR = SOF_TOP / "../.." /"build-rimage"

if py_platform.system() == "Windows":
xtensa_tools_version_postfix = "-win32"
elif py_platform.system() == "Linux":
xtensa_tools_version_postfix = "-linux"
else:
xtensa_tools_version_postfix = "-unsupportedOS"
warnings.warn(f"Your operating system: {py_platform.system()} is not supported")


def build_libraries(LMDK_BUILD_DIR, RIMAGE_BUILD_DIR, args):
library_dir = LMDK_BUILD_DIR / "libraries"
"""Cmake build"""
for lib in args.libraries:
library_cmake = library_dir / lib / "CMakeLists.txt"
if library_cmake.is_file():
print(f"\nBuilding loadable module: " + lib)
lib_path = pathlib.Path(library_dir, lib, "build")
print(f"\nRemoving existing artifacts")
rmtree_if_exists(lib_path)
lib_path.mkdir(parents=True, exist_ok=True)
rimage_bin = RIMAGE_BUILD_DIR / "rimage.exe"
if not rimage_bin.is_file():
rimage_bin = RIMAGE_BUILD_DIR / "rimage"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that it works for programs out of PATH.

print(shutil.which("C:\\Users\\paweldox\\zephyrproject\\build-rimage\\rimage"))
None

Right, so using the path argument works:

print(shutil.which("rimage", path="C:/Users/paweldox/zephyrproject/build-rimage/"))

=> 'C:/Users/paweldox/zephyrproject/build-rimage/rimage.EXE'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I've checked it on linux and windows to be sure.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you missed my point. I tested the path argument on Windows. You don't need is_file().

if args.key:
key = "-DSIGNING_KEY=" + args.key.__str__()
else:
key = "-DSIGNING_KEY=" + PlatformConfig.RIMAGE_KEY.__str__()
execute_command(["cmake", "-B", "build", "-G", "Ninja",
"-DRIMAGE_COMMAND="+str(rimage_bin), key],
cwd=library_dir/lib)
execute_command(["cmake", "--build", "build", "-v"], cwd=library_dir/lib)


def parse_args():
parser = argparse.ArgumentParser(description='Building loadable modules using python scripts')
parser.add_argument("-k", "--key", type=pathlib.Path, required=False,
help="Path to a non-default rimage signing key.")

parser.add_argument("-l", "--libraries", nargs="*", default=[],
help=""" Function for CMake building modules. We can build more then one module
just by adding more module names.""")
return parser.parse_args()


def main():
args = parse_args()

if args.libraries:
build_libraries(LMDK_BUILD_DIR, RIMAGE_BUILD_DIR, args)


if __name__ == "__main__":
main()
Empty file.
31 changes: 31 additions & 0 deletions lmdk/scripts/tools/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause


import shlex
import subprocess
import shutil
import os


def rmtree_if_exists(directory):
"This is different from ignore_errors=False because it deletes everything or nothing"
if os.path.exists(directory):
shutil.rmtree(directory)


def execute_command(*run_args, **run_kwargs):
"""[summary] Provides wrapper for subprocess.run that prints
command executed when 'more verbose' verbosity level is set."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You stripped down this function to the point where... it does not print the command executed, which was its entire purpose!?

But there are some bits left that don't do anything...

I don't know why you started by blindly copying huge parts of xtensa-build-zephyr.py instead of just the bits you need one by one. After way too many force-pushes there's extremely little code copied from xtensa-build-zephyr.py now. This has been been really difficult to make sense of and time consuming to review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look at comment to PR. I've started that script as a part of xtensa-build-zephyr.py . After your's suggestions I've separated parts I needed to external pythons scripts without changes from original spaghetti code.

It all started as simple function in xtensa-build-zephyr.py. I just followed suggestions from you and it looks as it looks.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Process digressions aside: what does this execute_command() function do now? It does not do what what the obsolete pydoc says it does. If it does nothing any more, why is it kept?

command_args = run_args[0]

# If you really need the shell in some non-portable section then
# invoke subprocess.run() directly.
if run_kwargs.get('shell') or not isinstance(command_args, list):
raise RuntimeError("Do not rely on non-portable shell parsing")

if not 'check' in run_kwargs:
run_kwargs['check'] = True
#pylint:disable=subprocess-run-check

return subprocess.run(*run_args, **run_kwargs)
5 changes: 3 additions & 2 deletions src/include/module/module/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "interface.h"
#include "../ipc4/base-config.h"
#include <sof/list.h>

#define module_get_private_data(mod) ((mod)->priv.private)
#define module_set_private_data(mod, data) ((mod)->priv.private = data)
Expand Down Expand Up @@ -54,7 +55,7 @@ struct module_data {
* Below #ifdef is a temporary solution used until work on separating a common interface
* for loadable modules is completed.
*/
#ifdef SOF_MODULE_API_PRIVATE
#ifdef SOF_MONOLITHIC_BUILD
enum module_state state;
size_t new_cfg_size; /**< size of new module config data */
void *runtime_params;
Expand Down Expand Up @@ -84,7 +85,7 @@ struct processing_module {
* Below #ifdef is a temporary solution used until work on separating a common interface
* for loadable modules is completed.
*/
#ifdef SOF_MODULE_API_PRIVATE
#ifdef SOF_MONOLITHIC_BUILD
struct sof_ipc_stream_params *stream_params;
struct list_item sink_buffer_list; /* list of sink buffers to save produced output */

Expand Down
3 changes: 2 additions & 1 deletion src/include/sof/audio/module_adapter/iadk/adsp_stddef.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
#include <stddef.h>
#include <stdint.h>
#include <user/trace.h>
#ifndef SOF_MONOLITHIC_BUILD
#include <rtos/string.h>

#endif /* SOF_MONOLITHIC_BUILD */
#ifdef __ZEPHYR__
#include <zephyr/sys/util.h>
#endif /* __ZEPHYR__ */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
#define NATIVE_SYSTEM_SERVICE_H

#include <stdint.h>

#ifndef SOF_MONOLITHIC_BUILD
#include "logger.h"
#endif
#include "adsp_stddef.h"
#include <module/iadk/adsp_error_code.h>

Expand Down
13 changes: 9 additions & 4 deletions src/include/sof/audio/module_adapter/module/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

#ifndef __SOF_AUDIO_MODULE_GENERIC__
#define __SOF_AUDIO_MODULE_GENERIC__

#include <stdint.h>
#include <sof/list.h>
#ifndef SOF_MONOLITHIC_BUILD
#include <sof/audio/component.h>
#include <sof/ut.h>
#include <sof/lib/memory.h>
Expand All @@ -30,8 +32,9 @@
#define IS_PROCESSING_MODE_SINK_SOURCE(mod) ((mod)->proc_type == MODULE_PROCESS_TYPE_SOURCE_SINK)

#define MAX_BLOB_SIZE 8192
#endif /* SOF_MONOLITHIC_BUILD */
#define MODULE_MAX_SOURCES 8

#ifndef SOF_MONOLITHIC_BUILD
#define API_CALL(cd, cmd, sub_cmd, value, ret) \
do { \
ret = (cd)->api((cd)->self, \
Expand Down Expand Up @@ -87,7 +90,7 @@ UT_STATIC void sys_comp_module_##adapter##_init(void) \
} \
\
DECLARE_MODULE(sys_comp_module_##adapter##_init)

#endif /* SOF_MONOLITHIC_BUILD */
/**
* \enum module_state
* \brief Module-specific states
Expand Down Expand Up @@ -141,12 +144,13 @@ struct module_processing_data {
void *out_buff; /**< A pointer to module output buffer. */
};

#ifndef SOF_MONOLITHIC_BUILD
/*
* Definition used to extend structure definitions to include fields for exclusive use by SOF.
* This is a temporary solution used until work on separating a common interface for loadable
* modules is completed.
*/
#define SOF_MODULE_API_PRIVATE
#define SOF_MONOLITHIC_BUILD
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to put this under #ifndef SOF_MONOLITHIC_BUILD and it makes little sense that way - if it isn't defined, then we define it... From this commit I don't see any other places where this can be defined, so this doesn't seem to protect against redefinition.


#include <module/module/base.h>

Expand Down Expand Up @@ -320,4 +324,5 @@ void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_str
int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev,
int cmd);
int module_adapter_sink_src_prepare(struct comp_dev *dev);
#endif /* SOF_MONOLITHIC_BUILD */
#endif /* __SOF_AUDIO_MODULE_GENERIC__ */