Skip to content

Commit d1050ca

Browse files
committed
bikeshed
1 parent cd613aa commit d1050ca

File tree

10 files changed

+130
-121
lines changed

10 files changed

+130
-121
lines changed

examples/demo/meson.build

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
11
project('demo', ['cpp'],
2-
default_options: ['warning_level=1', 'cpp_std=gnu++17',
2+
default_options: ['warning_level=1', 'cpp_std=c++20',
33
'b_colorout=auto', 'optimization=2', 'b_pie=true'])
44

55
# Include autogenerated wrapcfg/meson.build
66
subdir('wrapcfg')
77

88
# Add additional source files to predefined variable in wrapcfg/meson.build
9-
demo_module_sources += files(
9+
demo_sources += files(
1010
'swdemo/src/demo.cpp',
1111
'swdemo/src/main.cpp',
1212
)
1313

1414
# You can add extra compilation arguments by adding a dependency to predefined
1515
# variable
16-
demo_module_deps += [
16+
demo_deps += [
1717
declare_dependency(include_directories: ['swdemo/include'])
1818
]
1919

2020
# Include autogenerated wrapcfg/modules/meson.build
21+
# - Builds the extension modules
22+
# - Generates the pyi file for the extension modules
2123
subdir('wrapcfg/modules')
22-
23-
# add this here
24-
# - if this is complicated, then it needs to be autogenerated
25-
# - or sw_module_NAME_pyi_deps
26-
# .. easy way is to just make the module dependent on it, then pyi
27-
# only has to depend on that
28-
# custom_target(
29-
# command: [sw_cmd_gen_pyi],
30-
# depends: [rpydemo_module, init_py],
31-
# )

examples/demo/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ version = "0.0.1"
3131

3232
[tool.semiwrap]
3333

34-
[tool.semiwrap.modules."swdemo"]
34+
[tool.semiwrap.extension_modules."swdemo._demo"]
3535
name = "demo"
3636

37-
[tool.semiwrap.modules.swdemo.headers]
37+
[tool.semiwrap.extension_modules."swdemo._demo".headers]
3838
demo = "swdemo/include/demo.h"

src/semiwrap/cmd_gen_libinit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ def main():
121121

122122
pyproject = PyProject(pathlib.Path(pyproject_toml))
123123

124-
module = pyproject.get_module(package_name)
125-
depends = pyproject.get_module_deps(module)
124+
module = pyproject.get_extension(package_name)
125+
depends = pyproject.get_extension_deps(module)
126126

127127
# TODO: libs
128128
# .. oh, those were going to get created by the downloader hatch plugin

src/semiwrap/cmd_gen_modinit_hpp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def _write_wrapper_hpp(
6868
#include <robotpy_build.h>
6969
7070
// Use this to define your module instead of PYBIND11_MODULE
71-
#define SEMIWRAP_PYBIND11_MODULE(variable) PYBIND11_MODULE(_{module_name}, variable)
71+
#define SEMIWRAP_PYBIND11_MODULE(variable) PYBIND11_MODULE({module_name}, variable)
7272
7373
// TODO: namespace semiwrap::autogen {{
7474

src/semiwrap/cmd_genmeson.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
InputFile,
1515
OutputFile,
1616
BuildTarget,
17-
Module,
17+
ExtensionModule,
1818
makeplan,
1919
)
2020
from .util import maybe_write_file
@@ -46,14 +46,14 @@ def _make_string(s: str):
4646

4747
class VarCache:
4848
def __init__(self) -> None:
49-
self.cache: T.Dict[T.Union[InputFile, OutputFile, BuildTarget, Module], str] = (
49+
self.cache: T.Dict[T.Union[InputFile, OutputFile, BuildTarget, ExtensionModule], str] = (
5050
{}
5151
)
5252

5353
# this might get annoying to debug, but for now this is easier...
5454
self.idx = 1
5555

56-
def getvar(self, item: T.Union[InputFile, OutputFile, BuildTarget, Module]) -> str:
56+
def getvar(self, item: T.Union[InputFile, OutputFile, BuildTarget, ExtensionModule]) -> str:
5757
var = self.cache.get(item)
5858
if var is None:
5959

@@ -70,7 +70,7 @@ def getvar(self, item: T.Union[InputFile, OutputFile, BuildTarget, Module]) -> s
7070
# var = f"sw_out_{self.idx}"
7171
elif isinstance(item, BuildTarget):
7272
var = f"_sw_target_{self.idx}"
73-
elif isinstance(item, Module):
73+
elif isinstance(item, ExtensionModule):
7474
var = f"{item.name}_module"
7575
else:
7676
assert False
@@ -103,7 +103,7 @@ def _render_build_target(r: RenderBuffer, vc: VarCache, bt: BuildTarget):
103103
assert depfile is None, bt
104104
cmd.append("'@DEPFILE@'")
105105
depfile = _make_string(arg.name)
106-
elif isinstance(arg, Module):
106+
elif isinstance(arg, ExtensionModule):
107107
cmd.append(f"'@INPUT{len(tinput)}@'")
108108
tinput.append(vc.getvar(arg))
109109
else:
@@ -131,14 +131,14 @@ def _render_build_target(r: RenderBuffer, vc: VarCache, bt: BuildTarget):
131131
r.writeln(")")
132132

133133

134-
def _render_module_stage0(r: RenderBuffer, vc: VarCache, m: Module):
134+
def _render_module_stage0(r: RenderBuffer, vc: VarCache, m: ExtensionModule):
135135

136136
# variables generated here should be deterministic so that users can add
137137
# their own things to it, or use it directly
138138

139139
r.writeln(f"# {m.package_name}")
140-
r.writeln(f"{m.name}_module_sources = []")
141-
r.writeln(f"{m.name}_module_deps = [declare_dependency(")
140+
r.writeln(f"{m.name}_sources = []")
141+
r.writeln(f"{m.name}_deps = [declare_dependency(")
142142
with r.indent():
143143

144144
if m.sources:
@@ -156,23 +156,23 @@ def _render_module_stage0(r: RenderBuffer, vc: VarCache, m: Module):
156156
r.writeln(")]")
157157

158158

159-
def _render_module_stage1(r: RenderBuffer, vc: VarCache, m: Module):
159+
def _render_module_stage1(r: RenderBuffer, vc: VarCache, m: ExtensionModule):
160160

161161
# variables generated here should be deterministic so that users can
162162
# use it directly if they wish
163163

164164
subdir = _make_string(m.install_path.as_posix())
165-
package_name = _make_string(m.package_name)
165+
module_name = _make_string(m.package_name.split(".")[-1])
166166
mvar = vc.getvar(m)
167167

168168
r.writeln(f"# {m.package_name}")
169169
r.writeln(f"{mvar} = sw_py.extension_module(")
170170
with r.indent():
171171
r.write_trim(
172172
f"""
173-
'_{m.name}',
174-
sources: [{m.name}_module_sources],
175-
dependencies: [{m.name}_module_deps],
173+
{module_name},
174+
sources: [{m.name}_sources],
175+
dependencies: [{m.name}_deps],
176176
install: true,
177177
subdir: {subdir},
178178
"""
@@ -196,12 +196,12 @@ def gen_meson(project_root: pathlib.Path) -> T.Tuple[str, str, T.List[Entrypoint
196196
# standard boilerplate here
197197
r0.write_trim(
198198
"""
199-
# This file is automatically generated, DO NOT EDIT
200-
#
201-
# The generator's stable API includes variables that do not start with
202-
# an underscore. Any variables with an underscore may change in the future
203-
# without warning
204-
#
199+
# This file is automatically generated, DO NOT EDIT
200+
#
201+
# The generator's stable API includes variables that do not start with
202+
# an underscore. Any variables with an underscore may change in the future
203+
# without warning
204+
#
205205
206206
sw_py = import('python').find_installation()
207207
@@ -228,7 +228,7 @@ def gen_meson(project_root: pathlib.Path) -> T.Tuple[str, str, T.List[Entrypoint
228228
# is simpler to generate
229229

230230
plan = makeplan(pathlib.Path(project_root))
231-
modules: T.List[Module] = []
231+
modules: T.List[ExtensionModule] = []
232232
pyi_targets: T.List[BuildTarget] = []
233233

234234
for item in plan:
@@ -238,7 +238,7 @@ def gen_meson(project_root: pathlib.Path) -> T.Tuple[str, str, T.List[Entrypoint
238238
pyi_targets.append(item)
239239
else:
240240
_render_build_target(r0, vc, item)
241-
elif isinstance(item, Module):
241+
elif isinstance(item, ExtensionModule):
242242
# defer these to the end
243243
modules.append(item)
244244
elif isinstance(item, Entrypoint):
@@ -250,9 +250,9 @@ def gen_meson(project_root: pathlib.Path) -> T.Tuple[str, str, T.List[Entrypoint
250250
r0.writeln()
251251
r0.write_trim(
252252
"""
253-
#
254-
# Module configurations
255-
#
253+
#
254+
# Module configurations
255+
#
256256
"""
257257
)
258258
r0.writeln()

src/semiwrap/config/pyproject_toml.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
@dataclasses.dataclass
1414
class TypeCasterConfig:
1515
"""
16-
Specifies type casters that this package exports. robotpy-build
16+
Specifies type casters that this package exports. semiwrap
1717
will attempt to detect these types at generation time and include
1818
them in generated wrappers.
1919
2020
.. code-block:: toml
2121
22-
[[tool.robotpy-build.wrappers."PACKAGENAME".type_casters]]
22+
[[tool.semiwrap.modules."PACKAGENAME".type_casters]]
2323
header = "my_type_caster.h"
2424
types = ["foo_t", "ns::ins::bar_t"]
2525
@@ -41,25 +41,34 @@ class TypeCasterConfig:
4141

4242

4343
@dataclasses.dataclass
44-
class ModuleConfig:
44+
class ExtensionModuleConfig:
4545
"""
4646
Configuration for generating pybind11 wrappers around specified header files.
47-
The
47+
48+
.. code-block:: toml
49+
50+
[tool.semiwrap.extension_modules."PACKAGE.NAME"]
51+
4852
"""
4953

50-
#: Name that other projects/wrappers use in their 'depends' list
51-
name: str
54+
#: The name used internally to refer to this extension module. The name is
55+
#: used as the prefix of variable names in build files.
56+
#:
57+
#: If not specified, the default name is the package name with invalid
58+
#: characters replaced by underscores.
59+
name: Optional[str] = None
5260

5361
#: Name of generated file that ensures the shared libraries and any
54-
#: dependencies are loaded. Defaults to ``_init_{name}.py``
62+
#: dependencies are loaded. Defaults to ``_init_XXX.py``, where XXX
63+
#: is the last element of the package name
5564
#:
5665
#: Generally, you should create an ``__init__.py`` file that imports
5766
#: this module, otherwise your users will need to do so.
5867
libinit: Optional[str] = None
5968

6069
#: Name of pkgconf libraries that this is wrapping. This is also added to
6170
#: depends list.
62-
wraps: List[str] = []
71+
wraps: List[str] = dataclasses.field(default_factory=list)
6372

6473
#: List of pkgconf library dependencies. This affects this wrapper
6574
#: library in the following ways:
@@ -75,10 +84,6 @@ class ModuleConfig:
7584
#: project root.
7685
extra_includes: List[str] = dataclasses.field(default_factory=list)
7786

78-
# #: Optional source files to compile. Path is relative to the root of
79-
# #: the project.
80-
# sources: List[str] = dataclasses.field(default_factory=list)
81-
8287
#: Specifies header files that autogenerated pybind11 wrappers will be
8388
#: created for. Simple C++ headers will most likely 'just work', but
8489
#: complex headers will need to have an accompanying :attr:`generation_data`
@@ -92,21 +97,21 @@ class ModuleConfig:
9297
#:
9398
#: .. code-block:: toml
9499
#:
95-
#: [tool.robotpy-build.wrappers."PACKAGENAME".headers]
100+
#: [tool.semiwrap.extension_modules."PACKAGE.NAME".headers]
96101
#: Name = "header.h"
97102
#:
98103
#: .. seealso:: :ref:`autowrap`
99104
#:
100-
headers: Dict[str, str] = {}
105+
headers: Dict[str, str] = dataclasses.field(default_factory=dict)
101106

102107
#: Path to a directory of yaml files. Generation data will be looked up
103108
#: using the key in the generate dictionary.
104109
#:
105-
#: These YAML files can be generated via the robotpy-build command line tool:
110+
#: These YAML files can be generated via the semiwrap command line tool:
106111
#:
107112
#: .. code-block:: sh
108113
#:
109-
#: robotpy-build create-gen --write
114+
#: semiwrap create-gen --write
110115
#:
111116
#: .. seealso:: :ref:`gendata`
112117
#:
@@ -116,7 +121,7 @@ class ModuleConfig:
116121
type_casters: List[TypeCasterConfig] = dataclasses.field(default_factory=list)
117122

118123
#: Preprocessor definitions to apply when compiling this wrapper.
119-
pp_defines: List[str] = dataclasses.field(default_factory=list)
124+
# pp_defines: List[str] = dataclasses.field(default_factory=list)
120125

121126
#: If True, skip this wrapper; typically used in conjection with an override.
122127
ignore: bool = False
@@ -138,13 +143,14 @@ class SemiwrapToolConfig:
138143
scan_headers_ignore: List[str] = dataclasses.field(default_factory=list)
139144

140145
#: List of python packages with __init__.py to update when ``python setup.py update_init``
141-
#: is called -- this is an argument to the ``robotpy-build create-imports`` command, and
146+
#: is called -- this is an argument to the ``semiwrap create-imports`` command, and
142147
#: may contain a space and the second argument to create-imports.
143148
# update_init: List[str] = []
144149

145-
#: Modules to autogenerate. The key is the python package name
146-
#: that the module will live in
147-
modules: Dict[str, ModuleConfig] = dataclasses.field(default_factory=dict)
150+
#: Modules to autogenerate. The key is the name of the python package that will
151+
#: be generated. For example, "package.name" will cause the shared library
152+
#: 'package/name-{abi tag}.so' to be installed in
153+
extension_modules: Dict[str, ExtensionModuleConfig] = dataclasses.field(default_factory=dict)
148154

149155

150156
@dataclasses.dataclass

src/semiwrap/config/util.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ValidationError(Exception):
1111

1212

1313
def _convert_validation_error(
14-
fname: str, ve: errors.ValidationError
14+
fname, ve: errors.ValidationError
1515
) -> ValidationError:
1616
locs = []
1717
msg = []
@@ -36,7 +36,7 @@ def _convert_validation_error(
3636
return ValidationError(vmsg)
3737

3838

39-
def parse_input(value: typing.Any, spec: typing.Type[T], fname: str) -> T:
39+
def parse_input(value: typing.Any, spec: typing.Type[T], fname) -> T:
4040
try:
4141
return validobj.validation.parse_input(value, spec)
4242
except errors.ValidationError as ve:

0 commit comments

Comments
 (0)