(argv: List[str] | None = None)
| 376 | |
| 377 | |
| 378 | def main(argv: List[str] | None = None) -> int: |
| 379 | ap = argparse.ArgumentParser(description=__doc__) |
| 380 | ap.add_argument("--mujoco-include", default=os.path.join( |
| 381 | _PLUGIN_ROOT, "third_party", "install", "MuJoCo", "include", |
| 382 | )) |
| 383 | ap.add_argument("--output", default=os.path.join( |
| 384 | _PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "introspect_snapshot.json", |
| 385 | )) |
| 386 | ap.add_argument("--libclang", default=None, |
| 387 | help="path to libclang.dll/.so/.dylib; overrides auto-detect") |
| 388 | ap.add_argument("--urlab-source-root", default=os.path.join( |
| 389 | _PLUGIN_ROOT, "Source", "URLab", "Public", |
| 390 | ), help="root for the EMj* hand-enum libclang scrape; skipped if empty") |
| 391 | args = ap.parse_args(argv) |
| 392 | |
| 393 | try: |
| 394 | import clang.cindex as cx |
| 395 | except ImportError: |
| 396 | print("ERROR: clang.cindex not installed. Run " |
| 397 | "`uv run --with libclang python build_introspect_snapshot.py` " |
| 398 | "or `pip install libclang`.", file=sys.stderr) |
| 399 | return 1 |
| 400 | |
| 401 | if args.libclang: |
| 402 | cx.Config.set_library_file(args.libclang) |
| 403 | elif os.environ.get("LIBCLANG_LIBRARY_FILE"): |
| 404 | cx.Config.set_library_file(os.environ["LIBCLANG_LIBRARY_FILE"]) |
| 405 | |
| 406 | mujoco_include = args.mujoco_include |
| 407 | if not os.path.exists(mujoco_include): |
| 408 | print(f"ERROR: --mujoco-include not found: {mujoco_include}", file=sys.stderr) |
| 409 | return 2 |
| 410 | |
| 411 | mjspec_h = os.path.join(mujoco_include, "mujoco", "mjspec.h") |
| 412 | mjmodel_h = os.path.join(mujoco_include, "mujoco", "mjmodel.h") |
| 413 | mjxmacro_h = os.path.join(mujoco_include, "mujoco", "mjxmacro.h") |
| 414 | |
| 415 | # mjspecmacro.h ships in the installed MuJoCo headers (post-3.9.0); hashed |
| 416 | # alongside the others so the snapshot invalidates when it changes. |
| 417 | mjspecmacro_h = os.path.join(mujoco_include, "mujoco", "mjspecmacro.h") |
| 418 | |
| 419 | # Synthesize a small dispatch source that #includes the headers we |
| 420 | # care about. Letting clang chew on a real .c lets it resolve types |
| 421 | # without us threading -include flags. |
| 422 | dispatch_c = "\n".join([ |
| 423 | "#include <mujoco/mjmodel.h>", |
| 424 | "#include <mujoco/mjspec.h>", |
| 425 | "#include <mujoco/mjxmacro.h>", |
| 426 | "#include <mujoco/mujoco.h>", |
| 427 | ]) |
| 428 | args_clang = [ |
| 429 | "-x", "c", |
| 430 | "-std=c11", |
| 431 | f"-I{mujoco_include}", |
| 432 | "-DMJ_STATIC", # avoid MJAPI dllimport/export linkage attrs |
| 433 | ] |
| 434 | |
| 435 | try: |
no test coverage detected