2121import shutil
2222from argparse import ArgumentParser
2323
24- ROOT = os .path .abspath (os .path .join (os .path .dirname (__file__ ), os .pardir , os .pardir ))
24+ ROOT = os .path .abspath (os .path .join (os .path .dirname (__file__ ),
25+ os .pardir , os .pardir ))
2526sys .path .insert (0 , ROOT )
2627from tools .targets import Target , TARGET_MAP , TARGET_NAMES
2728
2829MAKE_PY_LOCATTION = os .path .join (ROOT , 'tools' , 'make.py' )
2930TEST_PY_LOCATTION = os .path .join (ROOT , 'tools' , 'test.py' )
30- MBED_PSA_TESTS = '*psa-spm*,*psa-crypto_access_control'
3131TFM_MBED_APP = os .path .join (ROOT , 'tools' , 'psa' , 'tfm' , 'mbed_app.json' )
32+ MBED_PSA_TESTS = '*psa-spm*,*psa-crypto_access_control'
3233TFM_TESTS = {
3334 '*psa-spm_smoke' : ['USE_PSA_TEST_PARTITIONS' , 'USE_SMOKE_TESTS_PART1' ],
3435 '*psa-spm_client' : ['USE_PSA_TEST_PARTITIONS' , 'USE_CLIENT_TESTS_PART1' ],
35- '*psa-spm_server' : ['USE_PSA_TEST_PARTITIONS' , 'USE_SERVER_TESTS_PART1' , 'USE_SERVER_TESTS_PART2' ],
36- '*psa-crypto_access_control' : ['USE_PSA_TEST_PARTITIONS' , 'USE_CRYPTO_ACL_TEST' ]
36+ '*psa-spm_server' : ['USE_PSA_TEST_PARTITIONS' , 'USE_SERVER_TESTS_PART1' ,
37+ 'USE_SERVER_TESTS_PART2' ],
38+ '*psa-crypto_access_control' : ['USE_PSA_TEST_PARTITIONS' ,
39+ 'USE_CRYPTO_ACL_TEST' ]
3740}
3841
3942
40- def _psa_backend (target_name ):
41- return 'TFM' if 'TFM' in Target .get_target (target_name ).labels else 'MBED_SPM'
43+ def _psa_backend (target ):
44+ """
45+ Returns a target PSA backend.
46+
47+ :param target: Target name as in targets.json
48+ :return: PSA backend as string (TFM/MBED_SPM)
49+ """
50+ return 'TFM' if 'TFM' in Target .get_target (target ).labels else 'MBED_SPM'
51+
52+
53+ def _get_target_info (target ):
54+ """
55+ Creates a PSA target tuple with default toolchain and
56+ artifact delivery directory.
57+
58+ :param target: Target name.
59+ :return: tuple (target, toolchain, delivery directory).
60+ """
61+ delivery_dir = os .path .join (ROOT , 'targets' ,
62+ TARGET_MAP [target ].delivery_dir )
63+
64+ if not os .path .exists (delivery_dir ):
65+ raise Exception ("{} does not have delivery_dir" .format (target ))
66+
67+ return tuple ([TARGET_MAP [target ].name ,
68+ TARGET_MAP [target ].default_toolchain ,
69+ delivery_dir ])
4270
4371
44- def get_mbed_official_psa_release ():
72+ def get_mbed_official_psa_release (target = None ):
73+ """
74+ Creates a list of PSA targets with default toolchain and
75+ artifact delivery directory.
76+
77+ :param target: Ask for specific target, None for all targets.
78+ :return: List of tuples (target, toolchain, delivery directory).
79+ """
4580 psa_targets_release_list = []
46- psa_secure_targets = [t for t in TARGET_NAMES if Target .get_target (t ).is_PSA_secure_target ]
47- for t in psa_secure_targets :
48- delivery_dir = os .path .join (ROOT , 'targets' , TARGET_MAP [t ].delivery_dir )
49- if not os .path .exists (delivery_dir ):
50- raise Exception ("{} does not have delivery_dir" .format (TARGET_MAP [t ].name ))
51- psa_targets_release_list .append (
52- tuple (
53- [
54- TARGET_MAP [t ].name ,
55- TARGET_MAP [t ].default_toolchain ,
56- delivery_dir ,
57- ]
58- )
59- )
81+ psa_secure_targets = [t for t in TARGET_NAMES if
82+ Target .get_target (t ).is_PSA_secure_target ]
83+ if target is not None :
84+ if target not in psa_secure_targets :
85+ raise Exception ("{} is not a PSA secure target" .format (target ))
86+ psa_targets_release_list .append (_get_target_info (target ))
87+ else :
88+ for t in psa_secure_targets :
89+ psa_targets_release_list .append (_get_target_info (target ))
6090
6191 return psa_targets_release_list
6292
6393
6494def create_mbed_ignore (build_dir ):
95+ """
96+ Creates a .mbedignore file in a given directory.
97+
98+ :param build_dir: Directory to create .mbedignore file.
99+ """
65100 with open (os .path .join (build_dir , '.mbedignore' ), 'w' ) as f :
66101 f .write ('*\n ' )
67102
68103
69104def build_mbed_spm_platform (target , toolchain , profile = 'release' ):
70- subprocess .call ([
105+ """
106+ Builds Secure images for MBED-SPM target.
107+
108+ :param target: target to be built.
109+ :param toolchain: toolchain to be used.
110+ :param profile: build profile.
111+ """
112+ subprocess .check_call ([
71113 sys .executable , '-u' , TEST_PY_LOCATTION ,
72114 '--greentea' ,
73115 '--profile' , profile ,
74116 '-t' , toolchain ,
75117 '-m' , target ,
76118 '--source' , ROOT ,
77119 '--build' , os .path .join (ROOT , 'BUILD' , 'tests' , target ),
78- '--test-spec' , os .path .join (ROOT , 'BUILD' , 'tests' , target , 'test_spec.json' ),
79- '--build-data' , os .path .join (ROOT , 'BUILD' , 'tests' , target , 'build_data.json' ),
120+ '--test-spec' , os .path .join (ROOT , 'BUILD' , 'tests' ,
121+ target , 'test_spec.json' ),
122+ '--build-data' , os .path .join (ROOT , 'BUILD' , 'tests' ,
123+ target , 'build_data.json' ),
80124 '-n' , MBED_PSA_TESTS
81- ])
125+ ], stdout = subprocess . PIPE )
82126
83- subprocess .call ([
127+ subprocess .check_call ([
84128 sys .executable , '-u' , MAKE_PY_LOCATTION ,
85129 '-t' , toolchain ,
86130 '-m' , target ,
87131 '--profile' , profile ,
88132 '--source' , ROOT ,
89133 '--build' , os .path .join (ROOT , 'BUILD' , target ),
90134 '--artifact-name' , 'psa_release_1.0'
91- ])
135+ ], stdout = subprocess . PIPE )
92136
93137
94138def _tfm_test_defines (test ):
139+ """
140+ Creates a define list to enable test partitions on TF-M.
141+
142+ :param test: Test name.
143+ :return: List of defines with a leading -D.
144+ """
95145 return ['-D{}' .format (define ) for define in TFM_TESTS [test ]]
96146
97147
98148def build_tfm_platform (target , toolchain , profile = 'release' ):
149+ """
150+ Builds Secure images for TF-M target.
151+
152+ :param target: target to be built.
153+ :param toolchain: toolchain to be used.
154+ :param profile: build profile.
155+ """
99156 for test in TFM_TESTS .keys ():
100- subprocess .call ([
157+ subprocess .check_call ([
101158 sys .executable , '-u' , TEST_PY_LOCATTION ,
102159 '--greentea' ,
103160 '--profile' , profile ,
104161 '-t' , toolchain ,
105162 '-m' , target ,
106163 '--source' , ROOT ,
107164 '--build' , os .path .join (ROOT , 'BUILD' , 'tests' , target ),
108- '--test-spec' , os .path .join (ROOT , 'BUILD' , 'tests' , target , 'test_spec.json' ),
109- '--build-data' , os .path .join (ROOT , 'BUILD' , 'tests' , target , 'build_data.json' ),
110- '--app-config' , TFM_MBED_APP , '-n' , test ] + _tfm_test_defines (test ))
111-
112- subprocess .call ([
165+ '--test-spec' , os .path .join (ROOT , 'BUILD' , 'tests' ,
166+ target , 'test_spec.json' ),
167+ '--build-data' , os .path .join (ROOT , 'BUILD' , 'tests' ,
168+ target , 'build_data.json' ),
169+ '--app-config' , TFM_MBED_APP , '-n' , test ] + _tfm_test_defines (test ),
170+ stdout = subprocess .PIPE )
171+
172+ subprocess .check_call ([
113173 sys .executable , '-u' , MAKE_PY_LOCATTION ,
114174 '-t' , toolchain ,
115175 '-m' , target ,
116176 '--profile' , profile ,
117177 '--source' , ROOT ,
118178 '--build' , os .path .join (ROOT , 'BUILD' , target ),
119179 '--app-config' , TFM_MBED_APP
120- ])
180+ ], stdout = subprocess . PIPE )
121181
122182
123- def commit_biannries (target , delivery_dir ):
124- cmd = [
125- 'git' ,
126- '-C' , ROOT ,
127- 'add' , os .path .relpath (delivery_dir , ROOT )
128- ]
183+ def commit_binaries (target , delivery_dir ):
184+ """
185+ Commits changes in secure binaries.
129186
130- subprocess .call (cmd )
131- commit_message = 'Update secure binaries for {}' .format (target )
132- cmd = [
187+ :param target: Target name.
188+ :param delivery_dir: Secure images should be moved to this folder
189+ by the build system.
190+ """
191+ changes_made = subprocess .call ([
133192 'git' ,
134193 '-C' , ROOT ,
135- 'commit' ,
136- '-m' , commit_message
137- ]
138-
139- subprocess .call (cmd )
140-
141-
142- def build_psa_platform (target , toolchain , delivery_dir , debug = False , git_commit = False ):
194+ 'diff' , '--exit-code' ,
195+ delivery_dir
196+ ], stdout = subprocess .PIPE )
197+
198+ if changes_made :
199+ subprocess .check_call ([
200+ 'git' ,
201+ '-C' , ROOT ,
202+ 'add' , os .path .relpath (delivery_dir , ROOT )
203+ ], stdout = subprocess .PIPE )
204+
205+ commit_message = '-m\" Update secure binaries for {}\" ' .format (target )
206+ subprocess .check_call ([
207+ 'git' ,
208+ '-C' , ROOT ,
209+ 'commit' ,
210+ commit_message
211+ ], stdout = subprocess .PIPE )
212+
213+
214+ def build_psa_platform (target , toolchain , delivery_dir , debug = False ,
215+ git_commit = False ):
216+ """
217+ Calls the correct build function and commits if requested.
218+
219+ :param target: Target name.
220+ :param toolchain: Toolchain to be used.
221+ :param delivery_dir: Artifact directory, where images should be placed.
222+ :param debug: Build with debug profile.
223+ :param git_commit: Commit the changes.
224+ """
143225 profile = 'debug' if debug else 'release'
144226 if _psa_backend (target ) is 'TFM' :
145227 build_tfm_platform (target , toolchain , profile )
146228 else :
147229 build_mbed_spm_platform (target , toolchain , profile )
148230
149231 if git_commit :
150- commit_biannries (target , delivery_dir )
232+ commit_binaries (target , delivery_dir )
151233
152234
153235def get_parser ():
154236 parser = ArgumentParser ()
155237 parser .add_argument ("-m" , "--mcu" ,
156238 help = "build for the given MCU" ,
157- default = '*' ,
239+ default = None ,
158240 metavar = "MCU" )
159241
160242 parser .add_argument ("-d" , "--debug" ,
@@ -170,30 +252,26 @@ def get_parser():
170252 return parser
171253
172254
173- def filter_target (mcu ):
174- def filter_func (t ):
175- return t [0 ] == mcu
176-
177- return filter_func
178-
179-
180- def main ():
181- parser = get_parser ()
182- options = parser .parse_args ()
255+ def prep_build_dir ():
256+ """
257+ Creates a clean BUILD directory
258+ """
183259 build_dir = os .path .join (ROOT , 'BUILD' )
184260 if os .path .exists (build_dir ):
185261 shutil .rmtree (build_dir )
186262
187263 os .makedirs (build_dir )
188264 create_mbed_ignore (build_dir )
189- target_filter_function = None
190- psa_platforms_list = get_mbed_official_psa_release ()
191265
192- if options .mcu is not '*' :
193- target_filter_function = filter_target (options .mcu )
194266
195- for target , toolchain , delivery_dir in filter (target_filter_function , psa_platforms_list ):
196- build_psa_platform (target , toolchain , delivery_dir , options .debug , options .commit )
267+ def main ():
268+ parser = get_parser ()
269+ options = parser .parse_args ()
270+ prep_build_dir ()
271+ psa_platforms_list = get_mbed_official_psa_release (options .mcu )
272+
273+ for target , tc , directory in psa_platforms_list :
274+ build_psa_platform (target , tc , directory , options .debug , options .commit )
197275
198276
199277if __name__ == '__main__' :
0 commit comments