{"id":18365781,"url":"https://github.com/martchus/reflective-rapidjson","last_synced_at":"2025-08-13T14:06:33.636Z","repository":{"id":94310594,"uuid":"107463944","full_name":"Martchus/reflective-rapidjson","owner":"Martchus","description":"Code generator for serializing/deserializing C++ objects to/from JSON using Clang and RapidJSON","archived":false,"fork":false,"pushed_at":"2025-01-06T17:42:00.000Z","size":412,"stargazers_count":40,"open_issues_count":1,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-02T15:51:19.723Z","etag":null,"topics":["clang","cpp-library","deserialization","hacktoberfest","json","rapidjson","reflection","serialization"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Martchus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-18T21:15:49.000Z","updated_at":"2025-02-01T18:55:21.000Z","dependencies_parsed_at":"2023-12-20T11:17:54.713Z","dependency_job_id":"f690d1d3-ef16-4eca-a0e2-492248b38931","html_url":"https://github.com/Martchus/reflective-rapidjson","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/Martchus/reflective-rapidjson","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Martchus%2Freflective-rapidjson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Martchus%2Freflective-rapidjson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Martchus%2Freflective-rapidjson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Martchus%2Freflective-rapidjson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Martchus","download_url":"https://codeload.github.com/Martchus/reflective-rapidjson/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Martchus%2Freflective-rapidjson/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270254160,"owners_count":24552985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clang","cpp-library","deserialization","hacktoberfest","json","rapidjson","reflection","serialization"],"created_at":"2024-11-05T23:14:31.496Z","updated_at":"2025-08-13T14:06:33.519Z","avatar_url":"https://github.com/Martchus.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Reflective RapidJSON\n\nThe main goal of this project is to provide a code generator for serializing/deserializing C++ objects to/from JSON\nusing Clang and RapidJSON.\n\nExtending the generator to generate code for other formats or other applications of reflection is possible as well.\nA serializer/deserializer for a platform independent binary format has already been implemented.\n\nIt would also be possible to extend the library/generator to provide generic reflection (not implemented yet).\n\nThe following documentation focuses on the JSON (de)serializer. However, most of it is also true for the mentioned\nbinary (de)serializer which works quite similarly.\n\n## Open for other reflection approaches\nThe reflection implementation used behind the scenes of this library is exchangeable:\n\n* This repository already provides a small, additional header to use RapidJSON with Boost.Hana. This allows to\n  serialize or dezerialize simple data structures declared using the `BOOST_HANA_DEFINE_STRUCT` macro rather than\n  requiring the code generator.\n* When native reflection becomes standardized, it would be possible to make use of it as well. In this case,\n  the code generator could still act as a fallback.\n\n## Current state\nThe basic functionality is implemented, tested and documented:\n\n* Serialization and deserialization of datatypes listed under \"Supported datatypes\"\n    * Nesting and inheritance is possible\n    * Adapting 3rdparty structs/classes is supported\n* Basic error handling when deserializing\n* CMake macro to conveniently include the code generator into the build process\n* Allow to use Boost.Hana\n\n### Planned features and TODOs\nThere are still things missing which would likely be very useful in practise. The following list contains the\nopen TODOs which are supposed to be most relevant in practise:\n\n* [ ] Allow to specify which member variables should be considered\n    * This could work similarly to Qt's Signals \u0026 Slots macros.\n    * But there should also be a way to do this for 3rdparty types.\n    * Note that currently all public, non-static member variables are (de)serialized.\n* [ ] Support getter/setter methods\n    * [ ] Allow to serialize the result of methods\n    * [ ] Allow to pass a deserialized value to a method\n* [ ] Validate enum values when deserializing\n* [ ] Untie serialization and deserialization\n\nFor a full list of further ideas, see [TODOs.md](./TODOs.md).\n\n## Supported datatypes\nThe following table shows the mapping of supported C++ types to supported JSON types:\n\n| C++ type                                                                     | JSON type    |\n| ---------------------------------------------------------------------------- |:------------:|\n| custom structures/classes                                                    | object       |\n| `bool`                                                                       | true/false   |\n| signed and unsigned integral types                                           | number       |\n| `float` and `double`                                                         | number       |\n| `enum` and `enum class`                                                      | number       |\n| `std::string`                                                                | string       |\n| `std::string_view`                                                           | string/null  |\n| `const char *`                                                               | string/null  |\n| iteratable lists (`std::vector`, `std::list`, ...)                           | array        |\n| sets (`std::set`, `std::unordered_set`, `std::multiset`, ...)                | array        |\n| `std::pair`, `std::tuple`                                                    | array        |\n| `std::unique_ptr`, `std::shared_ptr`, `std::optional`                        | depends/null |\n| `std::map`, `std::unordered_map`, `std::multimap`, `std::unordered_multimap` | object       |\n| `std::variant`                                                               | object       |\n| `JsonSerializable`                                                           | object       |\n\n### Remarks\n* Raw pointers are not supported. This prevents\n  forgetting to free memory which would have to be allocated when deserializing.\n* For the same reason `const char *` and `std::string_view` are only supported for serialization.\n* Enums are (de)serialized as their underlying integer value. When deserializing, it is currently *not* checked\n  whether the present integer value is a valid enumeration item.\n* The JSON type for smart pointers and `std::optional` depends on the type the pointer/optional refers to.\n  It can also be `null` for null pointers or `std::optional` without value.\n* If multiple `std::shared_ptr` instances point to the same object this object is serialized multiple times.\n  When deserializing those identical objects, it is currently not possible to share the memory (again). So each\n  `std::shared_ptr` will point to its own copy. Note that this limitation is *not* present when using binary\n  (de)serialization instead of JSON.\n* For deserialization\n    * iteratables must provide an `emplace_back` method. So deserialization of eg. `std::forward_list`\n      is currently not supported.\n    * custom types must provide a default constructor.\n    * constant member variables are skipped.\n* It is possible to treat custom types as set/map using the macro `REFLECTIVE_RAPIDJSON_TREAT_AS_MAP_OR_HASH`,\n  `REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_MAP_OR_HASH`, `REFLECTIVE_RAPIDJSON_TREAT_AS_SET` or\n  `REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_SET`.\n* The key type of `std::map`, `std::unordered_map`, `std::multimap` and `std::unordered_multimap` must be\n  `std::string`.\n* An array is used to represent the multiple values of an `std::multimap` and `std::unordered_multimap` (for\n  consistency also when there is only one value present). This is because the JSON RFC says that\n  \"The names within an object SHOULD be unique\".\n* An `std::variant` is represented by an object like `{\"index\": ..., \"data\": ...}` where `index` is the\n  zero-based index of the alternative held by the variant and `data` the value held by the variant. The\n  type of `data` is `null` for `std::monostate` and otherwise deduced as usual.\n* For custom (de)serialization, see the section below.\n* The binary (de)serializer supports approximately the same C++ types but obviously maps them to a platform\n  independent binary representation rather than a JSON type.\n\n\n## Usage\nThis example shows how the library can be used to make a `struct` serializable:\n\u003cpre\u003e\n#include \u0026lt;reflective_rapidjson/json/serializable.h\u0026gt;\n\n// define structures, eg.\nstruct TestObject : public ReflectiveRapidJSON::JsonSerializable\u0026lt;TestObject\u0026gt; {\n    int number;\n    double number2;\n    vector\u0026lt;int\u0026gt; numbers;\n    string text;\n    bool boolean;\n};\nstruct NestingObject : public ReflectiveRapidJSON::JsonSerializable\u0026lt;NestingObject\u0026gt; {\n    string name;\n    TestObject testObj;\n};\nstruct NestingArray : public ReflectiveRapidJSON::JsonSerializable\u0026lt;NestingArray\u0026gt; {\n    string name;\n    vector\u0026lt;TestObject\u0026gt; testObjects;\n};\n\n// serialize to JSON\nNestingArray obj{ ... };\ncout \u0026lt;\u0026lt; \"JSON: \" \u0026lt;\u0026lt; obj.toJson().GetString();\n\n// deserialize from JSON\nconst auto obj = NestingArray::fromJson(...);\n\n// in exactly one of the project's translation units\n#include \"reflection/code-defining-structs.h\"\n\u003c/pre\u003e\n\nNote that the header included at the bottom must be generated by invoking the code generator appropriately, eg.:\n\u003cpre\u003e\nreflective_rapidjson_generator \\\n    --input-file \"$srcdir/code-defining-structs.cpp\" \\\n    --output-file \"$builddir/reflection/code-defining-structs.h\"\n\u003c/pre\u003e\n\nThere are further arguments available, see:\n\u003cpre\u003e\nreflective_rapidjson_generator --help\n\u003c/pre\u003e\n\n### Mixing with direct RapidJSON usage and further notes\nIt is of course possible to mix automatic serialization/deserialization with direct RapidJSON usage. This can be\ndone by invoking the `push` and `pull` functions within the `ReflectiveRapidJSON::JsonReflector` namespace directly.\n\nThe `push` functions are used on serialization to populate intermediate data structures for the serializer of the\nRapidJSON library. The intermediate JSON document can also easily be obtained via\n`JsonSerializable\u003cType\u003e::toJsonDocument()`.\n\nNote that this means a copy of the provided data will be made. That includes all strings as well. Currently there\nis no way to use RapidJSON's copy-free `SetString`-overloads instead. As a consequence the mentioned intermediate\nJSON document can be serialized without causing any further read accesses to the actual data structures.\n\nThe `pull` functions are used to populate your data structures from intermediate data structures produced by the\nparser of RapidJSON. Also in this case a copy will be made so only owning data structures can be used when\ndeserializing (see remarks regarding supported datatypes).\n\n#### Binary (de)serialization\nIt works very similar to the example above. Just use the `BinarySerializable` class instead (or in addition):\n\n\u003cpre\u003e\n#include \u0026lt;reflective_rapidjson/binary/serializable.h\u0026gt;\nstruct TestObject : public ReflectiveRapidJSON::BinarySerializable\u0026lt;TestObject\u0026gt;\n\u003c/pre\u003e\n\n#### Invoking code generator with CMake macro\nIt is possible to use the provided CMake macro to automate the code generator invocation:\n\u003cpre\u003e\n# find the package and make macro available\nfind_package(reflective_rapidjson REQUIRED)\nlist(APPEND CMAKE_MODULE_PATH ${REFLECTIVE_RAPIDJSON_MODULE_DIRS})\ninclude(ReflectionGenerator)\n\n# \"link\" against reflective_rapidjson\n# it is a header-only lib so this will only add the required include paths\n# to your target\ntarget_link_libraries(mytarget PRIVATE reflective_rapidjson)\n\n# invoke macro\nadd_reflection_generator_invocation(\n    INPUT_FILES code-defining-structs.cpp\n    GENERATORS json binary\n    OUTPUT_LISTS LIST_OF_GENERATED_HEADERS\n    CLANG_OPTIONS_FROM_TARGETS mytarget\n)\n\u003c/pre\u003e\n\nThis will produce the file `code-defining-structs.h` in the directory `reflection` in the current build directory. So\nmake sure the current build directory is added to the include directories of your target. The default output directory can\nalso be overridden by passing `OUTPUT_DIRECTORY custom/directory` to the arguments.\n\nIt is possible to specify multiple input files at once. A separate output file is generated for each input. The output files\nwill always have the extension `.h`, independently of the extension of the input file.\n\nThe full paths of the generated files are also appended to the variable `LIST_OF_GENERATED_HEADERS` which then can be added\nto the sources of your target. Of course this can be skipped if not required/wanted.\n\nThe `GENERATORS` argument specifies the generators to run. Use `json` to generate code for JSON (de)serialization and `binary`\nto generate code for binary (de)serialization. As shown in the example, multiple generators can be specified at a time.\n\nThe macro will also automatically pass Clang's resource directory which is detected by invoking `clang -print-resource-dir`.\nTo adjust that, just set the cache variable `REFLECTION_GENERATOR_CLANG_RESOURCE_DIR` before including the module.\n\nFor an explanation of the `CLANG_OPTIONS_FROM_TARGETS` argument, read the next section.\n\n#### Passing Clang options\nIt is possible to pass additional options to the Clang tool invocation used by the code generator.\nThis can be done using the `--clang-opt` argument or the `CLANG_OPTIONS` argument when using the CMake macro.\n\nFor example, additional definitions could be added using `--clang-opt -DSOME_DEFINE -DANOTHER_DEFINE`.\nBut it is actually possible to pass anything from `clang --help`, including the `-X...` options.\n\n##### Specifying Clang's resource directory\nIn case you get a massive number of errors, ensure Clang's resource directory can be located.\n[Clang documentation](https://clang.llvm.org/docs/LibTooling.html#libtooling-builtin-includes):\n\n\u003e The default location to look for builtin headers is in a path `$(dirname /path/to/tool)/../lib/clang/3.3/include` relative to the tool binary.\n\nTo adjust the default location, just add eg. `--clang-opt -resource-dir /usr/lib/clang/5.0.1` to the arguments.\n\n##### Pass options from regular targets\nIt makes most sense to specify the same options for the code generator as during the actual compilation. This way the code\ngenerator uses the same flags, defines and include directories as the compiler and hence behaves like the compiler.  \nWhen using the CMake macro, it is possible to automatically pass all compile flags, compile definitions and include directories\nfrom certain targets to the code generator. Those targets can be specified using the macro's `CLANG_OPTIONS_FROM_TARGETS` argument.\n\n#### Notes regarding cross-compilation\n* For cross compilation, it is required to build the code generator for the platform you're building on.\n* Since the code generator is likely not required under the target platform, you should add `-DNO_GENERATOR:BOOL=ON` to the CMake\n  arguments when building Reflective RapidJSON for the target platform.\n* When using the `add_reflection_generator_invocation` macro, you need to set the following CMake cache variables:\n    * `REFLECTION_GENERATOR_EXECUTABLE:FILEPATH=/path/to/reflective_rapidjson_generator`\n        * specifies the path of the code generator executable built for the platform you're building on\n        * only required if the executable is not in the path anyways\n    * `REFLECTION_GENERATOR_TRIPLE:STRING=machine-vendor-operatingsystem`\n        * specifies the GNU platform triple for the target platform\n        * examples for cross compiling with mingw-w64 under GNU/Linux:  \n          `x86_64-w64-mingw32`, `i686-w64-mingw32`\n    * `REFLECTION_GENERATOR_INCLUDE_DIRECTORIES:STRING=/custom/prefix/include`\n        * implicit include directories for target platform\n        * example for cross compiling with mingw-w64 under GNU/Linux:  \n          `/usr/lib/gcc/x86_64-w64-mingw32/7.2.1/include;/usr/x86_64-w64-mingw32/include/c++/7.2.1/x86_64-w64-mingw32;/usr/x86_64-w64-mingw32/include`\n* The Arch Linux packages mentioned at the end of the README file also include `mingw-w64` variants which give a concrete example how\n  cross-compilation can be done.\n\n### Using Boost.Hana instead of the code generator\nThe same example as above. However, this time Boost.Hana is used - so it doesn't require invoking the generator.\n\n\u003cpre\u003e\n#include \u0026lt;reflective_rapidjson/json/serializable-boosthana.h\u0026gt;\n\n// define structures using BOOST_HANA_DEFINE_STRUCT, eg.\nstruct TestObject : public JsonSerializable\u0026lt;TestObject\u0026gt; {\n    BOOST_HANA_DEFINE_STRUCT(TestObject,\n        (int, number),\n        (double, number2),\n        (vector\u0026lt;int\u0026gt;, numbers),\n        (string, text),\n        (bool, boolean)\n    );\n};\nstruct NestingObject : public JsonSerializable\u0026lt;NestingObject\u0026gt; {\n    BOOST_HANA_DEFINE_STRUCT(NestingObject,\n        (string, name),\n        (TestObject, testObj)\n    );\n};\nstruct NestingArray : public JsonSerializable\u0026lt;NestingArray\u0026gt; {\n    BOOST_HANA_DEFINE_STRUCT(NestingArray,\n        (string, name),\n        (vector\u0026lt;TestObject\u0026gt;, testObjects)\n    );\n};\n\n// serialize to JSON\nNestingArray obj{ ... };\ncout \u0026lt;\u0026lt; \"JSON: \" \u0026lt;\u0026lt; obj.toJson().GetString();\n\n// deserialize from JSON\nconst auto obj = NestingArray::fromJson(...);\n\u003c/pre\u003e\n\nSo beside the `BOOST_HANA_DEFINE_STRUCT` macro, the usage remains the same.\n\n#### Disadvantages\n* Use of ugly macro required\n* No context information for errors like type-mismatch available\n* Inherited members not considered\n* Proper support for enums is unlikely\n\n### Enable reflection for 3rd party classes/structs\nIt is obvious that the previously shown examples do not work for classes\ndefined in 3rd party header files as it requires adding an additional\nbase class.\n\nTo work around this issue, one can use the `REFLECTIVE_RAPIDJSON_MAKE_JSON_SERIALIZABLE`\nmacro. It will enable the `toJson` and `fromJson` methods for the specified class\nin the `ReflectiveRapidJSON::JsonReflector` namespace:\n\n\u003cpre\u003e\n// somewhere in included header\nstruct ThridPartyStruct\n{ ... };\n\n// somewhere in own header or source file\nREFLECTIVE_RAPIDJSON_MAKE_JSON_SERIALIZABLE(ThridPartyStruct)\n\n// (de)serialization\nReflectiveRapidJSON::JsonReflector::toJson(...).GetString();\nReflectiveRapidJSON::JsonReflector::fromJson\u0026lt;ThridPartyStruct\u0026gt;(\"...\");\n\u003c/pre\u003e\n\nThe code generator will emit the code in the same way as if `JsonSerializable` was\nused.\n\nBy the way, the functions in the `ReflectiveRapidJSON::JsonReflector` namespace can also\nbe used when inheriting from `JsonSerializable` (instead of the member functions).\n\n### (De)serializing private members\nBy default, private members are not considered for (de)serialization. However, it is possible\nto enable this by adding `friend` methods for the helper functions of Reflective RapidJSON.\n\nTo make things easier, there's a macro provided:\n\u003cpre\u003e\nstruct SomeStruct : public JsonSerializable\u0026lt;SomeStruct\u0026gt; {\n    REFLECTIVE_RAPIDJSON_ENABLE_PRIVATE_MEMBERS(SomeStruct);\n\npublic:\n    std::string publicMember = \"will be (de)serialized anyways\";\n\nprivate:\n    std::string privateMember = \"will be (de)serialized with the help of REFLECTIVE_RAPIDJSON_ENABLE_PRIVATE_MEMBERS macro\";\n};\n\u003c/pre\u003e\n\n#### Caveats\n* It will obviously not work for 3rd party structs.\n* This way to allow (de)serialization of private members must be applied when using Boost.Hana\n  and there are any private members present. The reason is that accessing the private members can\n  currently not prevented when using Boost.Hana.\n\n### Custom (de)serialization\nSometimes it is appropriate to implement custom (de)serialization. For instance, a\ncustom object representing a time value should likely be serialized as a string rather\nthan an object containing the internal structure.\n\nAn example for such custom (de)serialization can be found in the file\n`json/reflector-chronoutilities.h`. It provides (de)serialization of `DateTime` and\n`TimeSpan` objects from the C++ utilities library mentioned under dependencies.\n\n### Versioning\n#### JSON (de)serializer\nThe JSON (de)serializer doesn't support versioning at this point. It'll simply read/write the\nmembers present in the struct. Additional members (which were e.g. present in older/newer\nversions of the struct) are ignored when reading and in consequence dropped when writing.\n\n#### Binary (de)serializer\nThe binary (de)serializer supports *very* experimental versioning. Otherwise adding/removing\nmembers is a breaking change. The versioning looks like this:\n\n\u003cpre\u003e\n// enable definition of the macros shown below (otherwise use long macros defined in\n// `lib/versioning.h`)\n#define REFLECTIVE_RAPIDJSON_SHORT_MACROS\n\n#include \u0026lt;reflective_rapidjson/binary/serializable.h\u0026gt;\n\n// example struct where version is *not* serialized/deserialized; defaults to version from\n// outer scope when reading/writing, defaults to version 0 on top-level\nstruct Nested : public BinarySerializable\u0026lt;Nested\u0026gt; { //\n    std::uint32_t foo; // will be read/written in any case\n\nas_of_version(3):\n    std::uint32_t bar; // will be read/written if outer scope version is \u0026gt;= 3\n};\n\n// example struct where version is serialized/deserialized; defaults to version 3 when writing\nstruct Example : public BinarySerializable\u0026lt;Example, 3\u0026gt; {\n    Nested nested;      // will be read/written in any case, version is \"propagated down\"\n    std::uint32_t a, b; // will be read/written in any case\n\nuntil_version(2):\n    std::uint32_t c, d; // will be read/written if version is \u0026lt;= 2\n\nas_of_version(3):\n    std::uint32_t e, f; // will be read/written if version is \u0026gt;= 3\n\nas_of_version(4):\n    std::uint32_t g;    // will be read/written if version is \u0026gt;= 4\n};\n\u003c/pre\u003e\n\nThe version specified as template argument is also assumed to be the highest supported version.\nIf a higher version is encountered during deserialization, `BinaryVersionNotSupported` is thrown\nand the deserialization aborted.\n\nNote that the versioning is mostly untested at this point.\n\n### Remarks\n* Static member variables and member functions are currently ignored by the generator.\n* It is currently not possible to ignore a specific member variable.\n\n### Further examples\n* Checkout the test cases for further examples. Relevant files are in\n  the directories `lib/tests` and `generator/tests`.\n* There's also my\n  [tag editor](https://github.com/Martchus/tageditor), which uses Reflective RapidJSON to provide\n  a JSON export.\n  See [json.h](https://github.com/Martchus/tageditor/blob/master/cli/json.h) and\n  [mainfeatures.cpp#exportToJson](https://github.com/Martchus/tageditor/blob/master/cli/mainfeatures.cpp#L856).\n\n## Architecture\nThe following diagram gives an overview about the architecture of the code generator and wrapper library\naround RapidJSON:\n\n![Architecture overview](./doc/arch.svg)\n\n* blue: classes from LibTooling/Clang\n* grey: conceivable extension or use\n\n## Install instructions\n\n### Dependencies\nThe following dependencies are required at build time. Note that Reflective RapidJSON itself\nand *none* of these dependencies are required at runtime by an application which makes use of\nReflective RapidJSON.\n\n* C++ compiler and C++ standard library supporting at least C++17\n* the [CMake](https://cmake.org) build system\n* LibTooling from [Clang](https://clang.llvm.org) for the code generator (optional when using\n  Boost.Hana)\n* [RapidJSON](https://github.com/Tencent/rapidjson) for JSON (de)serialization\n* [C++ utilities](https://github.com/Martchus/cpp-utilities) for various helper functions\n\n#### Optional\n* [Boost.Hana](http://www.boost.org/doc/libs/1_65_1/libs/hana/doc/html/index.html) for using\n  `BOOST_HANA_DEFINE_STRUCT` instead of code generator\n* [CppUnit](https://www.freedesktop.org/wiki/Software/cppunit) for building and running the tests\n* [Doxygen](http://www.doxygen.org) for generating API documentation\n* [Graphviz](http://www.graphviz.org) for diagrams in the API documentation\n\n#### Remarks\n* It is not required to use CMake as build system for your own project. However, when using a\n  different build system, there is no helper for adding the code generator to the build process\n  provided (so far).\n* I usually develop using the latest version of those dependencies. So it is recommend to get the\n  the latest versions as well although very likely older versions might work as well. When adapting\n  to new versions of LLVM/Clang I usually take care that it also still works with previous versions.\n* The binary (de)serializer requires C++ utilities at runtime. So when using it, it is required to\n  link against C++ utilities.\n\n### How to build\n#### 1. Install dependencies\nInstall all required dependencies. Under a typical GNU/Linux system most of these dependencies\ncan be installed via the package manager. Otherwise follow the links in the \"Dependencies\" section\nabove.\n\nC++ utilities is likely not available as package. However, it is possible to build C++ utilities\ntogether with `reflective-rapidjson` to simplify the build process. The following build script makes\nuse of this. (To use system C++ utilities, just skip any lines with \"`c++utilities`\" in the following\nexamples.)\n\n#### 2. Make dependencies available\n\nWhen installing (some) of the dependencies at custom locations, it is likely neccassary to tell\nCMake where to find them. If you installed everything using packages provided by the system,\nyou can skip this step of course.\n\nTo specify custom locations, just set some environment variables before invoking CMake. This\ncan likely be done in your IDE settings and of course at command line. Here is a Bash example:\n\u003cpre\u003e\nexport PATH=$CUSTOM_INSTALL_PREFIX/bin:$PATH\nexport CMAKE_PREFIX_PATH=$CUSTOM_INSTALL_PREFIX:$CMAKE_PREFIX_PATH\nexport CMAKE_LIBRARY_PATH=$CUSTOM_INSTALL_PREFIX/lib:$CMAKE_LIBRARY_PATH\nexport CMAKE_INCLUDE_PATH=$CUSTOM_INSTALL_PREFIX/include:$CMAKE_INCLUDE_PATH\n\u003c/pre\u003e\n\nThere are also a lot of [useful variables](https://cmake.org/Wiki/CMake_Useful_Variables)\nthat can be specified as CMake arguments. It is also possible to create a\n[toolchain file](https://cmake.org/cmake/help/v3.10/manual/cmake-toolchains.7.html).\n\n\n#### 3. Get sources, eg. using Git:\n\u003cpre\u003e\ncd $SOURCES\ngit clone https://github.com/Martchus/cpp-utilities.git c++utilities\ngit clone https://github.com/Martchus/reflective-rapidjson.git\n\u003c/pre\u003e\n\nIf you don't want to build the development version, just checkout the desired version tag.\n\n#### 4. Run the build script\nHere is an example for building with GNU Make:\n\u003cpre\u003e\ncd $BUILD_DIR\n# generate Makefile\ncmake \\\n -DCMAKE_BUILD_TYPE:STRING=Release \\\n -DCMAKE_INSTALL_PREFIX:PATH=\"/final/install/prefix\" \\\n -DBUNDLED_CPP_UTILITIES_PATH:PATH=\"$SOURCES/c++utilities\" \\\n \"$SOURCES/reflective-rapidjson\"\n# build library and generators\nmake\n# build and run tests (optional, requires CppUnit)\nmake check\n# build tests but do not run them (optional, requires CppUnit)\nmake tests\n# generate API documentation (optional, requires Doxygen)\nmake apidoc\n# install header files, libraries and generator\nmake install DESTDIR=\"/temporary/install/location\"\n\u003c/pre\u003e\nAdd eg. `-j$(nproc)` to `make` arguments for using all cores.\n\n### Packages\n* Arch Linux\n    * for PKGBUILDs checkout [my GitHub repository](https://github.com/Martchus/PKGBUILDs) or\n      [the AUR](https://aur.archlinux.org/packages?SeB=m\u0026K=Martchus)\n    * there is also a [binary repository](https://martchus.dyn.f3l.de/repo/arch/ownstuff)\n* Tumbleweed\n    * RPM \\*.spec files and binaries are available via openSUSE Build Service\n        * latest releases: [download page](https://software.opensuse.org/download.html?project=home:mkittler\u0026package=reflective-rapidjson-devel),\n          [project page](https://build.opensuse.org/project/show/home:mkittler)\n        * Git master: [download page](https://software.opensuse.org/download.html?project=home:mkittler:vcs\u0026package=reflective-rapidjson-devel),\n          [project page](https://build.opensuse.org/project/show/home:mkittler:vcs)\n* Windows\n    * for mingw-w64 PKGBUILDs checkout [my GitHub repository](https://github.com/Martchus/PKGBUILDs)\n\nThese packages show the required dependencies and commands to build. So they might be useful for\nmaking Reflective RapidJSON available under other platforms, too.\n\n## Copyright notice and license\nCopyright © 2017-2024 Marius Kittler\n\nAll code is licensed under [GPL-2-or-later](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartchus%2Freflective-rapidjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartchus%2Freflective-rapidjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartchus%2Freflective-rapidjson/lists"}