python_c-extensions / src /compiler.py
Carbaz's picture
Sync from GitHub
cc7a977 verified
Raw
History Blame Contribute Delete
2.77 kB
"""Compilation and tests module for the AI Python C Extensions Generator application."""
import os
import subprocess
import sys
from logging import getLogger
_logger = getLogger(__name__)
# Define a function to write outputs to a file with a given filename.
def write_file(data, path):
"""Write data to a file with the specified filename."""
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w") as file:
file.write(data)
# Extension compilation function.
def build_extension(compile_path):
"""Compile the C extension using 'setup.py' and return the compilation output."""
# Set default COMSPEC to cmd.exe on Windows to avoid issues with some C compilers.
if sys.platform == "win32":
_logger.info('PATCHING COMSPEC FOR WINDOWS COMPILATION COMPATIBILITY...')
preset_comspec = os.environ.get("COMSPEC")
os.environ["COMSPEC"] = "C:\\Windows\\System32\\cmd.exe"
try:
_logger.info('STARTING COMPILATION PROCESS...')
compile_cmd = ["python", "setup.py", "build_ext", "--inplace"]
compile_result = subprocess.run(compile_cmd, env=os.environ, cwd=compile_path,
check=True, text=True, capture_output=True)
except subprocess.CalledProcessError as ex:
_logger.error(f"COMPILATION FAILED WITH ERROR:\n{ex.stdout}\n{ex.stderr}")
raise Exception(f"An error occurred while building:\n{ex.stdout}\n{ex.stderr}")
finally:
# Restore original COMSPEC on Windows.
if sys.platform == "win32":
_logger.info('RESTORING ORIGINAL COMSPEC...')
os.environ["COMSPEC"] = preset_comspec
_logger.info('COMPILATION COMPLETED SUCCESSFULLY.')
return compile_result.stdout
# Extension compilation function.
def compile_extension(c_code, setup_code, module_name, compile_path):
"""Build the C extension from the provided codes."""
try: # Write the provided codes to their respective files.
_logger.info('WRITING GENERATED C CODE TO FILE...')
write_file(c_code, compile_path / f"{module_name}.c")
_logger.info('WRITING GENERATED SETUP CODE TO FILE...')
write_file(setup_code, compile_path / "setup.py")
except Exception as ex:
_logger.error(f"ERROR WHILE WRITING FILES:\n{ex}")
return f"An error occurred while writing files:\n{ex}"
try: # Build the extension and capture the output.
_logger.info('BUILDING THE EXTENSION...')
build_output = build_extension(compile_path)
except Exception as ex: # If build fails, return the error message.
_logger.error(f"ERROR WHILE BUILDING EXTENSION:\n{ex}")
return str(ex)
_logger.info('EXTENSION BUILT SUCCESSFULLY.')
return build_output