From 539917e24c2c3985b89594947bc033b3df30848b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 24 Sep 2023 15:34:08 -0400 Subject: [PATCH] subsys: README --- README.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b43d50c1..b7701781 100644 --- a/README.md +++ b/README.md @@ -1 +1,101 @@ -# subsys repo +# plugin initialization support + +subsys is a small header-only library providing support for plugin initialization + +## Features + +- provide application control of initialization order across c++ libraries +- circumvents the 'static order initialization fiasco' +- ensure initialization code runs exactly once if subsystem is linked +- enforce initialization order constraints +- defend against static linker stripping essential initialization code +- designed to work cleanly for libraries integrating into existing executable like python, java runtime, .. +- initialization state browseable at runtime + +## Getting Started + +### build + install `indentlog` dependency + +see [github/rconybea/indentlog](https://github.com/Rconybea/indentlog) + +### copy `subsys` repository locally +``` +$ git clone git@github.com:rconybea/subsys.git +$ ls -d subsys +subsys +``` + +### build + install +``` +$ cd subsys +$ mkdir build +$ cd build +$ cmake -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. +$ make +$ make install +``` + +`CMAKE_PREFIX_PATH` should point to prefix where `indentlog` is installed + +alternatively, if you're a nix user: +``` +$ git clone git@github.com:rconybea/xo-nix.git +$ ls -d xo-nix +xo-nix +$ cd xo-nix +$ nix-build -A subsys +``` + +### build for unit test coverage +``` +$ cd subsys +$ mkdir ccov +$ cd ccov +$ cmake -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} -DCODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug .. +``` + +## Examples + +### 1 +``` +// initialization code in .hpp for a subsystem foo, that relies on related subsystem bar + +#include "subsys/Subsystem.hpp" + +enum S_foo_tag {}; /* tag to represent initialization of subsystem foo */ + +template<> +struct InitSubsys { + static void init() { + // plugin initialization for subsystem foo + } + + static InitEvidence require() { + InitEvidence retval; + + // demand initialization of dependent subsystem bar, + // before initialization subsystem foo + // + retval ^= InitSubsys::require(); + + // initialization of this subsystem foo + retval ^= Subsystem::provide("foo", &init); + + return retval; + } +}; +``` + +``` +// in application code that relies on foo (perhaps along with other subsystems), +// for example in a pybind11 module: +// +PYBIND11_MODULE(pyfoo, m) { + // include foo in initialization set + InitSubsys::require(); + // ensure foo + dependencies are initialized + Subsystem::initialize_all(); + + ... +} +```