pymergetic-easybind 0.2.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. pymergetic_easybind-0.2.16/.clangd +2 -0
  2. pymergetic_easybind-0.2.16/.github/workflows/publish.yml +47 -0
  3. pymergetic_easybind-0.2.16/.gitignore +212 -0
  4. pymergetic_easybind-0.2.16/.vscode/tasks.json +16 -0
  5. pymergetic_easybind-0.2.16/CMakeLists.txt +317 -0
  6. pymergetic_easybind-0.2.16/LICENSE +201 -0
  7. pymergetic_easybind-0.2.16/NOTICE +91 -0
  8. pymergetic_easybind-0.2.16/PKG-INFO +206 -0
  9. pymergetic_easybind-0.2.16/README.md +176 -0
  10. pymergetic_easybind-0.2.16/RELEASING.md +68 -0
  11. pymergetic_easybind-0.2.16/cmake/easybind_dependencies.cmake +56 -0
  12. pymergetic_easybind-0.2.16/cmake/easybind_pip.cmake +79 -0
  13. pymergetic_easybind-0.2.16/pyproject.toml +94 -0
  14. pymergetic_easybind-0.2.16/pyrightconfig.json +4 -0
  15. pymergetic_easybind-0.2.16/scripts/clangd-update.sh +18 -0
  16. pymergetic_easybind-0.2.16/src/pymergetic/__init__.py +1 -0
  17. pymergetic_easybind-0.2.16/src/pymergetic/easybind/__init__.cpp +5 -0
  18. pymergetic_easybind-0.2.16/src/pymergetic/easybind/__project__.py +11 -0
  19. pymergetic_easybind-0.2.16/src/pymergetic/easybind/bind.hpp +30 -0
  20. pymergetic_easybind-0.2.16/src/pymergetic/easybind/devtools/__init__.py +53 -0
  21. pymergetic_easybind-0.2.16/src/pymergetic/easybind/devtools/pin_pyproject.py +480 -0
  22. pymergetic_easybind-0.2.16/src/pymergetic/easybind/devtools/release_helpers.py +154 -0
  23. pymergetic_easybind-0.2.16/src/pymergetic/easybind/devtools/release_tag.py +137 -0
  24. pymergetic_easybind-0.2.16/src/pymergetic/easybind/devtools/wait_pypi.py +64 -0
  25. pymergetic_easybind-0.2.16/src/pymergetic/easybind/export.hpp +26 -0
  26. pymergetic_easybind-0.2.16/src/pymergetic/easybind/module/__init__.cpp +11 -0
  27. pymergetic_easybind-0.2.16/src/pymergetic/easybind/module/node.cpp +353 -0
  28. pymergetic_easybind-0.2.16/src/pymergetic/easybind/module/node.hpp +91 -0
  29. pymergetic_easybind-0.2.16/src/pymergetic/easybind/module/node__init__.cpp +35 -0
  30. pymergetic_easybind-0.2.16/src/pymergetic/easybind/module/ns_module.hpp +87 -0
  31. pymergetic_easybind-0.2.16/src/pymergetic/easybind/py.typed +1 -0
  32. pymergetic_easybind-0.2.16/src/pymergetic/easybind/sample/__init__.cpp +97 -0
  33. pymergetic_easybind-0.2.16/src/pymergetic/easybind/sample/sample.cpp +115 -0
  34. pymergetic_easybind-0.2.16/src/pymergetic/easybind/sample/sample.hpp +102 -0
  35. pymergetic_easybind-0.2.16/src/pymergetic/easybind/sample/test1.py +1 -0
  36. pymergetic_easybind-0.2.16/src/pymergetic/easybind/sample/test2/__init__.py +1 -0
  37. pymergetic_easybind-0.2.16/src/pymergetic/easybind/version/__init__.py +38 -0
  38. pymergetic_easybind-0.2.16/tests/test_sample.py +42 -0
  39. pymergetic_easybind-0.2.16/uv.lock +606 -0
