Remove llvm_c_test from package

This commit is contained in:
Duncan Ogilvie
2026-05-11 16:45:05 +02:00
parent a681b3656e
commit 26763333c2
11 changed files with 120 additions and 53 deletions
+3 -3
View File
@@ -12,7 +12,7 @@ uv run <command> # Auto-rebuilds the extension if ne
# Testing
uv run run_tests.py # Main golden-master suite: C++ tests + paired Python comparison
uv run run_tests.py --regressions # Python regression scripts in tests/regressions/
uv run run_llvm_c_tests.py # Vendored llvm-c-test lit tests (C binary)
uv run run_llvm_c_tests.py # Vendored llvm-c-test lit tests (auto-rebuilds C binary)
uv run run_llvm_c_tests.py --use-python # Vendored llvm-c-test lit tests with Python implementation
uv run run_llvm_c_tests.py -v # Run lit tests with verbose output
./build/test_factorial # Run single C++ test
@@ -20,8 +20,8 @@ uv run test_factorial.py # Run single Python test
uv run pytest tests/regressions/... # Target a specific regression file or subset
uv run tests/test_module.py # Python tests are intended to be directly runnable scripts
uv run tests/regressions/test_const_bytes.py # Regression scripts should also run directly via __main__
uv run llvm-c-test --targets-list # Run llvm-c-test directly (dev-only tool)
./llvm-c-test --echo < input.bc # Can also invoke directly (auto-finds venv)
uv run python -m llvm_c_test --targets-list # Run Python llvm-c-test port directly (dev-only tool)
./build/llvm-c-test --echo < input.bc # Run vendored C llvm-c-test binary directly
uvx ty check # Type check Python code (not a test runner)
uvx ty check llvm_c_test/ # Type check specific directory
+4
View File
@@ -82,12 +82,16 @@ uv run run_tests.py
uv run run_tests.py --regressions
# Vendored llvm-c-test lit suite against the C test binary
# Rebuilds the vendored C binary before running lit.
uv run run_llvm_c_tests.py
uv run run_llvm_c_tests.py -v
# Vendored llvm-c-test lit suite against the Python implementation
uv run run_llvm_c_tests.py --use-python
# Run the Python llvm-c-test port directly during development
uv run python -m llvm_c_test --targets-list
# Type checking (not a test suite, but commonly run in CI/dev)
uvx ty check
```
+1 -1
View File
@@ -22,7 +22,7 @@ Port the LLVM-C test suite (`llvm-c-test`) from C/C++ to Python as a **drop-in r
```
llvm_c_test/
├── __init__.py
├── __main__.py # CLI entry point (uv run llvm-c-test)
├── __main__.py # CLI entry point (uv run python -m llvm_c_test)
├── main.py # Command dispatcher
├── helpers.py # tokenize_stdin(), shared utilities
├── targets.py # --targets-list
+5
View File
@@ -34,6 +34,11 @@ if not llvm_tools_dir:
if not llvm_c_test_cmd:
lit_config.fatal("LLVM_C_TEST_CMD environment variable not set")
# Forward PYTHONPATH for the dev-only Python llvm-c-test implementation.
# The package is intentionally not installed into site-packages.
if pythonpath := os.environ.get("PYTHONPATH"):
config.environment["PYTHONPATH"] = pythonpath
# Tool substitutions
# On Windows, wrap individual tool paths with quotes to handle backslashes in bash
+3 -3
View File
@@ -2,9 +2,9 @@
CLI entry point for llvm-c-test Python port.
Usage:
uv run llvm-c-test --targets-list
uv run llvm-c-test --calc < calc.test
uv run llvm-c-test --module-dump < input.bc
uv run python -m llvm_c_test --targets-list
uv run python -m llvm_c_test --calc < calc.test
uv run python -m llvm_c_test --module-dump < input.bc
"""
import sys
+6 -8
View File
@@ -10,9 +10,6 @@ readme = "README.md"
requires-python = ">=3.12"
dependencies = []
[project.scripts]
llvm-c-test = "llvm_c_test.main:main"
[project.urls]
Homepage = "https://github.com/LLVMParty/llvm-nanobind"
@@ -33,14 +30,17 @@ minimum-version = "build-system.requires"
# Setuptools-style build caching in a local directory
build-dir = "build/{wheel_tag}"
# Package builds only need the extension and generated stubs.
build.targets = ["llvm_stub"]
# Build stable ABI wheels for CPython 3.12+
wheel.py-api = "cp312"
# This setup only works properly in redirect mode
editable.mode = "redirect"
# Install the llvm_c_test Python package
wheel.packages = ["llvm_c_test"]
# Do not auto-copy Python packages into wheels; the extension module is installed by CMake.
wheel.packages = []
[[tool.scikit-build.overrides]]
if.platform-system = "win32"
@@ -51,9 +51,6 @@ cache-keys = [
{ file = "CMakeLists.txt" },
{ file = "src/**/*.cpp" },
{ file = "src/**/*.h" },
{ file = "llvm-c/llvm-c-test/*.c" },
{ file = "llvm-c/llvm-c-test/*.cpp" },
{ file = "llvm-c/llvm-c-test/*.h" },
]
[tool.ty.src]
@@ -103,3 +100,4 @@ exclude_lines = [
[tool.pytest.ini_options]
addopts = "--deselect tests/regressions/test_symbol_size_crash.py"
pythonpath = ["."]
+77 -33
View File
@@ -15,6 +15,9 @@ Options:
--llvm-prefix PATH Path to LLVM installation prefix
--use-python Use Python implementation instead of C binary
When running against the C binary, this script rebuilds the vendored
llvm-c-test target before invoking lit.
Examples:
python run_llvm_c_tests.py # Run all tests (C binary)
python run_llvm_c_tests.py --use-python # Run with Python implementation
@@ -114,14 +117,60 @@ def parse_args(args: list[str]) -> tuple[str | None, bool, list[str]]:
return llvm_prefix, use_python, remaining
def find_llvm_c_test_exe(build_dir: Path) -> Path:
"""Find the vendored llvm-c-test executable in a CMake build directory."""
exe_name = "llvm-c-test.exe" if sys.platform == "win32" else "llvm-c-test"
candidates = [
build_dir / exe_name,
build_dir / "Release" / exe_name,
build_dir / "RelWithDebInfo" / exe_name,
build_dir / "Debug" / exe_name,
build_dir / "MinSizeRel" / exe_name,
]
for candidate in candidates:
if candidate.exists():
return candidate
return candidates[0]
def build_vendored_llvm_c_test(project_root: Path) -> Path:
"""Rebuild the vendored C llvm-c-test target and return its executable path."""
build_dir = project_root / "build"
cmd = ["cmake", "--build", str(build_dir), "--target", "llvm-c-test-vendored"]
print("Building vendored llvm-c-test C binary...", flush=True)
result = subprocess.run(cmd, cwd=project_root)
if result.returncode != 0:
print(
f"Error: failed to build llvm-c-test-vendored (exit {result.returncode})",
file=sys.stderr,
)
sys.exit(result.returncode)
llvm_c_test_exe = find_llvm_c_test_exe(build_dir)
if not llvm_c_test_exe.exists():
print(
f"Error: llvm-c-test executable not found after build: {llvm_c_test_exe}",
file=sys.stderr,
)
print(
"Build with: cmake --build build --target llvm-c-test-vendored",
file=sys.stderr,
)
sys.exit(1)
return llvm_c_test_exe
def build_llvm_c_test_cmd(
use_python: bool, project_root: Path
use_python: bool, project_root: Path, llvm_c_test_exe: Path | None = None
) -> tuple[str, dict[str, str]]:
"""Build the llvm-c-test command string and extra environment variables.
Args:
use_python: If True, use Python implementation; otherwise use C binary.
project_root: Path to project root for locating files.
llvm_c_test_exe: Path to the vendored C binary when not using Python.
Returns:
Tuple of (command string, extra environment variables dict).
@@ -129,6 +178,17 @@ def build_llvm_c_test_cmd(
extra_env: dict[str, str] = {}
if use_python:
# The llvm_c_test package is a dev-only source package, not an installed
# distribution entry point. Make it importable for lit subprocesses while
# preferring the freshly built extension module from build/.
pythonpath_entries = [
str((project_root / "build").resolve()),
str(project_root.resolve()),
]
if existing_pythonpath := os.environ.get("PYTHONPATH"):
pythonpath_entries.append(existing_pythonpath)
extra_env["PYTHONPATH"] = os.pathsep.join(pythonpath_entries)
# Check if we should enable coverage or logging
coverage_run = os.environ.get("COVERAGE_RUN")
@@ -145,22 +205,20 @@ def build_llvm_c_test_cmd(
coverage_file_arg = coverage_file.as_posix()
cmd = f"{python_exe} -m coverage run --parallel-mode --data-file={coverage_file_arg} -m llvm_c_test"
else:
# Direct invocation using the installed script
# Direct invocation using the Python module
cmd = f"{python_exe} -m llvm_c_test"
return cmd, extra_env
else:
# Use C binary
llvm_c_test_exe = project_root / "build" / "llvm-c-test"
if sys.platform == "win32":
llvm_c_test_exe = llvm_c_test_exe.with_suffix(".exe")
# On Windows, quote the path to handle backslashes in bash
exe_path = str(llvm_c_test_exe)
if sys.platform == "win32":
exe_path = f'"{exe_path}"'
if llvm_c_test_exe is None:
llvm_c_test_exe = find_llvm_c_test_exe(project_root / "build")
return exe_path, extra_env
# On Windows, quote the path to handle backslashes in bash
exe_path = str(llvm_c_test_exe)
if sys.platform == "win32":
exe_path = f'"{exe_path}"'
return exe_path, extra_env
def prefer_windows_git_bash(env: dict[str, str]) -> str | None:
@@ -200,28 +258,14 @@ def main():
print("Run: cmake -B build -G Ninja && cmake --build build", file=sys.stderr)
sys.exit(1)
# Build the llvm-c-test command
llvm_c_test_cmd, extra_env = build_llvm_c_test_cmd(use_python, project_root)
# Verify C binary exists if not using Python
llvm_c_test_exe = None
if not use_python:
llvm_c_test_exe = project_root / "build" / "llvm-c-test"
if sys.platform == "win32":
llvm_c_test_exe = llvm_c_test_exe.with_suffix(".exe")
llvm_c_test_exe = build_vendored_llvm_c_test(project_root)
if not llvm_c_test_exe.exists():
print(
f"Error: llvm-c-test executable not found: {llvm_c_test_exe}",
file=sys.stderr,
)
print(
"Build with: cmake --build build --target llvm-c-test-vendored",
file=sys.stderr,
)
print(
"Or use --use-python to run with Python implementation", file=sys.stderr
)
sys.exit(1)
# Build the llvm-c-test command
llvm_c_test_cmd, extra_env = build_llvm_c_test_cmd(
use_python, project_root, llvm_c_test_exe
)
# Get LLVM tools directory
llvm_prefix = get_llvm_prefix(llvm_prefix_arg)
@@ -288,7 +332,7 @@ def main():
print(" Mode: Python implementation")
else:
print(" Mode: C binary")
print()
print(flush=True)
result = subprocess.run(lit_args, env=env)
sys.exit(result.returncode)
+7 -1
View File
@@ -106,10 +106,16 @@ def run_python_test(script: Path) -> tuple[str, str, int]:
# Build command with optional coverage wrapper
cmd = coverage_wrap(script.stem, [str(script)])
# Prefer the freshly built extension while keeping the repository root
# importable for dev-only helper packages such as tools.obfuscation.
pythonpath_entries = [str(BUILD_DIR.resolve()), str(Path(__file__).parent.resolve())]
if existing_pythonpath := os.environ.get("PYTHONPATH"):
pythonpath_entries.append(existing_pythonpath)
result = subprocess.run(
[sys.executable] + cmd,
capture_output=True,
env={**os.environ, "PYTHONPATH": str(BUILD_DIR)},
env={**os.environ, "PYTHONPATH": os.pathsep.join(pythonpath_entries)},
)
try:
stdout = result.stdout.decode("utf-8")
+12 -2
View File
@@ -31,6 +31,10 @@ is in llvm-c/llvm-c-test/debuginfo.c.
import subprocess
import sys
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[2]
def get_function_dbg_id(output: str) -> str | None:
@@ -50,19 +54,25 @@ def get_function_dbg_id(output: str) -> str | None:
def run_python_dibuilder():
"""Run Python --test-dibuilder and capture output."""
result = subprocess.run(
["uv", "run", "llvm-c-test", "--test-dibuilder"],
[sys.executable, "-m", "llvm_c_test", "--test-dibuilder"],
capture_output=True,
text=True,
cwd=PROJECT_ROOT,
)
return result.stdout
def run_c_dibuilder():
"""Run C --test-dibuilder and capture output."""
exe = PROJECT_ROOT / "build" / "llvm-c-test"
if sys.platform == "win32":
exe = exe.with_suffix(".exe")
result = subprocess.run(
["./build/llvm-c-test", "--test-dibuilder"],
[str(exe), "--test-dibuilder"],
capture_output=True,
text=True,
cwd=PROJECT_ROOT,
)
return result.stdout
+1 -1
View File
@@ -101,7 +101,7 @@ def test_symbol_size_crash():
print("\nTest completed (crash avoided by not accessing .size)")
print("\nTo trigger the crash, uncomment the 'size = sym_iter.size' line")
print("or run: cat <object_file> | llvm-c-test --object-list-symbols")
print("or run: cat <object_file> | ./build/llvm-c-test --object-list-symbols")
def test_with_existing_object():
Generated
+1 -1
View File
@@ -1,5 +1,5 @@
version = 1
revision = 3
revision = 2
requires-python = ">=3.12"
[[package]]