diff --git a/scripts/build_extensions.py b/scripts/build_extensions.py deleted file mode 100755 index 4877d07..0000000 --- a/scripts/build_extensions.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -import os -import sys -import shutil -from setuptools import setup, Extension -from Cython.Build import cythonize - - -def build_extensions(target_dirs): - """ - Compiles all .py files in the target directories (recursively) into .so/.pyd extensions. - Args: - target_dirs (list or str): List of directories or single directory path to scan. - """ - # Ensure input is a list - if isinstance(target_dirs, str): - target_dirs = [target_dirs] - - extensions = [] - project_root = os.getcwd() - - print(f"Scanning directories: {target_dirs}") - - for target_dir in target_dirs: - # Ensure target directory exists - if not os.path.exists(target_dir): - print(f"Warning: Directory '{target_dir}' not found. Skipping.") - continue - - # Get the absolute path of the target directory - abs_target_dir = os.path.abspath(target_dir) - - print(f"Scanning {abs_target_dir} for Python files...") - - # Walk through the directory - for root, dirs, files in os.walk(abs_target_dir): - for file in files: - if file.endswith(".py"): - file_path = os.path.join(root, file) - - # Skip this script if it happens to be in the target dir - if os.path.abspath(file_path) == os.path.abspath(__file__): - continue - - # Skip setup.py if it exists - if file == "setup.py": - continue - - # Determine the module name based on path relative to project root - # This ensures imports like 'from app.services import ...' work - try: - rel_path = os.path.relpath(file_path, project_root) - except ValueError: - # If file is not under project root, we can't easily determine module name - # relative to project root. Skip or warn. - print( - f"Skipping {file_path}: cannot determine relative path to {project_root}" - ) - continue - - # Convert file path to module name (e.g. app/services/foo.py -> app.services.foo) - module_name = os.path.splitext(rel_path)[0].replace(os.sep, ".") - - print(f"Found: {rel_path} -> {module_name}") - - extensions.append(Extension(module_name, [file_path])) - - if not extensions: - print("No Python files found to compile.") - return - - print(f"\nCompiling {len(extensions)} modules...") - - # Build options - # compiler_directives: language_level=3 for Python 3 - # force=True: force recompilation even if timestamps are up to date - try: - setup( - ext_modules=cythonize( - extensions, - compiler_directives={"language_level": "3"}, - build_dir="build", # Put intermediate files in build/ directory - force=True, - ), - script_args=["build_ext", "--inplace"], - ) - print("\nCompilation successful!") - except Exception as e: - print(f"\nCompilation failed: {e}") - sys.exit(1) - finally: - # Cleanup build directory (intermediate C files) - if os.path.exists("build"): - print("Cleaning up build artifacts...") - try: - shutil.rmtree("build") - except OSError as e: - print(f"Warning: Failed to clean up build directory: {e}") - - -if __name__ == "__main__": - # Default directories to compile if none provided - DEFAULT_TARGETS = ["app/services", "app/native", "app/services"] - - # Check for help flag - if len(sys.argv) > 1 and sys.argv[1] in ["--help", "-h"]: - print("Usage: python scripts/build_extensions.py [directory1] [directory2] ...") - print( - "Compiles all Python files in the given directories into C extensions (.so/.pyd)." - ) - print(f"Default directories if none provided: {DEFAULT_TARGETS}") - sys.exit(0) - - if len(sys.argv) > 1: - target_directories = sys.argv[1:] - else: - print(f"No directories specified. Using defaults: {DEFAULT_TARGETS}") - target_directories = DEFAULT_TARGETS - - build_extensions(target_directories)