mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
135 lines
4.4 KiB
Python
135 lines
4.4 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
if __package__ in {None, ""}:
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
from wrappergen.clang_frontend import build_module_model
|
|
from wrappergen.config import CompilationConfig, IgnoreConfig, WrapperConfig
|
|
from wrappergen.emit import write_module_outputs
|
|
else:
|
|
from .clang_frontend import build_module_model
|
|
from .config import CompilationConfig, IgnoreConfig, WrapperConfig
|
|
from .emit import write_module_outputs
|
|
|
|
|
|
def _existing_directories(paths: list[Path]) -> list[str]:
|
|
seen: set[str] = set()
|
|
results: list[str] = []
|
|
for path in paths:
|
|
resolved = str(path.resolve())
|
|
if path.is_dir() and resolved not in seen:
|
|
seen.add(resolved)
|
|
results.append(resolved)
|
|
return results
|
|
|
|
|
|
def _discover_headers(src_ifcparse: Path) -> list[str]:
|
|
return [
|
|
str(path.resolve())
|
|
for path in sorted(src_ifcparse.glob("*.h"))
|
|
if path.parent.name != "schemas"
|
|
]
|
|
|
|
|
|
def _discover_boost_include_dirs() -> list[Path]:
|
|
candidates: list[Path] = []
|
|
prefix = Path(sys.prefix)
|
|
candidates.extend(
|
|
[
|
|
prefix / "Library" / "include",
|
|
prefix / "include",
|
|
]
|
|
)
|
|
|
|
executable = Path(sys.executable).resolve()
|
|
conda_root = executable.parents[2] if len(executable.parents) >= 3 else None
|
|
if conda_root is None:
|
|
return candidates
|
|
|
|
pkgs = conda_root / "pkgs"
|
|
if not pkgs.is_dir():
|
|
return candidates
|
|
|
|
for pattern in ("libboost-headers-*", "boost-cpp-*"):
|
|
for package_dir in sorted(pkgs.glob(pattern), reverse=True):
|
|
include_dir = package_dir / "Library" / "include"
|
|
if (include_dir / "boost" / "lexical_cast.hpp").is_file():
|
|
candidates.append(include_dir)
|
|
return candidates
|
|
|
|
|
|
def build_default_wrapper_config(repo_root: Path) -> WrapperConfig:
|
|
src_ifcparse = repo_root / "src" / "ifcparse"
|
|
include_dirs = _existing_directories([src_ifcparse, *_discover_boost_include_dirs()])
|
|
return WrapperConfig(
|
|
module_name="ifcopenshell_experimental",
|
|
c_prefix="ifcopenshell",
|
|
api_header_name="ifcopenshell_experimental_c_api.h",
|
|
api_implementation_name="ifcopenshell_experimental_c_api.cpp",
|
|
extension_source_name="_ifcopenshell_experimental.cpp",
|
|
python_source_name="ifcopenshell_experimental.py",
|
|
allowed_namespaces=["ifcopenshell", "express"],
|
|
enum_names={"ifcopenshell::filetype": "FileType"},
|
|
parameter_names={"type": "filetype", "read_only": "readonly"},
|
|
class_handle_kinds={"ifcopenshell::file": "shared_ptr"},
|
|
class_owner_types={
|
|
"express::Base": "ifcopenshell::file",
|
|
"express::Entity": "ifcopenshell::file",
|
|
"express::Select": "ifcopenshell::file",
|
|
"express::DeclaredType": "ifcopenshell::file",
|
|
},
|
|
type_adapters={
|
|
"std::string": "string",
|
|
"int": "integer",
|
|
"size_t": "integer",
|
|
"std::size_t": "integer",
|
|
"unsigned int": "integer",
|
|
"uint32_t": "integer",
|
|
"bool": "bool",
|
|
"void": "void",
|
|
},
|
|
ignore=IgnoreConfig(
|
|
namespaces=["ifcopenshell::impl"],
|
|
classes=[],
|
|
enums=[],
|
|
methods=[],
|
|
),
|
|
compilation=CompilationConfig(
|
|
headers=_discover_headers(src_ifcparse),
|
|
include_dirs=include_dirs,
|
|
),
|
|
)
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(
|
|
description="Generate an experimental C API, CPython module, and Python facade for ifcparse."
|
|
)
|
|
parser.add_argument(
|
|
"--repo-root",
|
|
default=str(Path(__file__).resolve().parents[2]),
|
|
help="Repository root that contains src/ifcparse",
|
|
)
|
|
parser.add_argument(
|
|
"--output-dir",
|
|
default=str(Path(__file__).resolve().parent / "generated"),
|
|
help="Directory that will receive the generated files",
|
|
)
|
|
return parser.parse_args()
|
|
|
|
|
|
def main() -> int:
|
|
arguments = parse_args()
|
|
repo_root = Path(arguments.repo_root).resolve()
|
|
output_dir = Path(arguments.output_dir).resolve()
|
|
model = build_module_model(build_default_wrapper_config(repo_root))
|
|
write_module_outputs(model, output_dir)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|