easybind 0.2.0__tar.gz → 0.2.3__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 (30) hide show
  1. {easybind-0.2.0 → easybind-0.2.3}/CMakeLists.txt +8 -22
  2. {easybind-0.2.0 → easybind-0.2.3}/PKG-INFO +15 -8
  3. {easybind-0.2.0 → easybind-0.2.3}/README.md +14 -7
  4. {easybind-0.2.0 → easybind-0.2.3}/RELEASING.md +4 -0
  5. easybind-0.2.3/cmake/easybind_dependencies.cmake +56 -0
  6. easybind-0.2.3/cmake/easybind_pip.cmake +79 -0
  7. easybind-0.2.0/cmake/easybindConfig.cmake.in +0 -57
  8. {easybind-0.2.0 → easybind-0.2.3}/.clangd +0 -0
  9. {easybind-0.2.0 → easybind-0.2.3}/.github/workflows/publish.yml +0 -0
  10. {easybind-0.2.0 → easybind-0.2.3}/.gitignore +0 -0
  11. {easybind-0.2.0 → easybind-0.2.3}/.vscode/tasks.json +0 -0
  12. {easybind-0.2.0 → easybind-0.2.3}/LICENSE +0 -0
  13. {easybind-0.2.0 → easybind-0.2.3}/NOTICE +0 -0
  14. {easybind-0.2.0 → easybind-0.2.3}/pyproject.toml +0 -0
  15. {easybind-0.2.0 → easybind-0.2.3}/scripts/clangd-update.sh +0 -0
  16. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/__init__.cpp +0 -0
  17. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/bind.hpp +0 -0
  18. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/export.hpp +0 -0
  19. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/module/__init__.cpp +0 -0
  20. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/module/node.cpp +0 -0
  21. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/module/node.hpp +0 -0
  22. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/module/node__init__.cpp +0 -0
  23. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/module/ns_module.hpp +0 -0
  24. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/py.typed +0 -0
  25. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/sample/__init__.cpp +0 -0
  26. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/sample/sample.cpp +0 -0
  27. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/sample/sample.hpp +0 -0
  28. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/sample/test1.py +0 -0
  29. {easybind-0.2.0 → easybind-0.2.3}/src/easybind/sample/test2/__init__.py +0 -0
  30. {easybind-0.2.0 → easybind-0.2.3}/tests/test_sample.py +0 -0
@@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.25)
3
3
  project(easybind LANGUAGES CXX)
4
4
 
5
5
  include(GNUInstallDirs)
6
- include(FetchContent)
7
6
 
8
7
  set(CMAKE_CXX_STANDARD 20)
9
8
  set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -26,27 +25,9 @@ else()
26
25
  message(FATAL_ERROR "Python imported target not found (expected Python::Module or Python::Python)")
27
26
  endif()
28
27
 
29
- # Nanobind - fetch so builds don't depend on a preinstalled CMake package.
30
- FetchContent_Declare(
31
- nanobind
32
- GIT_REPOSITORY https://github.com/wjakob/nanobind.git
33
- GIT_TAG v2.12.0
34
- )
35
- FetchContent_MakeAvailable(nanobind)
36
-
37
- FetchContent_Declare(
38
- magic_enum
39
- GIT_REPOSITORY https://github.com/Neargye/magic_enum.git
40
- GIT_TAG v0.9.7
41
- )
42
- FetchContent_MakeAvailable(magic_enum)
43
-
44
- FetchContent_Declare(
45
- reflect_cpp
46
- GIT_REPOSITORY https://github.com/getml/reflect-cpp.git
47
- GIT_TAG v0.24.0
48
- )
49
- FetchContent_MakeAvailable(reflect_cpp)
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()
50
31
 
51
32
  # Some nanobind configurations don't automatically attach Python include dirs.
52
33
  foreach(_nb_tgt IN ITEMS nanobind nanobind_shared nanobind-static)
@@ -328,4 +309,9 @@ if(NOT EASYBIND_SKIP_INSTALL)
328
309
  install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/NOTICE"
329
310
  DESTINATION easybind
330
311
  )
312
+ install(FILES
313
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/easybind_dependencies.cmake"
314
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/easybind_pip.cmake"
315
+ DESTINATION easybind/cmake
316
+ )
331
317
  endif()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easybind
