arena allocator + incremental garbage collector
  • C++ 98.4%
  • CMake 1.6%
Find a file
2024-05-01 14:42:48 -04:00
.github/workflows build: adopt xo-cmake macros as dependency 2023-09-27 09:23:55 -04:00
cmake xo-subsys: build: streamline using recent xo-cmake improvements 2024-05-01 14:42:00 -04:00
include/xo/subsys subsys: + operator<< for InitEvidence 2023-10-09 16:57:05 -04:00
.gitignore xo-subsys: .gitignore: ignore .build* dirs 2024-05-01 14:42:48 -04:00
CMakeLists.txt xo-subsys: build: streamline using recent xo-cmake improvements 2024-05-01 14:42:00 -04:00
README.md build: adopt xo-cmake macros as dependency 2023-09-27 09:23:55 -04:00

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

copy subsys repository locally

$ git clone git@github.com:rconybea/subsys.git
$ ls -d subsys
subsys

build + install

$ cd subsys
$ mkdir build
$ cd build
$ INSTALL_PREFIX=/usr/local  # or wherever you prefer
$ cmake -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/share/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<S_foo_tag> {
     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<S_bar_tag>::require();

          // initialization of this subsystem foo
          retval ^= Subsystem::provide<S_foo_tag>("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<S_foo_tag>::require();
    // ensure foo + dependencies are initialized
    Subsystem::initialize_all();

    ...
}