Skip to content

Commit 9150518

Browse files
alzixAlexander Zilberkant
authored andcommitted
Integrate with mbeb-cli build system
PSA code generation will be called automatically upon mbed invocation. The autogenerated files will be created under <mbed-os-root>/PSA_AUTOGEN directory.
1 parent 117e3e8 commit 9150518

File tree

11 files changed

+151
-45
lines changed

11 files changed

+151
-45
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,6 @@ test_suite.json
9797

9898
# default delivery dir
9999
DELIVERY/
100+
101+
# Directory hosting PSA autogenerated source files
102+
PSA_AUTOGEN/

tools/build.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
import sys
2323
from time import time
24-
from os.path import join, abspath, dirname
24+
from os.path import join, abspath, dirname, normpath
2525

2626

2727
# Be sure that the tools directory is in the search path
@@ -44,7 +44,8 @@
4444
from tools.utils import argparse_dir_not_parent
4545
from tools.utils import NoValidToolchainException
4646
from tools.utils import print_end_warnings
47-
from tools.paths import is_relative_to_root
47+
from tools.psa import generate_psa_sources, clean_psa_autogen
48+
from tools.resources import OsAndSpeResourceFilter
4849

4950
def main():
5051
start = time()
@@ -171,6 +172,9 @@ def main():
171172
skipped = []
172173
end_warnings = []
173174

175+
if options.clean:
176+
clean_psa_autogen()
177+
174178
for toolchain in toolchains:
175179
for target_name in targets:
176180
target = Target.get_target(target_name)
@@ -192,10 +196,17 @@ def main():
192196
notifier = TerminalNotifier(options.verbose, options.silent)
193197
profile = extract_profile(parser, options, internal_tc_name)
194198

195-
if target.is_PSA_secure_target and \
196-
not is_relative_to_root(options.source_dir):
197-
options.source_dir = ROOT
198199
if options.source_dir:
200+
if target.is_PSA_target:
201+
generate_psa_sources(
202+
source_dirs=options.source_dir,
203+
ignore_paths=[options.build_dir]
204+
)
205+
206+
resource_filter = None
207+
if target.is_PSA_secure_target:
208+
resource_filter = OsAndSpeResourceFilter()
209+
199210
lib_build_res = build_library(
200211
options.source_dir, options.build_dir, target, toolchain_name,
201212
jobs=options.jobs,
@@ -205,7 +216,8 @@ def main():
205216
name=options.artifact_name,
206217
build_profile=profile,
207218
ignore=options.ignore,
208-
notify = notifier,
219+
notify=notifier,
220+
resource_filter=resource_filter
209221
)
210222
else:
211223
lib_build_res = build_mbed_libs(

tools/build_api.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
MBED_CONFIG_FILE, MBED_LIBRARIES_DRIVERS,
4242
MBED_LIBRARIES_PLATFORM, MBED_LIBRARIES_HAL,
4343
BUILD_DIR)
44-
from .resources import Resources, FileType, FileRef
44+
from .resources import Resources, FileType, FileRef, PsaManifestResourceFilter
4545
from .notifier.mock import MockNotifier
4646
from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH, Target
4747
from .libraries import Library
@@ -511,7 +511,7 @@ def build_project(src_paths, build_path, target, toolchain_name,
511511
report=None, properties=None, project_id=None,
512512
project_description=None, config=None,
513513
app_config=None, build_profile=None, stats_depth=None,
514-
ignore=None, spe_build=False):
514+
ignore=None, resource_filter=None):
515515
""" Build a project. A project may be a test or a user program.
516516
517517
Positional arguments:
@@ -539,6 +539,7 @@ def build_project(src_paths, build_path, target, toolchain_name,
539539
build_profile - a dict of flags that will be passed to the compiler
540540
stats_depth - depth level for memap to display file/dirs
541541
ignore - list of paths to add to mbedignore
542+
resource_filter - can be used for filtering out resources after scan
542543
"""
543544
# Convert src_path to a list if needed
544545
if not isinstance(src_paths, list):
@@ -581,8 +582,8 @@ def build_project(src_paths, build_path, target, toolchain_name,
581582
try:
582583
resources = Resources(notify).scan_with_toolchain(
583584
src_paths, toolchain, inc_dirs=inc_dirs)
584-
if spe_build:
585-
resources.filter_spe()
585+
resources.filter(resource_filter)
586+
586587
# Change linker script if specified
587588
if linker_script is not None:
588589
resources.add_file_ref(FileType.LD_SCRIPT, linker_script, linker_script)
@@ -664,7 +665,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
664665
archive=True, notify=None, macros=None, inc_dirs=None, jobs=1,
665666
report=None, properties=None, project_id=None,
666667
remove_config_header_file=False, app_config=None,
667-
build_profile=None, ignore=None):
668+
build_profile=None, ignore=None, resource_filter=None):
668669
""" Build a library
669670
670671
Positional arguments:
@@ -690,6 +691,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
690691
app_config - location of a chosen mbed_app.json file
691692
build_profile - a dict of flags that will be passed to the compiler
692693
ignore - list of paths to add to mbedignore
694+
resource_filter - can be used for filtering out resources after scan
693695
"""
694696