3
- Version: 0.2.0
3
+ Version: 0.2.3
4
4
  Summary: Self-registering nanobind helpers (import as easybind)
5
5
  Keywords: easybind,nanobind,bindings,pymergetic
6
6
  Author-Email: PymergeticOS Maintainers <raudzus@pymergetic.com>
@@ -64,18 +64,25 @@ The Python package is implemented as native extensions. It exposes:
64
64
  - `easybind.sample` (demo bindings)
65
65
 
66
66
  ## Build-time SDK
67
- `easybind` provides CMake helpers for hybrid extensions:
67
+ Installed wheels ship CMake helpers under **`easybind/cmake/`**:
68
68
 
69
- - `easybind::build_interface` (INTERFACE): baseline C++20 + PIC + shared include paths
70
- - `easybind_add_extension(target ...)`: wraps `nanobind_add_module(... NB_SHARED ...)`
69
+ - **`easybind_pip.cmake`** — `easybind_pip_setup()` finds Python, **`nanobind`** (pip), **`libeasybind`**, and include roots for `#include <easybind/...>`, then pulls in **`easybind_dependencies.cmake`**. Helpers: `easybind_pip_link_magic_enum(target)`, `easybind_pip_set_rpath_next_to_easybind(target easybind_pkg_dir)`.
70
+ - **`easybind_dependencies.cmake`** — pins **nanobind**, **magic_enum**, **reflect-cpp** (same tags as this repo). Use **`easybind_fetch_third_party_deps()`** to pull all three, or **`easybind_fetch_nanobind()`** / **`easybind_fetch_magic_enum()`** / **`easybind_fetch_reflect_cpp()`** when you only need a subset (e.g. pip already provides nanobind, so call only **`easybind_fetch_magic_enum()`**).
71
+
72
+ Typical consumer bootstrap:
71
73
 
72
- Example:
73
74
  ```cmake
74
- find_package(easybind CONFIG REQUIRED)
75
- easybind_add_extension(my_module src_bind/my_pkg/__cpp__/module.cpp)
76
- target_link_libraries(my_module PRIVATE easybind::easybind)
75
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
76
+ execute_process(COMMAND "${Python_EXECUTABLE}" -c
77
+ "import pathlib, easybind; print(pathlib.Path(easybind.__file__).resolve().parent / 'cmake' / 'easybind_pip.cmake')"
78
+ OUTPUT_VARIABLE _eb_pip OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)
79
+ include("${_eb_pip}")
80
+ easybind_pip_setup()
81
+ easybind_fetch_magic_enum() # if you include easybind headers that need magic_enum
77
82
  ```
78
83
 
84
+ When developing **inside** this repository, `easybind_add_extension(...)` is defined in the top-level `CMakeLists.txt` (not shipped in the wheel).
85
+
79
86
  ## Core idea
80
87
  - Each namespace/module defines a `ModuleNode` and a bind callback.
81
88
  - The module entry point calls `apply_init` to run the callback and recurse.
@@ -35,18 +35,25 @@ The Python package is implemented as native extensions. It exposes:
35
35
  - `easybind.sample` (demo bindings)
36
36
 
37
37
  ## Build-time SDK
38
- `easybind` provides CMake helpers for hybrid extensions:
38
+ Installed wheels ship CMake helpers under **`easybind/cmake/`**:
39
39
 
40
- - `easybind::build_interface` (INTERFACE): baseline C++20 + PIC + shared include paths
41
- - `easybind_add_extension(target ...)`: wraps `nanobind_add_module(... NB_SHARED ...)`
40
+ - **`easybind_pip.cmake`** — `easybind_pip_setup()` finds Python, **`nanobind`** (pip), **`libeasybind`**, and include roots for `#include <easybind/...>`, then pulls in **`easybind_dependencies.cmake`**. Helpers: `easybind_pip_link_magic_enum(target)`, `easybind_pip_set_rpath_next_to_easybind(target easybind_pkg_dir)`.
41
+ - **`easybind_dependencies.cmake`** — pins **nanobind**, **magic_enum**, **reflect-cpp** (same tags as this repo). Use **`easybind_fetch_third_party_deps()`** to pull all three, or **`easybind_fetch_nanobind()`** / **`easybind_fetch_magic_enum()`** / **`easybind_fetch_reflect_cpp()`** when you only need a subset (e.g. pip already provides nanobind, so call only **`easybind_fetch_magic_enum()`**).
42
+
43
+ Typical consumer bootstrap:
42
44
 
