Compile the generated source for a parser generator into an extension module. The extension module will be generated in the same directory as the provided path for the generated source, with the same basename (in addition to extension module metadata). For example, for the source mydir/
(
generated_source_path: str,
build_dir: str | None = None,
verbose: bool = False,
keep_asserts: bool = True,
disable_optimization: bool = False,
library_dir: str | None = None,
)
| 70 | |
| 71 | |
| 72 | def compile_c_extension( |
| 73 | generated_source_path: str, |
| 74 | build_dir: str | None = None, |
| 75 | verbose: bool = False, |
| 76 | keep_asserts: bool = True, |
| 77 | disable_optimization: bool = False, |
| 78 | library_dir: str | None = None, |
| 79 | ) -> pathlib.Path: |
| 80 | """Compile the generated source for a parser generator into an extension module. |
| 81 | |
| 82 | The extension module will be generated in the same directory as the provided path |
| 83 | for the generated source, with the same basename (in addition to extension module |
| 84 | metadata). For example, for the source mydir/parser.c the generated extension |
| 85 | in a darwin system with python 3.8 will be mydir/parser.cpython-38-darwin.so. |
| 86 | |
| 87 | If *build_dir* is provided, that path will be used as the temporary build directory |
| 88 | of distutils (this is useful in case you want to use a temporary directory). |
| 89 | |
| 90 | If *library_dir* is provided, that path will be used as the directory for a |
| 91 | static library of the common parser sources (this is useful in case you are |
| 92 | creating multiple extensions). |
| 93 | """ |
| 94 | import setuptools.command.build_ext |
| 95 | import setuptools.logging |
| 96 | from setuptools import Distribution, Extension |
| 97 | from setuptools._distutils.ccompiler import new_compiler |
| 98 | from setuptools._distutils.sysconfig import customize_compiler |
| 99 | from setuptools.modified import newer_group |
| 100 | |
| 101 | if verbose: |
| 102 | setuptools.logging.set_threshold(logging.DEBUG) |
| 103 | |
| 104 | source_file_path = pathlib.Path(generated_source_path) |
| 105 | extension_name = source_file_path.stem |
| 106 | extra_compile_args = get_extra_flags("CFLAGS", "PY_CFLAGS_NODIST") |
| 107 | extra_compile_args.append("-DPy_BUILD_CORE_MODULE") |
| 108 | # Define _Py_TEST_PEGEN to not call PyAST_Validate() in Parser/pegen.c |
| 109 | extra_compile_args.append("-D_Py_TEST_PEGEN") |
| 110 | if sys.platform == "win32" and sysconfig.get_config_var("Py_GIL_DISABLED"): |
| 111 | extra_compile_args.append("-DPy_GIL_DISABLED") |
| 112 | extra_link_args = get_extra_flags("LDFLAGS", "PY_LDFLAGS_NODIST") |
| 113 | if keep_asserts: |
| 114 | extra_compile_args.append("-UNDEBUG") |
| 115 | if disable_optimization: |
| 116 | if sys.platform == "win32": |
| 117 | extra_compile_args.append("/Od") |
| 118 | extra_link_args.append("/LTCG:OFF") |
| 119 | else: |
| 120 | extra_compile_args.append("-O0") |
| 121 | if sysconfig.get_config_var("GNULD") == "yes": |
| 122 | extra_link_args.append("-fno-lto") |
| 123 | |
| 124 | common_sources = [ |
| 125 | str(MOD_DIR.parent.parent.parent / "Python" / "Python-ast.c"), |
| 126 | str(MOD_DIR.parent.parent.parent / "Python" / "asdl.c"), |
| 127 | str(MOD_DIR.parent.parent.parent / "Parser" / "lexer" / "lexer.c"), |
| 128 | str(MOD_DIR.parent.parent.parent / "Parser" / "lexer" / "state.c"), |
| 129 | str(MOD_DIR.parent.parent.parent / "Parser" / "lexer" / "buffer.c"), |
searching dependent graphs…