695697
# Convert src_path to a list if needed
@@ -750,6 +752,8 @@ def build_library(src_paths, build_path, target, toolchain_name,
750752
try:
751753
res = Resources(notify).scan_with_toolchain(
752754
src_paths, toolchain, dependencies_paths, inc_dirs=inc_dirs)
755+
res.filter(resource_filter)
756+
res.filter(PsaManifestResourceFilter())
753757

754758
# Copy headers, objects and static libraries - all files needed for
755759
# static lib

tools/export/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def export_project(src_paths, export_path, target, ide, libraries_paths=None,
208208
linker_script=None, notify=None, name=None, inc_dirs=None,
209209
jobs=1, config=None, macros=None, zip_proj=None,
210210
inc_repos=False, build_profile=None, app_config=None,
211-
ignore=None):
211+
ignore=None, resource_filter=None):
212212
"""Generates a project file and creates a zip archive if specified
213213
214214
Positional Arguments:
@@ -230,6 +230,7 @@ def export_project(src_paths, export_path, target, ide, libraries_paths=None,
230230
zip_proj - string name of the zip archive you wish to creat (exclude arg
231231
if you do not wish to create an archive
232232
ignore - list of paths to add to mbedignore
233+
resource_filter - can be used for filtering out resources after scan
233234
"""
234235

