blob: e6e2b346be90c5e613e85b9e0e1bc1a9187b6616 [file] [log] [blame]
Pavel Macenauer59e057f2020-04-15 14:17:26 +00001#!/usr/bin/env python3
Richard Burtondc0c6ed2020-04-08 16:39:05 +01002# Copyright © 2020 Arm Ltd. All rights reserved.
Pavel Macenauer59e057f2020-04-15 14:17:26 +00003# Copyright 2020 NXP
Richard Burtondc0c6ed2020-04-08 16:39:05 +01004# SPDX-License-Identifier: MIT
Pavel Macenauer59e057f2020-04-15 14:17:26 +00005"""This script executes SWIG commands to generate armnn and armnn version wrappers.
Richard Burtondc0c6ed2020-04-08 16:39:05 +01006This script cannot be moved to ./script dir because it uses find_armnn function from setup.py script.
7Both scripts must be in the same folder.
8"""
9import os
10import re
11import subprocess
Pavel Macenauer59e057f2020-04-15 14:17:26 +000012import argparse
Richard Burtondc0c6ed2020-04-08 16:39:05 +010013
14from setup import find_includes
15
Pavel Macenauer59e057f2020-04-15 14:17:26 +000016__current_dir = os.path.dirname(os.path.realpath(__file__))
17__swig_exec = None
18__verbose = False
19
20SWIG_EXEC_ENV = "SWIG_EXECUTABLE"
Richard Burtondc0c6ed2020-04-08 16:39:05 +010021
22
Pavel Macenauer59e057f2020-04-15 14:17:26 +000023def get_swig_exec(swig_exec_env: str = SWIG_EXEC_ENV):
24 """Returns the swig command. Uses either an env variable or the `swig` command
25 and verifies it works.
26
27 Args:
28 swig_exec_env(str): Env variable pointing to the swig executable.
29
30 Returns:
31 str: Path to swig executable.
32
33 Raises:
34 RuntimeError: If unable to execute any version of swig.
35 """
36 swig_exec = os.getenv(swig_exec_env)
37 if swig_exec is None:
38 swig_exec = "swig"
39 if subprocess.Popen([swig_exec, "-version"], stdout=subprocess.DEVNULL):
40 return swig_exec
41 else:
42 raise RuntimeError("Unable to execute swig.")
43
44
45def check_swig_version(expected_version: str):
46 """Checks version of swig.
47
48 Args:
49 expected_version(str): String containing expected version.
50
51 Returns:
52 bool: True if version is correct, False otherwise
53 """
54 cmd = subprocess.Popen([__swig_exec, "-version"], stdout=subprocess.PIPE)
55 out, _ = cmd.communicate()
Richard Burtondc0c6ed2020-04-08 16:39:05 +010056
57 pattern = re.compile(r"(?<=Version ).+(?=$)", re.MULTILINE)
Pavel Macenauer59e057f2020-04-15 14:17:26 +000058 match = pattern.search(out.decode('utf-8'))
Richard Burtondc0c6ed2020-04-08 16:39:05 +010059
60 if match:
61 version_string = match.group(0).strip()
Pavel Macenauer59e057f2020-04-15 14:17:26 +000062 if __verbose:
63 print(f"SWIG version: {version_string}")
64 return version_string.startswith(expected_version)
Richard Burtondc0c6ed2020-04-08 16:39:05 +010065 else:
Richard Burtondc0c6ed2020-04-08 16:39:05 +010066 return False
67
68
Pavel Macenauer59e057f2020-04-15 14:17:26 +000069def generate_wrap(name: str, extr_includes):
70 """Generates the python wrapper using swig.
Richard Burtondc0c6ed2020-04-08 16:39:05 +010071
Pavel Macenauer59e057f2020-04-15 14:17:26 +000072 Args:
73 name(str): Name of the wrapper template.
74 extr_includes(str): Include paths.
Richard Burtondc0c6ed2020-04-08 16:39:05 +010075
Pavel Macenauer59e057f2020-04-15 14:17:26 +000076 Raises:
77 RuntimeError: If wrapper fails to be generated.
78 """
79 in_dir = os.path.join(__current_dir, "src", "pyarmnn", "swig")
80 out_dir = os.path.join(__current_dir, "src", "pyarmnn", "_generated")
81 if __verbose:
82 print(f"Generating wrap for {name} ...")
83 code = os.system(f"{__swig_exec} -c++ -python -Wall "
84 + "-o {} ".format(os.path.join(out_dir, f"{name}_wrap.cpp"))
85 + f"-outdir {out_dir} "
86 + f"{extr_includes} "
87 + f"-I{in_dir} "
88 + os.path.join(in_dir, f"{name}.i"))
Richard Burtondc0c6ed2020-04-08 16:39:05 +010089 if code != 0:
90 raise RuntimeError(f"Failed to generate {name} ext.")
91
92
93if __name__ == "__main__":
Pavel Macenauer59e057f2020-04-15 14:17:26 +000094 __swig_exec = get_swig_exec()
95
96 # This check is redundant in case CMake is used, it's here for standalone use
97 if not check_swig_version('4.'):
Richard Burtondc0c6ed2020-04-08 16:39:05 +010098 raise RuntimeError("Wrong swig version was found. Expected SWIG version is 4.x.x")
99
100 armnn_includes = find_includes()
101
Pavel Macenauer59e057f2020-04-15 14:17:26 +0000102 parser = argparse.ArgumentParser("Script to generate SWIG wrappers.")
103 parser.add_argument("-v", "--verbose", help="Verbose output.", action="store_true")
104 args = parser.parse_args()
Richard Burtondc0c6ed2020-04-08 16:39:05 +0100105
Pavel Macenauer59e057f2020-04-15 14:17:26 +0000106 __verbose = args.verbose
Richard Burtondc0c6ed2020-04-08 16:39:05 +0100107
wangg5f960d92020-08-26 01:44:32 +0000108 wrap_names = ['armnn_version',
109 'armnn',
wangg5f960d92020-08-26 01:44:32 +0000110 'armnn_onnxparser',
wangg5f960d92020-08-26 01:44:32 +0000111 'armnn_tfliteparser',
112 'armnn_deserializer']
Richard Burtondc0c6ed2020-04-08 16:39:05 +0100113
Pavel Macenauer59e057f2020-04-15 14:17:26 +0000114 for n in wrap_names:
Francis Murtagh55c87b72020-10-12 16:45:49 +0100115 generate_wrap(n, f"-I{' -I'.join(armnn_includes)} ")