easybind 0.1.6__tar.gz → 0.2.2__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.1.6 → easybind-0.2.2}/CMakeLists.txt +8 -22
  2. {easybind-0.1.6 → easybind-0.2.2}/PKG-INFO +16 -8
  3. {easybind-0.1.6 → easybind-0.2.2}/README.md +14 -7
  4. easybind-0.2.2/cmake/easybind_dependencies.cmake +56 -0
  5. easybind-0.2.2/cmake/easybind_pip.cmake +79 -0
  6. {easybind-0.1.6 → easybind-0.2.2}/pyproject.toml +1 -0
  7. easybind-0.1.6/cmake/easybindConfig.cmake.in +0 -57
  8. {easybind-0.1.6 → easybind-0.2.2}/.clangd +0 -0
  9. {easybind-0.1.6 → easybind-0.2.2}/.github/workflows/publish.yml +0 -0
  10. {easybind-0.1.6 → easybind-0.2.2}/.gitignore +0 -0
  11. {easybind-0.1.6 → easybind-0.2.2}/.vscode/tasks.json +0 -0
  12. {easybind-0.1.6 → easybind-0.2.2}/LICENSE +0 -0
  13. {easybind-0.1.6 → easybind-0.2.2}/NOTICE +0 -0
  14. {easybind-0.1.6 → easybind-0.2.2}/RELEASING.md +0 -0
  15. {easybind-0.1.6 → easybind-0.2.2}/scripts/clangd-update.sh +0 -0
  16. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/__init__.cpp +0 -0
  17. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/bind.hpp +0 -0
  18. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/export.hpp +0 -0
  19. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/module/__init__.cpp +0 -0
  20. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/module/node.cpp +0 -0
  21. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/module/node.hpp +0 -0
  22. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/module/node__init__.cpp +0 -0
  23. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/module/ns_module.hpp +0 -0
  24. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/py.typed +0 -0
  25. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/sample/__init__.cpp +0 -0
  26. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/sample/sample.cpp +0 -0
  27. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/sample/sample.hpp +0 -0
  28. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/sample/test1.py +0 -0
  29. {easybind-0.1.6 → easybind-0.2.2}/src/easybind/sample/test2/__init__.py +0 -0
  30. {easybind-0.1.6 → easybind-0.2.2}/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.1.6
3
+ Version: 0.2.2
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>
@@ -20,6 +20,7 @@ Project-URL: Homepage, https://github.com/pymergetic/easybind
20
20
  Project-URL: Repository, https://github.com/pymergetic/easybind
21
21
  Project-URL: Issues, https://github.com/pymergetic/easybind/issues
22
22
  Requires-Python: >=3.11
23
+ Requires-Dist: nanobind~=2.12.0
23
24
  Provides-Extra: dev
24
25
  Requires-Dist: pytest>=7.0.0; extra == "dev"
25
26
  Requires-Dist: build>=1.0.0; extra == "dev"
@@ -63,18 +64,25 @@ The Python package is implemented as native extensions. It exposes:
63
64
  - `easybind.sample` (demo bindings)
64
65
 
65
66
  ## Build-time SDK
66
- `easybind` provides CMake helpers for hybrid extensions:
67
+ Installed wheels ship CMake helpers under **`easybind/cmake/`**:
67
68
 
68
- - `easybind::build_interface` (INTERFACE): baseline C++20 + PIC + shared include paths
69
- - `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:
70
73
 
71
- Example:
72
74
  ```cmake
73
- find_package(easybind CONFIG REQUIRED)
74
- easybind_add_extension(my_module src_bind/my_pkg/__cpp__/module.cpp)
75
- 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
76
82
  ```
77
83
 
84
+ When developing **inside** this repository, `easybind_add_extension(...)` is defined in the top-level `CMakeLists.txt` (not shipped in the wheel).
85
+
78
86
  ## Core idea
79
87
  - Each namespace/module defines a `ModuleNode` and a bind callback.
80
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.
@@ -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()
@@ -8,6 +8,7 @@ dynamic = ["version"]
8
8
  description = "Self-registering nanobind helpers (import as easybind)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
+ dependencies = ["nanobind~=2.12.0"]
11
12
  license = "Apache-2.0"
12
13
  license-files = ["LICENSE", "NOTICE"]
13
14
  authors = [
@@ -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