diff --git a/xo-pyrprintjson/.github/workflows/main.yml b/xo-pyrprintjson/.github/workflows/main.yml new file mode 100644 index 00000000..af5526f6 --- /dev/null +++ b/xo-pyrprintjson/.github/workflows/main.yml @@ -0,0 +1,196 @@ +name: build xo-pyprintjson + dependencies + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - name: checkout source + uses: actions/checkout@v3 + + - name: Install catch2 + # install catch2. see [[https://stackoverflow.com/questions/57982945/how-to-apt-get-install-in-a-github-actions-workflow]] + run: sudo apt-get install -y catch2 + + - name: Install pybind11-dev + run: sudo apt-get install -y pybind11-dev + + # ---------------------------------------------------------------- + + - name: Clone xo-cmake + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-cmake + path: repo/xo-cmake + + - name: Configure xo-cmake + run: cmake -B ${{github.workspace}}/build_xo-cmake -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/xo-cmake + + - name: Build xo-cmake (trivial) + run: cmake --build ${{github.workspace}}/build_xo-cmake --config ${{env.BUILD_TYPE}} + + - name: Install xo-cmake + run: cmake --install ${{github.workspace}}/build_xo-cmake + + # ---------------------------------------------------------------- + + - name: Clone indentlog + uses: actions/checkout@v3 + with: + repository: Rconybea/indentlog + path: repo/indentlog + + - name: Configure indentlog + # configure cmake for indentlog in dedicated build directory. + run: cmake -B ${{github.workspace}}/build_indentlog -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/indentlog + + - name: Build indentlog + run: cmake --build ${{github.workspace}}/build_indentlog --config ${{env.BUILD_TYPE}} + + - name: Install indentlog + # install into ${{github.workspace}}/local + run: cmake --install ${{github.workspace}}/build_indentlog + + # ---------------------------------------------------------------- + + - name: Clone subsys + uses: actions/checkout@v3 + with: + repository: Rconybea/subsys + path: repo/subsys + + - name: Configure subsys + # configure cmake for subsys in dedicated build directory. + run: cmake -B ${{github.workspace}}/build_subsys -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/subsys + + - name: Build subsys + run: cmake --build ${{github.workspace}}/build_subsys --config ${{env.BUILD_TYPE}} + + - name: Install subsys + # install into ${{github.workspace}}/local + run: cmake --install ${{github.workspace}}/build_subsys + + # ---------------------------------------------------------------- + + - name: Clone refcnt + uses: actions/checkout@v3 + with: + repository: Rconybea/refcnt + path: repo/refcnt + + - name: Configure refcnt + # configure cmake for refcnt in dedicated build directory. + run: cmake -B ${{github.workspace}}/build_refcnt -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/refcnt + + - name: Build refcnt + run: cmake --build ${{github.workspace}}/build_refcnt --config ${{env.BUILD_TYPE}} + + - name: Install refcnt + # install into ${{github.workspace}}/local + run: cmake --install ${{github.workspace}}/build_refcnt + + # ---------------------------------------------------------------- + + - name: Clone reflect + uses: actions/checkout@v3 + with: + repository: Rconybea/reflect + path: repo/reflect + + - name: Configure reflect + # configure cmake for reflect in dedicated build directory. + run: cmake -B ${{github.workspace}}/build_reflect -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/reflect + + - name: Build reflect + run: cmake --build ${{github.workspace}}/build_reflect --config ${{env.BUILD_TYPE}} + + - name: Install reflect + # install into ${{github.workspace}}/local + run: cmake --install ${{github.workspace}}/build_reflect + + # ---------------------------------------------------------------- + + - name: Clone printjson + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-printjson + path: repo/printjson + + - name: Configure printjson + # configure cmake for printjson in dedicated build directory. + run: cmake -B ${{github.workspace}}/build_printjson -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/printjson + + - name: Build printjson + run: cmake --build ${{github.workspace}}/build_printjson --config ${{env.BUILD_TYPE}} + + - name: Install printjson + # install into ${{github.workspace}}/local + run: cmake --install ${{github.workspace}}/build_printjson + + # ---------------------------------------------------------------- + + - name: Clone pyutil + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-pyutil + path: repo/pyutil + + - name: Configure pyutil + # configure cmake for pyutil in dedicated build directory. + run: cmake -B ${{github.workspace}}/build_pyutil -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/pyutil + + - name: Build pyutil + run: cmake --build ${{github.workspace}}/build_pyutil --config ${{env.BUILD_TYPE}} + + - name: Install pyutil + # install into ${{github.workspace}}/local + run: cmake --install ${{github.workspace}}/build_pyutil + + # ---------------------------------------------------------------- + + - name: Clone pyreflect + uses: actions/checkout@v3 + with: + repository: Rconybea/xo-pyreflect + path: repo/pyreflect + + - name: Configure pyreflect + # configure cmake for pyreflect in dedicated build directory. + run: cmake -B ${{github.workspace}}/build_pyreflect -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/pyreflect + + - name: Build pyreflect + run: cmake --build ${{github.workspace}}/build_pyreflect --config ${{env.BUILD_TYPE}} + + - name: Install pyreflect + # install into ${{github.workspace}}/local + run: cmake --install ${{github.workspace}}/build_pyreflect + + # ---------------------------------------------------------------- + + - name: Configure self (pyprintjson) + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: cmake -B ${{github.workspace}}/build_pyprintjson -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + + - name: Build self (pyprintjson) + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build_pyprintjson --config ${{env.BUILD_TYPE}} + + - name: Test self (pyprintjson) + working-directory: ${{github.workspace}}/build_pyprintjson + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + run: ctest -C ${{env.BUILD_TYPE}} diff --git a/xo-pyrprintjson/.gitignore b/xo-pyrprintjson/.gitignore new file mode 100644 index 00000000..13c0afb7 --- /dev/null +++ b/xo-pyrprintjson/.gitignore @@ -0,0 +1,6 @@ +# clangd working space (see emacs+lsp) +.cache +# typical cmake build directory (source-tree-nephew) +.build* +# symlink to builddir/compile_commands.json; should be set manually in dev sandbox +compile_commands.json diff --git a/xo-pyrprintjson/CMakeLists.txt b/xo-pyrprintjson/CMakeLists.txt new file mode 100644 index 00000000..dd29fbc9 --- /dev/null +++ b/xo-pyrprintjson/CMakeLists.txt @@ -0,0 +1,29 @@ +# xo-pyprintjson/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_pyprintjson VERSION 1.0) + +include(GNUInstallDirs) +include(cmake/xo-bootstrap-macros.cmake) + +xo_cxx_toplevel_options3() + +# ---------------------------------------------------------------- +# c++ settings (usually temporary) + +set(PROJECT_CXX_FLAGS "") +add_definitions(${PROJECT_CXX_FLAGS}) + +# ---------------------------------------------------------------- +# sources + +add_subdirectory(src/pyprintjson) +#add_subdirectory(utest) + +# ---------------------------------------------------------------- +# provide find_package() support + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +# end CMakeLists.txt diff --git a/xo-pyrprintjson/README.md b/xo-pyrprintjson/README.md new file mode 100644 index 00000000..e85bc227 --- /dev/null +++ b/xo-pyrprintjson/README.md @@ -0,0 +1,71 @@ +# python bindings for c++ printjson library (xo-printjson) + +## Getting Started + +### build + install dependencies + +- [github/Rconybea/xo-pyutil](https://github.com/Rconybea/xo-pyutil) +- [github/Rconybea/xo-printjson](https://github.com/Rconybea/xo-printjson) + +### build + install + +``` +$ cd xo-pyprintjson +$ 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 +``` +(also see .github/workflows/main.yml) + +## Examples + +``` +PYTHONPATH=~/local2/lib:$PYTHONPATH python +>>> import xo_pyprintjson +>>> dir(xo_pyprintjson) +['PrintJson', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] +>>> dir(xo_pyprintjson.PrintJson) +['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'instance', 'print'] +>>> +``` + +## Development + +### build for unit test coverage +``` +$ cd xo-pyprintjson +$ 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 (language server) support + +LSP looks for compile commands in the root of the source tree; +while Cmake creates them in the root of its build directory. + +``` +$ cd xo-pyprintjson +$ ln -s build/compile_commands.json # supply compile commands to LSP +``` + +### display cmake variables + +- `-L` list variables +- `-A` include 'advanced' variables +- `-H` include help text + +``` +$ cd xo-pyprintjson/build +$ cmake -LAH +``` diff --git a/xo-pyrprintjson/cmake/xo-bootstrap-macros.cmake b/xo-pyrprintjson/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..aba31169 --- /dev/null +++ b/xo-pyrprintjson/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,35 @@ +# ---------------------------------------------------------------- +# for example: +# $ PREFIX=/usr/local # for example +# $ cmake -DCMAKE_MODULE_PATH=prefix -DCMAKE_INSTALL_PREFIX=$PREFIX -B .build +# +# will get +# CMAKE_MODULE_PATH +# from xo-cmake-config --cmake-module-path +# +# and expect .cmake macros in +# CMAKE_MODULE_PATH/xo_macros/xo_cxx.cmake +# ---------------------------------------------------------------- + +find_program(XO_CMAKE_CONFIG_EXECUTABLE NAMES xo-cmake-config REQUIRED) + +if ("${XO_CMAKE_CONFIG_EXECUTABLE}" STREQUAL "XO_CMAKE_CONFIG_EXECUTABLE-NOT_FOUND") + message(FATAL "could not find xo-cmake-config executable") +endif() + +message(STATUS "XO_CMAKE_CONFIG_EXECUTABLE=${XO_CMAKE_CONFIG_EXECUTABLE}") + +if (NOT XO_SUBMODULE_BUILD) + if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) + # default to typical install location for xo-project-macros + execute_process(COMMAND ${XO_CMAKE_CONFIG_EXECUTABLE} --cmake-module-path OUTPUT_VARIABLE CMAKE_MODULE_PATH) + message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") + endif() +endif() + +# needs to have been installed somewhere on CMAKE_MODULE_PATH, +# (e.g. from xo-cmake with the same value for CMAKE_INSTALL_PREFIX) +# +include(xo_macros/xo_cxx) + +xo_cxx_bootstrap_message() diff --git a/xo-pyrprintjson/cmake/xo_pyprintjsonConfig.cmake.in b/xo-pyrprintjson/cmake/xo_pyprintjsonConfig.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/xo-pyrprintjson/cmake/xo_pyprintjsonConfig.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/xo-pyrprintjson/include/README.md b/xo-pyrprintjson/include/README.md new file mode 100644 index 00000000..5d2b4c67 --- /dev/null +++ b/xo-pyrprintjson/include/README.md @@ -0,0 +1 @@ +placeholder for future pyprintjson #include files diff --git a/xo-pyrprintjson/src/pyprintjson/CMakeLists.txt b/xo-pyrprintjson/src/pyprintjson/CMakeLists.txt new file mode 100644 index 00000000..defff223 --- /dev/null +++ b/xo-pyrprintjson/src/pyprintjson/CMakeLists.txt @@ -0,0 +1,10 @@ +# xo_pyprintjson/src/pyprintjson/CMakeLists.txt + +set(SELF_LIB xo_pyprintjson) +set(SELF_SRCS pyprintjson.cpp) + +# ---------------------------------------------------------------- + +xo_pybind11_library(${SELF_LIB} ${PROJECT_NAME}Targets ${SELF_SRCS}) +xo_pybind11_dependency(${SELF_LIB} printjson) +xo_pybind11_header_dependency(${SELF_LIB} xo_pyreflect) diff --git a/xo-pyrprintjson/src/pyprintjson/EXAMPLES b/xo-pyrprintjson/src/pyprintjson/EXAMPLES new file mode 100644 index 00000000..5965b9b6 --- /dev/null +++ b/xo-pyrprintjson/src/pyprintjson/EXAMPLES @@ -0,0 +1,2 @@ +import pyprintjson +pj=pyprintjson.PrintJson() diff --git a/xo-pyrprintjson/src/pyprintjson/pyprintjson.cpp b/xo-pyrprintjson/src/pyprintjson/pyprintjson.cpp new file mode 100644 index 00000000..1e107f31 --- /dev/null +++ b/xo-pyrprintjson/src/pyprintjson/pyprintjson.cpp @@ -0,0 +1,49 @@ +/* @file pyprintjson.cpp */ + +// note: need pyreflect/ here bc pyreflect.hpp is generated, located in build directory +#include "pyprintjson.hpp" +#include "xo/pyreflect/pyreflect.hpp" + +#include "xo/printjson/PrintJson.hpp" +#include "xo/reflect/TaggedRcptr.hpp" +//#include "reflect/SelfTagging.hpp" +//#include "refcnt/Refcounted.hpp" +//#include "refcnt/Unowned.hpp" +#include "xo/pyutil/pyutil.hpp" +//#include +//#include +//#include +//#include + +namespace xo { + namespace py = pybind11; + + namespace json { + using xo::reflect::SelfTagging; + using xo::reflect::TaggedRcptr; + using xo::ref::unowned_ptr; + + PYBIND11_MODULE(PYPRINTJSON_MODULE_NAME(), m) { + PYREFLECT_IMPORT_MODULE(); + + py::class_>(m, "PrintJson") + .def_static("instance", &PrintJsonSingleton::instance) + .def("print", + [](PrintJson & pj, TaggedRcptr p) + { + pj.print_tp(p, &std::cout); std::cout << "\n"; + }, + py::arg("value")) + .def("print", + [](PrintJson & pj, rp const & p) + { + pj.print_obj(p, &std::cout); std::cout << "\n"; + }, + py::arg("value")); + + //m.def("print_json", [](){ return PrintJsonSingleton::instance_ptr(); }); + } /*pyprintjson*/ + } /*namespace json*/ +} /*namespace xo*/ + +/* end pyprintjson.cpp */ diff --git a/xo-pyrprintjson/src/pyprintjson/pyprintjson.hpp.in b/xo-pyrprintjson/src/pyprintjson/pyprintjson.hpp.in new file mode 100644 index 00000000..d80e5aba --- /dev/null +++ b/xo-pyrprintjson/src/pyprintjson/pyprintjson.hpp.in @@ -0,0 +1,25 @@ +/* @file pyprintjson.hpp + * + * automatically generated from src/pyprintjson/pyprintjson.hpp.in + * see src/pyprintjson/CMakeLists.txt + */ + +/* python requires module name = library name + * example: + * PYBIND11_MODULE(PYPRINTJSON_MODULE_NAME(), m) { ... } + */ +#define PYPRINTJSON_MODULE_NAME() @SELF_LIB@ + +/* example: + * py::module_::import(PYPRINTJSON_MODULE_NAME_STR) + */ +#define PYPRINTJSON_MODULE_NAME_STR "@SELF_LIB@" + +/* example: + * PYPRINTJSON_IMPORT_MODULE() + * replaces + * py::module_::import("pyprintjson") + */ +#define PYPRINTJSON_IMPORT_MODULE() py::module_::import("@SELF_LIB@") + +/* end pyprintjson.hpp */