Skip to content

Commit 3135d0f

Browse files
committed
TF-M build script
Create a script (tools/psa/build_tfm.py) to build Trusted Firmware M (TF-M) image. Current version of the script only clones the TF-M git repo and its dependencies and computes the version information of TF-M repo and write it to 'features/FEATURE_PSA/FEATURE_TFM/VERSION.txt' Signed-off-by: Devaraj Ranganna <[email protected]>
1 parent 237ad40 commit 3135d0f

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

tools/psa/build_tfm.py

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
"""
2+
Copyright (c) 2019 ARM Limited. All rights reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
"""
18+
19+
import os
20+
from os.path import join, abspath, dirname, isdir
21+
import sys
22+
import shutil
23+
import subprocess
24+
import logging
25+
26+
logger = logging.getLogger('TF-M-Builder')
27+
logging.basicConfig(level=logging.INFO,
28+
format='[%(name)s] %(asctime)s: %(message)s.',
29+
datefmt='%H:%M:%S')
30+
31+
ROOT = abspath(join(dirname(__file__), os.pardir, os.pardir))
32+
sys.path.insert(0, ROOT)
33+
34+
TF_M_BUILD_DIR = join(ROOT, os.pardir, 'tfm_build_dir')
35+
VERSION_FILE_PATH = join(ROOT, 'features/FEATURE_PSA/FEATURE_TFM')
36+
37+
dependencies = {
38+
"trusted-firmware-m":
39+
['https://git.trustedfirmware.org/trusted-firmware-m.git',
40+
'feature-twincpu'],
41+
"mbedtls": ['https://github.com/ARMmbed/mbedtls.git',
42+
'mbedtls-2.7.9'],
43+
"mbed-crypto": ['https://github.com/ARMmbed/mbed-crypto.git',
44+
'mbedcrypto-1.1.0'],
45+
"CMSIS_5": ['https://github.com/ARM-software/CMSIS_5.git', '5.5.0'],
46+
}
47+
48+
def is_git_installed():
49+
"""
50+
Check if git is installed
51+
"""
52+
command = ['git', '--version']
53+
try:
54+
with open(os.devnull, 'w') as fnull:
55+
return subprocess.call(command, stdout=fnull, stderr=fnull)
56+
except OSError as e:
57+
return e.errno
58+
59+
def is_git_lfs_installed():
60+
"""
61+
Check if git-lfs is installed
62+
"""
63+
command = ['git-lfs', '--version']
64+
try:
65+
with open(os.devnull, 'w') as fnull:
66+
return subprocess.call(command, stdout=fnull, stderr=fnull)
67+
except OSError as e:
68+
return e.errno
69+
70+
def run_cmd_and_return_output(command):
71+
"""
72+
Run the command in the sytem and return output.
73+
Commands are passed as a list of tokens.
74+
E.g. The command 'git remote -v' would be passed in as:
75+
['git', 'remote', '-v']
76+
77+
:param command: System command as a list of tokens
78+
"""
79+
output = ''
80+
logger.debug('[Exec] %s', ' '.join(command))
81+
try:
82+
with open(os.devnull, 'w') as fnull:
83+
output = subprocess.check_output(command, stderr=fnull)
84+
except subprocess.CalledProcessError as e:
85+
logger.error("The command %s failed with return code: %s",
86+
(' '.join(command)), e.returncode)
87+
clean_up_cloned_repos()
88+
return output.decode("utf-8")
89+
90+
def detect_and_write_tfm_version(tfm_dir):
91+
"""
92+
Identify the version of TF-M and write it to VERSION.txt
93+
:param tfm_dir: The filesystem path where TF-M repo is cloned
94+
"""
95+
cmd = ['git', '-C', tfm_dir, 'describe', '--tags',
96+
'--abbrev=12', '--dirty', '--always']
97+
tfm_version = run_cmd_and_return_output(cmd)
98+
logger.info('TF-M version: %s', tfm_version.strip('\n'))
99+
if not isdir(VERSION_FILE_PATH):
100+
os.makedirs(VERSION_FILE_PATH)
101+
with open(join(VERSION_FILE_PATH, 'VERSION.txt'), 'w') as f:
102+
f.write(tfm_version)
103+
104+
def check_repo_version(name, deps):
105+
"""
106+
Compare the version of cloned and expected and exit if they dont match
107+
:param name: Name of the git repository
108+
:param deps: Dictionary containing dependency details
109+
"""
110+
basedir = TF_M_BUILD_DIR
111+
if name == 'trusted-firmware-m':
112+
cmd = ['git', '-C', join(basedir, name),
113+
'rev-parse', '--abbrev-ref', 'HEAD']
114+
else:
115+
cmd = ['git', '-C', join(basedir, name),
116+
'describe', '--tags']
117+
_out = run_cmd_and_return_output(cmd)
118+
if _out.strip('\n') != deps.get(name)[1]:
119+
logger.error('Conflict: cloned "%s" and expected "%s"',
120+
_out.strip('\n'), deps.get(name)[1])
121+
logger.error('check and remove folder %s',
122+
join(basedir, name))
123+
sys.exit(1)
124+
else:
125+
logger.info('%s: version check OK', name)
126+
127+
def check_and_clone_repo(name, deps):
128+
"""
129+
Test if the repositories are already cloned. If not clone them
130+
:param name: Name of the git repository
131+
:param deps: Dictionary containing dependency details
132+
"""
133+
basedir = TF_M_BUILD_DIR
134+
if not isdir(join(basedir, name)):
135+
logger.info('Cloning %s repo', name)
136+
cmd = ['git', '-C', basedir, 'clone', '-b',
137+
deps.get(name)[1], deps.get(name)[0]]
138+
_out = run_cmd_and_return_output(cmd)
139+
logger.info('Cloned %s repo successfully', name)
140+
else:
141+
logger.info('%s repo exists, checking git version...', name)
142+
check_repo_version(name, deps)
143+
144+
def clone_tfm_repo():
145+
"""
146+
Clone TF-M git repos and it's dependencies
147+
"""
148+
check_and_clone_repo('trusted-firmware-m', dependencies)
149+
check_and_clone_repo('mbedtls', dependencies)
150+
check_and_clone_repo('mbed-crypto', dependencies)
151+
check_and_clone_repo('CMSIS_5', dependencies)
152+
detect_and_write_tfm_version(join(TF_M_BUILD_DIR, 'trusted-firmware-m'))
153+
154+
def clean_up_cloned_repos():
155+
"""
156+
Clean up cloned repos in case of any errors
157+
"""
158+
try:
159+
shutil.rmtree(TF_M_BUILD_DIR)
160+
except OSError as e:
161+
logger.error('Unable to cleanup cloned repos')
162+
logger.error('"%s" occured', e.strerror)
163+
164+
def main():
165+
"""
166+
Build Trusted Firmware M (TF-M) image for mbed-os supported TF-M targets.
167+
Current version of the script only clones TF-M git repo and dependencies
168+
and creates a VERSION.txt file under 'features/FEATURE_PSA/FEATURE_TFM'
169+
"""
170+
if not isdir(TF_M_BUILD_DIR):
171+
os.mkdir(TF_M_BUILD_DIR)
172+
clone_tfm_repo()
173+
174+
if __name__ == '__main__':
175+
if is_git_installed() != 0:
176+
logger.error('"git" is not installed. Exiting...')
177+
elif is_git_lfs_installed() != 0:
178+
logger.error('"git-lfs" is not installed. Exiting...')
179+
else:
180+
main()

0 commit comments

Comments
 (0)