def emit_gdb_helpers(self, ctx: CompileCtx) -> None: """ Emit support files for GDB helpers. """ lib_name = ctx.ada_api_settings.lib_name.lower() gdbinit_path = os.path.join(self.lib_root, 'gdbinit.py') gdb_c_path = os.path.join(self.src_dir, '{}-gdb.c'.format(lib_name)) # Always emit the ".gdbinit.py" GDB script write_source_file( gdbinit_path, ctx.render_template( 'gdb_py', langkit_path=os.path.dirname(os.path.dirname(__file__)), lib_name=lib_name, prefix=ctx.short_name_or_long, ), self.post_process_python) # Generate the C file to embed the absolute path to this script in the # generated library only if requested. if self.generate_gdb_hook: write_source_file( gdb_c_path, ctx.render_template('gdb_c', gdbinit_path=gdbinit_path, os_name=os.name), self.post_process_cpp) self.project_languages.add('C')
def emit_ocaml_api(self, ctx: CompileCtx) -> None: """ Generate binding for the external OCaml API. """ if not ctx.ocaml_api_settings: return ctx.ocaml_api_settings.init_type_graph() if not os.path.isdir(self.ocaml_dir): os.mkdir(self.ocaml_dir) with names.camel: # Write an empty ocamlformat file so we can call ocamlformat write_source_file(os.path.join(self.ocaml_dir, '.ocamlformat'), '') ctx = get_context() code = ctx.render_template("ocaml_api/module_ocaml", c_api=ctx.c_api_settings, ocaml_api=ctx.ocaml_api_settings) ocaml_filename = '{}.ml'.format(ctx.c_api_settings.lib_name) write_ocaml_file( os.path.join(self.ocaml_dir, ocaml_filename), code, self.post_process_ocaml, ) code = ctx.render_template("ocaml_api/module_sig_ocaml", c_api=ctx.c_api_settings, ocaml_api=ctx.ocaml_api_settings) ocaml_filename = '{}.mli'.format(ctx.c_api_settings.lib_name) write_ocaml_file( os.path.join(self.ocaml_dir, ocaml_filename), code, self.post_process_ocaml, ) # Emit dune file to easily compile and install bindings code = ctx.render_template("ocaml_api/dune_ocaml", c_api=ctx.c_api_settings, ocaml_api=ctx.ocaml_api_settings) write_source_file(os.path.join(self.ocaml_dir, 'dune'), code) write_source_file(os.path.join(self.ocaml_dir, 'dune-project'), '(lang dune 1.6)') # Write an empty opam file to install the lib with dune write_source_file( os.path.join(self.ocaml_dir, '{}.opam'.format(ctx.c_api_settings.lib_name)), '')
def emit_mains(self, ctx: CompileCtx) -> None: """ Emit sources and the project file for mains. """ with names.camel_with_underscores: write_ada_file(path.join(self.lib_root, 'src-mains'), AdaSourceKind.body, ['Parse'], ctx.render_template('main_parse_ada'), self.post_process_ada) write_source_file( self.mains_project, ctx.render_template('mains_project_file', lib_name=ctx.ada_api_settings.lib_name, source_dirs=self.main_source_dirs, main_programs=self.main_programs))
def emit_python_api(self, ctx: CompileCtx) -> None: """ Generate the Python binding module. """ def render_python_template(file_path: str, *args: Any, **kwargs: Any) -> None: with names.camel: code = ctx.render_template(*args, **kwargs) self.write_python_file(file_path, code) # Emit the Python modules themselves render_python_template(os.path.join(self.python_pkg_dir, '__init__.py'), 'python_api/module_py', c_api=ctx.c_api_settings, pyapi=ctx.python_api_settings, module_name=ctx.python_api_settings.module_name) # Emit the empty "py.type" file so that users can easily leverage type # annotations in the generated bindings. self.write_source_file(os.path.join(self.python_pkg_dir, "py.typed"), "") # Emit the setup.py script to easily install the Python binding setup_py_file = os.path.join(self.lib_root, 'python', 'setup.py') self.write_python_file(setup_py_file, ctx.render_template('python_api/setup_py'))
def emit_python_api(self, ctx: CompileCtx) -> None: """ Generate the Python binding module. """ def pretty_print(code: str) -> str: if not self.pretty_print: return code try: from black import FileMode, format_file_contents return format_file_contents(code, fast=True, mode=FileMode()) except ImportError: check_source_language( False, 'Black not available, not pretty-printing Python code', severity=Severity.warning, ok_for_codegen=True) return code def render_python_template(file_path: str, *args: Any, **kwargs: Any) -> None: with names.camel: code = ctx.render_template(*args, **kwargs) # If pretty-printing failed, write the original code anyway in # order to ease debugging. exc = None try: pp_code = pretty_print(code) except SyntaxError: pp_code = code write_source_file(file_path, pp_code, self.post_process_python) if exc: raise exc # Emit the Python modules themselves render_python_template(os.path.join(self.python_pkg_dir, '__init__.py'), 'python_api/module_py', c_api=ctx.c_api_settings, pyapi=ctx.python_api_settings, module_name=ctx.python_api_settings.module_name) # Emit the empty "py.type" file so that users can easily leverage type # annotations in the generated bindings. write_source_file(os.path.join(self.python_pkg_dir, "py.typed"), "") # Emit the setup.py script to easily install the Python binding setup_py_file = os.path.join(self.lib_root, 'python', 'setup.py') write_source_file(setup_py_file, ctx.render_template('python_api/setup_py'), self.post_process_python)
def emit_python_playground(self, ctx: CompileCtx) -> None: """ Emit sources for the Python playground script. """ playground_file = os.path.join( self.scripts_dir, '{}_playground'.format(ctx.short_name_or_long)) write_source_file( playground_file, ctx.render_template( 'python_api/playground_py', module_name=ctx.python_api_settings.module_name), self.post_process_python) os.chmod(playground_file, 0o775)
def emit_lib_project_file(self, ctx: CompileCtx) -> None: """ Emit a project file for the generated library. """ self._project_file_emitted = True write_source_file( self.main_project_file, ctx.render_template( 'project_file', lib_name=ctx.ada_api_settings.lib_name, os_path=os.path, project_path=os.path.dirname(self.main_project_file), ))