opencos-eda 0.2.48__tar.gz → 0.2.49__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {opencos_eda-0.2.48/opencos_eda.egg-info → opencos_eda-0.2.49}/PKG-INFO +1 -1
- opencos_eda-0.2.49/opencos/__init__.py +6 -0
- opencos_eda-0.2.49/opencos/_version.py +19 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/flist.py +8 -7
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/multi.py +13 -14
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/sweep.py +3 -2
- opencos_eda-0.2.49/opencos/deps/defaults.py +69 -0
- opencos_eda-0.2.49/opencos/deps/deps_commands.py +419 -0
- opencos_eda-0.2.49/opencos/deps/deps_file.py +326 -0
- opencos_eda-0.2.49/opencos/deps/deps_processor.py +670 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/deps_schema.py +7 -8
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda.py +84 -64
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_base.py +572 -316
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_config.py +80 -14
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_extract_targets.py +22 -14
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_tool_helper.py +33 -7
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/export_helper.py +166 -86
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/export_json_convert.py +31 -23
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/files.py +2 -1
- {opencos_eda-0.2.48/opencos → opencos_eda-0.2.49/opencos/hw}/oc_cli.py +9 -4
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/names.py +0 -4
- opencos_eda-0.2.49/opencos/peakrdl_cleanup.py +26 -0
- opencos_eda-0.2.49/opencos/seed.py +36 -0
- opencos_eda-0.2.49/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/helpers.py +3 -2
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_deps_helpers.py +35 -32
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_eda.py +36 -29
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_eda_elab.py +5 -3
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_eda_synth.py +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_oc_cli.py +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_tools.py +3 -2
- opencos_eda-0.2.49/opencos/tools/__init__.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/iverilog.py +2 -2
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/modelsim_ase.py +2 -2
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/riviera.py +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/slang.py +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/surelog.py +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/verilator.py +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/vivado.py +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/yosys.py +4 -3
- opencos_eda-0.2.49/opencos/util.py +737 -0
- opencos_eda-0.2.49/opencos/utils/__init__.py +0 -0
- opencos_eda-0.2.49/opencos/utils/markup_helpers.py +98 -0
- opencos_eda-0.2.49/opencos/utils/str_helpers.py +111 -0
- opencos_eda-0.2.49/opencos/utils/subprocess_helpers.py +108 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49/opencos_eda.egg-info}/PKG-INFO +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos_eda.egg-info/SOURCES.txt +12 -3
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos_eda.egg-info/entry_points.txt +1 -1
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/pyproject.toml +8 -3
- opencos_eda-0.2.48/opencos/__init__.py +0 -4
- opencos_eda-0.2.48/opencos/_version.py +0 -16
- opencos_eda-0.2.48/opencos/deps_helpers.py +0 -1346
- opencos_eda-0.2.48/opencos/peakrdl_cleanup.py +0 -20
- opencos_eda-0.2.48/opencos/seed.py +0 -28
- opencos_eda-0.2.48/opencos/util.py +0 -831
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/LICENSE +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/LICENSE.spdx +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/README.md +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/_waves_pkg.sv +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/__init__.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/build.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/elab.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/export.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/lec.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/open.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/proj.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/shell.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/sim.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/synth.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/targets.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/upload.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/commands/waves.py +0 -0
- {opencos_eda-0.2.48/opencos/tests → opencos_eda-0.2.49/opencos/deps}/__init__.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_config_defaults.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_config_max_verilator_waivers.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_config_reduced.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/eda_deps_bash_completion.bash +0 -0
- {opencos_eda-0.2.48/opencos/tools → opencos_eda-0.2.49/opencos/hw}/__init__.py +0 -0
- {opencos_eda-0.2.48/opencos → opencos_eda-0.2.49/opencos/hw}/pcie.py +0 -0
- /opencos_eda-0.2.48/opencos/tests/deps_files/no_deps_here/DEPS.yml → /opencos_eda-0.2.49/opencos/tests/__init__.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/custom_config.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_build.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tests/test_deps_schema.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/invio.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/invio_helpers.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/invio_yosys.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/questa.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/slang_yosys.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos/tools/tabbycad_yosys.py +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos_eda.egg-info/dependency_links.txt +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos_eda.egg-info/requires.txt +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/opencos_eda.egg-info/top_level.txt +0 -0
- {opencos_eda-0.2.48 → opencos_eda-0.2.49}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.49
|
|
4
4
|
Summary: A simple Python package for wrapping RTL simuliatons and synthesis
|
|
5
5
|
Author-email: Simon Sabato <simon@cognichip.ai>, Drew Ranck <drew@cognichip.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/cognichip/opencos
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
''' private helper package for `eda --version`'''
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
NAME = 'opencos-eda'
|
|
6
|
+
|
|
7
|
+
# Use standard library metadata module starting Python 3.8
|
|
8
|
+
if sys.version_info >= (3, 8):
|
|
9
|
+
|
|
10
|
+
from importlib import metadata
|
|
11
|
+
try:
|
|
12
|
+
VERSION = metadata.version(NAME)
|
|
13
|
+
except metadata.PackageNotFoundError:
|
|
14
|
+
# Handle case where the package is not installed (e.g., running from source checkout)
|
|
15
|
+
VERSION = "0.0.0"
|
|
16
|
+
|
|
17
|
+
else:
|
|
18
|
+
# This package only supports >= 3.8, so not doing the importlib_metadata method.
|
|
19
|
+
VERSION = "unknown" # Or raise an error, or handle differently
|
|
@@ -9,6 +9,7 @@ import os
|
|
|
9
9
|
|
|
10
10
|
from opencos import util
|
|
11
11
|
from opencos.eda_base import CommandDesign
|
|
12
|
+
from opencos.utils.str_helpers import strip_all_quotes
|
|
12
13
|
|
|
13
14
|
class CommandFList(CommandDesign):
|
|
14
15
|
'''Base class command handler for: eda flist ...'''
|
|
@@ -140,14 +141,14 @@ class CommandFList(CommandDesign):
|
|
|
140
141
|
if self.args['emit-non-sources']:
|
|
141
142
|
if self.files_non_source:
|
|
142
143
|
print('## reqs (non-source files that are dependencies):', file=fo)
|
|
143
|
-
prefix =
|
|
144
|
+
prefix = strip_all_quotes(self.args['prefix-non-sources'])
|
|
144
145
|
for f in self.files_non_source:
|
|
145
146
|
if self.args['emit-rel-path']:
|
|
146
147
|
f = os.path.relpath(f)
|
|
147
148
|
print('## ' + prefix + pq1 + f + pq2, file=fo)
|
|
148
149
|
|
|
149
150
|
if self.args['emit-define']:
|
|
150
|
-
prefix =
|
|
151
|
+
prefix = strip_all_quotes(self.args['prefix-define'])
|
|
151
152
|
for d, value in self.defines.items():
|
|
152
153
|
if value is None:
|
|
153
154
|
newline = prefix + d
|
|
@@ -176,31 +177,31 @@ class CommandFList(CommandDesign):
|
|
|
176
177
|
print(newline, file=fo)
|
|
177
178
|
|
|
178
179
|
if self.args['emit-incdir']:
|
|
179
|
-
prefix =
|
|
180
|
+
prefix = strip_all_quotes(self.args['prefix-incdir'])
|
|
180
181
|
for i in self.incdirs:
|
|
181
182
|
if self.args['emit-rel-path']:
|
|
182
183
|
i = os.path.relpath(i)
|
|
183
184
|
print(prefix + pq1 + i + pq2, file=fo)
|
|
184
185
|
if self.args['emit-v']:
|
|
185
|
-
prefix =
|
|
186
|
+
prefix = strip_all_quotes(self.args['prefix-v'])
|
|
186
187
|
for f in self.files_v:
|
|
187
188
|
if self.args['emit-rel-path']:
|
|
188
189
|
f = os.path.relpath(f)
|
|
189
190
|
print(prefix + pq1 + f + pq2, file=fo)
|
|
190
191
|
if self.args['emit-sv']:
|
|
191
|
-
prefix =
|
|
192
|
+
prefix = strip_all_quotes(self.args['prefix-sv'])
|
|
192
193
|
for f in self.files_sv:
|
|
193
194
|
if self.args['emit-rel-path']:
|
|
194
195
|
f = os.path.relpath(f)
|
|
195
196
|
print(prefix + pq1 + f + pq2, file=fo)
|
|
196
197
|
if self.args['emit-vhd']:
|
|
197
|
-
prefix =
|
|
198
|
+
prefix = strip_all_quotes(self.args['prefix-vhd'])
|
|
198
199
|
for f in self.files_vhd:
|
|
199
200
|
if self.args['emit-rel-path']:
|
|
200
201
|
f = os.path.relpath(f)
|
|
201
202
|
print(prefix + pq1 + f + pq2, file=fo)
|
|
202
203
|
if self.args['emit-cpp']:
|
|
203
|
-
prefix =
|
|
204
|
+
prefix = strip_all_quotes(self.args['prefix-cpp'])
|
|
204
205
|
for f in self.files_cpp:
|
|
205
206
|
if self.args['emit-rel-path']:
|
|
206
207
|
f = os.path.relpath(f)
|
|
@@ -9,10 +9,12 @@ import os
|
|
|
9
9
|
import shutil
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
-
from opencos import util, eda_base,
|
|
12
|
+
from opencos import util, eda_base, eda_config, export_helper, \
|
|
13
13
|
eda_tool_helper
|
|
14
|
-
from opencos.deps_helpers import get_deps_markup_file, deps_markup_safe_load
|
|
15
14
|
from opencos.eda_base import CommandParallel, get_eda_exec
|
|
15
|
+
from opencos.deps.deps_file import get_deps_markup_file, deps_markup_safe_load, \
|
|
16
|
+
deps_data_get_all_targets, deps_list_target_sanitize
|
|
17
|
+
from opencos.utils.str_helpers import fnmatch_or_re, dep_str2list
|
|
16
18
|
|
|
17
19
|
class CommandMulti(CommandParallel):
|
|
18
20
|
'''eda.py command handler for: eda multi <command> <args,targets,target-globs,...>'''
|
|
@@ -109,17 +111,17 @@ class CommandMulti(CommandParallel):
|
|
|
109
111
|
if self.path_hidden_or_work_dir(path):
|
|
110
112
|
continue
|
|
111
113
|
|
|
112
|
-
deps_markup_file =
|
|
114
|
+
deps_markup_file = get_deps_markup_file(path)
|
|
113
115
|
if deps_markup_file:
|
|
114
|
-
data =
|
|
115
|
-
deps_targets =
|
|
116
|
+
data = deps_markup_safe_load(deps_markup_file)
|
|
117
|
+
deps_targets = deps_data_get_all_targets(data)
|
|
116
118
|
rel_path = os.path.relpath(path)
|
|
117
119
|
|
|
118
120
|
debug(f'in {rel_path=} looking for {target_pattern=} in {deps_targets=}')
|
|
119
121
|
|
|
120
122
|
for t in deps_targets:
|
|
121
123
|
if target_pattern_needs_lookup:
|
|
122
|
-
matched =
|
|
124
|
+
matched = fnmatch_or_re(pattern=target_pattern, string=t)
|
|
123
125
|
else:
|
|
124
126
|
matched = t == target_pattern
|
|
125
127
|
if matched:
|
|
@@ -176,14 +178,11 @@ class CommandMulti(CommandParallel):
|
|
|
176
178
|
all_multi_tools = self.multi_which_tools(command)
|
|
177
179
|
|
|
178
180
|
deps_file = get_deps_markup_file(base_path)
|
|
179
|
-
data =
|
|
181
|
+
data = {}
|
|
180
182
|
if self.config['deps_markup_supported'] and deps_file:
|
|
181
183
|
data = deps_markup_safe_load(deps_file)
|
|
182
184
|
|
|
183
|
-
|
|
184
|
-
data = {}
|
|
185
|
-
|
|
186
|
-
deps_targets = deps_helpers.deps_data_get_all_targets(data)
|
|
185
|
+
deps_targets = deps_data_get_all_targets(data)
|
|
187
186
|
deps_file_defaults = data.get('DEFAULTS', {})
|
|
188
187
|
|
|
189
188
|
# Loop through all the targets in DEPS.yml, skipping DEFAULTS
|
|
@@ -196,7 +195,7 @@ class CommandMulti(CommandParallel):
|
|
|
196
195
|
# Since we support a few schema flavors for a target (our
|
|
197
196
|
# 'target_node' key in a DEPS.yml file) santize the entry
|
|
198
197
|
# so it's a {} with a 'deps' key:
|
|
199
|
-
entry_sanitized =
|
|
198
|
+
entry_sanitized = deps_list_target_sanitize(
|
|
200
199
|
entry, target_node=target_node, deps_file=deps_file
|
|
201
200
|
)
|
|
202
201
|
|
|
@@ -229,8 +228,8 @@ class CommandMulti(CommandParallel):
|
|
|
229
228
|
|
|
230
229
|
commands = x.get('commands', [])
|
|
231
230
|
tools = x.get('tools', [])
|
|
232
|
-
ignore_commands_list =
|
|
233
|
-
ignore_tools_list =
|
|
231
|
+
ignore_commands_list = dep_str2list(commands)
|
|
232
|
+
ignore_tools_list = dep_str2list(tools)
|
|
234
233
|
|
|
235
234
|
debug(f"{ignore_tools_list=}, {ignore_commands_list=} {target_node=}")
|
|
236
235
|
debug(f"{command=} --> {all_multi_tools=}")
|
|
@@ -8,6 +8,7 @@ import re
|
|
|
8
8
|
|
|
9
9
|
from opencos import util
|
|
10
10
|
from opencos.eda_base import CommandDesign, CommandParallel, get_eda_exec, which_tool
|
|
11
|
+
from opencos.utils.str_helpers import strip_outer_quotes
|
|
11
12
|
|
|
12
13
|
class CommandSweep(CommandDesign, CommandParallel):
|
|
13
14
|
'''Command handler for: eda sweep ...'''
|
|
@@ -77,7 +78,7 @@ class CommandSweep(CommandDesign, CommandParallel):
|
|
|
77
78
|
|
|
78
79
|
for sweep_arg_value in self.args['sweep']:
|
|
79
80
|
# Deal with --sweep= args we already parsed, but haven't expanded yet.
|
|
80
|
-
sweep_arg_value =
|
|
81
|
+
sweep_arg_value = strip_outer_quotes(sweep_arg_value)
|
|
81
82
|
sweep_axis_list_entry = self._process_sweep_arg(sweep_arg_value=sweep_arg_value)
|
|
82
83
|
if sweep_axis_list_entry:
|
|
83
84
|
sweep_axis_list.append(sweep_axis_list_entry)
|
|
@@ -136,7 +137,7 @@ class CommandSweep(CommandDesign, CommandParallel):
|
|
|
136
137
|
Return value is {} or {'lhs': str, 'operator': str (+ or =), 'values': list}
|
|
137
138
|
'''
|
|
138
139
|
|
|
139
|
-
sweep_arg_value =
|
|
140
|
+
sweep_arg_value = strip_outer_quotes(sweep_arg_value)
|
|
140
141
|
|
|
141
142
|
util.debug(f'{sweep_arg_value=}')
|
|
142
143
|
# Try to match a sweep range expansion:
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
''' opencos.deps.defaults -- pymodule for defaults referenced by other modules here'''
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
DEPS_FILE_EXTS = set([
|
|
5
|
+
'.yml', '.yaml', '.toml', '.json',
|
|
6
|
+
# Treat no extension DEPS as YAML.
|
|
7
|
+
''
|
|
8
|
+
])
|
|
9
|
+
|
|
10
|
+
ROOT_TABLE_KEYS_NOT_TARGETS = set([
|
|
11
|
+
"DEFAULTS",
|
|
12
|
+
"METADATA",
|
|
13
|
+
])
|
|
14
|
+
|
|
15
|
+
KNOWN_EDA_COMMANDS = set([
|
|
16
|
+
"sim",
|
|
17
|
+
"elab",
|
|
18
|
+
"synth",
|
|
19
|
+
"flist",
|
|
20
|
+
"proj",
|
|
21
|
+
"multi",
|
|
22
|
+
"tools-multi",
|
|
23
|
+
"sweep",
|
|
24
|
+
"build",
|
|
25
|
+
"waves",
|
|
26
|
+
"upload",
|
|
27
|
+
"open",
|
|
28
|
+
"export",
|
|
29
|
+
])
|
|
30
|
+
|
|
31
|
+
SUPPORTED_TARGET_TABLE_KEYS = set([
|
|
32
|
+
'args',
|
|
33
|
+
'defines',
|
|
34
|
+
'incdirs',
|
|
35
|
+
'top',
|
|
36
|
+
'deps',
|
|
37
|
+
'reqs',
|
|
38
|
+
'multi',
|
|
39
|
+
'tags',
|
|
40
|
+
'commands'] + list(KNOWN_EDA_COMMANDS))
|
|
41
|
+
|
|
42
|
+
SUPPORTED_DEP_KEYS_BY_TYPE = {
|
|
43
|
+
dict: set(['commands']),
|
|
44
|
+
str: set(['*']),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
SUPPORTED_TAG_KEYS = set([
|
|
48
|
+
'with-tools',
|
|
49
|
+
'with-args',
|
|
50
|
+
'args',
|
|
51
|
+
'deps',
|
|
52
|
+
'reqs',
|
|
53
|
+
'defines',
|
|
54
|
+
'incdirs',
|
|
55
|
+
'replace-config-tools',
|
|
56
|
+
'additive-config-tools',
|
|
57
|
+
])
|
|
58
|
+
|
|
59
|
+
SUPPORTED_COMMAND_KEYS = set([
|
|
60
|
+
'shell',
|
|
61
|
+
'work-dir-add-srcs', 'work-dir-add-sources',
|
|
62
|
+
'peakrdl',
|
|
63
|
+
'run-from-work-dir', # default True
|
|
64
|
+
'filepath-subst-target-dir', # default True
|
|
65
|
+
'dirpath-subst-target-dir', # default False
|
|
66
|
+
'var-subst-args',
|
|
67
|
+
'var-subst-os-env',
|
|
68
|
+
'tee',
|
|
69
|
+
])
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
'''opencos.deps.deps_commands - pymodule for processing DEPS markup deps-commands
|
|
2
|
+
|
|
3
|
+
This supports things like:
|
|
4
|
+
my_target:
|
|
5
|
+
- deps:
|
|
6
|
+
- commands:
|
|
7
|
+
- shell: <string>
|
|
8
|
+
- peakrdl: <string>
|
|
9
|
+
- work-dir-add-sources: <list>
|
|
10
|
+
'''
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
import re
|
|
16
|
+
import shutil
|
|
17
|
+
|
|
18
|
+
from opencos.util import debug, error, warning, ShellCommandList
|
|
19
|
+
from opencos.deps.defaults import SUPPORTED_COMMAND_KEYS
|
|
20
|
+
|
|
21
|
+
THISPATH = os.path.dirname(__file__)
|
|
22
|
+
PEAKRDL_CLEANUP_PY = os.path.join(THISPATH, '..', 'peakrdl_cleanup.py')
|
|
23
|
+
|
|
24
|
+
def path_substitutions_relative_to_work_dir(
|
|
25
|
+
exec_list: list, info_str: str, target_path: str,
|
|
26
|
+
enable_filepath_subst: bool, enable_dirpath_subst: bool
|
|
27
|
+
) -> list:
|
|
28
|
+
'''For shell commands, since eda.py Command objects operate out of a "work-dir", it can
|
|
29
|
+
make shell commands confusing with additional ../.. to get to the calling directory, and
|
|
30
|
+
the original target directory is completely lost otherwise.
|
|
31
|
+
|
|
32
|
+
By default, if a FILE exists in the calling target's path, we will substitute that file
|
|
33
|
+
instead of looking in the work-dir. (can be disabled via filepath-subst-target-dir: False)
|
|
34
|
+
|
|
35
|
+
Optionally if a DIR exists in the calling target's path, will will substitute that DIR
|
|
36
|
+
instead of relative to work-dir. This can be annoying with relative paths like ../ (which
|
|
37
|
+
would exist in both) so this is disabled by default (can be enabled with
|
|
38
|
+
dirpath-subst-target-dir: True)
|
|
39
|
+
'''
|
|
40
|
+
|
|
41
|
+
if not enable_filepath_subst and not enable_dirpath_subst:
|
|
42
|
+
return exec_list
|
|
43
|
+
|
|
44
|
+
# Look for path substitutions, b/c we later "work" in self.args['work-dir'], but
|
|
45
|
+
# files should be relative to our target_path.
|
|
46
|
+
for i,word in enumerate(exec_list):
|
|
47
|
+
m = re.search(r'(\.+\/+[^"\;\:\|\<\>\*]*)$', word)
|
|
48
|
+
if m:
|
|
49
|
+
# ./, ../, file=./../whatever It might be a filepath.
|
|
50
|
+
# [^"\;\:\|\<\>\*] is looking for non-path like characters, so we dont' have a trailing
|
|
51
|
+
# " : ; < > |
|
|
52
|
+
# try and see if this file or dir exists. Note that files in the
|
|
53
|
+
# self.args['work-dir'] don't need this, and we can't assume dir levels in the work-dir.
|
|
54
|
+
try:
|
|
55
|
+
try_path = os.path.abspath(os.path.join(os.path.abspath(target_path), m.group(1)))
|
|
56
|
+
if enable_filepath_subst and os.path.isfile(try_path):
|
|
57
|
+
# make the substitution
|
|
58
|
+
exec_list[i] = word.replace(m.group(1), try_path)
|
|
59
|
+
debug(f'file path substitution {info_str=} {target_path=}: replaced - {word=}'
|
|
60
|
+
f'is now ={exec_list[i]}. This can be disabled in DEPS with:',
|
|
61
|
+
'"filepath-subst-targetdir: false"')
|
|
62
|
+
elif enable_dirpath_subst and os.path.isdir(try_path):
|
|
63
|
+
# make the substitution
|
|
64
|
+
exec_list[i] = word.replace(m.group(1), try_path)
|
|
65
|
+
debug(f'dir path substitution {info_str=} {target_path=}: replaced - {word=}'
|
|
66
|
+
f'is now ={exec_list[i]}. This can be disabled in DEPS with:',
|
|
67
|
+
'"dirpath-subst-targetdir: false"')
|
|
68
|
+
except Exception:
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
return exec_list
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def line_with_var_subst( # pylint: disable=dangerous-default-value
|
|
75
|
+
line : str, replace_vars_dict: dict = {},
|
|
76
|
+
replace_vars_os_env: bool = False,
|
|
77
|
+
target_node: str = '', target_path: str = ''
|
|
78
|
+
) -> str:
|
|
79
|
+
'''Given a line (often from a shell style command) perform var substitution'''
|
|
80
|
+
|
|
81
|
+
# We can try for replacing any formatted strings, using self.args, and os.environ?
|
|
82
|
+
# We have to do this per-word, so that missing replacements or tcl-like things, such
|
|
83
|
+
# as '{}' wouldn't bail if trying to do line.format(**dict)
|
|
84
|
+
if '{' not in line:
|
|
85
|
+
return line
|
|
86
|
+
|
|
87
|
+
if replace_vars_os_env:
|
|
88
|
+
replace_dict = {}
|
|
89
|
+
replace_dict.update(os.environ)
|
|
90
|
+
replace_dict.update(replace_vars_dict)
|
|
91
|
+
else:
|
|
92
|
+
replace_dict = replace_vars_dict
|
|
93
|
+
|
|
94
|
+
words = line.split()
|
|
95
|
+
for i,word in enumerate(words):
|
|
96
|
+
try:
|
|
97
|
+
words[i] = word.format(**replace_dict)
|
|
98
|
+
except Exception:
|
|
99
|
+
# this was an attempt, no need to catch exceptions if we couldn't replace the word.
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
new_line = ' '.join(words)
|
|
103
|
+
if new_line != line:
|
|
104
|
+
debug(f'{target_node=} {target_path=} performed string format replacement,',
|
|
105
|
+
f'{line=} {new_line=}')
|
|
106
|
+
return new_line
|
|
107
|
+
|
|
108
|
+
debug(f'{target_node=} {target_path=} string format replacement attempted,',
|
|
109
|
+
f'no replacement. {line=}')
|
|
110
|
+
return line
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def parse_deps_shell_str(
|
|
114
|
+
line: str, target_path: str, target_node: str,
|
|
115
|
+
enable_filepath_subst_target_dir: bool = True,
|
|
116
|
+
enable_dirpath_subst_target_dir: bool = False,
|
|
117
|
+
enable: bool = True
|
|
118
|
+
) -> dict:
|
|
119
|
+
'''Returns None or a dict of a possible shell command from line (str)
|
|
120
|
+
|
|
121
|
+
Examples of 'line' str:
|
|
122
|
+
shell@echo "hello world" > hello.txt
|
|
123
|
+
shell@ generate_something.sh
|
|
124
|
+
shell@ generate_this.py --input=some_data.json
|
|
125
|
+
shell@ cp ./some_file.txt some_file_COPY.txt
|
|
126
|
+
shell@ vivado -mode tcl -script ./some.tcl -tclargs foo_ip 1.2 foo_part foo_our_name \
|
|
127
|
+
{property value}
|
|
128
|
+
|
|
129
|
+
Returns None if no parsing was performed, or if enable is False
|
|
130
|
+
|
|
131
|
+
target_path (str) -- from dependency parsing (relative path of the DEPS file)
|
|
132
|
+
target_node (str) -- from dependency parsing, the target containing this 'line' str.
|
|
133
|
+
'''
|
|
134
|
+
if not enable:
|
|
135
|
+
return {}
|
|
136
|
+
|
|
137
|
+
m = re.match(r'^\s*shell\@(.*)\s*$', line)
|
|
138
|
+
if not m:
|
|
139
|
+
return {}
|
|
140
|
+
|
|
141
|
+
exec_str = m.group(1)
|
|
142
|
+
exec_list = exec_str.split()
|
|
143
|
+
|
|
144
|
+
# Look for path substitutions, b/c we later "work" in self.args['work-dir'], but
|
|
145
|
+
# files should be relative to our target_path.
|
|
146
|
+
# Note this can be disable in DEPS via path-subst-target-dir=False
|
|
147
|
+
exec_list = path_substitutions_relative_to_work_dir(
|
|
148
|
+
exec_list=exec_list, info_str='shell@', target_path=target_path,
|
|
149
|
+
enable_filepath_subst=enable_filepath_subst_target_dir,
|
|
150
|
+
enable_dirpath_subst=enable_dirpath_subst_target_dir
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
'target_path': os.path.abspath(target_path),
|
|
155
|
+
'target_node': target_node,
|
|
156
|
+
'run_from_work_dir': True, # may be overriden later.
|
|
157
|
+
'exec_list': exec_list,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def parse_deps_work_dir_add_srcs(
|
|
162
|
+
line : str, target_path : str, target_node : str, enable : bool = True
|
|
163
|
+
) -> dict:
|
|
164
|
+
'''Returns None or a dict describing source files to add from the work-dir path
|
|
165
|
+
|
|
166
|
+
Examples of 'line' str:
|
|
167
|
+
work_dir_add_srcs@ my_csrs.sv
|
|
168
|
+
work_dir_add_srcs@ some_generated_file.sv some_dir/some_other.v ./gen-vhd-dir/even_more.vhd
|
|
169
|
+
|
|
170
|
+
Returns None if no parsing was performed, or if enable is False
|
|
171
|
+
|
|
172
|
+
target_path (str) -- from dependency parsing (relative path of the DEPS file)
|
|
173
|
+
target_node (str) -- from dependency parsing, the target containing this 'line' str.
|
|
174
|
+
'''
|
|
175
|
+
if not enable:
|
|
176
|
+
return {}
|
|
177
|
+
|
|
178
|
+
m = re.match(r'^\s*work_dir_add_srcs\@(.*)\s*$', line)
|
|
179
|
+
if not m:
|
|
180
|
+
return {}
|
|
181
|
+
|
|
182
|
+
files_str = m.group(1)
|
|
183
|
+
file_list = files_str.split()
|
|
184
|
+
|
|
185
|
+
d = {'target_path': os.path.abspath(target_path),
|
|
186
|
+
'target_node': target_node,
|
|
187
|
+
'file_list': file_list,
|
|
188
|
+
}
|
|
189
|
+
return d
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def parse_deps_peakrdl( # pylint: disable=too-many-locals
|
|
193
|
+
line: str, target_path: str, target_node: str, enable: bool = True,
|
|
194
|
+
enable_filepath_subst_target_dir: bool = True,
|
|
195
|
+
enable_dirpath_subst_target_dir: bool = False
|
|
196
|
+
) -> dict:
|
|
197
|
+
'''Returns None or a dict describing a PeakRDL CSR register generator dependency
|
|
198
|
+
|
|
199
|
+
Examples of 'line' str:
|
|
200
|
+
peakrdl@ --cpuif axi4-lite-flat --top oc_eth_10g_1port_csrs ./oc_eth_10g_csrs.rdl
|
|
201
|
+
|
|
202
|
+
Returns None if no parsing was performed, or if enable=False
|
|
203
|
+
|
|
204
|
+
target_path (str) -- from dependency parsing (relative path of the DEPS file)
|
|
205
|
+
target_node (str) -- from dependency parsing, the target containing this 'line' str.
|
|
206
|
+
'''
|
|
207
|
+
|
|
208
|
+
m = re.match(r'^\s*peakrdl\@(.*)\s*$', line)
|
|
209
|
+
if not m:
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
if not enable:
|
|
213
|
+
warning(f'peakrdl: encountered peakrdl command in {target_path=} {target_node=},' \
|
|
214
|
+
+ ' however it is not enabled in edy.py - eda.config[dep_command_enables]')
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
if not shutil.which('peakrdl'):
|
|
218
|
+
error('peakrdl: is not present in shell path, or the python package is not avaiable,' \
|
|
219
|
+
+ f' yet we encountered a peakrdl command in {target_path=} {target_node=}')
|
|
220
|
+
return None
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
args_str = m.group(1)
|
|
224
|
+
args_list = args_str.split()
|
|
225
|
+
|
|
226
|
+
# Fish out the .rdl name
|
|
227
|
+
# If there is --top=value or --top value, then fish out that value (that will be the
|
|
228
|
+
# value.sv and value_pkg.sv generated names.
|
|
229
|
+
|
|
230
|
+
sv_files = []
|
|
231
|
+
top = ''
|
|
232
|
+
for i,str_value in enumerate(args_list):
|
|
233
|
+
if '--top=' in str_value:
|
|
234
|
+
_, top = str_value.split('=')
|
|
235
|
+
elif '--top' in str_value:
|
|
236
|
+
if i + 1 < len(args_list):
|
|
237
|
+
top = args_list[i + 1]
|
|
238
|
+
|
|
239
|
+
for str_item in args_list:
|
|
240
|
+
if str_item[-4:] == '.rdl':
|
|
241
|
+
_, rdl_fileonly = os.path.split(str_item) # strip all path info
|
|
242
|
+
rdl_filebase, _ = os.path.splitext(rdl_fileonly) # strip .rdl ext
|
|
243
|
+
if not top:
|
|
244
|
+
top = rdl_filebase
|
|
245
|
+
|
|
246
|
+
assert top != '', \
|
|
247
|
+
f'peakrdl@ DEP, could not determine value {top=}: {line=}, {target_path=}, {target_node=}'
|
|
248
|
+
|
|
249
|
+
sv_files += [ f'peakrdl/{top}_pkg.sv', f'peakrdl/{top}.sv' ]
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
shell_commands = [
|
|
253
|
+
[ 'peakrdl', 'regblock', '-o', str(Path('peakrdl/'))] + args_list,
|
|
254
|
+
# Edit file to apply some verilator waivers, etc, from peakrdl_cleanup.py:
|
|
255
|
+
[ 'python3', PEAKRDL_CLEANUP_PY, str(Path(f'peakrdl/{top}.sv')),
|
|
256
|
+
str(Path(f'peakrdl/{top}.sv')) ],
|
|
257
|
+
]
|
|
258
|
+
|
|
259
|
+
ret_dict = {
|
|
260
|
+
'shell_commands_list': [], # Entry needs target_path, target_node, exec_list
|
|
261
|
+
'work_dir_add_srcs': {}, # Single dict needs target_path, target_node, file_list
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
# Make these look like a dep_shell_command:
|
|
265
|
+
for one_cmd_as_list in shell_commands:
|
|
266
|
+
ret_dict['shell_commands_list'].append(
|
|
267
|
+
parse_deps_shell_str(
|
|
268
|
+
line=(' shell@ ' + ' '.join(one_cmd_as_list)),
|
|
269
|
+
target_path=target_path,
|
|
270
|
+
target_node=target_node,
|
|
271
|
+
enable_filepath_subst_target_dir=enable_filepath_subst_target_dir,
|
|
272
|
+
enable_dirpath_subst_target_dir=enable_dirpath_subst_target_dir
|
|
273
|
+
)
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# Make the work_dir_add_srcs dict:
|
|
277
|
+
ret_dict['work_dir_add_srcs'] = parse_deps_work_dir_add_srcs(
|
|
278
|
+
line = ' work_dir_add_srcs@ ' + ' '.join(sv_files),
|
|
279
|
+
target_path = target_path,
|
|
280
|
+
target_node = target_node
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
return ret_dict
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def deps_commands_handler( #pylint: disable=too-many-locals,too-many-branches
|
|
288
|
+
config: dict, eda_args: dict,
|
|
289
|
+
dep : str, deps_file : str, target_node : str, target_path : str,
|
|
290
|
+
commands : list
|
|
291
|
+
) -> (list, list):
|
|
292
|
+
''' Returns a tuple of (shell_commands_list, work_dir_add_srcs_list), from processing
|
|
293
|
+
a DEPS.yml entry for something like:
|
|
294
|
+
|
|
295
|
+
target_foo:
|
|
296
|
+
deps:
|
|
297
|
+
- some_file
|
|
298
|
+
- commands: # (list of dicts) These are directly in a 'deps' list.
|
|
299
|
+
- shell: ...
|
|
300
|
+
- peakrdl: ...
|
|
301
|
+
- work-dir-add-sources: ...
|
|
302
|
+
- shell: ...
|
|
303
|
+
|
|
304
|
+
target_foo:
|
|
305
|
+
commands: # (list of dicts) These are in a target, but not ordered with other deps
|
|
306
|
+
- shell: ...
|
|
307
|
+
- peakrdl: ...
|
|
308
|
+
- work-dir-add-sources: ...
|
|
309
|
+
- shell: ...
|
|
310
|
+
|
|
311
|
+
We'd like to handle the list in a 'commands' entry, supporting it in a few places in a
|
|
312
|
+
DEPS.yml, so this this a generic way to do that. Currently these are broken down into Shell
|
|
313
|
+
commands and Files that will be later added to our sources (b/c we haven't run the Shell
|
|
314
|
+
commands yet, and the Files aren't present yet but we'd like them in our eda.py filelist in
|
|
315
|
+
order.
|
|
316
|
+
|
|
317
|
+
'''
|
|
318
|
+
|
|
319
|
+
shell_commands_list = []
|
|
320
|
+
work_dir_add_srcs_list = []
|
|
321
|
+
|
|
322
|
+
for command in commands:
|
|
323
|
+
assert isinstance(command, dict), \
|
|
324
|
+
(f'{type(command)=} must be dict, for {deps_file=} {target_node=} {target_path=} with'
|
|
325
|
+
f'{commands=}')
|
|
326
|
+
|
|
327
|
+
for key in command.keys():
|
|
328
|
+
if key not in SUPPORTED_COMMAND_KEYS:
|
|
329
|
+
error(f'deps_commands.process_commands - command {key=} not in',
|
|
330
|
+
f'{SUPPORTED_COMMAND_KEYS=}')
|
|
331
|
+
|
|
332
|
+
var_subst_dict = {} # this is per-command.
|
|
333
|
+
if config['dep_command_enables'].get('var_subst_os_env', False) and \
|
|
334
|
+
command.get('var-subst-os-env', False):
|
|
335
|
+
var_subst_dict.update(dict(os.environ))
|
|
336
|
+
if config['dep_command_enables'].get('var_subst_args', False) and \
|
|
337
|
+
command.get('var-subst-args', False):
|
|
338
|
+
var_subst_dict = eda_args
|
|
339
|
+
|
|
340
|
+
tee_fpath = command.get('tee', None)
|
|
341
|
+
|
|
342
|
+
# These are both optional bools, default True, would have to explicitly be set to False
|
|
343
|
+
# to take effect:
|
|
344
|
+
run_from_work_dir = command.get('run-from-work-dir', True)
|
|
345
|
+
filepath_subst_target_dir = command.get('filepath-subst-target-dir', True)
|
|
346
|
+
dirpath_subst_target_dir = command.get('dirpath-subst-target-dir', False)
|
|
347
|
+
|
|
348
|
+
for key,item in command.items():
|
|
349
|
+
|
|
350
|
+
# skip the tee and var-subst-* keys, since these types are bools and not commands.
|
|
351
|
+
if key in ['tee',
|
|
352
|
+
'var-subst-os-env',
|
|
353
|
+
'var-subst-args',
|
|
354
|
+
'run-from-work-dir',
|
|
355
|
+
'filepath-subst-target-dir',
|
|
356
|
+
'dirpath-subst-target-dir']:
|
|
357
|
+
continue
|
|
358
|
+
|
|
359
|
+
# Optional variable substituion in commands
|
|
360
|
+
if isinstance(item, str):
|
|
361
|
+
item = line_with_var_subst(item, replace_vars_dict=var_subst_dict,
|
|
362
|
+
target_node=target_node, target_path=deps_file)
|
|
363
|
+
|
|
364
|
+
if key == 'shell':
|
|
365
|
+
# For now, piggyback on parse_deps_shell_str:
|
|
366
|
+
ret_dict = parse_deps_shell_str(
|
|
367
|
+
line=('shell@ ' + item),
|
|
368
|
+
target_path=target_path,
|
|
369
|
+
target_node=target_node,
|
|
370
|
+
enable_filepath_subst_target_dir=filepath_subst_target_dir,
|
|
371
|
+
enable_dirpath_subst_target_dir=dirpath_subst_target_dir,
|
|
372
|
+
enable=config['dep_command_enables']['shell'],
|
|
373
|
+
)
|
|
374
|
+
# To support 'tee: <some-file>' need to append it to last
|
|
375
|
+
# list item in ret_dict['exec_list'], and make it a util.ShellCommandList.
|
|
376
|
+
if tee_fpath:
|
|
377
|
+
ret_dict['exec_list'] = ShellCommandList(
|
|
378
|
+
ret_dict['exec_list'], tee_fpath=tee_fpath
|
|
379
|
+
)
|
|
380
|
+
ret_dict['run_from_work_dir'] = run_from_work_dir
|
|
381
|
+
assert ret_dict, f'shell command failed in {dep=} {target_node=} in {deps_file=}'
|
|
382
|
+
shell_commands_list.append(ret_dict) # process this later, append to ret tuple
|
|
383
|
+
|
|
384
|
+
elif key in ['work-dir-add-srcs', 'work-dir-add-sources']:
|
|
385
|
+
# For now, piggyback on parse_deps_work_dir_add_srcs:
|
|
386
|
+
ret_dict = parse_deps_work_dir_add_srcs(
|
|
387
|
+
line = 'work_dir_add_srcs@ ' + item,
|
|
388
|
+
target_path = target_path,
|
|
389
|
+
target_node = target_node,
|
|
390
|
+
enable=config['dep_command_enables']['work_dir_add_srcs'],
|
|
391
|
+
)
|
|
392
|
+
assert ret_dict, \
|
|
393
|
+
f'work-dir-add-srcs command failed in {dep=} {target_node=} in {deps_file=}'
|
|
394
|
+
|
|
395
|
+
work_dir_add_srcs_list.append(ret_dict) # process this later, append to ret tuple
|
|
396
|
+
|
|
397
|
+
elif key == 'peakrdl':
|
|
398
|
+
# for now, piggyback on parse_deps_peakrdl:
|
|
399
|
+
ret_dict = parse_deps_peakrdl(
|
|
400
|
+
line = 'peakrdl@ ' + item,
|
|
401
|
+
target_path = target_path,
|
|
402
|
+
target_node = target_node,
|
|
403
|
+
enable_filepath_subst_target_dir=filepath_subst_target_dir,
|
|
404
|
+
enable_dirpath_subst_target_dir=dirpath_subst_target_dir,
|
|
405
|
+
enable=config['dep_command_enables']['peakrdl']
|
|
406
|
+
)
|
|
407
|
+
assert ret_dict, f'peakrdl command failed in {dep=} {target_node=} in {deps_file=}'
|
|
408
|
+
|
|
409
|
+
# add all the shell commands:
|
|
410
|
+
shell_commands_list += ret_dict['shell_commands_list'] # several entries.
|
|
411
|
+
# all the work_dir_add_srcs:
|
|
412
|
+
work_dir_add_srcs_list += [ ret_dict['work_dir_add_srcs'] ] # single entry append
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
else:
|
|
416
|
+
assert False, \
|
|
417
|
+
f'unknown {key=} in {command=}, {item=} {dep=} {target_node=} in {deps_file=}'
|
|
418
|
+
|
|
419
|
+
return (shell_commands_list, work_dir_add_srcs_list)
|