43
- Example:
44
45
  ```cmake
45
- find_package(easybind CONFIG REQUIRED)
46
- easybind_add_extension(my_module src_bind/my_pkg/__cpp__/module.cpp)
47
- target_link_libraries(my_module PRIVATE easybind::easybind)
46
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
47
+ execute_process(COMMAND "${Python_EXECUTABLE}" -c
48
+ "import pathlib, easybind; print(pathlib.Path(easybind.__file__).resolve().parent / 'cmake' / 'easybind_pip.cmake')"
49
+ OUTPUT_VARIABLE _eb_pip OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)
50
+ include("${_eb_pip}")
51
+ easybind_pip_setup()
52
+ easybind_fetch_magic_enum() # if you include easybind headers that need magic_enum
48
53
  ```
49
54
 
55
+ When developing **inside** this repository, `easybind_add_extension(...)` is defined in the top-level `CMakeLists.txt` (not shipped in the wheel).
56
+
50
57
  ## Core idea
51
58
  - Each namespace/module defines a `ModuleNode` and a bind callback.
52
59
  - The module entry point calls `apply_init` to run the callback and recurse.
@@ -37,3 +37,7 @@ Locally, a plain `python -m build` on Linux may still emit a bare `linux_x86_64`
37
37
  ## Submodule / monorepo note
38
38
 
39
39
  If this repo is a **git submodule** inside another project, **tags for versioning must exist on this repository’s own remote**, not only on the parent repo. Tag and release from the `easybind` repo (or push tags there after merging).
