commit 515f632cb59b459d53abc06972f9c0c7ebf67318 Author: Roland Conybeare Date: Fri Oct 6 23:10:40 2023 -0400 initial commit (kitbashed from kalman project) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..9c372fd5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,50 @@ +# xo-pyreflect/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_pyreflect VERSION 0.1) +enable_language(CXX) + +# common XO cmake macros (see github.com:Rconybea/xo-cmake) +include(xo_macros/xo_cxx) +include(xo_macros/code-coverage) + +# ---------------------------------------------------------------- +# unit test setup + +enable_testing() +# activate code coverage for all executables + libraries (when configured with -DCODE_COVERAGE=ON) +add_code_coverage() +# 1. assuming that /nix/store/ prefixes .hpp files belonging to gcc, catch2 etc. +# we're not interested in code coverage for these sources. +# 2. exclude the utest/ subdir, we don't need coverage on the unit tests themselves; +# rather, want coverage on the code that the unit tests exercise. +# +# NOTE: this seems to work only with the 'ccov-all' target. In particular, doesn't seem to do anything with the 'ccov' target +# +add_code_coverage_all_targets(EXCLUDE /nix/store/* ${PROJECT_SOURCE_DIR}/utest/* ${PROJECT_BINARY_DIR}/local/* ${PROJECT_SOURCE_DIR}/repo/*) + +# ---------------------------------------------------------------- +# c++ settings (usually temporary) + +set(PROJECT_CXX_FLAGS "") +add_definitions(${PROJECT_CXX_FLAGS}) + +xo_toplevel_compile_options() + +# ---------------------------------------------------------------- +# sources + +# note: library=pyreflect (not xo_pyreflect) -> establishes pyreflectTargets +add_subdirectory(src/pyreflect) +#add_subdirectory(utest) + +# ---------------------------------------------------------------- +# provide find_package() support + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} pyreflectTargets) + +# ---------------------------------------------------------------- +# install .hpp files + +#xo_install_include_tree() diff --git a/README.md b/README.md new file mode 100644 index 00000000..c020ad6e --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# python bindings for c++ reflection library (xo-reflect) + +### build + install +``` +$ cd xo-pyreflect +$ mkdir build +$ cd build +$ INSTALL_PREFIX=/usr/local # or wherever you prefer, e.g. ~/local +$ cmake -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/share/cmake -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. +$ make +$ make install +``` + +### build for unit test coverage +``` +$ cd xo-pyreflect +$ mkdir build-ccov +$ cd build-ccov +$ cmake -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/share/cmake -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} -DCODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug .. +``` + +### LSP support +``` +$ cd xo-pyreflect +$ ln -s build/compile_commands.json # lsp will look for compile_commands.json in the root of the source tree +``` diff --git a/cmake/xo_pyreflectConfig.cmake.in b/cmake/xo_pyreflectConfig.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/cmake/xo_pyreflectConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/src/pyreflect/CMakeLists.txt b/src/pyreflect/CMakeLists.txt new file mode 100644 index 00000000..9b63978f --- /dev/null +++ b/src/pyreflect/CMakeLists.txt @@ -0,0 +1,11 @@ +# xo_pyreflect/CMakeLists.txt + +set(SELF_LIB pyreflect) +set(SELF_SRCS pyreflect.cpp) + +# ---------------------------------------------------------------- +# pybind11 dep + +xo_pybind11_library(${SELF_LIB} ${SELF_SRCS}) + +xo_dependency(${SELF_LIB} reflect) diff --git a/src/pyreflect/pyreflect.cpp b/src/pyreflect/pyreflect.cpp new file mode 100644 index 00000000..3a9f81bb --- /dev/null +++ b/src/pyreflect/pyreflect.cpp @@ -0,0 +1,52 @@ +/* @file pyreflect.cpp */ + +// note: need pyreflect/ here bc pyreflect.hpp is generated, located in build directory +#include "src/pyreflect/pyreflect.hpp" +#include "xo/reflect/TypeDescr.hpp" +#include "xo/reflect/TaggedRcptr.hpp" +#include "xo/reflect/SelfTagging.hpp" +//#include "time/Time.hpp" +//#include "xo/pyutil/pytime.hpp" +#include "xo/pyutil/pyutil.hpp" +//#include +//#include +//#include +//#include + +namespace xo { + using xo::time::utc_nanos; + using xo::ref::unowned_ptr; + using xo::ref::rp; + namespace py = pybind11; + + namespace reflect { + PYBIND11_MODULE(PYREFLECT_MODULE_NAME(), m) { + + /* note: possibly move this to pytime/ if/when we provide it */ + //py::class_(m, "utc_nanos"); + + //py::class_(m, "TypeDescr"); + py::class_>(m, "TypeDescr") + .def_static("print_reflected_types", + [](){ TypeDescrBase::print_reflected_types(std::cout); }) + .def_property_readonly("canonical_name", &TypeDescrBase::canonical_name) + .def("__repr__", &TypeDescrBase::display_string); + + /* note: this means python will use + * std::unique_ptr + * when it encounters a TaggedRcptr instance. + * Maintains refcount at cost of 2nd level of indirection. + */ + py::class_(m, "TaggedRcptr") + .def_property_readonly("td", &TaggedPtr::td) + .def("__repr__", &TaggedRcptr::display_string); + + py::class_>(m, "SelfTagging") + .def("self_tp", &SelfTagging::self_tp); + + } /*pyreflect*/ + } /*namespace reflect*/ +} /*namespace xo*/ + +/* end pyreflect.cpp */ diff --git a/src/pyreflect/pyreflect.hpp.in b/src/pyreflect/pyreflect.hpp.in new file mode 100644 index 00000000..62b64a25 --- /dev/null +++ b/src/pyreflect/pyreflect.hpp.in @@ -0,0 +1,25 @@ +/* @file pyreflect.hpp + * + * automatically generated from src/xo_pyreflect/pyreflect.hpp.in + * see src/xo_pyreflect/CMakeLists.txt + */ + +/* python requires module name = library name + * example: + * PYBIND11_MODULE(PYREFLECT_MODULE_NAME(), m) { ... } + */ +#define PYREFLECT_MODULE_NAME() @SELF_LIB@ + +/* example: + * py::module_::import(PYREFLECT_MODULE_NAME_STR) + */ +#define PYREFLECT_MODULE_NAME_STR "@SELF_LIB@" + +/* example: + * PYREFLECT_IMPORT_MODULE() + * replaces + * py::module_::import("pyreflect") + */ +#define PYREFLECT_IMPORT_MODULE() py::module_::import("@SELF_LIB@") + +/* end pyreflect.hpp */