@@ -0,0 +1,2 @@
1
+ CompileFlags:
2
+ CompilationDatabase: build
@@ -0,0 +1,47 @@
1
+ # Build sdist + manylinux_2_28 x86_64 wheels (cibuildwheel), upload to PyPI on tag v*.
2
+ # PyPA does not publish manylinux_2_27 images; manylinux_2_28 is the closest official policy.
3
+ # Requires repository secret: PYPI_API_TOKEN
4
+
5
+ name: Publish to PyPI
6
+
7
+ on:
8
+ push:
9
+ tags:
10
+ - "v*"
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ publish:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - uses: actions/setup-python@v5
24
+ with:
25
+ python-version: "3.12"
26
+
27
+ - name: Install build tools
28
+ run: pip install --upgrade build twine
29
+
30
+ - name: Build sdist
31
+ run: python -m build --sdist
32
+
33
+ - name: Build manylinux wheels
34
+ uses: pypa/cibuildwheel@v3.4.0
35
+
36
+ - name: Stage wheels next to sdist
37
+ run: cp wheelhouse/*.whl dist/
38
+
39
+ - name: Check distributions
40
+ run: twine check dist/*
41
+
42
+ - name: Publish to PyPI
43
+ uses: pypa/gh-action-pypi-publish@release/v1
44
+ with:
45
+ password: ${{ secrets.PYPI_API_TOKEN }}
46
+ # Re-runs for the same tag would 400 "File already exists" on PyPI; skip duplicates instead of failing.
47
+ skip-existing: true
@@ -0,0 +1,212 @@
1
+ **/*.pyi
2
+
3
+ # Generated by setuptools-scm at build time (see pyproject.toml).
4
+ src/pymergetic/easybind/_version.py
5
+
6
+ # Byte-compiled / optimized / DLL files
7
+ __pycache__/
8
+ *.py[codz]
9
+ *$py.class
10
+
11
+ # C extensions
12
+ *.so
13
+
14
+ # Distribution / packaging
15
+ .Python
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+ MANIFEST
33
+
34
+ # PyInstaller
35
+ # Usually these files are written by a python script from a template
36
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Installer logs
41
+ pip-log.txt
42
+ pip-delete-this-directory.txt
43
+
44
+ # Unit test / coverage reports
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+ .coverage
49
+ .coverage.*
50
+ .cache
51
+ nosetests.xml
52
+ coverage.xml
53
+ *.cover
54
+ *.py.cover
55
+ .hypothesis/
56
+ .pytest_cache/
57
+ cover/
58
+
59
+ # Translations
60
+ *.mo
61
+ *.pot
62
+
63
+ # Django stuff:
64
+ *.log
65
+ local_settings.py
66
+ db.sqlite3
67
+ db.sqlite3-journal
68
+
69
+ # Flask stuff:
70
+ instance/
71
+ .webassets-cache
72
+
73
+ # Scrapy stuff:
74
+ .scrapy
75
+
76
+ # Sphinx documentation
77
+ docs/_build/
78
+
79
+ # PyBuilder
80
+ .pybuilder/
81
+ target/
82
+
83
+ # Jupyter Notebook
84
+ .ipynb_checkpoints
85
+
86
+ # IPython
87
+ profile_default/
88
+ ipython_config.py
89
+
90
+ # pyenv
91
+ # For a library or package, you might want to ignore these files since the code is
92
+ # intended to run in multiple environments; otherwise, check them in:
93
+ # .python-version
94
+
95
+ # pipenv
96
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
97
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
98
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
99
+ # install all needed dependencies.
100
+ #Pipfile.lock
101
+
102
+ # UV
103
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
104
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
105
+ # commonly ignored for libraries.
106
+ #uv.lock
107
+
108
+ # poetry
109
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
110
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
111
+ # commonly ignored for libraries.
112
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
113
+ #poetry.lock
114
+ #poetry.toml
115
+
116
+ # pdm
117
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
118
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
119
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
120
+ #pdm.lock
121
+ #pdm.toml
122
+ .pdm-python
123
+ .pdm-build/
124
+
125
+ # pixi
126
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
127
+ #pixi.lock
128
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
129
+ # in the .venv directory. It is recommended not to include this directory in version control.
130
+ .pixi
131
+
132
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
133
+ __pypackages__/
134
+
135
+ # Celery stuff
136
+ celerybeat-schedule
137
+ celerybeat.pid
138
+
139
+ # SageMath parsed files
140
+ *.sage.py
141
+
142
+ # Environments
143
+ .env
144
+ .envrc
145
+ .venv
146
+ env/
147
+ venv/
148
+ ENV/
149
+ env.bak/
150
+ venv.bak/
151
+
152
+ # Spyder project settings
153
+ .spyderproject
154
+ .spyproject
155
+
156
+ # Rope project settings
157
+ .ropeproject
158
+
159
+ # mkdocs documentation
160
+ /site
161
+
162
+ # mypy
163
+ .mypy_cache/
164
+ .dmypy.json
165
+ dmypy.json
166
+
167
+ # Pyre type checker
168
+ .pyre/
169
+
170
+ # pytype static type analyzer
171
+ .pytype/
172
+
173
+ # Cython debug symbols
174
+ cython_debug/
175
+
176
+ # PyCharm
177
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
178
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
179
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
180
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
181
+ #.idea/
182
+
183
+ # Abstra
184
+ # Abstra is an AI-powered process automation framework.
185
+ # Ignore directories containing user credentials, local state, and settings.
186
+ # Learn more at https://abstra.io/docs
187
+ .abstra/
188
+
189
+ # Visual Studio Code
190
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
191
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
192
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
193
+ # you could uncomment the following to ignore the entire vscode folder
194
+ # .vscode/
195
+
196
+ # Ruff stuff:
197
+ .ruff_cache/
198
+
199
+ # PyPI configuration file
200
+ .pypirc
201
+
202
+ # Cursor
203
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
204
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
205
+ # refer to https://docs.cursor.com/context/ignore-files
206
+ .cursorignore
207
+ .cursorindexingignore
208
+
209
+ # Marimo
210
+ marimo/_static/
211
+ marimo/_lsp/
212
+ __marimo__/
@@ -0,0 +1,16 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "tasks": [
4
+ {
5
+ "label": "clangd: compile_commands (fallback cmake, no pip)",
6
+ "type": "shell",
7
+ "command": "bash",
8
+ "args": ["scripts/clangd-update.sh"],
9
+ "problemMatcher": [],
10
+ "presentation": {
11
+ "reveal": "always",
12
+ "panel": "shared"
13
+ }
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,317 @@
1
+ cmake_minimum_required(VERSION 3.25)
2
+
3
+ project(easybind LANGUAGES CXX)
4
+
5
+ include(GNUInstallDirs)
6
+
7
+ set(CMAKE_CXX_STANDARD 20)
8
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
9
+
10
+ option(EASYBIND_SKIP_INSTALL "Skip installing easybind artifacts" OFF)
11
+ if(NOT PROJECT_IS_TOP_LEVEL)
12
+ set(EASYBIND_SKIP_INSTALL ON)
13
+ endif()
14
+
15
+ # Ensure Python development headers/targets are available for nanobind + modules.
16
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
17
+
18
+ # Prefer Python::Module (extension modules), fall back to Python::Python.
19
+ set(EASYBIND_PYTHON_TARGET "")
20
+ if(TARGET Python::Module)
21
+ set(EASYBIND_PYTHON_TARGET Python::Module)
22
+ elseif(TARGET Python::Python)
23
+ set(EASYBIND_PYTHON_TARGET Python::Python)
24
+ else()
25
+ message(FATAL_ERROR "Python imported target not found (expected Python::Module or Python::Python)")
26
+ endif()
27
+
28
+ # Third-party sources: pins live in cmake/easybind_dependencies.cmake (also installed for consumers).
29
+ include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/easybind_dependencies.cmake")
30
+ easybind_fetch_third_party_deps()
31
+
32
+ # Some nanobind configurations don't automatically attach Python include dirs.
33
+ foreach(_nb_tgt IN ITEMS nanobind nanobind_shared nanobind-static)
34
+ if(TARGET ${_nb_tgt})
35
+ target_link_libraries(${_nb_tgt} PRIVATE ${EASYBIND_PYTHON_TARGET})
36
+ set_target_properties(${_nb_tgt} PROPERTIES
37
+ CXX_VISIBILITY_PRESET default
38
+ VISIBILITY_INLINES_HIDDEN OFF
39
+ )
40
+ target_compile_options(${_nb_tgt} PRIVATE
41
+ $<$<CXX_COMPILER_ID:GNU,Clang>:-fvisibility=default>
42
+ )
43
+ endif()
44
+ endforeach()
45
+
46
+ function(easybind_add_extension target_name)
47
+ nanobind_add_module(${target_name} NB_SHARED ${ARGN})
48
+ target_link_libraries(${target_name} PRIVATE ${EASYBIND_PYTHON_TARGET})
49
+ if(APPLE)
50
+ set_target_properties(${target_name} PROPERTIES
51
+ BUILD_RPATH "@loader_path"
52
+ INSTALL_RPATH "@loader_path"
53
+ )
54
+ else()
55
+ set_target_properties(${target_name} PROPERTIES
56
+ BUILD_RPATH "$ORIGIN"
57
+ INSTALL_RPATH "$ORIGIN"
58
+ )
59
+ endif()
60
+ endfunction()
61
+
62
+ add_library(easybind__module__ SHARED
63
+ src/pymergetic/easybind/module/node.cpp
64
+ )
65
+ set_target_properties(easybind__module__ PROPERTIES
66
+ OUTPUT_NAME "easybind"
67
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind"
68
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind"
69
+ )
70
+ target_include_directories(easybind__module__ PRIVATE
71
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
72
+ )
73
+ target_compile_definitions(easybind__module__ PRIVATE EASYBIND_BUILD)
74
+ if(DEFINED nanobind_SOURCE_DIR)
75
+ target_include_directories(easybind__module__ PRIVATE
76
+ ${nanobind_SOURCE_DIR}/include
77
+ )
78
+ endif()
79
+ target_link_libraries(easybind__module__ PRIVATE ${EASYBIND_PYTHON_TARGET})
80
+ if(TARGET nanobind)
81
+ target_link_libraries(easybind__module__ PRIVATE nanobind)
82
+ add_dependencies(easybind__module__ nanobind)
83
+ elseif(TARGET nanobind_shared)
84
+ target_link_libraries(easybind__module__ PRIVATE nanobind_shared)
85
+ add_dependencies(easybind__module__ nanobind_shared)
86
+ elseif(TARGET nanobind-static)
87
+ target_link_libraries(easybind__module__ PRIVATE nanobind-static)
88
+ target_compile_definitions(easybind__module__ PRIVATE NB_STATIC)
89
+ add_dependencies(easybind__module__ nanobind-static)
90
+ endif()
91
+ if(APPLE)
92
+ set_target_properties(easybind__module__ PROPERTIES
93
+ BUILD_RPATH "@loader_path"
94
+ INSTALL_RPATH "@loader_path"
95
+ )
96
+ else()
97
+ set_target_properties(easybind__module__ PROPERTIES
98
+ BUILD_RPATH "$ORIGIN"
99
+ INSTALL_RPATH "$ORIGIN"
100
+ )
101
+ endif()
102
+ set_target_properties(easybind__module__ PROPERTIES
103
+ CXX_VISIBILITY_PRESET hidden
104
+ VISIBILITY_INLINES_HIDDEN ON
105
+ )
106
+ target_compile_options(easybind__module__ PRIVATE
107
+ $<$<CXX_COMPILER_ID:GNU,Clang>:-fvisibility=hidden>
108
+ )
109
+
110
+ add_library(easybind_sample__module__ SHARED
111
+ src/pymergetic/easybind/sample/sample.cpp
112
+ )
113
+ set_target_properties(easybind_sample__module__ PROPERTIES
114
+ OUTPUT_NAME "easybind-sample"
115
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind/sample"
116
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind/sample"
117
+ )
118
+ target_include_directories(easybind_sample__module__ PRIVATE
119
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
120
+ )
121
+ if(TARGET magic_enum::magic_enum)
122
+ target_link_libraries(easybind_sample__module__ PRIVATE magic_enum::magic_enum)
123
+ target_include_directories(easybind_sample__module__ PRIVATE
124
+ ${magic_enum_SOURCE_DIR}/include
125
+ )
126
+ else()
127
+ target_include_directories(easybind_sample__module__ PRIVATE
128
+ ${magic_enum_SOURCE_DIR}/include
129
+ )
130
+ endif()
131
+ target_compile_definitions(easybind_sample__module__ PRIVATE EASYBIND_SAMPLE_BUILD)
132
+ if(APPLE)
133
+ set_target_properties(easybind_sample__module__ PROPERTIES
134
+ BUILD_RPATH "@loader_path"
135
+ INSTALL_RPATH "@loader_path"
136
+ )
137
+ else()
138
+ set_target_properties(easybind_sample__module__ PROPERTIES
139
+ BUILD_RPATH "$ORIGIN"
140
+ INSTALL_RPATH "$ORIGIN"
141
+ )
142
+ endif()
143
+ set_target_properties(easybind_sample__module__ PROPERTIES
144
+ CXX_VISIBILITY_PRESET hidden
145
+ VISIBILITY_INLINES_HIDDEN ON
146
+ )
147
+ target_compile_options(easybind_sample__module__ PRIVATE
148
+ $<$<CXX_COMPILER_ID:GNU,Clang>:-fvisibility=hidden>
149
+ )
150
+
151
+ easybind_add_extension(easybind_sample__init__
152
+ src/pymergetic/easybind/sample/__init__.cpp
153
+ )
154
+ target_link_libraries(easybind_sample__init__ PRIVATE
155
+ easybind__module__
156
+ easybind_sample__module__
157
+ )
158
+ set_target_properties(easybind_sample__init__ PROPERTIES
159
+ OUTPUT_NAME "__init__"
160
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind/sample"
161
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind/sample"
162
+ )
163
+ target_include_directories(easybind_sample__init__ PRIVATE
164
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
165
+ )
166
+ if(TARGET magic_enum::magic_enum)
167
+ target_link_libraries(easybind_sample__init__ PRIVATE magic_enum::magic_enum)
168
+ target_include_directories(easybind_sample__init__ PRIVATE
169
+ ${magic_enum_SOURCE_DIR}/include
170
+ )
171
+ else()
172
+ target_include_directories(easybind_sample__init__ PRIVATE
173
+ ${magic_enum_SOURCE_DIR}/include
174
+ )
175
+ endif()
176
+ if(DEFINED reflect_cpp_SOURCE_DIR)
177
+ target_include_directories(easybind_sample__init__ PRIVATE
178
+ ${reflect_cpp_SOURCE_DIR}/include
179
+ )
180
+ endif()
181
+ # sample/__init__.so lives in pymergetic/easybind/sample/; it links libeasybind-sample.so (same
182
+ # dir), libeasybind.so + libnanobind.so (parent). RPATH needs BOTH $ORIGIN and
183
+ # $ORIGIN/.. or auditwheel cannot resolve libeasybind-sample.so (path null).
184
+ if(APPLE)
185
+ set_target_properties(easybind_sample__init__ PROPERTIES
186
+ BUILD_RPATH "@loader_path;@loader_path/.."
187
+ INSTALL_RPATH "@loader_path;@loader_path/.."
188
+ )
189
+ elseif(UNIX)
190
+ set_target_properties(easybind_sample__init__ PROPERTIES
191
+ BUILD_RPATH "$ORIGIN;$ORIGIN/.."
192
+ INSTALL_RPATH "$ORIGIN;$ORIGIN/.."
193
+ )
194
+ else()
195
+ set_target_properties(easybind_sample__init__ PROPERTIES
196
+ BUILD_RPATH "$ORIGIN"
197
+ INSTALL_RPATH "$ORIGIN"
198
+ )
199
+ endif()
200
+
201
+ if(NOT EASYBIND_SKIP_INSTALL)
202
+ install(TARGETS easybind_sample__module__
203
+ LIBRARY DESTINATION pymergetic/easybind/sample
204
+ RUNTIME DESTINATION pymergetic/easybind/sample
205
+ ARCHIVE DESTINATION pymergetic/easybind/sample
206
+ )
207
+ install(TARGETS easybind_sample__init__
208
+ LIBRARY DESTINATION pymergetic/easybind/sample
209
+ RUNTIME DESTINATION pymergetic/easybind/sample
210
+ ARCHIVE DESTINATION pymergetic/easybind/sample
211
+ )
212
+
213
+ # If nanobind is built as a shared library, ship it alongside extensions so
214
+ # `libnanobind.so` is resolvable at runtime.
215
+ if(TARGET nanobind)
216
+ install(TARGETS nanobind
217
+ LIBRARY DESTINATION pymergetic/easybind
218
+ RUNTIME DESTINATION pymergetic/easybind
219
+ ARCHIVE DESTINATION pymergetic/easybind
220
+ )
221
+ endif()
222
+ endif()
223
+
224
+ easybind_add_extension(easybind__init__
225
+ src/pymergetic/easybind/__init__.cpp
226
+ src/pymergetic/easybind/module/__init__.cpp
227
+ src/pymergetic/easybind/module/node__init__.cpp
228
+ )
229
+ target_link_libraries(easybind__init__ PRIVATE easybind__module__)
230
+ set_target_properties(easybind__init__ PROPERTIES
231
+ OUTPUT_NAME "__init__"
232
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind"
233
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pymergetic/easybind"
234
+ )
235
+ target_include_directories(easybind__init__ PRIVATE
236
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
237
+ )
238
+ if(TARGET magic_enum::magic_enum)
239
+ target_link_libraries(easybind__init__ PRIVATE magic_enum::magic_enum)
240
+ target_include_directories(easybind__init__ PRIVATE
241
+ ${magic_enum_SOURCE_DIR}/include
242
+ )
243
+ else()
244
+ target_include_directories(easybind__init__ PRIVATE
245
+ ${magic_enum_SOURCE_DIR}/include
246
+ )
247
+ endif()
248
+ if(DEFINED reflect_cpp_SOURCE_DIR)
249
+ target_include_directories(easybind__init__ PRIVATE
250
+ ${reflect_cpp_SOURCE_DIR}/include
251
+ )
252
+ endif()
253
+ if(APPLE)
254
+ set_target_properties(easybind__init__ PROPERTIES
255
+ BUILD_RPATH "@loader_path"
256
+ INSTALL_RPATH "@loader_path"
257
+ )
258
+ else()
259
+ set_target_properties(easybind__init__ PROPERTIES
260
+ BUILD_RPATH "$ORIGIN"
261
+ INSTALL_RPATH "$ORIGIN"
262
+ )
263
+ endif()
264
+
265
+ # Build-time stub generation (package layout).
266
+ function(easybind_add_stub_package stub_target_prefix module_target)
267
+ foreach(module_name IN LISTS ARGN)
268
+ string(REPLACE "." "/" module_path "${module_name}")
269
+ set(output_path "${CMAKE_CURRENT_SOURCE_DIR}/src/${module_path}/__init__.pyi")
270
+ get_filename_component(output_dir "${output_path}" DIRECTORY)
271
+ file(MAKE_DIRECTORY "${output_dir}")
272
+
273
+ string(REPLACE "." "_" module_target_suffix "${module_name}")
274
+ set(stub_target "${stub_target_prefix}_${module_target_suffix}_stub")
275
+
276
+ nanobind_add_stub(${stub_target}
277
+ MODULE ${module_name}
278
+ OUTPUT ${output_path}
279
+ PYTHON_PATH $<TARGET_FILE_DIR:${module_target}>
280
+ DEPENDS ${module_target}
281
+ )
282
+ endforeach()
283
+ endfunction()
284
+
285
+ easybind_add_stub_package(easybind
286
+ easybind__init__
287
+ pymergetic.easybind
288
+ pymergetic.easybind.module)
289
+ easybind_add_stub_package(easybind_sample
290
+ easybind_sample__init__
291
+ pymergetic.easybind.sample)
292
+
293
+ if(NOT EASYBIND_SKIP_INSTALL)
294
+ install(TARGETS easybind__module__
295
+ LIBRARY DESTINATION pymergetic/easybind
296
+ RUNTIME DESTINATION pymergetic/easybind
297
+ ARCHIVE DESTINATION pymergetic/easybind
298
+ )
299
+ install(TARGETS easybind__init__
300
+ LIBRARY DESTINATION pymergetic/easybind
301
+ RUNTIME DESTINATION pymergetic/easybind
302
+ ARCHIVE DESTINATION pymergetic/easybind
303
+ )
304
+
305
+ install(DIRECTORY src/pymergetic
306
+ DESTINATION .
307
+ )
308
+ # Third-party licenses (nanobind, magic_enum, reflect-cpp): see NOTICE.
309
+ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/NOTICE"
310
+ DESTINATION pymergetic/easybind
311
+ )
312
+ install(FILES
313
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/easybind_dependencies.cmake"
314
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/easybind_pip.cmake"
315
+ DESTINATION pymergetic/easybind/cmake
316
+ )
317
+ endif()