2 ''''export SCRIPT_PATH="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" # '''
3 ''''export PY_PATH=${SCRIPT_PATH}/venv/bin/python # '''
4 ''''test -f ${PY_PATH} && exec ${PY_PATH} "$0" "$@" # '''
5 ''''echo "Error: Virtual environment not found. Please run 'one-prepare-venv' command." # '''
8 # Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
10 # Licensed under the Apache License, Version 2.0 (the "License");
11 # you may not use this file except in compliance with the License.
12 # You may obtain a copy of the License at
14 # http://www.apache.org/licenses/LICENSE-2.0
16 # Unless required by applicable law or agreed to in writing, software
17 # distributed under the License is distributed on an "AS IS" BASIS,
18 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 # See the License for the specific language governing permissions and
20 # limitations under the License.
30 from types import SimpleNamespace
32 import onelib.backends as backends
33 import onelib.utils as oneutils
35 # TODO Find better way to suppress trackback on error
36 sys.tracebacklimit = 0
39 def _get_parser(backends_list):
40 codegen_usage = 'one-codegen [-h] [-v] [-C CONFIG] [-b BACKEND] [--] [COMMANDS FOR BACKEND]'
41 parser = argparse.ArgumentParser(
42 description='command line tool for code generation', usage=codegen_usage)
44 oneutils.add_default_arg(parser)
46 # get backend list in the directory
47 backends_name = [ntpath.basename(f) for f in backends_list]
49 backends_name_message = '(There is no available backend drivers)'
51 backends_name_message = '(available backend drivers: ' + ', '.join(
53 backend_help_message = 'backend name to use ' + backends_name_message
54 parser.add_argument('-b', '--backend', type=str, help=backend_help_message)
59 def _verify_arg(parser, args, cfg_args, backend_args, unknown_args):
60 """verify given arguments"""
61 cmd_backend_exist = oneutils.is_valid_attr(args, 'backend')
62 cfg_backend_exist = oneutils.is_valid_attr(cfg_args, 'backend')
63 cfg_backends_exist = oneutils.is_valid_attr(cfg_args, 'backends')
65 # check if required arguments is given
67 if not cmd_backend_exist and not cfg_backend_exist and not cfg_backends_exist:
68 missing.append('-b/--backend')
70 parser.error('the following arguments are required: ' + ' '.join(missing))
72 if not oneutils.is_valid_attr(args, 'config'):
73 if not backend_args and not unknown_args:
74 parser.error('commands for the backend is missing.')
76 if cfg_backend_exist and cfg_backends_exist:
78 '\'backend\' option and \'backends\' option cannot be used simultaneously.')
80 # Check if given backend from command line exists in the configuration file
81 if cmd_backend_exist and cfg_backend_exist:
82 if args.backend != cfg_args.backend:
83 parser.error('Not found the command of given backend')
85 if cfg_backend_exist and not oneutils.is_valid_attr(cfg_args, 'command'):
86 parser.error('\'command\' key is missing in the configuration file.')
88 if cfg_backends_exist:
89 cfg_backends = getattr(cfg_args, 'backends').split(',')
90 # check if commands of given backends exist
91 for b in cfg_backends:
92 if not oneutils.is_valid_attr(cfg_args, b):
93 parser.error('Not found the command for ' + b)
95 # Check if given backend from command line exists in the configuration file
97 if args.backend not in cfg_backends:
98 parser.error('Not found the command of given backend')
101 def _parse_arg(parser):
105 argv = copy.deepcopy(sys.argv)
109 args = [list(y) for x, y in itertools.groupby(argv, lambda z: z == '--') if not x]
111 codegen_args = parser.parse_args(codegen_args)
112 # one-codegen has two interfaces
113 # 1. one-codegen [-h] [-v] [-C CONFIG] [-b BACKEND] [COMMANDS FOR BACKEND]
115 codegen_args = args[0]
116 codegen_args, unknown_args = parser.parse_known_args(codegen_args)
117 # 2. one-codegen [-h] [-v] [-C CONFIG] [-b BACKEND] -- [COMMANDS FOR BACKEND]
119 codegen_args = args[0]
120 backend_args = args[1]
121 codegen_args = parser.parse_args(codegen_args)
123 if len(args) and codegen_args.version:
124 oneutils.print_version_and_exit(__file__)
126 return codegen_args, backend_args, unknown_args
131 backends_list = backends.get_list('compile')
134 parser = _get_parser(backends_list)
135 args, backend_args, unknown_args = _parse_arg(parser)
137 # parse configuration file
138 cfg_args = SimpleNamespace()
139 oneutils.parse_cfg(args.config, 'one-codegen', cfg_args)
141 # parse configuration file (args has arguments parsed from command line + cfg)
142 # oneutils.parse_cfg(args.config, 'one-codegen', args)
145 _verify_arg(parser, args, cfg_args, backend_args, unknown_args)
147 one-codegen defines its behavior for below cases.
151 [3] one-codegen -C ${cfg} (backend, command key in cfg)
152 [4] one-codegen -C ${cfg} (backends key in cfg)
153 [5] one-codegen -b ${backend} ${command}
154 [6] one-codegen -b ${backend} -- ${command}
155 [7] one-codegen -b ${backend} -C {cfg} (backend, command key in cfg)
156 [8] one-codegen -b ${backend} -C {cfg} (backends key in cfg) (Only 'backend' is invoked,
157 even though cfg file has multiple backends)
158 [9] one-codegen -b ${backend} -C ${cfg} -- ${command} (backend, command key in cfg)
159 [10] one-codegen -b ${backend} -C ${cfg} -- ${command} (backends key in cfg) (Only 'backend' is invoked,
160 even though cfg file has multiple backends)
162 All other cases are not allowed or an undefined behavior.
164 cmd_overwrite = False
165 if oneutils.is_valid_attr(args, 'config'):
167 if backend_args and not unknown_args:
168 given_backends = [args.backend]
172 if oneutils.is_valid_attr(args, 'backend'):
173 given_backends = [args.backend]
174 if oneutils.is_valid_attr(cfg_args, 'backend'):
175 assert (oneutils.is_valid_attr(cfg_args, 'command'))
176 setattr(cfg_args, args.backend, cfg_args.command)
179 if oneutils.is_valid_attr(cfg_args, 'backend'):
180 assert (oneutils.is_valid_attr(cfg_args, 'command'))
181 given_backends = [cfg_args.backend]
182 setattr(cfg_args, cfg_args.backend, cfg_args.command)
184 if oneutils.is_valid_attr(cfg_args, 'backends'):
185 given_backends = cfg_args.backends.split(',')
188 assert (backend_args or unknown_args)
189 given_backends = [args.backend]
191 for given_backend in given_backends:
192 # make a command to run given backend driver
194 backend_base = given_backend + '-compile'
195 for cand in backends_list:
196 if ntpath.basename(cand) == backend_base:
199 # Find backend from system path
200 codegen_path = shutil.which(backend_base)
203 raise FileNotFoundError(backend_base + ' not found')
205 codegen_cmd = [codegen_path]
206 if not cmd_overwrite and oneutils.is_valid_attr(cfg_args, given_backend):
207 codegen_cmd += getattr(cfg_args, given_backend).split()
209 codegen_cmd += backend_args
210 codegen_cmd += unknown_args
213 oneutils.run(codegen_cmd, err_prefix=backend_base)
216 if __name__ == '__main__':
217 oneutils.safemain(main, __file__)