40
+
41
+ ## Downstream: cppdantic
42
+
43
+ The **cppdantic** demo package depends on **easybind** with a compatible-release pin (`easybind~=A.B.C` in its `pyproject.toml`). **Release easybind to PyPI first**, then bump those pins in the cppdantic repo to the new **`A.B.C`** before tagging cppdantic. See **cppdantic**’s **`RELEASING.md`** for the full order.
@@ -0,0 +1,56 @@
1
+ # Single source of truth for FetchContent pins used by easybind and downstream CMake projects.
2
+ # Include from the installed package: include("${EASYBIND_PKG_DIR}/cmake/easybind_dependencies.cmake")
3
+
4
+ include_guard(GLOBAL)
5
+
6
+ include(FetchContent)
7
+
8
+ set(EASYBIND_NANOBIND_GIT_TAG "v2.12.0"
9
+ CACHE STRING "nanobind Git tag (align with easybind’s nanobind / PyPI pin)")
10
+ set(EASYBIND_MAGIC_ENUM_GIT_TAG "v0.9.7" CACHE STRING "magic_enum Git tag")
11
+ set(EASYBIND_REFLECT_CPP_GIT_TAG "v0.24.0" CACHE STRING "reflect-cpp Git tag")
12
+
13
+ function(easybind_fetch_nanobind)
14
+ FetchContent_GetProperties(nanobind)
15
+ if(nanobind_POPULATED)
16
+ return()
17
+ endif()
18
+ FetchContent_Declare(
19
+ nanobind
20
+ GIT_REPOSITORY https://github.com/wjakob/nanobind.git
21
+ GIT_TAG "${EASYBIND_NANOBIND_GIT_TAG}"
22
+ )
23
+ FetchContent_MakeAvailable(nanobind)
24
+ endfunction()
25
+
26
+ function(easybind_fetch_magic_enum)
27
+ FetchContent_GetProperties(magic_enum)
28
+ if(magic_enum_POPULATED)
29
+ return()
30
+ endif()
31
+ FetchContent_Declare(
32
+ magic_enum
33
+ GIT_REPOSITORY https://github.com/Neargye/magic_enum.git
34
+ GIT_TAG "${EASYBIND_MAGIC_ENUM_GIT_TAG}"
35
+ )
36
+ FetchContent_MakeAvailable(magic_enum)
37
+ endfunction()
38
+
39
+ function(easybind_fetch_reflect_cpp)
40
+ FetchContent_GetProperties(reflect_cpp)
41
+ if(reflect_cpp_POPULATED)
42
+ return()
43
+ endif()
44
+ FetchContent_Declare(
45
+ reflect_cpp
46
+ GIT_REPOSITORY https://github.com/getml/reflect-cpp.git
47
+ GIT_TAG "${EASYBIND_REFLECT_CPP_GIT_TAG}"
48
+ )
49
+ FetchContent_MakeAvailable(reflect_cpp)
50
+ endfunction()
51
+
52
+ function(easybind_fetch_third_party_deps)
53
+ easybind_fetch_nanobind()
54
+ easybind_fetch_magic_enum()
55
+ easybind_fetch_reflect_cpp()
56
+ endfunction()
@@ -0,0 +1,79 @@
1
+ # Helpers for CMake projects that depend on the pip-installed easybind package.
2
+ # Bootstrap (once per project):
3
+ # find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
4
+ # execute_process(COMMAND "${Python_EXECUTABLE}" -c
5
+ # "import pathlib, easybind; print(pathlib.Path(easybind.__file__).resolve().parent / 'cmake' / 'easybind_pip.cmake')"
6
+ # OUTPUT_VARIABLE _eb_pip OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)
7
+ # include("${_eb_pip}")
8
+ # easybind_pip_setup()
9
+
10
+ # Must run before include_guard: guard skips the whole file on re-include, and this must be this file’s directory.
11
+ get_filename_component(_EASYBIND_PIP_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
12
+ include_guard(GLOBAL)
13
+
14
+ function(easybind_pip_setup)
15
+ if(NOT Python_FOUND)
16
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
17
+ endif()
18
+
19
+ execute_process(
20
+ COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
21
+ OUTPUT_STRIP_TRAILING_WHITESPACE
22
+ OUTPUT_VARIABLE nanobind_ROOT
23
+ COMMAND_ERROR_IS_FATAL ANY
24
+ )
25
+ find_package(nanobind CONFIG REQUIRED)
26
+
27
+ # This file lives in …/site-packages/easybind/cmake/
28
+ get_filename_component(EASYBIND_PKG_DIR "${_EASYBIND_PIP_CMAKE_DIR}/.." ABSOLUTE)
29
+ get_filename_component(EASYBIND_INCLUDE_ROOT "${EASYBIND_PKG_DIR}/.." ABSOLUTE)
30
+
31
+ # Prefer explicit path — find_library can fail with NO_DEFAULT_PATH on some setups.
32
+ if(APPLE)
33
+ set(_eb_core "${EASYBIND_PKG_DIR}/libeasybind.dylib")
34
+ elseif(UNIX)
35
+ set(_eb_core "${EASYBIND_PKG_DIR}/libeasybind.so")
36
+ else()
37
+ find_library(
38
+ _eb_core
39
+ NAMES easybind
40
+ PATHS "${EASYBIND_PKG_DIR}"
41
+ NO_DEFAULT_PATH
42
+ REQUIRED
43
+ )
44
+ endif()
45
+ if(NOT EXISTS "${_eb_core}")
46
+ message(FATAL_ERROR "easybind core library not found at ${_eb_core} (EASYBIND_PKG_DIR=${EASYBIND_PKG_DIR})")
47
+ endif()
48
+ set(EASYBIND_CORE_LIB "${_eb_core}")
49
+
50
+ include("${_EASYBIND_PIP_CMAKE_DIR}/easybind_dependencies.cmake")
51
+
52
+ set(EASYBIND_PKG_DIR "${EASYBIND_PKG_DIR}" PARENT_SCOPE)
53
+ set(EASYBIND_INCLUDE_ROOT "${EASYBIND_INCLUDE_ROOT}" PARENT_SCOPE)
54
+ set(EASYBIND_CORE_LIB "${EASYBIND_CORE_LIB}" PARENT_SCOPE)
55
+ endfunction()
56
+
57
+ function(easybind_pip_link_magic_enum target)
58
+ if(TARGET magic_enum::magic_enum)
59
+ target_link_libraries(${target} PRIVATE magic_enum::magic_enum)
60
+ else()
61
+ target_include_directories(${target} PRIVATE "${magic_enum_SOURCE_DIR}/include")
62
+ endif()
63
+ endfunction()
64
+
65
+ # RPATH so the extension finds libeasybind (and siblings) next to the pip easybind package.
66
+ # Pass the same EASYBIND_PKG_DIR you got from easybind_pip_setup().
67
+ function(easybind_pip_set_rpath_next_to_easybind target easybind_pkg_dir)
68
+ if(APPLE)
69
+ set(_install "@loader_path/../easybind")
70
+ set(_build "@loader_path;@loader_path/../easybind")
71
+ else()
72
+ set(_install "$ORIGIN/../easybind")
73
+ set(_build "$ORIGIN;${easybind_pkg_dir}")
74
+ endif()
75
+ set_target_properties(${target} PROPERTIES
76
+ INSTALL_RPATH "${_install}"
77
+ BUILD_RPATH "${_build}"
78
+ )
79
+ endfunction()
@@ -1,57 +0,0 @@
1
- @PACKAGE_INIT@
2
-
3
- include(CMakeFindDependencyMacro)
4
-
5
- find_dependency(Python COMPONENTS Interpreter Development.Module)
6
-
7
- set(EASYBIND_PYTHON_TARGET "")
8
- if(TARGET Python::Module)
9
- set(EASYBIND_PYTHON_TARGET Python::Module)
10
- elseif(TARGET Python::Python)
11
- set(EASYBIND_PYTHON_TARGET Python::Python)
12
- else()
13
- message(FATAL_ERROR "Python imported target not found (expected Python::Module or Python::Python)")
14
- endif()
15
-
16
- find_dependency(nanobind CONFIG QUIET)
17
- if(NOT nanobind_FOUND)
18
- include(FetchContent)
19
- FetchContent_Declare(
20
- nanobind
21
- GIT_REPOSITORY https://github.com/wjakob/nanobind.git
22
- GIT_TAG v2.9.2
23
- )
24
- FetchContent_MakeAvailable(nanobind)
25
- endif()
26
-
27
- find_path(EASYBIND_BOOST_INCLUDE_DIR boost/asio.hpp)
28
- if(NOT EASYBIND_BOOST_INCLUDE_DIR)
29
- include(FetchContent)
30
- set(_easybind_boost_ver "1.85.0")
31
- string(REPLACE "." "_" _easybind_boost_ver_us "${_easybind_boost_ver}")
32
- set(_easybind_boost_url "https://archives.boost.io/release/${_easybind_boost_ver}/source/boost_${_easybind_boost_ver_us}.tar.gz")
33
- FetchContent_Declare(easybind_boost URL ${_easybind_boost_url})
34
- FetchContent_MakeAvailable(easybind_boost)
35
- set(EASYBIND_BOOST_INCLUDE_DIR "${easybind_boost_SOURCE_DIR}")
36
- endif()
37
-
38
- include("${CMAKE_CURRENT_LIST_DIR}/easybindTargets.cmake")
39
-
40
- function(easybind_add_extension target_name)
41
- nanobind_add_module(${target_name} NB_SHARED ${ARGN})
42
- target_link_libraries(${target_name} PRIVATE easybind::build_interface)
43
- target_link_libraries(${target_name} PRIVATE ${EASYBIND_PYTHON_TARGET})
44
- target_include_directories(${target_name} PRIVATE ${EASYBIND_BOOST_INCLUDE_DIR})
45
- target_compile_definitions(${target_name} PRIVATE BOOST_ERROR_CODE_HEADER_ONLY=1 BOOST_SYSTEM_NO_DEPRECATED=1)
46
- if(APPLE)
47
- set_target_properties(${target_name} PROPERTIES
48
- BUILD_RPATH "@loader_path"
49
- INSTALL_RPATH "@loader_path"
50
- )
51
- else()
52
- set_target_properties(${target_name} PROPERTIES
53
- BUILD_RPATH "$ORIGIN"
54
- INSTALL_RPATH "$ORIGIN"
55
- )
56
- endif()
57
- endfunction()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes