Skip to content

Commit

Permalink
#20 Add castxml_compiler option
Browse files Browse the repository at this point in the history
  • Loading branch information
kwabenantim committed Nov 22, 2024
1 parent 2db10e4 commit 309835f
Show file tree
Hide file tree
Showing 21 changed files with 46 additions and 40 deletions.
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exclude =
__pycache__,
.git,
.github,
.venv,
build,
cppwg/templates,
doc,
Expand Down
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,30 @@ pip install .
## Usage

```
usage: cppwg [-h] [-w WRAPPER_ROOT] [-p PACKAGE_INFO] [-c CASTXML_BINARY]
[--std STD] [-i [INCLUDES ...]] [-q] [-l [LOGFILE]] [-v]
SOURCE_ROOT
usage: cppwg [-h] [-w WRAPPER_ROOT] [-p PACKAGE_INFO] [-c CASTXML_BINARY]
[-m CASTXML_COMPILER] [--std STD] [-i [INCLUDES ...]] [-q]
[-l [LOGFILE]] [-v] SOURCE_ROOT
Generate Python Wrappers for C++ code
positional arguments:
SOURCE_ROOT Path to the root directory of the input C++ source
code.
SOURCE_ROOT Path to the root directory of the input C++ source code.
options:
-h, --help show this help message and exit
-w WRAPPER_ROOT, --wrapper_root WRAPPER_ROOT
Path to the output directory for the Pybind11 wrapper
code.
-p PACKAGE_INFO, --package_info PACKAGE_INFO
-w, --wrapper_root WRAPPER_ROOT
Path to the output directory for the Pybind11 wrapper code.
-p, --package_info PACKAGE_INFO
Path to the package info file.
-c CASTXML_BINARY, --castxml_binary CASTXML_BINARY
-c, --castxml_binary CASTXML_BINARY
Path to the castxml executable.
-m, --castxml_compiler CASTXML_COMPILER
Path to a compiler to be used by castxml.
--std STD C++ standard e.g. c++17.
-i [INCLUDES ...], --includes [INCLUDES ...]
-i, --includes [INCLUDES ...]
List of paths to include directories.
-q, --quiet Disable informational messages.
-l [LOGFILE], --logfile [LOGFILE]
-l, --logfile [LOGFILE]
Output log messages to a file.
-v, --version Print cppwg version.
```
Expand Down Expand Up @@ -97,7 +97,8 @@ cd examples/shapes
cppwg src/cpp \
--wrapper_root wrapper \
--package_info wrapper/package_info.yaml \
--includes src/cpp/geometry src/cpp/math_funcs src/cpp/mesh src/cpp/primitives
--includes src/cpp/geometry src/cpp/math_funcs src/cpp/primitives \
--std c++17
```

For the `Rectangle` class, this creates two files in
Expand Down
8 changes: 8 additions & 0 deletions cppwg/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ def parse_args() -> argparse.Namespace:
help="Path to the castxml executable.",
)

parser.add_argument(
"-m",
"--castxml_compiler",
type=str,
help="Path to a compiler to be used by castxml.",
)

# Note: we're passing in std directly because syntax like
# --castxml_cflags "-std=c++17" isn't supported by argparse because of
# the initial "-" in the argument. See https://bugs.python.org/issue9334
Expand Down Expand Up @@ -112,6 +119,7 @@ def generate(args: argparse.Namespace) -> None:
package_info_path=args.package_info,
castxml_binary=args.castxml_binary,
castxml_cflags=castxml_cflags,
castxml_compiler=args.castxml_compiler,
)

generator.generate()
Expand Down
16 changes: 15 additions & 1 deletion cppwg/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import os
import re
import shutil
import subprocess
import uuid
from pathlib import Path
Expand Down Expand Up @@ -40,6 +41,8 @@ class CppWrapperGenerator:
The path to the castxml binary
castxml_cflags : str
Optional cflags to be passed to castxml e.g. "-std=c++17"
castxml_compiler : str
Optional compiler path to be passed to CastXML
package_info_path : str
The path to the package info yaml config file; defaults to "package_info.yaml"
source_ns : pygccxml.declarations.namespace_t
Expand All @@ -56,6 +59,7 @@ def __init__(
castxml_binary: Optional[str] = None,
package_info_path: Optional[str] = None,
castxml_cflags: Optional[str] = None,
castxml_compiler: Optional[str] = None,
):
logger = logging.getLogger()

Expand Down Expand Up @@ -100,6 +104,16 @@ def __init__(
if castxml_cflags:
self.castxml_cflags = f"{self.castxml_cflags} {castxml_cflags}"

# Try to set castxml compiler
if castxml_compiler:
self.castxml_compiler = castxml_compiler
else:
compiler_path = shutil.which("clang++")
if compiler_path:
self.castxml_compiler = compiler_path
else:
self.castxml_compiler = None

# Sanitize source_root
self.source_root: str = os.path.abspath(source_root)
if not os.path.isdir(self.source_root):
Expand Down Expand Up @@ -195,7 +209,6 @@ def log_unknown_classes(self) -> None:

# Check for uninstantiated class templates not parsed by pygccxml
for hpp_file_path in self.package_info.source_hpp_files:

class_list = utils.find_classes_in_source_file(hpp_file_path)

for _, class_name, _ in class_list:
Expand All @@ -216,6 +229,7 @@ def parse_headers(self) -> None:
self.castxml_binary,
self.source_includes,
self.castxml_cflags,
self.castxml_compiler,
)
self.source_ns = source_parser.parse()

Expand Down
2 changes: 0 additions & 2 deletions cppwg/info/class_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class CppClassInfo(CppEntityInfo):
"""

def __init__(self, name: str, class_config: Optional[Dict[str, Any]] = None):

super().__init__(name, class_config)

self.base_decls: List["declaration_t"] = [] # noqa: F821
Expand Down Expand Up @@ -298,7 +297,6 @@ class instantiation. For example, class "Foo" with template arguments

template_string = ""
for idx, arg in enumerate(template_arg_list):

# Do standard name replacements
arg_str = str(arg)
for name, replacement in self.name_replacements.items():
Expand Down
1 change: 0 additions & 1 deletion cppwg/info/cpp_entity_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class CppEntityInfo(BaseInfo):
"""

def __init__(self, name: str, entity_config: Optional[Dict[str, Any]] = None):

super().__init__(name, entity_config)

self.name_override: str = ""
Expand Down
1 change: 0 additions & 1 deletion cppwg/info/free_function_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class CppFreeFunctionInfo(CppEntityInfo):
def __init__(
self, name: str, free_function_config: Optional[Dict[str, Any]] = None
):

super().__init__(name, free_function_config)

def update_from_ns(self, source_ns: "namespace_t") -> None: # noqa: F821
Expand Down
1 change: 0 additions & 1 deletion cppwg/info/method_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class CppMethodInfo(CppEntityInfo):
"""

def __init__(self, name: str, _) -> None:

super().__init__(name)

self.class_info: Optional["CppClassInfo"] = None # noqa: F821
Expand Down
1 change: 0 additions & 1 deletion cppwg/info/variable_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ class CppVariableInfo(CppEntityInfo):
"""An information structure for individual variables to be wrapped."""

def __init__(self, name: str, variable_config: Optional[Dict[str, Any]] = None):

super().__init__(name, variable_config)
12 changes: 7 additions & 5 deletions cppwg/parsers/source_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@ class CppSourceParser:
----------
castxml_cflags : str
Optional cflags to be passed to CastXML e.g. "-std=c++17"
castxml_compiler : str
Optional compiler path to be passed to CastXML
castxml_binary : str
The path to the CastXML binary
global_ns : namespace_t
The namespace containing all parsed C++ declarations
source_includes : List[str]
The list of source include paths
source_ns : namespace_t
The namespace containing C++ declarations from the source tree
source_root : str
The root directory of the source code
wrapper_header_collection : str
Expand All @@ -51,12 +49,14 @@ def __init__(
castxml_binary: str,
source_includes: List[str],
castxml_cflags: str = "",
castxml_compiler: str = None,
):
self.source_root: str = source_root
self.wrapper_header_collection: str = wrapper_header_collection
self.castxml_binary: str = castxml_binary
self.source_includes: List[str] = source_includes
self.castxml_cflags: str = castxml_cflags
self.castxml_compiler: str = castxml_compiler

def parse(self) -> namespace_t:
"""
Expand All @@ -74,8 +74,10 @@ def parse(self) -> namespace_t:
xml_generator_path=self.castxml_binary,
xml_generator="castxml",
cflags=self.castxml_cflags,
compiler_path=self.castxml_compiler,
include_paths=self.source_includes,
)
logger.info(f"Using compiler: {xml_generator_config.compiler_path}")

# Parse all the C++ source code to extract declarations
logger.info("Parsing source code for declarations.")
Expand All @@ -85,7 +87,7 @@ def parse(self) -> namespace_t:
compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE,
)

# Get access to the global namespace
# Get access to the global namespace containing all parsed C++ declarations
global_ns: namespace_t = declarations.get_global_namespace(decls)

# Filter declarations for which files exist
Expand Down
1 change: 0 additions & 1 deletion cppwg/writers/base_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class CppBaseWrapperWriter:
"""

def __init__(self, wrapper_templates: Dict[str, str]) -> None:

self.wrapper_templates = wrapper_templates
self.tidy_replacements = OrderedDict(
[
Expand Down
4 changes: 1 addition & 3 deletions cppwg/writers/class_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,7 @@ def write(self, work_dir: str) -> None:
continue

# Find and define virtual function "trampoline" overrides
methods_needing_override: List["member_function_t"] = ( # noqa: F821
self.add_virtual_overrides(idx)
)
methods_needing_override = self.add_virtual_overrides(idx)

# Add the virtual "trampoline" overrides from "Foo_Overrides" to
# the "Foo" wrapper class definition if needed
Expand Down
1 change: 0 additions & 1 deletion cppwg/writers/constructor_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def __init__(
ctor_decl: "constructor_t", # noqa: F821
wrapper_templates: Dict[str, str],
) -> None:

super().__init__(wrapper_templates)

self.class_info: "CppClassInfo" = class_info # noqa: F821
Expand Down
1 change: 0 additions & 1 deletion cppwg/writers/free_function_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class CppFreeFunctionWrapperWriter(CppBaseWrapperWriter):
"""

def __init__(self, free_function_info, wrapper_templates) -> None:

super().__init__(wrapper_templates)

self.free_function_info: CppFreeFunctionInfo = free_function_info
Expand Down
1 change: 0 additions & 1 deletion cppwg/writers/header_collection_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def __init__(
wrapper_root: str,
hpp_collection_file: str,
):

self.package_info: PackageInfo = package_info
self.wrapper_root: str = wrapper_root
self.hpp_collection_file: str = hpp_collection_file
Expand Down
1 change: 0 additions & 1 deletion cppwg/writers/method_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def __init__(
method_decl: "member_function_t", # noqa: F821
wrapper_templates: Dict[str, str],
) -> None:

super().__init__(wrapper_templates)

self.class_info: "CppClassInfo" = class_info # noqa: F821
Expand Down
1 change: 0 additions & 1 deletion examples/cells/src/py/pycells/_syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@


class TemplateClassDict:

def __init__(self, template_dict):
self._dict = {}
for arg_tuple, cls in template_dict.items():
Expand Down
1 change: 0 additions & 1 deletion examples/cells/tests/test_cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


class TestCells(unittest.TestCase):

def testVtkCaster(self):
scene = Scene[2]()
renderer = scene.GetRenderer()
Expand Down
1 change: 0 additions & 1 deletion examples/shapes/src/py/pyshapes/_syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@


class TemplateClassDict:

def __init__(self, template_dict):
self._dict = {}
for arg_tuple, cls in template_dict.items():
Expand Down
3 changes: 0 additions & 3 deletions examples/shapes/src/py/tests/test_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@


class TestClasses(unittest.TestCase):

def testGeometry(self):

p0 = pyshapes.geometry.Point_2()
self.assertTrue(p0.GetLocation() == [0.0, 0.0])

Expand Down Expand Up @@ -36,7 +34,6 @@ def testGeometry(self):
self.assertTrue(len(cuboid.rGetVertices()) == 8)

def testSyntax(self):

self.assertEqual(pyshapes.geometry.Point[2], pyshapes.geometry.Point_2)

point = pyshapes.geometry.Point[3](0.0, 1.0, 2.0)
Expand Down
1 change: 0 additions & 1 deletion examples/shapes/src/py/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class TestFunctions(unittest.TestCase):

def testAdd(self):
a = 4
b = 5
Expand Down

0 comments on commit 309835f

Please sign in to comment.