235236
# Convert src_path to a list if needed
@@ -279,6 +280,8 @@ def export_project(src_paths, export_path, target, ide, libraries_paths=None,
279280
if toolchain.config.name:
280281
name = toolchain.config.name
281282

283+
resources.filter(resource_filter)
284+
282285
files, exporter = generate_project_files(
283286
resources, export_path, target, name, toolchain, ide, zip_proj, macros=macros
284287
)

tools/make.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from __future__ import print_function
2222
from builtins import str
2323
import sys
24-
from os.path import join, abspath, dirname
24+
from os.path import join, abspath, dirname, normpath
2525

2626
# Be sure that the tools directory is in the search path
2727
ROOT = abspath(join(dirname(__file__), ".."))
@@ -34,7 +34,6 @@
3434
from tools.paths import RPC_LIBRARY
3535
from tools.paths import USB_LIBRARIES
3636
from tools.paths import DSP_LIBRARIES
37-
from tools.paths import is_relative_to_root
3837
from tools.tests import TESTS, Test, TEST_MAP
3938
from tools.tests import TEST_MBED_LIB
4039
from tools.tests import test_known, test_name_known
@@ -56,7 +55,8 @@
5655
from tools.utils import print_large_string
5756
from tools.settings import ROOT
5857
from tools.targets import Target
59-
58+
from tools.psa import generate_psa_sources, clean_psa_autogen
59+
from tools.resources import OsAndSpeResourceFilter
6060

6161
def default_args_dict(options):
6262
return dict(
@@ -74,7 +74,8 @@ def wrapped_build_project(src_dir, build_dir, mcu, end_warnings, options, *args,
7474
error = False
7575
try:
7676
bin_file, update_file = build_project(
77-
src_dir, build_dir, mcu, *args, **kwargs
77+
src_dir, build_dir, mcu,
78+
*args, **kwargs
7879
)
7980
if update_file:
8081
print('Update Image: %s' % update_file)
@@ -304,6 +305,10 @@ def main():
304305
elif options.list_tests is True:
305306
print('\n'.join(map(str, sorted(TEST_MAP.values()))))
306307
else:
308+
309+
if options.clean:
310+
clean_psa_autogen()
311+
307312
# Target
308313
if options.mcu is None:
309314
args_error(parser, "argument -m/--mcu is required")
@@ -315,9 +320,6 @@ def main():
315320
toolchain = options.tool[0]
316321

317322
target = Target.get_target(mcu)
318-
if target.is_PSA_secure_target and \
319-
not is_relative_to_root(options.source_dir):
320-
options.source_dir = ROOT
321323

322324
if (options.program is None) and (not options.source_dir):
323325
args_error(parser, "one of -p, -n, or --source is required")
@@ -337,6 +339,16 @@ def main():
337339
args_error(parser, str(e))
338340

339341
if options.source_dir is not None:
342+
if target.is_PSA_target:
343+
generate_psa_sources(
344+
source_dirs=options.source_dir,
345+
ignore_paths=[options.build_dir]
346+
)
347+
348+
resource_filter = None
349+
if target.is_PSA_secure_target:
350+
resource_filter = OsAndSpeResourceFilter()
351+
340352
wrapped_build_project(
341353
options.source_dir,
342354
options.build_dir,
@@ -346,6 +358,7 @@ def main():
346358
toolchain_name,
347359
notify=notify,
348360
build_profile=extract_profile(parser, options, internal_tc_name),
361+
resource_filter=resource_filter,
349362
**default_args_dict(options)
350363
)
351364
else:

tools/paths.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,3 @@
8585
CPPUTEST_TESTRUNNER_INC = join(TEST_DIR, "utest", "testrunner")
8686

8787
CPPUTEST_LIBRARY = join(BUILD_DIR, "cpputest")
88-
89-
90-
def is_relative_to_root(dirs):
91-
if not isinstance(dirs, list):
92-
dirs = [dirs]
93-
dirs = [realpath(d) for d in dirs]
94-
out = commonprefix(dirs + [ROOT])
95-
return out == ROOT

tools/project.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
)
4141
from tools.tests import TESTS, TEST_MAP
4242
from tools.tests import test_known, test_name_known, Test
43-
from tools.targets import TARGET_NAMES
43+
from tools.targets import TARGET_NAMES, Target
4444
from tools.utils import (
4545
argparse_filestring_type,
4646
argparse_profile_filestring_type,
@@ -53,6 +53,8 @@
5353
from tools.utils import NotSupportedException
5454
from tools.options import extract_profile, list_profiles, extract_mcus
5555
from tools.notifier.term import TerminalNotifier
56+
from tools.psa import generate_psa_sources, clean_psa_autogen
57+
from tools.resources import OsAndSpeResourceFilter
5658

5759
""" The CLI entry point for exporting projects from the mbed tools to any of the
5860
supported IDEs or project structures.
@@ -126,7 +128,7 @@ def setup_project(
126128

127129
def export(target, ide, build=None, src=None, macros=None, project_id=None,
128130
zip_proj=False, build_profile=None, export_path=None, notify=None,
129-
app_config=None, ignore=None):
131+
app_config=None, ignore=None, resource_filter=None):
130132
"""Do an export of a project.
131133
132134
Positional arguments:
@@ -141,6 +143,7 @@ def export(target, ide, build=None, src=None, macros=None, project_id=None,
141143
clean - start from a clean state before exporting
142144
zip_proj - create a zip file or not
143145
ignore - list of paths to add to mbedignore
146+
resource_filter - can be used for filtering out resources after scan
144147
145148
Returns an object of type Exporter (tools/exports/exporters.py)
146149
"""
@@ -168,7 +171,8 @@ def export(target, ide, build=None, src=None, macros=None, project_id=None,
168171
build_profile=build_profile,
169172
notify=TerminalNotifier(),
170173
app_config=app_config,
171-
ignore=ignore
174+
ignore=ignore,
175+
resource_filter=resource_filter
172176
)
173177

174178
def clean(source_dir):
@@ -376,6 +380,7 @@ def main():
376380

377381
if options.clean:
378382
clean(options.source_dir)
383+
clean_psa_autogen()
379384

380385
ide = resolve_exporter_alias(options.ide)
381386
exporter, toolchain_name = get_exporter_toolchain(ide)
@@ -385,6 +390,16 @@ def main():
385390
args_error(parser, "%s not supported by %s" % (mcu, ide))
386391

387392
try:
393+
target = Target.get_target(mcu)
394+
if target.is_PSA_target:
395+
generate_psa_sources(source_dirs=options.source_dir,
396+
ignore_paths=[]
397+
)
398+
399+
resource_filter = None
400+
if target.is_PSA_secure_target:
401+
resource_filter = OsAndSpeResourceFilter()
402+
388403
export(
389404
mcu,
390405
ide,
@@ -396,12 +411,14 @@ def main():
396411
build_profile=profile,
397412
app_config=options.app_config,
398413
export_path=options.build_dir,
399-
ignore=options.ignore
414+
ignore=options.ignore,
415+
resource_filter=resource_filter
400416
)
401417
except NotSupportedException as exc:
402418
print("[Not Supported] %s" % str(exc))
403419
exit(1)
404420
exit(0)
405421

422+
406423
if __name__ == "__main__":
407424
main()

tools/resources/__init__.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from os.path import (join, splitext, dirname, relpath, basename, split, normpath,
4242
abspath, exists)
4343

44+
from tools.settings import ROOT
4445
from .ignore import MbedIgnoreSet, IGNORE_FILENAME
4546

4647
# Support legacy build conventions: the original mbed build system did not have
@@ -594,7 +595,45 @@ def scan_with_config(self, src_paths, config):
594595
config.load_resources(self)
595596
return self
596597

597-
def filter_spe(self):
598-
spe_filter = lambda x: 'COMPONENT_SPE' in x
599-
for type in [FileType.ASM_SRC, FileType.C_SRC, FileType.CPP_SRC]:
600-
self._file_refs[type] = set([f for f in self._file_refs[type] if spe_filter(f.name) or spe_filter(f.path)])
598+
def filter(self, res_filter):
599+
if res_filter is None:
600+
return
601+
602+
for t in res_filter.file_types:
603+
self._file_refs[t] = set(filter(
604+
res_filter.predicate, self._file_refs[t]))
605+
606+
607+
class ResourceFilter(object):
608+
def __init__(self, file_types):
609+
self.file_types = file_types
610+
611+
def predicate(self, ref):
612+
raise NotImplemented
613+
614+
615+
class SpeOnlyResourceFilter(ResourceFilter):
616+
def __init__(self):
617+
ResourceFilter.__init__(
618+
self, [FileType.ASM_SRC, FileType.C_SRC, FileType.CPP_SRC])
619+
620+
def predicate(self, ref):
621+
return 'COMPONENT_SPE' in ref.name
622+
623+
624+
class OsAndSpeResourceFilter(ResourceFilter):
625+
def __init__(self):
626+
ResourceFilter.__init__(
627+
self, [FileType.ASM_SRC, FileType.C_SRC, FileType.CPP_SRC])
628+
629+
def predicate(self, ref):
630+
return ROOT in abspath(ref.name) or 'COMPONENT_SPE' in ref.name
631+
632+
633+
class PsaManifestResourceFilter(ResourceFilter):
634+
def __init__(self):
635+
ResourceFilter.__init__(
636+
self, [FileType.JSON])
637+
638+
def predicate(self, ref):
639+
return not ref.name.endswith('_psa.json')

0 commit comments

Comments
 (0)