21
21
import shutil
22
22
from argparse import ArgumentParser
23
23
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 ))
25
26
sys .path .insert (0 , ROOT )
26
27
from tools .targets import Target , TARGET_MAP , TARGET_NAMES
27
28
28
29
MAKE_PY_LOCATTION = os .path .join (ROOT , 'tools' , 'make.py' )
29
30
TEST_PY_LOCATTION = os .path .join (ROOT , 'tools' , 'test.py' )
30
- MBED_PSA_TESTS = '*psa-spm*,*psa-crypto_access_control'
31
31
TFM_MBED_APP = os .path .join (ROOT , 'tools' , 'psa' , 'tfm' , 'mbed_app.json' )
32
+ MBED_PSA_TESTS = '*psa-spm*,*psa-crypto_access_control'
32
33
TFM_TESTS = {
33
34
'*psa-spm_smoke' : ['USE_PSA_TEST_PARTITIONS' , 'USE_SMOKE_TESTS_PART1' ],
34
35
'*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' ]
37
40
}
38
41
39
42
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 ])
42
70
43
71
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
+ """
45
80
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 ))
60
90
61
91
return psa_targets_release_list
62
92
63
93
64
94
def 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
+ """
65
100
with open (os .path .join (build_dir , '.mbedignore' ), 'w' ) as f :
66
101
f .write ('*\n ' )
67
102
68
103
69
104
def 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 ([
71
113
sys .executable , '-u' , TEST_PY_LOCATTION ,
72
114
'--greentea' ,
73
115
'--profile' , profile ,
74
116
'-t' , toolchain ,
75
117
'-m' , target ,
76
118
'--source' , ROOT ,
77
119
'--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' ),
80
124
'-n' , MBED_PSA_TESTS
81
- ])
125
+ ], stdout = subprocess . PIPE )
82
126
83
- subprocess .call ([
127
+ subprocess .check_call ([
84
128
sys .executable , '-u' , MAKE_PY_LOCATTION ,
85
129
'-t' , toolchain ,
86
130
'-m' , target ,
87
131
'--profile' , profile ,
88
132
'--source' , ROOT ,
89
133
'--build' , os .path .join (ROOT , 'BUILD' , target ),
90
134
'--artifact-name' , 'psa_release_1.0'
91
- ])
135
+ ], stdout = subprocess . PIPE )
92
136
93
137
94
138
def _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
+ """
95
145
return ['-D{}' .format (define ) for define in TFM_TESTS [test ]]
96
146
97
147
98
148
def 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
+ """
99
156
for test in TFM_TESTS .keys ():
100
- subprocess .call ([
157
+ subprocess .check_call ([
101
158
sys .executable , '-u' , TEST_PY_LOCATTION ,
102
159
'--greentea' ,
103
160
'--profile' , profile ,
104
161
'-t' , toolchain ,
105
162
'-m' , target ,
106
163
'--source' , ROOT ,
107
164
'--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 ([
113
173
sys .executable , '-u' , MAKE_PY_LOCATTION ,
114
174
'-t' , toolchain ,
115
175
'-m' , target ,
116
176
'--profile' , profile ,
117
177
'--source' , ROOT ,
118
178
'--build' , os .path .join (ROOT , 'BUILD' , target ),
119
179
'--app-config' , TFM_MBED_APP
120
- ])
180
+ ], stdout = subprocess . PIPE )
121
181
122
182
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.
129
186
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 ([
133
192
'git' ,
134
193
'-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
+ """
143
225
profile = 'debug' if debug else 'release'
144
226
if _psa_backend (target ) is 'TFM' :
145
227
build_tfm_platform (target , toolchain , profile )
146
228
else :
147
229
build_mbed_spm_platform (target , toolchain , profile )
148
230
149
231
if git_commit :
150
- commit_biannries (target , delivery_dir )
232
+ commit_binaries (target , delivery_dir )
151
233
152
234
153
235
def get_parser ():
154
236
parser = ArgumentParser ()
155
237
parser .add_argument ("-m" , "--mcu" ,
156
238
help = "build for the given MCU" ,
157
- default = '*' ,
239
+ default = None ,
158
240
metavar = "MCU" )
159
241
160
242
parser .add_argument ("-d" , "--debug" ,
@@ -170,30 +252,26 @@ def get_parser():
170
252
return parser
171
253
172
254
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
+ """
183
259
build_dir = os .path .join (ROOT , 'BUILD' )
184
260
if os .path .exists (build_dir ):
185
261
shutil .rmtree (build_dir )
186
262
187
263
os .makedirs (build_dir )
188
264
create_mbed_ignore (build_dir )
189
- target_filter_function = None
190
- psa_platforms_list = get_mbed_official_psa_release ()
191
265
192
- if options .mcu is not '*' :
193
- target_filter_function = filter_target (options .mcu )
194
266
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 )
197
275
198
276
199
277
if __name__ == '__main__' :
0 commit comments