bovnar 0.9.1__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.

Potentially problematic release.


This version of bovnar might be problematic. Click here for more details.

Files changed (162) hide show
  1. bovnar-0.9.1/.github/workflows/wheels.yml +71 -0
  2. bovnar-0.9.1/.gitignore +10 -0
  3. bovnar-0.9.1/CMakeLists.txt +171 -0
  4. bovnar-0.9.1/CMakeLists_tests.txt +685 -0
  5. bovnar-0.9.1/LICENSE +44 -0
  6. bovnar-0.9.1/PKG-INFO +122 -0
  7. bovnar-0.9.1/README.md +530 -0
  8. bovnar-0.9.1/clean.sh +8 -0
  9. bovnar-0.9.1/cmake/FindGMP.cmake +29 -0
  10. bovnar-0.9.1/cmake/convert_expect_fail.cmake +37 -0
  11. bovnar-0.9.1/cmake/convert_json_roundtrip.cmake +56 -0
  12. bovnar-0.9.1/cmake/pretty_print_contains.cmake +38 -0
  13. bovnar-0.9.1/cmake/pretty_print_idempotent.cmake +49 -0
  14. bovnar-0.9.1/doc/0_bovnar_tutorial.md +1 -0
  15. bovnar-0.9.1/doc/1_bovnar_spec.md +1 -0
  16. bovnar-0.9.1/doc/2_bovnar_unit_system.md +1 -0
  17. bovnar-0.9.1/doc/3_bovnar_readwrite_api.md +1 -0
  18. bovnar-0.9.1/doc/4_bovnar_python_bindings.md +1 -0
  19. bovnar-0.9.1/doc/5_bovnar.ebnf +1 -0
  20. bovnar-0.9.1/doc/6_bovnar_faq.md +1 -0
  21. bovnar-0.9.1/doc/7_bovnar_conformance.md +1 -0
  22. bovnar-0.9.1/doc/8_unit_cheatsheet.md +1 -0
  23. bovnar-0.9.1/examples/arrays.bvnr +134 -0
  24. bovnar-0.9.1/examples/crypto_portfolio.bvnr +109 -0
  25. bovnar-0.9.1/examples/financial.bvnr +123 -0
  26. bovnar-0.9.1/examples/floats.bvnr +164 -0
  27. bovnar-0.9.1/examples/integers.bvnr +154 -0
  28. bovnar-0.9.1/examples/numpy_roundtrip.bvnr +148 -0
  29. bovnar-0.9.1/examples/references.bvnr +127 -0
  30. bovnar-0.9.1/examples/strings.bvnr +92 -0
  31. bovnar-0.9.1/examples/structs.bvnr +181 -0
  32. bovnar-0.9.1/examples/symbols.bvnr +113 -0
  33. bovnar-0.9.1/examples/test.bvnr +1 -0
  34. bovnar-0.9.1/examples/units.bvnr +857 -0
  35. bovnar-0.9.1/highlighter/geany/filetypes.Bovnar.conf +90 -0
  36. bovnar-0.9.1/highlighter/geany/install.sh +2 -0
  37. bovnar-0.9.1/highlighter/sublime/Bovnar-Cyberpunk.sublime-color-scheme +278 -0
  38. bovnar-0.9.1/highlighter/sublime/Bovnar.sublime-syntax +409 -0
  39. bovnar-0.9.1/highlighter/sublime/install.sh +26 -0
  40. bovnar-0.9.1/highlighter/vim/bovnar-ft.vim +1 -0
  41. bovnar-0.9.1/highlighter/vim/bovnar.vim +219 -0
  42. bovnar-0.9.1/highlighter/vim/install.sh +5 -0
  43. bovnar-0.9.1/highlighter/vscode/bovnar-highlight/language-configuration.json +16 -0
  44. bovnar-0.9.1/highlighter/vscode/bovnar-highlight/package.json +82 -0
  45. bovnar-0.9.1/highlighter/vscode/bovnar-highlight/syntaxes/Bovnar.tmLanguage.json +480 -0
  46. bovnar-0.9.1/highlighter/vscode/bovnar-highlight/themes/bovnar-cyberpunk-color-theme.json +329 -0
  47. bovnar-0.9.1/highlighter/vscode/install.sh +2 -0
  48. bovnar-0.9.1/include/bovnar.h +578 -0
  49. bovnar-0.9.1/include/bovnar_currency.h +65 -0
  50. bovnar-0.9.1/include/bovnar_dom.h +123 -0
  51. bovnar-0.9.1/include/bovnar_si_units.h +59 -0
  52. bovnar-0.9.1/include/bvn_float.h +200 -0
  53. bovnar-0.9.1/include/bvn_int.h +95 -0
  54. bovnar-0.9.1/merge.sh +8 -0
  55. bovnar-0.9.1/pyproject.toml +92 -0
  56. bovnar-0.9.1/python/README.md +83 -0
  57. bovnar-0.9.1/python/bovnar/__init__.py +631 -0
  58. bovnar-0.9.1/python/bovnar/_ffi.py +420 -0
  59. bovnar-0.9.1/python/bovnar/_numpy.py +321 -0
  60. bovnar-0.9.1/python/bovnar/_pint_bridge.py +216 -0
  61. bovnar-0.9.1/python/bovnar/_pint_units.py +722 -0
  62. bovnar-0.9.1/python/bovnar/currency.py +385 -0
  63. bovnar-0.9.1/python/bovnar/dom.py +406 -0
  64. bovnar-0.9.1/python/bovnar/enums.py +588 -0
  65. bovnar-0.9.1/python/bovnar/exceptions.py +70 -0
  66. bovnar-0.9.1/python/bovnar/quantity.py +83 -0
  67. bovnar-0.9.1/python/bovnar/reader.py +339 -0
  68. bovnar-0.9.1/python/bovnar/structs.py +346 -0
  69. bovnar-0.9.1/python/bovnar/units.py +312 -0
  70. bovnar-0.9.1/python/bovnar/writer.py +664 -0
  71. bovnar-0.9.1/python/tests/conftest.py +197 -0
  72. bovnar-0.9.1/python/tests/test_analytics.py +597 -0
  73. bovnar-0.9.1/python/tests/test_array_parser.py +373 -0
  74. bovnar-0.9.1/python/tests/test_currency_units.py +695 -0
  75. bovnar-0.9.1/python/tests/test_dom.py +490 -0
  76. bovnar-0.9.1/python/tests/test_enums.py +213 -0
  77. bovnar-0.9.1/python/tests/test_example_numpy_roundtrip.py +133 -0
  78. bovnar-0.9.1/python/tests/test_numpy_bridge.py +154 -0
  79. bovnar-0.9.1/python/tests/test_pint_bridge.py +183 -0
  80. bovnar-0.9.1/python/tests/test_reader.py +414 -0
  81. bovnar-0.9.1/python/tests/test_structs.py +353 -0
  82. bovnar-0.9.1/python/tests/test_unit_physics.py +1021 -0
  83. bovnar-0.9.1/python/tests/test_units.py +886 -0
  84. bovnar-0.9.1/python/tests/test_write_array.py +380 -0
  85. bovnar-0.9.1/python/tests/test_writer.py +939 -0
  86. bovnar-0.9.1/run_tests.sh +268 -0
  87. bovnar-0.9.1/src/bovnar.c +2178 -0
  88. bovnar-0.9.1/src/dom/bovnar_dom.c +605 -0
  89. bovnar-0.9.1/src/dom/bovnar_dom_builder.c +730 -0
  90. bovnar-0.9.1/src/dom/bvn_dom_impl.h +63 -0
  91. bovnar-0.9.1/src/io/bovnar_io.c +182 -0
  92. bovnar-0.9.1/src/io/bvn_io_impl.h +92 -0
  93. bovnar-0.9.1/src/lexer/bovnar_lexer.c +1885 -0
  94. bovnar-0.9.1/src/lexer/bovnar_state_table.c +814 -0
  95. bovnar-0.9.1/src/lexer/bvn_lexer_impl.h +344 -0
  96. bovnar-0.9.1/src/lexer/bvn_val_impl.h +150 -0
  97. bovnar-0.9.1/src/utils/bovnar_currency.c +328 -0
  98. bovnar-0.9.1/src/utils/bovnar_si_units.c +629 -0
  99. bovnar-0.9.1/src/utils/bovnar_utils.c +2566 -0
  100. bovnar-0.9.1/src/utils/bvn_float.c +2243 -0
  101. bovnar-0.9.1/src/utils/bvn_float.h +29 -0
  102. bovnar-0.9.1/src/utils/bvn_float_impl.h +1055 -0
  103. bovnar-0.9.1/src/utils/bvn_int.c +717 -0
  104. bovnar-0.9.1/src/utils/bvn_internal_dims.h +46 -0
  105. bovnar-0.9.1/src/utils/bvn_unit_impl.h +104 -0
  106. bovnar-0.9.1/src/validator/bovnar_validator.c +1053 -0
  107. bovnar-0.9.1/src/writer/bovnar_canon_observer.c +80 -0
  108. bovnar-0.9.1/src/writer/bovnar_write_utils.c +430 -0
  109. bovnar-0.9.1/src/writer/bovnar_writer.c +1046 -0
  110. bovnar-0.9.1/strip.sh +3 -0
  111. bovnar-0.9.1/strip_comments.sh +391 -0
  112. bovnar-0.9.1/tests/bovnar_currency_test.c +312 -0
  113. bovnar-0.9.1/tests/bovnar_dom_test.c +429 -0
  114. bovnar-0.9.1/tests/bovnar_extended_reader_test.c +632 -0
  115. bovnar-0.9.1/tests/bovnar_fuzz_dom.c +277 -0
  116. bovnar-0.9.1/tests/bovnar_fuzz_reader.c +281 -0
  117. bovnar-0.9.1/tests/bovnar_fuzz_seed_gen.c +351 -0
  118. bovnar-0.9.1/tests/bovnar_fuzz_test.c +1028 -0
  119. bovnar-0.9.1/tests/bovnar_fuzz_utils.c +427 -0
  120. bovnar-0.9.1/tests/bovnar_fuzz_writer.c +677 -0
  121. bovnar-0.9.1/tests/bovnar_high_severity_test.c +2630 -0
  122. bovnar-0.9.1/tests/bovnar_reader_test.c +239 -0
  123. bovnar-0.9.1/tests/bovnar_si_units_test.c +1544 -0
  124. bovnar-0.9.1/tests/bovnar_socketpair_roundtrip_test.c +768 -0
  125. bovnar-0.9.1/tests/bovnar_unit_ext_test.c +1498 -0
  126. bovnar-0.9.1/tests/bovnar_utils_test.c +470 -0
  127. bovnar-0.9.1/tests/bovnar_writer_test.c +1019 -0
  128. bovnar-0.9.1/tests/bvn_float_fix_dec_test.c +729 -0
  129. bovnar-0.9.1/tests/bvn_float_test.c +911 -0
  130. bovnar-0.9.1/tests/bvn_int_test.c +387 -0
  131. bovnar-0.9.1/tests/bvnr_conformance.c +1407 -0
  132. bovnar-0.9.1/tests/bvnr_conformance_iut.c +360 -0
  133. bovnar-0.9.1/tests/json/bad_key.json +1 -0
  134. bovnar-0.9.1/tests/json/bad_nul.json +1 -0
  135. bovnar-0.9.1/tests/json/bad_overflow.json +1 -0
  136. bovnar-0.9.1/tests/json/bad_trailing.json +1 -0
  137. bovnar-0.9.1/tests/json/roundtrip.json +19 -0
  138. bovnar-0.9.1/web/apple-touch-icon.png +0 -0
  139. bovnar-0.9.1/web/bovnar-logo-horizontal.svg +7 -0
  140. bovnar-0.9.1/web/bovnar-logo-stacked.svg +6 -0
  141. bovnar-0.9.1/web/bovnar-mark-tile.svg +8 -0
  142. bovnar-0.9.1/web/bovnar-mark.svg +5 -0
  143. bovnar-0.9.1/web/bovnar-og.png +0 -0
  144. bovnar-0.9.1/web/bovnar_highlight.js +145 -0
  145. bovnar-0.9.1/web/bovnar_parser.js +549 -0
  146. bovnar-0.9.1/web/doc/0_bovnar_tutorial.md +943 -0
  147. bovnar-0.9.1/web/doc/1_bovnar_spec.md +2275 -0
  148. bovnar-0.9.1/web/doc/2_bovnar_unit_system.md +1967 -0
  149. bovnar-0.9.1/web/doc/3_bovnar_readwrite_api.md +1116 -0
  150. bovnar-0.9.1/web/doc/4_bovnar_python_bindings.md +1111 -0
  151. bovnar-0.9.1/web/doc/5_bovnar.ebnf +786 -0
  152. bovnar-0.9.1/web/doc/6_bovnar_faq.md +1190 -0
  153. bovnar-0.9.1/web/doc/7_bovnar_conformance.md +528 -0
  154. bovnar-0.9.1/web/doc/8_unit_cheatsheet.md +763 -0
  155. bovnar-0.9.1/web/earth.jpg +0 -0
  156. bovnar-0.9.1/web/earth_night.jpg +0 -0
  157. bovnar-0.9.1/web/favicon.ico +0 -0
  158. bovnar-0.9.1/web/favicon.svg +2 -0
  159. bovnar-0.9.1/web/httpd.sh +2 -0
  160. bovnar-0.9.1/web/impressum.html +152 -0
  161. bovnar-0.9.1/web/index.html +5866 -0
  162. bovnar-0.9.1/web/site.webmanifest +13 -0
@@ -0,0 +1,71 @@
1
+ name: Wheels
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*']
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ concurrency:
11
+ group: wheels-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ build_wheels:
16
+ name: Wheels on ${{ matrix.os }}
17
+ runs-on: ${{ matrix.os }}
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ os:
22
+ - ubuntu-latest # manylinux x86_64
23
+ - ubuntu-24.04-arm # manylinux aarch64 (native runner)
24
+ - macos-14 # arm64 native + x86_64 cross-compiled
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+
28
+ - name: Build wheels
29
+ uses: pypa/cibuildwheel@v2.21
30
+
31
+ - uses: actions/upload-artifact@v4
32
+ with:
33
+ name: cibw-wheels-${{ matrix.os }}
34
+ path: ./wheelhouse/*.whl
35
+
36
+ build_sdist:
37
+ name: Source distribution
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+
42
+ - name: Build sdist
43
+ run: pipx run build --sdist
44
+
45
+ - name: Check metadata
46
+ run: pipx run twine check dist/*
47
+
48
+ - uses: actions/upload-artifact@v4
49
+ with:
50
+ name: cibw-sdist
51
+ path: ./dist/*.tar.gz
52
+
53
+ publish:
54
+ name: Publish to PyPI
55
+ needs: [build_wheels, build_sdist]
56
+ runs-on: ubuntu-latest
57
+ # Only publish on a version tag (e.g. v0.2.0).
58
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
59
+ environment:
60
+ name: pypi
61
+ url: https://pypi.org/p/bovnar
62
+ permissions:
63
+ id-token: write # OIDC token for PyPI Trusted Publishing
64
+ steps:
65
+ - uses: actions/download-artifact@v4
66
+ with:
67
+ pattern: cibw-*
68
+ path: dist
69
+ merge-multiple: true
70
+
71
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,10 @@
1
+ build/*
2
+ build*/*
3
+ __pycache__/*
4
+ .claude/
5
+ .cache/
6
+ bovnar_merged.txt
7
+ *.pyc
8
+ bovnar_merged_conly.txt
9
+ bovnar_merged_all.txt
10
+ bovnar.zip
@@ -0,0 +1,171 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(bovnar C)
3
+
4
+ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
5
+
6
+ set(CMAKE_C_STANDARD 99)
7
+ set(CMAKE_C_STANDARD_REQUIRED ON)
8
+ set(CMAKE_C_EXTENSIONS OFF)
9
+
10
+ option(BVNR_HARDEN
11
+ "Enable runtime hardening flags (stack protector, FORTIFY, format security)"
12
+ ON)
13
+ option(BVNR_WERROR
14
+ "Promote all warnings to errors (for CI)"
15
+ OFF)
16
+ option(BVNR_BUILD_TESTS
17
+ "Build and register the C/Python test suite"
18
+ ON)
19
+
20
+ set(BVNR_C_FLAGS
21
+ -std=c99
22
+ -Wall
23
+ -Wextra
24
+ -Wpedantic
25
+ -Wshadow
26
+ -Wcast-qual
27
+ -Wconversion
28
+ -Wno-override-init
29
+ -Wno-missing-field-initializers
30
+ -pedantic
31
+ $<$<C_COMPILER_ID:GNU>:-fanalyzer>
32
+ -fPIC
33
+ -fvisibility=hidden
34
+ # bvnr_source_t / bvnr_sink_t are opaque storage that the
35
+ # library reinterprets via an internal impl struct. Strict
36
+ # aliasing would mis-optimise those accesses, so disable it.
37
+ -fno-strict-aliasing
38
+ )
39
+ if(BVNR_HARDEN)
40
+ # -Wformat=2 / -Wformat-security: compile-time only, zero runtime cost.
41
+ list(APPEND BVNR_C_FLAGS
42
+ -Wformat=2
43
+ -Wformat-security
44
+ )
45
+ # FORTIFY_SOURCE: cheap runtime checks on libc string/io calls; needs
46
+ # optimisation to be active, so silently no-op in Debug.
47
+ list(APPEND BVNR_C_FLAGS
48
+ $<$<NOT:$<CONFIG:Debug>>:-D_FORTIFY_SOURCE=2>)
49
+ # Stack protector: ~10-15% slowdown on the parser hot path because the
50
+ # state-machine functions touch local arrays. Apply it only to the
51
+ # CLI executable (where user input enters via argv / files) instead
52
+ # of the inner library translation units — see the bovnar target below.
53
+ endif()
54
+ if(BVNR_WERROR)
55
+ list(APPEND BVNR_C_FLAGS -Werror)
56
+ endif()
57
+
58
+ # LTO tuning uses GCC-only spellings (-flto=auto, -fno-semantic-interposition).
59
+ # Other compilers — notably AppleClang for the macOS cibuildwheel wheels — get a
60
+ # plain optimised build so the same tree builds everywhere. The GCC path is
61
+ # unchanged.
62
+ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
63
+ set(BVNR_LTO_CFLAGS " -flto=auto -fno-semantic-interposition")
64
+ else()
65
+ set(BVNR_LTO_CFLAGS "")
66
+ endif()
67
+
68
+ set(CMAKE_C_FLAGS_DEBUG "-O0 -g3" CACHE STRING "C flags for Debug" FORCE)
69
+ set(CMAKE_C_FLAGS_RELEASE "-O3 -g0${BVNR_LTO_CFLAGS}" CACHE STRING "C flags for Release" FORCE)
70
+ set(CMAKE_C_FLAGS_MINSIZEREL "-Os -g0" CACHE STRING "C flags for MinSizeRel" FORCE)
71
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g3${BVNR_LTO_CFLAGS}" CACHE STRING "C flags for RelWithDebInfo" FORCE)
72
+
73
+ if((CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
74
+ AND CMAKE_C_COMPILER_ID STREQUAL "GNU")
75
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
76
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto=auto")
77
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -flto=auto")
78
+ endif()
79
+
80
+ set(BVNR_SOURCES_LEXER
81
+ src/lexer/bovnar_lexer.c
82
+ src/lexer/bovnar_state_table.c
83
+ )
84
+
85
+ set(BVNR_SOURCES_VALIDATOR
86
+ src/validator/bovnar_validator.c
87
+ )
88
+
89
+ set(BVNR_SOURCES_WRITER
90
+ src/writer/bovnar_writer.c
91
+ src/writer/bovnar_write_utils.c
92
+ src/writer/bovnar_canon_observer.c
93
+ )
94
+
95
+ set(BVNR_SOURCES_IO
96
+ src/io/bovnar_io.c
97
+ )
98
+
99
+ set(BVNR_SOURCES_DOM
100
+ src/dom/bovnar_dom.c
101
+ src/dom/bovnar_dom_builder.c
102
+ )
103
+
104
+ set(BVNR_SOURCES_UTILS
105
+ src/utils/bovnar_utils.c
106
+ src/utils/bovnar_si_units.c
107
+ src/utils/bovnar_currency.c
108
+ src/utils/bvn_int.c
109
+ src/utils/bvn_float.c
110
+ )
111
+
112
+ set(BVNR_SOURCES
113
+ ${BVNR_SOURCES_LEXER}
114
+ ${BVNR_SOURCES_VALIDATOR}
115
+ ${BVNR_SOURCES_WRITER}
116
+ ${BVNR_SOURCES_IO}
117
+ ${BVNR_SOURCES_DOM}
118
+ ${BVNR_SOURCES_UTILS}
119
+ )
120
+
121
+ add_library(bvnr_objects OBJECT ${BVNR_SOURCES})
122
+ target_compile_options(bvnr_objects PRIVATE ${BVNR_C_FLAGS})
123
+ target_include_directories(bvnr_objects
124
+ PUBLIC
125
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
126
+ PRIVATE
127
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/io
128
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/lexer
129
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils
130
+ )
131
+
132
+ add_library(bvnr_static STATIC $<TARGET_OBJECTS:bvnr_objects>)
133
+ target_include_directories(bvnr_static
134
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
135
+ target_link_libraries(bvnr_static PUBLIC m)
136
+
137
+ add_library(bvnr_shared SHARED $<TARGET_OBJECTS:bvnr_objects>)
138
+ target_compile_options(bvnr_shared PRIVATE ${BVNR_C_FLAGS})
139
+ target_include_directories(bvnr_shared
140
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
141
+ target_link_libraries(bvnr_shared PUBLIC m)
142
+
143
+ add_executable(bovnar src/bovnar.c)
144
+ target_compile_options(bovnar PRIVATE ${BVNR_C_FLAGS})
145
+ if(BVNR_HARDEN)
146
+ # Stack protector is applied to the CLI binary's own TU (where argv
147
+ # and stdin are first touched). Library TUs are exempt so the
148
+ # parser hot path stays fast.
149
+ target_compile_options(bovnar PRIVATE -fstack-protector-strong)
150
+ endif()
151
+ set_target_properties(bovnar PROPERTIES POSITION_INDEPENDENT_CODE ON)
152
+ target_link_options(bovnar PRIVATE -pie)
153
+ target_link_libraries(bovnar PRIVATE bvnr_static m)
154
+
155
+ # The test suite spins up dozens of executables at configure time and pulls in
156
+ # CTest/GMP/pytest wiring. Skip it when building the Python wheel
157
+ # (scikit-build-core defines SKBUILD) so `pip install` only compiles the lib.
158
+ if(BVNR_BUILD_TESTS AND NOT SKBUILD)
159
+ include(CMakeLists_tests.txt)
160
+ # Python test registration lives entirely in CMakeLists_tests.txt
161
+ # (granular per-file targets with proper labels and library injection).
162
+ endif()
163
+
164
+ # When built as a Python wheel, install the shared library directly into the
165
+ # `bovnar` package directory so the ctypes loader (_ffi.py) finds it in-place,
166
+ # with no LIBBOVNAR_PATH or system install required.
167
+ if(SKBUILD)
168
+ install(TARGETS bvnr_shared
169
+ LIBRARY DESTINATION bovnar # libbvnr_shared.so / .dylib
170
+ RUNTIME DESTINATION bovnar) # bvnr_shared.dll (Windows)
171
+ endif()