def extract_java_system_properties(unit, args): props = [] if len(args) % 2: print>>sys.stderr, 'wrong use of SYSTEM_PROPERTIES in {}: odd number of arguments'.format(unit.path()) # TODO: configure error return [] for x, y in zip(args[::2], args[1::2]): if x == 'FILE': if y.startswith('${BINDIR}') or y.startswith('${ARCADIA_BUILD_ROOT}') or y.startswith('/'): print>>sys.stderr, 'wrong use of SYSTEM_PROPERTIES in {}: absolute/build file path {}'.format(unit.path(), y) # TODO: configure error continue y = _common.rootrel_arc_src(y, unit) if not os.path.exists(unit.resolve('$S/' + y)): print>>sys.stderr, 'wrong use of SYSTEM_PROPERTIES in {}: can\'t resolve {}'.format(unit.path(), y) # TODO: configure error continue y = '${ARCADIA_ROOT}/' + y props.append({'type': 'file', 'path': y}) else: props.append({'type': 'inline', 'key': x, 'value': y}) return props
def onresource_files(unit, *args): """ RESOURCE_FILES([PREFIX {prefix}] {path}) expands into RESOURCE({path} resfs/file/{prefix}{path} - resfs/src/resfs/file/{prefix}{path}={rootrel_arc_src(path)} ) resfs/src/{key} stores a source root (or build root) relative path of the source of the value of the {key} resource. resfs/file/{key} stores any value whose source was a file on a filesystem. resfs/src/resfs/file/{key} must store its path. This form is for use from other plugins: RESOURCE_FILES([DEST {dest}] {path}) expands into RESOURCE({path} resfs/file/{dest}) """ prefix = '' dest = None res = [] args = iter(args) for arg in args: if arg == 'PREFIX': prefix, dest = next(args), None elif arg == 'DEST': dest, prefix = next(args), None else: path = arg key = 'resfs/file/' + (dest or (prefix + path)) src = 'resfs/src/{}={}'.format(key, rootrel_arc_src(path, unit)) res += ['-', src, path, key] unit.onresource(res)
def onpy_srcs(unit, *args): """ PY_SRCS() - is rule to build extended versions of Python interpreters and containing all application code in its executable file. It can be used to collect only the executables but not shared libraries, and, in particular, not to collect the modules that are imported using import directive. The main disadvantage is the lack of IDE support; There is also no readline yet. The application can be collect from any of the sources from which the C library, and with the help of PY_SRCS .py , .pyx,.proto and .swg files. At the same time extensions for Python on C language generating from .pyx and .swg, will be registered in Python's as built-in modules, and sources on .py are stored as static data: when the interpreter starts, the initialization code will add a custom loader of these modules to sys.meta_path. By default .pyx files are collected as C++-extensions. To collect them as C (similar to BUILDWITH_CYTHON_C, but with the ability to specify namespace), you must specify the Directive CYTHON_C. Building with pyx automatically registers modules, you do not need to call PY_REGISTER for them __init__.py never required, but if present (and specified in PY_SRCS), it will be imported when you import package modules with __init__.py Oh. Example of library declaration with PY_SRCS(): PY_LIBRARY(mymodule) PY_SRCS({| CYTHON_C} { | TOP_LEVEL | NAMESPACE ns} a.py sub/dir/b.py e.proto sub/dir/f.proto c.pyx sub/dir/d.pyx g.swg sub/dir/h.swg) END() Documentation: https://wiki.yandex-team.ru/devtools/commandsandvars/py_srcs/ """ # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. unit.onuse_python([]) if '/library/python/runtime' not in unit.path(): unit.onpeerdir(['library/python/runtime']) is_program = unit.get('MODULE_TYPE') == 'PROGRAM' if is_program: py_program(unit) py_namespace_value = unit.get('PY_NAMESPACE_VALUE') if py_namespace_value == ".": ns = "" else: ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_coverage = unit.get('CYTHON_COVERAGE') == 'yes' optimize_proto = unit.get('OPTIMIZE_PY_PROTOS_FLAG') == 'yes' cython_includes = [] for path in unit.includes(): cython_includes += ['-I', resolve_to_ymake_path(path)] cython_directives = [] if cython_coverage: cython_directives += ['-X', 'linetrace=True'] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] protos = [] evs = [] swigs = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: main_mod = arg == 'MAIN' if main_mod: arg = next(args) if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: if arg.startswith('../'): ymake.report_configure_error( 'PY_SRCS item starts with "../": {!r}'.format(arg)) mod = ns + stripext(arg).replace('/', '.') if main_mod: unit.onpy_main(mod) pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) elif path.endswith('.proto'): protos.append(pathmod) elif path.endswith('.ev'): evs.append(pathmod) elif path.endswith('.swg'): swigs.append(path) # ignore mod, use last (and only) ns else: ymake.report_configure_error( 'in PY_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: files2res = set() if cython_coverage: def process_pyx(filename, path, out_suffix): # skip generated files if not is_arc_src(path, unit): return # source file files2res.add((filename, path)) # generated files2res.add((filename + out_suffix, path + out_suffix)) # used includes for entry in parse_pyx_includes(filename, path, unit.resolve('$S')): files2res.add(entry) else: def process_pyx(filename, path, out_suffix): pass for pyxs, cython, out_suffix in [ (pyxs_c, unit.onbuildwith_cython_c, ".c"), (pyxs_cpp, unit.onbuildwith_cython_cpp, ".cpp"), ]: for path, mod in pyxs: filename = rootrel_arc_src(path, unit) cython([ path, '--module-name', mod, '--init-suffix', mangle(mod), '--source-root', '${ARCADIA_ROOT}', # set arcadia root relative __file__ for generated modules '-X', 'set_initial_path={}'.format(filename), ] + cython_includes + cython_directives) unit.onpy_register([mod]) process_pyx(filename, path, out_suffix) if files2res: # Compile original and generated sources into target for proper cython coverage calculation unit.onresource_files( [x for name, path in files2res for x in ('DEST', name, path)]) if pys: pys_seen = set() pys_dups = {m for _, m in pys if (m in pys_seen or pys_seen.add(m))} if pys_dups: ymake.report_configure_error( 'Duplicate(s) is found in the PY_SRCS macro: {}'.format( pys_dups)) res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) unit.onpy_compile_bytecode([root_rel_path + '-', path]) key = '/py_modules/' + mod res += [ path, key, '-', 'resfs/src/{}={}'.format(key, root_rel_path), path + '.yapyc', '/py_code/' + mod, ] unit.onresource(res) add_python_lint_checks(unit, [path for path, mod in pys]) if protos: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) grpc = unit.get('GRPC_FLAG') == 'yes' if grpc: unit.onpeerdir(['contrib/libs/grpc/python', 'contrib/libs/grpc']) proto_paths = [path for path, mod in protos] unit.ongenerate_py_protos(proto_paths) unit.onpy_srcs([pb2_arg(path, mod, unit) for path, mod in protos]) if grpc: unit.onpy_srcs( [pb2_grpc_arg(path, mod, unit) for path, mod in protos]) if optimize_proto: unit.onsrcs(proto_paths) pb_cc_outs = [pb_cc_arg(path, unit) for path in proto_paths] if grpc: pb_cc_outs += [pb_grpc_arg(path, unit) for path in proto_paths] for pb_cc_outs_chunk in generate_chunks(pb_cc_outs, 10): if is_program: unit.onjoin_srcs( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk) else: unit.onjoin_srcs_global( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk) if evs: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) unit.ongenerate_py_evs([path for path, mod in evs]) unit.onpy_srcs([ev_arg(path, mod, unit) for path, mod in evs]) if optimize_proto: unit.onsrcs([path for path, mod in evs]) pb_cc_outs = [ev_cc_arg(path, unit) for path, _ in evs] for pb_cc_outs_chunk in generate_chunks(pb_cc_outs, 10): if is_program: unit.onjoin_srcs( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk) else: unit.onjoin_srcs_global( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk) if swigs: unit.onsrcs(swigs) prefix = unit.get('MODULE_PREFIX') project = unit.get('REALPRJNAME') unit.onpy_register([prefix + project]) path = '${ARCADIA_BUILD_ROOT}/' + '{}/{}.py'.format( unit.path()[3:], project) arg = '{}={}'.format(path, ns + project.replace('/', '.')) unit.onpy_srcs([arg])
def to_build_root(path, unit): if is_arc_src(path, unit): return '${ARCADIA_BUILD_ROOT}/' + rootrel_arc_src(path, unit) return path
def onpy_srcs(unit, *args): """ @usage PY_SRCS({| CYTHON_C} { | TOP_LEVEL | NAMESPACE ns} Files...) PY_SRCS() - is rule to build extended versions of Python interpreters and containing all application code in its executable file. It can be used to collect only the executables but not shared libraries, and, in particular, not to collect the modules that are imported using import directive. The main disadvantage is the lack of IDE support; There is also no readline yet. The application can be collect from any of the sources from which the C library, and with the help of PY_SRCS .py , .pyx,.proto and .swg files. At the same time extensions for Python on C language generating from .pyx and .swg, will be registered in Python's as built-in modules, and sources on .py are stored as static data: when the interpreter starts, the initialization code will add a custom loader of these modules to sys.meta_path. By default .pyx files are collected as C++-extensions. To collect them as C (similar to BUILDWITH_CYTHON_C, but with the ability to specify namespace), you must specify the Directive CYTHON_C. Building with pyx automatically registers modules, you do not need to call PY_REGISTER for them __init__.py never required, but if present (and specified in PY_SRCS), it will be imported when you import package modules with __init__.py Oh. Example of library declaration with PY_SRCS(): PY2_LIBRARY(mymodule) PY_SRCS(a.py sub/dir/b.py e.proto sub/dir/f.proto c.pyx sub/dir/d.pyx g.swg sub/dir/h.swg) END() PY_REGISTER honors Python2 and Python3 differences and adjusts itself to Python version of a current module Documentation: https://wiki.yandex-team.ru/arcadia/python/pysrcs/#modulipylibrarypy3libraryimakrospysrcs """ # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. upath = unit.path()[3:] py3 = is_py3(unit) with_py = not unit.get('PYBUILD_NO_PY') with_pyc = not unit.get('PYBUILD_NO_PYC') in_proto_library = unit.get('PY_PROTO') or unit.get('PY3_PROTO') need_gazetteer_peerdir = False if not upath.startswith('contrib/tools/python') and not upath.startswith( 'library/python/runtime') and unit.get('NO_PYTHON_INCLS') != 'yes': unit.onpeerdir(['contrib/libs/python']) unit_needs_main = unit.get('MODULE_TYPE') in ('PROGRAM', 'DLL') if unit_needs_main: py_program(unit, py3) py_namespace_value = unit.get('PY_NAMESPACE_VALUE') if py_namespace_value == ".": ns = "" else: ns = (unit.get('PY_NAMESPACE_VALUE') or upath.replace('/', '.')) + '.' cython_coverage = unit.get('CYTHON_COVERAGE') == 'yes' cythonize_py = False optimize_proto = unit.get('OPTIMIZE_PY_PROTOS_FLAG') == 'yes' cython_directives = [] if cython_coverage: cython_directives += ['-X', 'linetrace=True'] pyxs_c = [] pyxs_c_h = [] pyxs_c_api_h = [] pyxs_cpp = [] pyxs = pyxs_cpp swigs_c = [] swigs_cpp = [] swigs = swigs_cpp pys = [] protos = [] evs = [] dump_dir = unit.get('PYTHON_BUILD_DUMP_DIR') dump_output = None if dump_dir: import thread pid = os.getpid() tid = thread.get_ident() dump_name = '{}-{}.dump'.format(pid, tid) dump_output = open(os.path.join(dump_dir, dump_name), 'a') args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_C_H': pyxs = pyxs_c_h elif arg == 'CYTHON_C_API_H': pyxs = pyxs_c_api_h elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] elif arg == 'CYTHONIZE_PY': cythonize_py = True # SWIG. elif arg == 'SWIG_C': swigs = swigs_c elif arg == 'SWIG_CPP': swigs = swigs_cpp # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or not in_proto_library and arg.endswith( '.gztproto'): pass # Sources. else: main_mod = arg == 'MAIN' if main_mod: arg = next(args) if '=' in arg: main_py = False path, mod = arg.split('=', 1) else: if arg.endswith('.gztproto'): need_gazetteer_peerdir = True path = '{}.proto'.format(arg[:-9]) else: path = arg main_py = (path == '__main__.py' or path.endswith('/__main__.py')) if not py3 and unit_needs_main and main_py: mod = '__main__' else: if arg.startswith('../'): ymake.report_configure_error( 'PY_SRCS item starts with "../": {!r}'.format(arg)) if arg.startswith('/'): ymake.report_configure_error( 'PY_SRCS item starts with "/": {!r}'.format(arg)) continue mod = ns + stripext(arg).replace('/', '.') if py3 and mod == '__main__': ymake.report_configure_error( 'TOP_LEVEL __main__.py is not allowed in PY3_PROGRAM') if main_mod: py_main(unit, mod + ":main") elif py3 and unit_needs_main and main_py: py_main(unit, mod) pathmod = (path, mod) if dump_output is not None: dump_output.write('{path}\t{module}\n'.format( path=rootrel_arc_src(path, unit), module=mod)) if path.endswith('.py'): if cythonize_py: pyxs.append(pathmod) else: pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) elif path.endswith('.proto'): protos.append(pathmod) elif path.endswith('.ev'): evs.append(pathmod) elif path.endswith('.swg'): swigs.append(pathmod) # Allow pyi files in PY_SRCS for autocomplete in IDE, but skip it during building elif path.endswith('.pyi'): pass else: ymake.report_configure_error( 'in PY_SRCS: unrecognized arg {!r}'.format(path)) if dump_output is not None: dump_output.close() if pyxs: files2res = set() # Include map stores files which were included in the processing pyx file, # to be able to find source code of the included file inside generated file # for currently processing pyx file. include_map = collections.defaultdict(set) if cython_coverage: def process_pyx(filename, path, out_suffix, noext): # skip generated files if not is_arc_src(path, unit): return # source file files2res.add((filename, path)) # generated if noext: files2res.add((os.path.splitext(filename)[0] + out_suffix, os.path.splitext(path)[0] + out_suffix)) else: files2res.add((filename + out_suffix, path + out_suffix)) # used includes for entry in parse_pyx_includes(filename, path, unit.resolve('$S')): files2res.add(entry) include_arc_rel = entry[0] include_map[filename].add(include_arc_rel) else: def process_pyx(filename, path, out_suffix, noext): pass for pyxs, cython, out_suffix, noext in [ (pyxs_c, unit.on_buildwith_cython_c_dep, ".c", False), (pyxs_c_h, unit.on_buildwith_cython_c_h, ".c", True), (pyxs_c_api_h, unit.on_buildwith_cython_c_api_h, ".c", True), (pyxs_cpp, unit.on_buildwith_cython_cpp_dep, ".cpp", False), ]: for path, mod in pyxs: filename = rootrel_arc_src(path, unit) cython_args = [path] dep = path if path.endswith('.py'): pxd = '/'.join(mod.split('.')) + '.pxd' if unit.resolve_arc_path(pxd): dep = pxd cython_args.append(dep) cython_args += [ '--module-name', mod, '--init-suffix', mangle(mod), '--source-root', '${ARCADIA_ROOT}', # set arcadia root relative __file__ for generated modules '-X', 'set_initial_path={}'.format(filename), ] + cython_directives cython(cython_args) py_register(unit, mod, py3) process_pyx(filename, path, out_suffix, noext) if files2res: # Compile original and generated sources into target for proper cython coverage calculation unit.onresource_files( [x for name, path in files2res for x in ('DEST', name, path)]) if include_map: data = [] prefix = 'resfs/cython/include' for line in sorted('{}/{}={}'.format(prefix, filename, ':'.join( sorted(files))) for filename, files in include_map.iteritems()): data += ['-', line] unit.onresource(data) for swigs, on_swig_python in [ (swigs_c, unit.on_swig_python_c), (swigs_cpp, unit.on_swig_python_cpp), ]: for path, mod in swigs: # Make output prefix basename match swig module name. prefix = path[:path.rfind('/') + 1] + mod.rsplit('.', 1)[-1] swg_py = '{}/{}/{}.py'.format('${ARCADIA_BUILD_ROOT}', upath, prefix) on_swig_python([path, prefix]) onpy_register(unit, mod + '_swg') onpy_srcs(unit, swg_py + '=' + mod) if pys: pys_seen = set() pys_dups = {m for _, m in pys if (m in pys_seen or pys_seen.add(m))} if pys_dups: ymake.report_configure_error( 'Duplicate(s) is found in the PY_SRCS macro: {}'.format( pys_dups)) res = [] if py3: for path, mod in pys: dest = 'py/' + mod.replace('.', '/') + '.py' if with_py: res += ['DEST', dest, path] if with_pyc: root_rel_path = rootrel_arc_src(path, unit) dst = path + uniq_suffix(path, unit) unit.on_py3_compile_bytecode( [root_rel_path + '-', path, dst]) res += ['DEST', dest + '.yapyc3', dst + '.yapyc3'] unit.onresource_files(res) add_python_lint_checks( unit, 3, [path for path, mod in pys] + unit.get(['_PY_EXTRA_LINT_FILES_VALUE']).split()) else: for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) if with_py: key = '/py_modules/' + mod res += [ path, key, '-', 'resfs/src/{}={}'.format(key, root_rel_path), ] if with_pyc: src = unit.resolve_arc_path(path) or path dst = path + uniq_suffix(path, unit) unit.on_py_compile_bytecode( [root_rel_path + '-', src, dst]) res += [dst + '.yapyc', '/py_code/' + mod] unit.onresource(res) add_python_lint_checks( unit, 2, [path for path, mod in pys] + unit.get(['_PY_EXTRA_LINT_FILES_VALUE']).split()) if protos: if not upath.startswith('contrib/libs/protobuf/python/google_lib'): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) unit.onpeerdir(unit.get("PY_PROTO_DEPS").split()) proto_paths = [path for path, mod in protos] unit.on_generate_py_protos_internal(proto_paths) unit.onpy_srcs([ pb2_arg(py_suf, path, mod, unit) for path, mod in protos for py_suf in unit.get("PY_PROTO_SUFFIXES").split() ]) if optimize_proto: unit.onsrcs(proto_paths) if need_gazetteer_peerdir: unit.onpeerdir(['kernel/gazetteer/proto']) pb_cc_outs = [ pb_cc_arg(cc_suf, path, unit) for path in proto_paths for cc_suf in unit.get("CPP_PROTO_SUFFIXES").split() ] for pb_cc_outs_chunk in generate_chunks(pb_cc_outs, 10): if unit_needs_main: unit.onjoin_srcs( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk) else: unit.onjoin_srcs_global( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk) if evs: if not upath.startswith('contrib/libs/protobuf/python/google_lib'): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) unit.on_generate_py_evs_internal([path for path, mod in evs]) unit.onpy_srcs([ev_arg(path, mod, unit) for path, mod in evs]) if optimize_proto: unit.onsrcs([path for path, mod in evs]) pb_cc_outs = [ev_cc_arg(path, unit) for path, _ in evs] for pb_cc_outs_chunk in generate_chunks(pb_cc_outs, 10): if unit_needs_main: unit.onjoin_srcs( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk) else: unit.onjoin_srcs_global( ['join_' + listid(pb_cc_outs_chunk) + '.cpp'] + pb_cc_outs_chunk)
def get_srcdir(path, unit): return rootrel_arc_src(path, unit)[:-len(path)].rstrip('/')
def on_go_process_srcs(unit): """ _GO_PROCESS_SRCS() macro processes only 'CGO' files. All remaining *.go files and other input files are currently processed by a link command of the GO module (GO_LIBRARY, GO_PROGRAM) """ srcs_files = get_appended_values(unit, 'GO_SRCS_VALUE') asm_files = [] c_files = [] cxx_files = [] go_files = [] in_files = [] proto_files = [] s_files = [] syso_files = [] classifed_files = { '.c': c_files, '.cc': cxx_files, '.cpp': cxx_files, '.cxx': cxx_files, '.go': go_files, '.in': in_files, '.proto': proto_files, '.s': asm_files, '.syso': syso_files, '.C': cxx_files, '.S': s_files, } # Classify files specifed in _GO_SRCS() macro by extension and process CGO_EXPORT keyword # which can preceed C/C++ files only is_cgo_export = False for f in srcs_files: _, ext = os.path.splitext(f) ext_files = classifed_files.get(ext) if ext_files is not None: if is_cgo_export: is_cgo_export = False if ext in ('.c', '.cc', '.cpp', '.cxx', '.C'): unit.oncopy_file_with_deps_no_auto( [f, f, 'OUTPUT_INCLUDES', '${BINDIR}/_cgo_export.h']) f = '${BINDIR}/' + f else: ymake.report_configure_error( 'Unmatched CGO_EXPORT keyword in SRCS()/_GO_SRCS() macro' ) ext_files.append(f) elif f == 'CGO_EXPORT': is_cgo_export = True else: # FIXME(snermolaev): We can report an unsupported files for _GO_SRCS here pass if is_cgo_export: ymake.report_configure_error( 'Unmatched CGO_EXPORT keyword in SRCS()/_GO_SRCS() macro') for f in go_files: if f.endswith('_test.go'): ymake.report_configure_error( 'file {} must be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) go_test_files = get_appended_values(unit, 'GO_TEST_SRCS_VALUE') go_xtest_files = get_appended_values(unit, 'GO_XTEST_SRCS_VALUE') for f in go_test_files + go_xtest_files: if not f.endswith('_test.go'): ymake.report_configure_error( 'file {} should not be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) # Add gofmt style checks resolved_go_files = [] for path in itertools.chain(go_files, go_test_files, go_xtest_files): if path.endswith('.go'): resolved = unit.resolve_arc_path([path]) if resolved != path and need_lint(resolved): resolved_go_files.append(resolved) if resolved_go_files: basedirs = {} for f in resolved_go_files: basedir = os.path.dirname(f) if basedir not in basedirs: basedirs[basedir] = [] basedirs[basedir].append(f) for basedir in basedirs: unit.onadd_check(['gofmt'] + basedirs[basedir]) is_test_module = unit.enabled('GO_TEST_MODULE') # Go coverage instrumentation (NOTE! go_files list is modified here) if is_test_module and unit.enabled('GO_TEST_COVER'): cover_info = [] for f in go_files: if f.endswith('_test.go'): continue cover_var = 'GoCover_' + base64.b32encode(f).rstrip('=') cover_file = unit.resolve_arc_path(f) unit.on_go_gen_cover_go([cover_file, cover_var]) if cover_file.startswith('$S/'): cover_file = arc_project_prefix + cover_file[3:] cover_info.append('{}:{}'.format(cover_var, cover_file)) # go_files should be empty now since the initial list shouldn't contain # any non-go or go test file. The value of go_files list will be used later # to update the value of GO_SRCS_VALUE go_files = [] unit.set(['GO_COVER_INFO_VALUE', ' '.join(cover_info)]) # We have cleaned up the list of files from GO_SRCS_VALUE var and we have to update # the value since it is used in module command line unit.set([ 'GO_SRCS_VALUE', ' '.join(itertools.chain(go_files, asm_files, syso_files)) ]) unit_path = unit.path() # Add go vet check if unit.get(['GO_VET']) == 'yes' and need_lint(unit_path): unit.onadd_check([ "govet", '$(BUILD_ROOT)/' + tobuilddir(os.path.join(unit_path, unit.filename() + '.vet.txt'))[3:] ]) # Process .proto files for f in proto_files: unit.on_go_proto_cmd(f) # Process .in files for f in in_files: unit.onsrc(f) # Generate .symabis for .s files (starting from 1.12 version) if compare_versions('1.12', unit.get('GOSTD_VERSION')) >= 0 and len(asm_files) > 0: unit.on_go_compile_symabis(asm_files) # Process cgo files cgo_files = get_appended_values(unit, 'CGO_SRCS_VALUE') cgo_cflags = [] if len(c_files) + len(cxx_files) + len(s_files) + len(cgo_files) > 0: if is_test_module: cgo_cflags.append( os.path.join('-I${ARCADIA_ROOT}', unit.get('GO_TEST_FOR_DIR')[3:])) cgo_cflags.append('-I$CURDIR') unit.oncgo_cflags(cgo_cflags) cgo_cflags = get_appended_values(unit, 'CGO_CFLAGS_VALUE') for f in itertools.chain(c_files, cxx_files, s_files): unit.onsrc([f] + cgo_cflags) if len(cgo_files) > 0: if not unit.enabled('CGO_ENABLED'): ymake.report_configure_error( 'trying to build with CGO (CGO_SRCS is non-empty) when CGO is disabled' ) import_path = rootrel_arc_src(unit_path, unit) go_std_root = unit.get('GOSTD') + os.path.sep if import_path.startswith(go_std_root): import_path = import_path[len(go_std_root):] if import_path != runtime_cgo_path: unit.onpeerdir(os.path.join(go_std_root, runtime_cgo_path)) race_mode = 'race' if unit.enabled('RACE') else 'norace' import_runtime_cgo = 'false' if import_path in import_runtime_cgo_false[ race_mode] else 'true' import_syscall = 'false' if import_path in import_syscall_false[ race_mode] else 'true' args = [import_path] + cgo_files + [ 'FLAGS', '-import_runtime_cgo=' + import_runtime_cgo, '-import_syscall=' + import_syscall ] unit.on_go_compile_cgo1(args) cgo2_cflags = get_appended_values(unit, 'CGO2_CFLAGS_VALUE') for f in cgo_files: if f.endswith('.go'): unit.onsrc([f[:-2] + 'cgo2.c'] + cgo_cflags + cgo2_cflags) else: ymake.report_configure_error( 'file {} should not be listed in CGO_SRCS() macros'.format( f)) args = [go_package_name(unit)] + cgo_files if len(c_files) > 0: args += ['C_FILES'] + c_files if len(s_files) > 0: args += ['S_FILES'] + s_files if len(syso_files) > 0: args += ['OBJ_FILES'] + syso_files unit.on_go_compile_cgo2(args)
def onpy_srcs(unit, *args): """ PY_SRCS() - is rule to build extended versions of Python interpreters and containing all application code in its executable file. It can be used to collect only the executables but not shared libraries, and, in particular, not to collect the modules that are imported using import directive. The main disadvantage is the lack of IDE support; There is also no readline yet. The application can be collect from any of the sources from which the C library, and with the help of PY_SRCS .py , .pyx,.proto and .swg files. At the same time extensions for Python on C language generating from .pyx and .swg, will be registered in Python's as built-in modules, and sources on .py are stored as static data: when the interpreter starts, the initialization code will add a custom loader of these modules to sys.meta_path. By default .pyx files are collected as C++-extensions. To collect them as C (similar to BUILDWITH_CYTHON_C, but with the ability to specify namespace), you must specify the Directive CYTHON_C. Building with pyx automatically registers modules, you do not need to call PY_REGISTER for them __init__.py never required, but if present (and specified in PY_SRCS), it will be imported when you import package modules with __init__.py Oh. Example of library declaration with PY_SRCS(): PY_LIBRARY(mymodule) PY_SRCS({| CYTHON_C} { | TOP_LEVEL | NAMESPACE ns} a.py sub/dir/b.py e.proto sub/dir/f.proto c.pyx sub/dir/d.pyx g.swg sub/dir/h.swg) END() Documentation: https://wiki.yandex-team.ru/devtools/commandsandvars/py_srcs/ """ # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. unit.onuse_python([]) if '/library/python/runtime' not in unit.path(): unit.onpeerdir(['library/python/runtime']) if unit.get('MODULE_TYPE') == 'PROGRAM': py_program(unit) py_namespace_value = unit.get('PY_NAMESPACE_VALUE') if py_namespace_value == ".": ns = "" else: ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_directives = [] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] protos = [] evs = [] swigs = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: mod = ns + stripext(arg).replace('/', '.') pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) elif path.endswith('.proto'): protos.append(pathmod) elif path.endswith('.ev'): evs.append(pathmod) elif path.endswith('.swg'): swigs.append(path) # ignore mod, use last (and only) ns else: ymake.report_configure_error( 'in PY_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: for pyxs, cython in [ (pyxs_c, unit.onbuildwith_cython_c), (pyxs_cpp, unit.onbuildwith_cython_cpp), ]: for path, mod in pyxs: cython([ path, '--module-name', mod, '--init-name', 'init' + mangle(mod), ] + cython_directives) unit.onpy_register([mod]) if pys: res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) unit.onpy_compile_bytecode([root_rel_path + '-', path]) key = '/py_modules/' + mod res += [ path, key, '-', 'resfs/src/{}={}'.format(key, root_rel_path), path + '.yapyc', '/py_code/' + mod, ] unit.onresource(res) add_python_lint_checks(unit, [path for path, mod in pys]) if protos: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) grpc = unit.get('GRPC_FLAG') == 'yes' if grpc: unit.onpeerdir(['contrib/libs/grpc/python']) unit.ongenerate_py_protos([path for path, mod in protos]) unit.onpy_srcs([pb2_arg(path, mod, unit) for path, mod in protos]) if grpc: unit.onpy_srcs( [pb2_grpc_arg(path, mod, unit) for path, mod in protos]) if evs: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) unit.ongenerate_py_evs([path for path, mod in evs]) unit.onpy_srcs([ev_arg(path, mod, unit) for path, mod in evs]) if swigs: unit.onsrcs(swigs) prefix = unit.get('MODULE_PREFIX') project = unit.get('REALPRJNAME') unit.onpy_register([prefix + project]) path = '${ARCADIA_BUILD_ROOT}/' + '{}/{}.py'.format( unit.path()[3:], project) arg = '{}={}'.format(path, ns + project.replace('/', '.')) unit.onpy_srcs([arg])
def on_go_process_srcs(unit): """ _GO_PROCESS_SRCS() macro processes only 'CGO' files. All remaining *.go files and other input files are currently processed by a link command of the GO module (GO_LIBRARY, GO_PROGRAM) """ srcs_files = get_appended_values(unit, 'GO_SRCS_VALUE') for f in srcs_files: if f.endswith('_test.go'): ymake.report_configure_error( 'file {} must be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) go_test_files = get_appended_values(unit, 'GO_TEST_SRCS_VALUE') go_xtest_files = get_appended_values(unit, 'GO_XTEST_SRCS_VALUE') for f in go_test_files + go_xtest_files: if not f.endswith('_test.go'): ymake.report_configure_error( 'file {} should not be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) if unit.get('GO_TEST_MODULE') and unit.get('GO_TEST_COVER'): temp_srcs_files = [] cover_info = [] for f in srcs_files: if f.endswith('.go') and not f.endswith('_test.go'): cover_var = 'GoCover_' + base64.b32encode(f).rstrip('=') cover_file = unit.resolve_arc_path(f) unit.on_go_gen_cover_go([cover_file, cover_var]) if cover_file.startswith('$S/'): cover_file = arc_project_prefix + cover_file[3:] cover_info.append('{}:{}'.format(cover_var, cover_file)) else: temp_srcs_files.append(f) srcs_files = temp_srcs_files unit.set(['GO_SRCS_VALUE', ' '.join(srcs_files)]) unit.set(['GO_COVER_INFO_VALUE', ' '.join(cover_info)]) resolved_go_files = [] for path in srcs_files + go_test_files + go_xtest_files: if path.endswith(".go"): resolved = unit.resolve_arc_path([path]) if resolved != path and not resolved.startswith( "$S/vendor") and not resolved.startswith("$S/contrib"): resolved_go_files.append(resolved) if resolved_go_files: basedirs = {} for f in resolved_go_files: basedir = os.path.dirname(f) if basedir not in basedirs: basedirs[basedir] = [] basedirs[basedir].append(f) for basedir in basedirs: unit.onadd_check(["gofmt"] + basedirs[basedir]) go_std_root = unit.get('GOSTD') + os.path.sep proto_files = filter(lambda x: x.endswith('.proto'), srcs_files) if len(proto_files) > 0: for f in proto_files: unit.on_go_proto_cmd(f) in_files = filter(lambda x: x.endswith('.in'), srcs_files) if len(in_files) > 0: for f in in_files: unit.onsrc(f) if compare_versions('1.12', unit.get('GOSTD_VERSION')) >= 0: asm_files = filter(lambda x: x.endswith('.s'), srcs_files) if len(asm_files) > 0: unit.on_go_compile_symabis(asm_files) s_files = filter(lambda x: x.endswith('.S'), srcs_files) c_files = filter(lambda x: x.endswith('.c'), srcs_files) syso_files = filter(lambda x: x.endswith('.syso'), srcs_files) if len(c_files) + len(s_files) > 0: cgo_flags = get_appended_values(unit, 'CGO_CFLAGS_VALUE') for f in c_files + s_files: unit.onsrc([f] + cgo_flags) cgo_files = get_appended_values(unit, 'CGO_SRCS_VALUE') if len(cgo_files) > 0: if not unit.enabled('CGO_ENABLED'): ymake.report_configure_error( 'trying to build with CGO (CGO_SRCS is non-empty) when CGO is disabled' ) import_path = rootrel_arc_src(unit.path(), unit) if import_path.startswith(go_std_root): import_path = import_path[len(go_std_root):] if import_path != runtime_cgo_path: unit.onpeerdir(os.path.join(go_std_root, runtime_cgo_path)) race_mode = 'race' if unit.enabled('RACE') else 'norace' import_runtime_cgo = 'false' if import_path in import_runtime_cgo_false[ race_mode] else 'true' import_syscall = 'false' if import_path in import_syscall_false[ race_mode] else 'true' args = [import_path] + cgo_files + [ 'FLAGS', '-import_runtime_cgo=' + import_runtime_cgo, '-import_syscall=' + import_syscall ] unit.on_go_compile_cgo1(args) args = [go_package_name(unit)] + cgo_files if len(c_files) > 0: args += ['C_FILES'] + c_files if len(s_files) > 0: args += ['S_FILES'] + s_files if len(syso_files) > 0: args += ['OBJ_FILES'] + syso_files unit.on_go_compile_cgo2(args)
def on_go_process_srcs(unit): """ _GO_PROCESS_SRCS() macro processes only 'CGO' files. All remaining *.go files and other input files are currently processed by a link command of the GO module (GO_LIBRARY, GO_PROGRAM) """ go_files = get_appended_values(unit, 'GO_SRCS_VALUE') for f in go_files: if f.endswith('_test.go'): ymake.report_configure_error( 'file {} must be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) go_test_files = get_appended_values(unit, 'GO_TEST_SRCS_VALUE') go_xtest_files = get_appended_values(unit, 'GO_XTEST_SRCS_VALUE') for f in go_test_files + go_xtest_files: if not f.endswith('_test.go'): ymake.report_configure_error( 'file {} should not be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) resolved_go_files = [] for path in go_files + go_test_files + go_xtest_files: if path.endswith(".go"): resolved = unit.resolve_arc_path([path]) if resolved != path and not resolved.startswith( "$S/vendor") and not resolved.startswith("$S/contrib"): resolved_go_files.append(resolved) if resolved_go_files: basedirs = {} for f in resolved_go_files: basedir = os.path.dirname(f) if basedir not in basedirs: basedirs[basedir] = [] basedirs[basedir].append(f) for basedir in basedirs: unit.onadd_check(["gofmt"] + basedirs[basedir]) go_std_root = unit.get('GOSTD') + os.path.sep proto_files = filter(lambda x: x.endswith('.proto'), go_files) if len(proto_files) > 0: for f in proto_files: unit.on_go_proto_cmd(f) in_files = filter(lambda x: x.endswith('.in'), go_files) if len(in_files) > 0: for f in in_files: unit.onsrc(f) if compare_versions('1.12', unit.get('GOSTD_VERSION')) >= 0: asm_files = filter(lambda x: x.endswith('.s'), go_files) if len(asm_files) > 0: unit.on_go_compile_symabis(asm_files) s_files = filter(lambda x: x.endswith('.S'), go_files) c_files = filter(lambda x: x.endswith('.c'), go_files) if len(c_files) + len(s_files) > 0: cgo_flags = get_appended_values(unit, 'CGO_CFLAGS_VALUE') for f in c_files + s_files: unit.onsrc([f] + cgo_flags) cgo_files = get_appended_values(unit, 'CGO_SRCS_VALUE') if len(cgo_files) > 0: import_path = rootrel_arc_src(unit.path(), unit) if import_path.startswith(go_std_root): import_path = import_path[len(go_std_root):] if import_path != runtime_cgo_path: unit.onpeerdir(os.path.join(go_std_root, runtime_cgo_path)) import_runtime_cgo = 'false' if import_path in [ runtime_cgo_path, runtime_msan_path, runtime_race_path ] else 'true' import_syscall = 'false' if import_path == runtime_cgo_path else 'true' args = [import_path] + cgo_files + [ 'FLAGS', '-import_runtime_cgo=' + import_runtime_cgo, '-import_syscall=' + import_syscall ] unit.on_go_compile_cgo1(args) args = [ unit.get('GO_PACKAGE_VALUE') or unit.get('MODULE_TYPE') == 'PROGRAM' and 'main' or unit.get('REALPRJNAME') ] + cgo_files if len(c_files) > 0: args += ['C_FILES'] + c_files if len(s_files) > 0: args += ['S_FILES'] + s_files unit.on_go_compile_cgo2(args)
def on_go_process_srcs(unit): """ _GO_PROCESS_SRCS() macro processes only 'CGO' files. All remaining *.go files and other input files are currently processed by a link command of the GO module (GO_LIBRARY, GO_PROGRAM) """ go_files = get_appended_values(unit, 'GO_SRCS_VALUE') for f in go_files: if f.endswith('_test.go'): ymake.report_configure_error( 'file {} must be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) go_test_files = get_appended_values(unit, 'GO_TEST_SRCS_VALUE') go_xtest_files = get_appended_values(unit, 'GO_XTEST_SRCS_VALUE') for f in go_test_files + go_xtest_files: if not f.endswith('_test.go'): ymake.report_configure_error( 'file {} should not be listed in GO_TEST_SRCS() or GO_XTEST_SRCS() macros' .format(f)) go_std_root = unit.get('GOSTD') + os.path.sep proto_files = filter(lambda x: x.endswith('.proto'), go_files) if len(proto_files) > 0: for f in proto_files: unit.ongo_proto_cmd(f) in_files = filter(lambda x: x.endswith('.in'), go_files) if len(in_files) > 0: for f in in_files: unit.onsrc(f) s_files = filter(lambda x: x.endswith('.S'), go_files) c_files = filter(lambda x: x.endswith('.c'), go_files) if len(c_files) + len(s_files) > 0: cgo_flags = get_appended_values(unit, 'CGO_CFLAGS_VALUE') for f in c_files + s_files: unit.onsrc([f] + cgo_flags) cgo_files = get_appended_values(unit, 'CGO_SRCS_VALUE') if len(cgo_files) > 0: import_path = rootrel_arc_src(unit.path(), unit) if import_path.startswith(go_std_root): import_path = import_path[len(go_std_root):] if import_path != runtime_cgo_path: unit.onpeerdir(os.path.join(go_std_root, runtime_cgo_path)) import_runtime_cgo = 'false' if import_path in [ runtime_cgo_path, runtime_msan_path, runtime_race_path ] else 'true' import_syscall = 'false' if import_path == runtime_cgo_path else 'true' args = [import_path] + cgo_files + [ 'FLAGS', '-import_runtime_cgo=' + import_runtime_cgo, '-import_syscall=' + import_syscall ] unit.ongo_compile_cgo1(args) args = [unit.get('GO_PACKAGE_VALUE') or unit.get('REALPRJNAME') ] + cgo_files if len(c_files) > 0: args += ['C_FILES'] + c_files if len(s_files) > 0: args += ['S_FILES'] + s_files unit.ongo_compile_cgo2(args)
def onpy_srcs(unit, *args): """ PY_SRCS() - is rule to build extended versions of Python interpreters and containing all application code in its executable file. It can be used to collect only the executables but not shared libraries, and, in particular, not to collect the modules that are imported using import directive. The main disadvantage is the lack of IDE support; There is also no readline yet. The application can be collect from any of the sources from which the C library, and with the help of PY_SRCS .py , .pyx,.proto and .swg files. At the same time extensions for Python on C language generating from .pyx and .swg, will be registered in Python's as built-in modules, and sources on .py are stored as static data: when the interpreter starts, the initialization code will add a custom loader of these modules to sys.meta_path. By default .pyx files are collected as C++-extensions. To collect them as C (similar to BUILDWITH_CYTHON_C, but with the ability to specify namespace), you must specify the Directive CYTHON_C. Building with pyx automatically registers modules, you do not need to call PY_REGISTER for them __init__.py never required, but if present (and specified in PY_SRCS), it will be imported when you import package modules with __init__.py Oh. Example of library declaration with PY_SRCS(): PY_LIBRARY(mymodule) PY_SRCS({| CYTHON_C} { | TOP_LEVEL | NAMESPACE ns} a.py sub/dir/b.py e.proto sub/dir/f.proto c.pyx sub/dir/d.pyx g.swg sub/dir/h.swg) END() Documentation: https://wiki.yandex-team.ru/devtools/commandsandvars/py_srcs/ """ # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. unit.onuse_python([]) if '/library/python/runtime' not in unit.path(): unit.onpeerdir(['library/python/runtime']) if unit.get('MODULE_TYPE') == 'PROGRAM': py_program(unit) py_namespace_value = unit.get('PY_NAMESPACE_VALUE') if py_namespace_value == ".": ns = "" else: ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_directives = [] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] protos = [] evs = [] swigs = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: mod = ns + stripext(arg).replace('/', '.') pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) elif path.endswith('.proto'): protos.append(pathmod) elif path.endswith('.ev'): evs.append(pathmod) elif path.endswith('.swg'): swigs.append(path) # ignore mod, use last (and only) ns else: ymake.report_configure_error('in PY_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: for pyxs, cython in [ (pyxs_c, unit.onbuildwith_cython_c), (pyxs_cpp, unit.onbuildwith_cython_cpp), ]: for path, mod in pyxs: filename = get_pyx_mod_name(unit, path) cython([ path, '--module-name', mod, '--init-name', 'init' + mangle(mod), '--source-root', '${ARCADIA_ROOT}', # set arcadia root relative __file__ for generated modules '-X', 'set_initial_path={}'.format(filename), ] + cython_directives) unit.onpy_register([mod]) if pys: res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) unit.onpy_compile_bytecode([root_rel_path + '-', path]) key = '/py_modules/' + mod res += [ path, key, '-', 'resfs/src/{}={}'.format(key, root_rel_path), path + '.yapyc', '/py_code/' + mod, ] unit.onresource(res) add_python_lint_checks(unit, [path for path, mod in pys]) if protos: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) grpc = unit.get('GRPC_FLAG') == 'yes' if grpc: unit.onpeerdir(['contrib/libs/grpc/python']) unit.ongenerate_py_protos([path for path, mod in protos]) unit.onpy_srcs([pb2_arg(path, mod, unit) for path, mod in protos]) if grpc: unit.onpy_srcs([pb2_grpc_arg(path, mod, unit) for path, mod in protos]) if evs: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) unit.ongenerate_py_evs([path for path, mod in evs]) unit.onpy_srcs([ev_arg(path, mod, unit) for path, mod in evs]) if swigs: unit.onsrcs(swigs) prefix = unit.get('MODULE_PREFIX') project = unit.get('REALPRJNAME') unit.onpy_register([prefix + project]) path = '${ARCADIA_BUILD_ROOT}/' + '{}/{}.py'.format(unit.path()[3:], project) arg = '{}={}'.format(path, ns + project.replace('/', '.')) unit.onpy_srcs([arg])
def onpy3_srcs(unit, *args): # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. if '/contrib/tools/python3/src/Lib' not in unit.path(): unit.onuse_python3([]) if '/library/python/runtime_py3' not in unit.path(): unit.onpeerdir(['library/python/runtime_py3']) if unit.get('MODULE_TYPE') == 'PROGRAM': py3_program(unit) py_namespace_value = unit.get('PY_NAMESPACE_VALUE') if py_namespace_value == ".": ns = "" else: ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_directives = [] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: mod = ns + stripext(arg).replace('/', '.') pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) else: ymake.report_configure_error('in PY3_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: for pyxs, cython in [ (pyxs_c, unit.onbuildwith_cython_c), (pyxs_cpp, unit.onbuildwith_cython_cpp), ]: for path, mod in pyxs: filename = get_pyx_mod_name(unit, path) cython([ path, '--module-name', mod, '--init-name', 'PyInit_' + mangle(mod), '--source-root', '${ARCADIA_ROOT}', # set arcadia root relative __file__ for generated modules '-X', 'set_initial_path={}'.format(filename), ] + cython_directives) unit.onpy3_register([mod]) if pys: res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) unit.onpy3_compile_bytecode([root_rel_path + '-', path]) dest = 'py/' + mod.replace('.', '/') + '.py' res += [ 'DEST', dest, path, 'DEST', dest + '.yapyc', path + '.yapyc' ] unit.onresource_files(res)
def onpy_srcs(unit, *args): # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. unit.onuse_python([]) if '/library/python/runtime' not in unit.path(): unit.onpeerdir(['library/python/runtime']) if unit.get('MODULE_TYPE') == 'PROGRAM': py_program(unit) ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_directives = [] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] protos = [] evs = [] swigs = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: mod = ns + stripext(arg).replace('/', '.') pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) elif path.endswith('.proto'): protos.append(pathmod) elif path.endswith('.ev'): evs.append(pathmod) elif path.endswith('.swg'): swigs.append(path) # ignore mod, use last (and only) ns else: ymake.report_configure_error('in PY_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: for pyxs, cython in [ (pyxs_c, unit.onbuildwith_cython_c), (pyxs_cpp, unit.onbuildwith_cython_cpp), ]: for path, mod in pyxs: cython([ path, '--module-name', mod, '--init-name', 'init' + mangle(mod), ] + cython_directives) unit.onpy_register([mod]) if pys: res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) unit.onpy_compile_bytecode([root_rel_path + '-', path]) key = '/py_modules/' + mod res += [ path, key, '-', 'resfs/src/{}={}'.format(key, root_rel_path), path + '.yapyc', '/py_code/' + mod, ] unit.onresource(res) add_python_lint_checks(unit, [path for path, mod in pys]) if protos: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) grpc = unit.get('GRPC_FLAG') == 'yes' if grpc: unit.onpeerdir(['contrib/libs/grpc/python']) unit.ongenerate_py_protos([path for path, mod in protos]) unit.onpy_srcs([pb2_arg(path, mod, unit) for path, mod in protos]) if grpc: unit.onpy_srcs([pb2_grpc_arg(path, mod, unit) for path, mod in protos]) if evs: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) unit.ongenerate_py_evs([path for path, mod in evs]) unit.onpy_srcs([ev_arg(path, mod, unit) for path, mod in evs]) if swigs: unit.onsrcs(swigs) prefix = unit.get('MODULE_PREFIX') project = unit.get('REALPRJNAME') unit.onpy_register([prefix + project]) path = '${ARCADIA_BUILD_ROOT}/' + '{}/{}.py'.format(unit.path()[3:], project) arg = '{}={}'.format(path, ns + project.replace('/', '.')) unit.onpy_srcs([arg])
def onpy3_srcs(unit, *args): # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. if '/contrib/tools/python3/src/Lib' not in unit.path(): unit.onuse_python3([]) if '/library/python/runtime_py3' not in unit.path(): unit.onpeerdir(['library/python/runtime_py3']) if unit.get('MODULE_TYPE') == 'PROGRAM': py3_program(unit) py_namespace_value = unit.get('PY_NAMESPACE_VALUE') if py_namespace_value == ".": ns = "" else: ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_coverage = unit.get('CYTHON_COVERAGE') == 'yes' cython_directives = [] if cython_coverage: cython_directives += ['-X', 'linetrace=True'] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: main_mod = arg == 'MAIN' if main_mod: arg = next(args) if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: if arg.startswith('../'): ymake.report_configure_error( 'PY3_SRCS item starts with "../": {!r}'.format( arg)) mod = ns + stripext(arg).replace('/', '.') if main_mod: unit.onpy3_main(mod) pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) else: ymake.report_configure_error( 'in PY3_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: files2res = set() if cython_coverage: def process_pyx(filename, path, out_suffix): # skip generated files if not is_arc_src(path, unit): return # source file files2res.add((filename, path)) # generated files2res.add((filename + out_suffix, path + out_suffix)) # used includes for entry in parse_pyx_includes(filename, path, unit.resolve('$S')): files2res.add(entry) else: def process_pyx(filename, path, out_suffix): pass for pyxs, cython, out_suffix in [ (pyxs_c, unit.onbuildwith_cython_c, ".c"), (pyxs_cpp, unit.onbuildwith_cython_cpp, ".cpp"), ]: for path, mod in pyxs: filename = rootrel_arc_src(path, unit) cython([ path, '--module-name', mod, '--init-suffix', mangle(mod), '--source-root', '${ARCADIA_ROOT}', # set arcadia root relative __file__ for generated modules '-X', 'set_initial_path={}'.format(filename), ] + cython_directives) unit.onpy3_register([mod]) process_pyx(filename, path, out_suffix) if files2res: # Compile original and generated sources into target for proper cython coverage calculation unit.onresource_files( [x for name, path in files2res for x in ('DEST', name, path)]) if pys: res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) unit.onpy3_compile_bytecode([root_rel_path + '-', path]) dest = 'py/' + mod.replace('.', '/') + '.py' res += [ 'DEST', dest, path, 'DEST', dest + '.yapyc3', path + '.yapyc3' ] unit.onresource_files(res)
def onpy3_srcs(unit, *args): # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. unit.onuse_python3([]) if '/library/python/runtime_py3' not in unit.path(): unit.onpeerdir(['library/python/runtime_py3']) if unit.get('MODULE_TYPE') == 'PROGRAM': py3_program(unit) py_namespace_value = unit.get('PY_NAMESPACE_VALUE') if py_namespace_value == ".": ns = "" else: ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_directives = [] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: mod = ns + stripext(arg).replace('/', '.') pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) else: ymake.report_configure_error( 'in PY3_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: for pyxs, cython in [ (pyxs_c, unit.onbuildwith_cython_c), (pyxs_cpp, unit.onbuildwith_cython_cpp), ]: for path, mod in pyxs: cython([ path, '--module-name', mod, '--init-name', 'PyInit_' + mangle(mod), ] + cython_directives) unit.onpy3_register([mod]) if pys: res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) dest = 'py/' + mod.replace('.', '/') + '.py' res += [ 'DEST', dest, path # TODO Compile and add .pyc ] unit.onresource_files(res)
def onpy_srcs(unit, *args): # Each file arg must either be a path, or "${...}/buildpath=modname", where # "${...}/buildpath" part will be used as a file source in a future macro, # and "modname" will be used as a module name. unit.onuse_python([]) if '/library/python/runtime' not in unit.path(): unit.onpeerdir(['library/python/runtime']) if unit.get('MODULE_TYPE') == 'PROGRAM': py_program(unit) ns = (unit.get('PY_NAMESPACE_VALUE') or unit.path()[3:].replace('/', '.')) + '.' cython_directives = [] pyxs_c = [] pyxs_cpp = [] pyxs = pyxs_cpp pys = [] protos = [] evs = [] swigs = [] args = iter(args) for arg in args: # Namespace directives. if arg == 'TOP_LEVEL': ns = '' elif arg == 'NAMESPACE': ns = next(args) + '.' # Cython directives. elif arg == 'CYTHON_C': pyxs = pyxs_c elif arg == 'CYTHON_CPP': pyxs = pyxs_cpp elif arg == 'CYTHON_DIRECTIVE': cython_directives += ['-X', next(args)] # Unsupported but legal PROTO_LIBRARY arguments. elif arg == 'GLOBAL' or arg.endswith('.gztproto'): pass # Sources. else: if '=' in arg: path, mod = arg.split('=', 1) else: path = arg if arg == '__main__.py' or arg.endswith('/__main__.py'): mod = '__main__' else: mod = ns + stripext(arg).replace('/', '.') pathmod = (path, mod) if path.endswith('.py'): pys.append(pathmod) elif path.endswith('.pyx'): pyxs.append(pathmod) elif path.endswith('.proto'): protos.append(pathmod) elif path.endswith('.ev'): evs.append(pathmod) elif path.endswith('.swg'): swigs.append(path) # ignore mod, use last (and only) ns else: ymake.report_configure_error( 'in PY_SRCS: unrecognized arg {!r}'.format(path)) if pyxs: for pyxs, cython in [ (pyxs_c, unit.onbuildwith_cython_c), (pyxs_cpp, unit.onbuildwith_cython_cpp), ]: for path, mod in pyxs: cython([ path, '--module-name', mod, '--init-name', 'init' + mangle(mod), ] + cython_directives) unit.onpy_register([mod]) if pys: res = [] for path, mod in pys: root_rel_path = rootrel_arc_src(path, unit) unit.onpy_compile_bytecode([root_rel_path + '-', path]) key = '/py_modules/' + mod res += [ path, key, '-', 'resfs/src/{}={}'.format(key, root_rel_path), path + '.yapyc', '/py_code/' + mod, ] unit.onresource(res) add_python_lint_checks(unit, [path for path, mod in pys]) if protos: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) grpc = unit.get('GRPC_FLAG') == 'yes' if grpc: unit.onpeerdir(['contrib/libs/grpc/python']) unit.ongenerate_py_protos([path for path, mod in protos]) unit.onpy_srcs([pb2_arg(path, mod, unit) for path, mod in protos]) if grpc: unit.onpy_srcs( [pb2_grpc_arg(path, mod, unit) for path, mod in protos]) if evs: if '/contrib/libs/protobuf/python/google_lib' not in unit.path(): unit.onpeerdir(['contrib/libs/protobuf/python/google_lib']) unit.ongenerate_py_evs([path for path, mod in evs]) unit.onpy_srcs([ev_arg(path, mod, unit) for path, mod in evs]) if swigs: unit.onsrcs(swigs) prefix = unit.get('MODULE_PREFIX') project = unit.get('REALPRJNAME') unit.onpy_register([prefix + project]) path = '${ARCADIA_BUILD_ROOT}/' + '{}/{}.py'.format( unit.path()[3:], project) arg = '{}={}'.format(path, ns + project.replace('/', '.')) unit.onpy_srcs([arg])