{"id":13831289,"url":"https://github.com/blockspacer/flextool","last_synced_at":"2025-07-09T13:33:20.699Z","repository":{"id":53877791,"uuid":"261573419","full_name":"blockspacer/flextool","owner":"blockspacer","description":"C++ compile-time programming  (serialization, reflection, code modification, enum to string, better enum, enum to json, extend or parse language, etc.)","archived":false,"fork":false,"pushed_at":"2021-09-09T14:55:45.000Z","size":20923,"stargazers_count":42,"open_issues_count":3,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-08-05T10:16:44.426Z","etag":null,"topics":["clang","cling","codestyle","cplusplus","cpp","cpp11","cpp14","introspection","libtooling","llvm","metaclass","preprocessor","refactoring","reflection","serialization","source-to-source","static-analysis","transpiling"],"latest_commit_sha":null,"homepage":"https://blockspacer.github.io/flex_docs/","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blockspacer.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}},"created_at":"2020-05-05T20:13:57.000Z","updated_at":"2024-05-06T18:13:05.000Z","dependencies_parsed_at":"2022-08-27T18:32:05.845Z","dependency_job_id":null,"html_url":"https://github.com/blockspacer/flextool","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockspacer%2Fflextool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockspacer%2Fflextool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockspacer%2Fflextool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockspacer%2Fflextool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blockspacer","download_url":"https://codeload.github.com/blockspacer/flextool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225553371,"owners_count":17487293,"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","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","cling","codestyle","cplusplus","cpp","cpp11","cpp14","introspection","libtooling","llvm","metaclass","preprocessor","refactoring","reflection","serialization","source-to-source","static-analysis","transpiling"],"created_at":"2024-08-04T10:01:23.767Z","updated_at":"2025-07-09T13:33:20.671Z","avatar_url":"https://github.com/blockspacer.png","language":"CMake","readme":"﻿\u0026nbsp;\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://blockspacer.github.io/flex_docs\"\u003e\n    \u003cimg src=\"https://blockspacer.github.io/flex_docs/images/logo.png\" width=\"100px\" alt=\"flextool\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003ch3 align=\"center\"\u003eAdd custom features to C++ language, like \u003ca href=\"https://www.fluentcpp.com/2018/03/09/c-metaclasses-proposal-less-5-minutes/\"\u003emetaclasses\u003c/a\u003e, \u003ca href=\"https://twitter.com/TartanLlama/status/1159457033441165313\"\u003eRust-like traits\u003c/a\u003e, reflection and many more\u003c/h3\u003e\n\u003cp align=\"center\"\u003eA fully open source, powerful solution for modification and generation of C++ source code. Reduce the amount of boilerplate code in your C++ projects.\u003c/p\u003e\n\u003chr /\u003e\n\n![Open Source Love](https://img.shields.io/badge/Open%20Source-%E2%9D%A4-pink.svg)\n![First Timers Only](https://img.shields.io/badge/first--timers--only-friendly-blue.svg?style=flat)\n![Up For Grabs](https://img.shields.io/badge/up--for--grabs-friendly-green.svg?style=flat)\n![GitHub](https://img.shields.io/github/license/blockspacer/flextool.svg)\n![GitHub forks](https://img.shields.io/github/forks/blockspacer/flextool.svg)\n![GitHub issues](https://img.shields.io/github/issues/blockspacer/flextool.svg)\n![GitHub pull requests](https://img.shields.io/github/issues-pr/blockspacer/flextool.svg)\n![GitHub contributors](https://img.shields.io/github/contributors/blockspacer/flextool.svg)\n![GitHub commit activity the past week, 4 weeks, year](https://img.shields.io/github/commit-activity/w/blockspacer/flextool.svg)\n![GitHub last commit](https://img.shields.io/github/last-commit/blockspacer/flextool.svg)\n![GitHub top language](https://img.shields.io/github/languages/top/blockspacer/flextool.svg)\n![GitHub language count](https://img.shields.io/github/languages/count/blockspacer/flextool.svg)\n[![Project Status: WIP - Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](http://www.repostatus.org/badges/latest/wip.svg)](http://www.repostatus.org/#wip)\n[![license](https://img.shields.io/github/license/blockspacer/flextool.svg?style=flat-square)](https://github.com/blockspacer/flextool/master/LICENSE)\n[![Total alerts](https://img.shields.io/lgtm/alerts/g/bsamseth/cpp-project.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/blockspacer/flextool/alerts/)\n[![Lines of Code](https://tokei.rs/b1/github/blockspacer/flextool)](https://github.com/blockspacer/flextool)\n[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/blockspacer/flextool.svg)](http://isitmaintained.com/project/blockspacer/flextool \"Average time to resolve an issue\")\n[![Percentage of issues still open](http://isitmaintained.com/badge/open/blockspacer/flextool.svg)](http://isitmaintained.com/project/blockspacer/flextool \"Percentage of issues still open\")\n\nMain project page: https://blockspacer.github.io/flex_docs/\n\n## Tutorials and examples\n\n- [Tutorial](https://blockspacer.github.io/flex_docs/tutorial/)\n- [Usage](https://blockspacer.github.io/flex_docs/building_projects/)\n- [Plugins](https://blockspacer.github.io/flex_docs/adding_plugins/)\n- [Tracing and log levels](https://blockspacer.github.io/flex_docs/bug_report/)\n\n## Supported platforms\n\nTested on Ubuntu 20.04.2 LTS.\n\nMay work on other platforms with minor modifications.\n\n## Before installation: Add conan remotes\n\nTo be able to add the list of dependency remotes please type the following command:\n\n```bash\ncmake -E time conan config install conan/remotes/\n# OR:\n# cmake -E time conan config install conan/remotes_disabled_ssl/\n```\n\n## Before installation\n\n- [Installation Guide](https://blockspacer.github.io/flex_docs/download/)\n\n- conan packages\n\nNOTE: cling with LLVM build may take couple of hours.\n\nCommand below uses `--profile clang12_compiler12_compiler`.\n\nExample conan profile `~/.conan/profiles/clang`:\n\n```txt\n[settings]\n# We are building in Ubuntu Linux\nos_build=Linux\nos=Linux\narch_build=x86_64\narch=x86_64\n\ncompiler=clang\ncompiler.version=10\ncompiler.libcxx=libstdc++11\n\n[env]\nCC=/usr/bin/clang-10\nCXX=/usr/bin/clang++-10\n\n[build_requires]\ncmake_installer/3.15.5@conan/stable\n```\n\nCreate clang12_compiler profile:\n\n```bash\n[settings]\n# We are building in Ubuntu Linux\n\nos_build=Linux\nos=Linux\narch_build=x86_64\narch=x86_64\n\ncompiler=clang\ncompiler.version=12\ncompiler.libcxx=libstdc++11\ncompiler.cppstd=17\n\nllvm_9:build_type=Release\n\n[env]\nCC=/usr/bin/clang-12\nCXX=/usr/bin/clang++-12\n\n[build_requires]\ncmake_installer/3.15.5@conan/stable\n```\n\nBefore creation of conan profile file, see: https://docs.conan.io/en/latest/using_packages/using_profiles.html.\n\nWe use `.cmake` script to download and install conan packages.\n\n```bash\ngit clone https://github.com/blockspacer/conan_github_downloader.git ~/conan_github_downloader\n\ncmake \\\n  -DSCRIPT_PATH=\"$PWD/get_conan_dependencies.cmake\"\\\n  -DENABLE_CLING=TRUE\\\n  -DENABLE_LLVM=TRUE\\\n  -DENABLE_LLVM_INSTALLER=FALSE\\\n  -DEXTRA_CONAN_OPTS=\"--profile;clang12_compiler\\\n;-s;build_type=Debug\\\n;-s;cling_conan:build_type=Release\\\n;-s;llvm_12:build_type=Release\\\n;--build;missing\" \\\n  -P ~/conan_github_downloader/conan_github_downloader.cmake\n\n# clean build cache\nconan remove \"*\" --build --force\n```\n\n## Easy install with common plugins\n\nIf you want to install flextool and its plugins in single command, change the options provided to `tools/buildConanThirdparty.cmake`.\n\nNOTE: `tools/buildConanThirdparty.cmake` will perform a FULL RE-BUILD; it may take couple of hours.\n\nCommand below uses `--profile clang12_compiler12_compiler`. Before creation of conan profile file, see: https://docs.conan.io/en/latest/using_packages/using_profiles.html.\n\nWe use `buildConanThirdparty.cmake` script to download and install conan packages.\n\nNOTE: set `-DENABLE_CLING=FALSE` if you already installed Cling using `tools/buildConanThirdparty.cmake` above.\n\n```bash\ngit clone https://github.com/blockspacer/conan_github_downloader.git ~/conan_github_downloader\n\ncmake \\\n  -DSCRIPT_PATH=\"$PWD/get_conan_dependencies.cmake\"\\\n  -DENABLE_CLING=TRUE\\\n  -DENABLE_LLVM=TRUE\\\n  -DENABLE_LLVM_INSTALLER=FALSE\\\n  -DENABLE_FLEXTOOL=TRUE \\\n  -DENABLE_BASIS_PLUGIN_HELPER=TRUE \\\n  -DENABLE_FLEX_REFLECT_PLUGIN=TRUE \\\n  -DENABLE_SQUARETS=TRUE \\\n  -DENABLE_FLEX_SQUARETS_PLUGIN=TRUE \\\n  -DENABLE_FLEX_PIMPL_PLUGIN=TRUE \\\n  -DENABLE_FLEX_TYPECLASS_PLUGIN=TRUE \\\n  -DENABLE_FLEX_META_PLUGIN=TRUE \\\n  -DENABLE_FLEX_META_DEMO=TRUE \\\n  -DEXTRA_CONAN_OPTS=\"--profile;clang12_compiler\\\n;-s;build_type=Debug\\\n;-s;cling_conan:build_type=Release\\\n;-s;llvm_12:build_type=Release\\\n;--build;missing\" \\\n  -P ~/conan_github_downloader/conan_github_downloader.cmake\n\n# clean build cache\nconan remove \"*\" --build --force\n```\n\n## Installation (without plugins)\n\nUse command below to re-build flextool (plugins must be installed separately).\n\nCommand below uses `--profile clang12_compiler12_compiler`. Before creation of conan profile file, see: https://docs.conan.io/en/latest/using_packages/using_profiles.html\n\n```bash\nexport VERBOSE=1\nexport CONAN_REVISIONS_ENABLED=1\nexport CONAN_VERBOSE_TRACEBACK=1\nexport CONAN_PRINT_RUN_COMMANDS=1\nexport CONAN_LOGGING_LEVEL=10\n\n# NOTE: change `build_type=Debug` to `build_type=Release` in production\n# NOTE: use --build=missing if you got error `ERROR: Missing prebuilt package`\ncmake -E time \\\n  conan create . conan/stable \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_tools:build_type=Release \\\n  --profile clang12_compiler \\\n      -e flextool:enable_tests=True \\\n      -e flextool:enable_llvm_tools=True\n\n# clean build cache\nconan remove \"*\" --build --force\n```\n\n## NOTE: flextool not compatible with `compile_commands.json`\n\nDisable generation of compilation database when you use flextool.\n\nIf you are using CMake, set `CMAKE_EXPORT_COMPILE_COMMANDS` to `FALSE`.\n\nIf `compile_commands.json` exists in build folder (or in parent folder), flextool may fail.\n\n## Standing on the Shoulders of Giants\n\nThis project is possible because of [flexferrum's `autoprogrammer`](https://github.com/flexferrum/autoprogrammer).\n\nArticles about flexferrum's `autoprogrammer` in media:\n\n- [RUS] (article) metaclasses https://habr.com/ru/article/448466/\n- [RUS] (slides) C++17 metaclasses https://assets.ctfassets.net/oxjq45e8ilak/55bGdX2PnYzmrpM8rwCjcE/791e7eee3236c2023e86e169faca8a0e/Sergei_Sadovnikov_Metaclasses_in_C___dream_Reality.pdf\n\n## Dev-only build (local conan flow)\n\n```bash\nfind . -type f -name \"*_buildflags.h\" -exec rm {} \\;\nfind . -type f -name \"*_buildflags.tmp\" -exec rm {} \\;\n\n(rm -rf local_build || true)\n\nexport CONAN_REVISIONS_ENABLED=1\nexport CONAN_VERBOSE_TRACEBACK=1\nexport CONAN_PRINT_RUN_COMMANDS=1\nexport CONAN_LOGGING_LEVEL=10\n\nexport PKG_NAME=flextool/master@conan/stable\n\n(CONAN_REVISIONS_ENABLED=1 \\\n    conan remove --force $PKG_NAME || true)\n\n# NOTE: use --build=missing if you got error `ERROR: Missing prebuilt package`\ncmake -E time \\\n  conan install . \\\n  --install-folder local_build \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_12:build_type=Release \\\n  -o openssl:shared=True \\\n  -e basis:enable_tests=True \\\n  -o chromium_base:shared=True \\\n  -e chromium_base:enable_tests=True \\\n  -o perfetto:is_hermetic_clang=False \\\n  --profile clang12_compiler \\\n  -e flexlib:enable_tests=True \\\n  -o flexlib:shared=False \\\n  -o perfetto:is_hermetic_clang=False \\\n  -o flexlib:enable_cling=True \\\n  -e flextool:enable_tests=True \\\n  -o flextool:enable_cling=True\n\n(rm local_build/CMakeCache.txt || true)\n\ncmake -E time \\\n  conan source . \\\n  --source-folder . \\\n  --install-folder local_build\n\n# You can use `cmake --build . -- -j14` on second run.\ncmake -E time \\\n  conan build . \\\n  --build-folder local_build \\\n  --source-folder . \\\n  --install-folder local_build\n\nconan package . \\\n  --build-folder local_build \\\n  --package-folder local_build/package_dir \\\n  --source-folder . \\\n  --install-folder local_build\n\ncmake -E time \\\n  conan export-pkg . conan/stable \\\n  --package-folder local_build/package_dir \\\n  -s build_type=Debug \\\n   --force \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_12:build_type=Release \\\n  -o openssl:shared=True \\\n  -e basis:enable_tests=True \\\n  -o chromium_base:shared=True \\\n  -e chromium_base:enable_tests=True \\\n  -o perfetto:is_hermetic_clang=False \\\n  --profile clang12_compiler \\\n  -e flexlib:enable_tests=True \\\n  -o flexlib:shared=False \\\n  -o perfetto:is_hermetic_clang=False \\\n  -o flexlib:enable_cling=True \\\n  -e flextool:enable_tests=True \\\n  -o flextool:enable_cling=True\n\ncmake -E time \\\n  conan test test_package \\\n  flextool/master@conan/stable \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_12:build_type=Release \\\n  -o openssl:shared=True \\\n  -e basis:enable_tests=True \\\n  -o chromium_base:shared=True \\\n  -e chromium_base:enable_tests=True \\\n  -o perfetto:is_hermetic_clang=False \\\n  --profile clang12_compiler \\\n  -e flexlib:enable_tests=True \\\n  -o flexlib:shared=False \\\n  -o perfetto:is_hermetic_clang=False \\\n  -o flexlib:enable_cling=True \\\n  -e flextool:enable_tests=True \\\n  -o flextool:enable_cling=True\n```\n\n## For contibutors: conan editable mode\n\nWith the editable packages, you can tell Conan where to find the headers and the artifacts ready for consumption in your local working directory.\nThere is no need to run `conan create` or `conan export-pkg`.\n\nFor details, see: [https://docs.conan.io/en/latest/developing_packages/editable_packages.html](https://docs.conan.io/en/latest/developing_packages/editable_packages.html)\n\nBuild locally:\n\n```bash\nexport VERBOSE=1\nexport CONAN_REVISIONS_ENABLED=1\nexport CONAN_VERBOSE_TRACEBACK=1\nexport CONAN_PRINT_RUN_COMMANDS=1\nexport CONAN_LOGGING_LEVEL=10\n\ncmake -E time \\\n  conan install . \\\n  --install-folder local_build \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_tools:build_type=Release \\\n  --profile clang12_compiler \\\n      -e flextool:enable_tests=True \\\n      -e flextool:enable_llvm_tools=True\n\ncmake -E time \\\n  conan source . \\\n  --source-folder local_build \\\n  --install-folder local_build\n\nconan build . \\\n  --build-folder local_build \\\n  --source-folder local_build \\\n  --install-folder local_build\n\nconan package . \\\n  --build-folder local_build \\\n  --package-folder local_build/package_dir \\\n  --source-folder local_build \\\n  --install-folder local_build\n```\n\nSet package to editable mode:\n\n```bash\nconan editable add local_build/package_dir \\\n  flextool/master@conan/stable\n```\n\nNote that `conanfile.py` is modified to detect local builds via `self.in_local_cache`.\n\nAfter change source in folder local_build (run commands in source package folder):\n\n```\nconan build . \\\n  --build-folder local_build \\\n  --source-folder local_build \\\n  --install-folder local_build\n\nconan package . \\\n  --build-folder local_build \\\n  --package-folder local_build/package_dir \\\n  --source-folder local_build \\\n  --install-folder local_build\n```\n\nBuild your test project.\n\nIn order to revert the editable mode just remove the link using:\n\n```bash\nconan editable remove \\\n  flextool/master@conan/stable\n```\n\n## For contibutors: conan workspace\n\nAllows to build multiple projects at once; it just creates `CMakeLists.txt` with `add_subdirectory` pointing to each package folder.\n\nNOTE: You can open workspace in IDE as usual CMake based project (change build directory to WorkspaceProject path)!\n\nFor details, see: [https://docs.conan.io/en/latest/developing_packages/workspaces.html](https://docs.conan.io/en/latest/developing_packages/workspaces.html)\n\nFor example, we want to build both flextool and flexlib at the same time (flextool requires flexlib).\n\n```bash\n# change ~ to desired build folder\ncd ~\n\n# Replace paths to yours!\n# Make sure each project in NOT in editable mode!\ncat \u003c\u003cEOF \u003e ~/conanws.yml\neditables:\n    flexlib/master@conan/stable:\n        path: /......../flexlib\n    flextool/master@conan/stable:\n        path: /......../flextool\nlayout: layout_flex\nworkspace_generator: cmake\nroot:\n    - flextool/master@conan/stable\nEOF\n\ncat \u003c\u003cEOF \u003e ~/layout_flex\n# This helps to define the location of CMakeLists.txt within package\n[source_folder]\n.\n\n# This defines where the conanbuildinfo.cmake will be written to\n[build_folder]\nbuild/{{settings.build_type}}\nEOF\n```\n\n```bash\nmkdir build_flex\n\ncd build_flex\n\ncat \u003c\u003cEOF \u003e CMakeLists.txt\ncmake_minimum_required(VERSION 3.0)\n\nproject(WorkspaceProject)\n\ninclude(\\${CMAKE_BINARY_DIR}/conanworkspace.cmake)\n\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flexlib_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flextool_SRC}/cmake\")\n\nconan_workspace_subdirectories()\n\nadd_dependencies(flextool flexlib)\nEOF\n\n# must contain `include(${CMAKE_BINARY_DIR}/conanworkspace.cmake)` without slash `\\` (slash added for bash cat command)\ncat CMakeLists.txt\n\n# combines options from all projects\nconan workspace install \\\n  ../conanws.yml \\\n  --profile=clang \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_tools:build_type=Release \\\n    -o openssl:shared=True \\\n    -o chromium_base:shared=True \\\n    -e basis:enable_tests=True \\\n    -e abseil:enable_llvm_tools=True \\\n    -o chromium_base:use_alloc_shim=True \\\n    -o chromium_tcmalloc:use_alloc_shim=True \\\n    -o perfetto:is_hermetic_clang=False \\\n    -e flextool:enable_tests=True \\\n    -e flextool:enable_llvm_tools=True \\\n    -o flexlib:shared=False \\\n    -o flexlib:enable_clang_from_conan=False \\\n    -e flexlib:enable_tests=True\n```\n\nBuild into folder created by `conan workspace install`:\n\n```bash\n# NOTE: change `build_type=Debug` to `build_type=Release` in production\nexport build_type=Debug\n\n# optional\n# remove old CMakeCache\n(rm CMakeCache.txt || true)\n\n# configure via cmake\ncmake -E time cmake . \\\n  -DCMAKE_VERBOSE_MAKEFILE=TRUE \\\n  -DENABLE_TESTS=TRUE \\\n  -DBASE_NEED_GEN_BUILD_DATE=FALSE \\\n  -DENABLE_DOCTEST=ON \\\n  -DBUILD_SHARED_LIBS=FALSE \\\n  -DCONAN_AUTO_INSTALL=OFF \\\n  -DCMAKE_BUILD_TYPE=${build_type}\n\n# remove generated files\n# change paths to yours\n# rm ~/flex_typeclass_plugin/build/Debug/*generated*\n\n# build code\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  -- -j8\n\n# run unit tests for flexlib\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flexlib_run_all_tests\n\n# run unit tests for flextool\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flextool_run_all_tests\n```\n\nWorkspace allows to make quick changes in existing source files.\n\nWe use `self.in_local_cache` to detect conan editable mode:\n\n```python\n# Local build\n# see https://docs.conan.io/en/latest/developing_packages/editable_packages.html\nif not self.in_local_cache:\n    self.copy(\"conanfile.py\", dst=\".\", keep_path=False)\n```\n\nMake sure that all targets have globally unique names.\n\nFor example: you can not have a target in each project with the same name like \"test\". You can solve that issue by adding project-specific prefix to name of each target like \"${ROOT_PROJECT_NAME}-test_main_gtest\".\n\nBecause `CMAKE_BINARY_DIR` will point to folder created by `conan workspace install`, make sure that you prefer `CMAKE_CURRENT_BINARY_DIR` to `CMAKE_BINARY_DIR` etc.\n\n## For contibutors: conan workspace with plugins\n\nBefore installation: plugins require pre-built flextool (in same workspace). You must build workspace without plugins; only then you will be able to re-build it with plugins.\n\nAdd plugins to yml file:\n\n```yml\neditables:\n    chromium_base/master@conan/stable:\n        path: /........./chromium_base\n    basis/master@conan/stable:\n        path: /........./basis\n    flex_support_headers/master@conan/stable:\n        path: /........./flex_support_headers\n    flexlib/master@conan/stable:\n        path: /........./flexlib\n    flextool/master@conan/stable:\n        path: /........./flextool\n    flex_reflect_plugin/master@conan/stable:\n        path: /........./flex_reflect_plugin\n    squarets/master@conan/stable:\n        path: /........./squarets\n    flex_squarets_plugin/master@conan/stable:\n        path: /........./flex_squarets_plugin\n    flex_typeclass_plugin/master@conan/stable:\n        path: /........./flex_typeclass_plugin\n    flex_pimpl_plugin/master@conan/stable:\n        path: /........./flex_pimpl_plugin\n    flex_meta_plugin/master@conan/stable:\n        path: /........./flex_meta_plugin\n    flex_meta_demo/master@conan/stable:\n        path: /........./flex_meta_demo\nlayout: layout_flex\nworkspace_generator: cmake\nroot:\n    - flex_reflect_plugin/master@conan/stable\n    - squarets/master@conan/stable\n    - flex_squarets_plugin/master@conan/stable\n    - flex_typeclass_plugin/master@conan/stable\n    - flex_pimpl_plugin/master@conan/stable\n    - flex_meta_plugin/master@conan/stable\n    - flex_meta_demo/master@conan/stable\n```\n\nUse `add_dependencies` in `CMakeLists.txt`:\n\n```bash\nmkdir build_flex\n\ncd build_flex\n\ncat \u003c\u003cEOF \u003e CMakeLists.txt\ncmake_minimum_required(VERSION 3.0)\n\nproject(WorkspaceProject)\n\ninclude(\\${CMAKE_BINARY_DIR}/conanworkspace.cmake)\n\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_chromium_base_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_basis_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flex_support_headers_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flexlib_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flex_reflect_plugin_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_squarets_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flex_squarets_plugin_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flex_typeclass_plugin_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flex_meta_plugin_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flex_meta_demo_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flex_pimpl_plugin_SRC}/cmake\")\nlist(PREPEND CMAKE_MODULE_PATH \"\\${PACKAGE_flextool_SRC}/cmake\")\n\nconan_workspace_subdirectories()\n\nadd_dependencies(basis chromium_base-static)\nadd_dependencies(flexlib basis)\nadd_dependencies(flextool flexlib basis flex_support_headers)\nadd_dependencies(flex_reflect_plugin flextool)\nadd_dependencies(flex_squarets_plugin squarets)\nadd_dependencies(flex_squarets_plugin flextool)\nadd_dependencies(flex_pimpl_plugin flextool)\nadd_dependencies(flex_pimpl_plugin flex_reflect_plugin)\nadd_dependencies(flex_pimpl_plugin flex_squarets_plugin)\nadd_dependencies(flex_typeclass_plugin flextool)\nadd_dependencies(flex_typeclass_plugin flex_squarets_plugin)\nadd_dependencies(flex_meta_demo flex_meta_plugin)\nadd_dependencies(flex_meta_demo flex_typeclass_plugin)\nadd_dependencies(flex_meta_demo flex_pimpl_plugin)\nadd_dependencies(flex_meta_demo flex_squarets_plugin)\nEOF\n```\n\nAdd plugins options to `conan workspace install`:\n\n```bash\n# combines options from all projects\nconan workspace install \\\n  ../conanws.yml \\\n  --profile=clang \\\n  -s build_type=Debug \\\n    -s cling_conan:build_type=Release \\\n    -s llvm_tools:build_type=Release \\\n    -e basis:enable_tests=True \\\n    -o openssl:shared=True \\\n    -o chromium_base:shared=True \\\n    -o chromium_base:use_alloc_shim=True \\\n    -o perfetto:is_hermetic_clang=False \\\n    -o chromium_tcmalloc:use_alloc_shim=True \\\n    -e flextool:enable_tests=True \\\n    -e flextool:enable_llvm_tools=True \\\n    -o flexlib:shared=False \\\n    -o flexlib:enable_clang_from_conan=False \\\n    -e flexlib:enable_tests=True \\\n    -o flex_reflect_plugin:shared=True \\\n    -o flex_reflect_plugin:enable_clang_from_conan=False \\\n    -e flex_reflect_plugin:enable_tests=True \\\n    -o squarets:shared=False \\\n    -o squarets:enable_clang_from_conan=False \\\n    -e squarets:enable_tests=True \\\n    -o flex_squarets_plugin:shared=False \\\n    -o flex_squarets_plugin:enable_clang_from_conan=False \\\n    -e flex_squarets_plugin:enable_tests=True \\\n    -o flex_meta_plugin:shared=False \\\n    -o flex_meta_plugin:enable_clang_from_conan=False \\\n    -e flex_meta_plugin:enable_tests=True \\\n    -o flex_typeclass_plugin:shared=False \\\n    -o flex_typeclass_plugin:enable_clang_from_conan=False \\\n    -e flex_typeclass_plugin:enable_tests=True \\\n    -o flex_pimpl_plugin:shared=False \\\n    -o flex_pimpl_plugin:enable_clang_from_conan=False \\\n    -e flex_pimpl_plugin:enable_tests=True \\\n    -o flex_meta_demo:enable_clang_from_conan=False \\\n    -e flex_meta_demo:enable_tests=True\n```\n\nBuild and test workspace:\n\n```bash\n# NOTE: change `build_type=Debug` to `build_type=Release` in production\nexport build_type=Debug\n\n# optional\n# remove old CMakeCache\n(rm CMakeCache.txt || true)\n\n# configure via cmake\ncmake -E time cmake . \\\n  -DCMAKE_VERBOSE_MAKEFILE=TRUE \\\n  -DENABLE_TESTS=TRUE \\\n  -DBASE_NEED_GEN_BUILD_DATE=FALSE \\\n  -DENABLE_DOCTEST=ON \\\n  -DBUILD_SHARED_LIBS=FALSE \\\n  -DCONAN_AUTO_INSTALL=OFF \\\n  -DCMAKE_BUILD_TYPE=${build_type}\n\n# remove generated files\n# change paths to yours\n# rm ~/flex_typeclass_plugin/build/Debug/*generated*\n\n# build code\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  -- -j8\n\n# run unit tests for flexlib\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flexlib_run_all_tests\n\n# run unit tests for flextool\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flextool_run_all_tests\n\n# run unit tests for flex_reflect_plugin\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flex_reflect_plugin_run_all_tests\n\n# run unit tests for squarets\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target squarets_run_all_tests\n\n# run unit tests for flex_squarets_plugin\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flex_squarets_plugin_run_all_tests\n\n# run unit tests for flex_squarets_plugin\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flex_meta_plugin_run_all_tests\n\n# run unit tests for flex_squarets_plugin\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flex_typeclass_plugin_run_all_tests\n\n# run unit tests for flex_squarets_plugin\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flex_pimpl_plugin_run_all_tests\n\n# run unit tests for flex_squarets_plugin\ncmake -E time cmake --build . \\\n  --config ${build_type} \\\n  --target flex_meta_demo_run_all_tests\n```\n\n## For contibutors: cppcheck\n\nMake sure you use `Debug` build with `-e flextool:enable_llvm_tools=True`.\n\nInstall cppcheck via conan:\n\n```bash\ncd /tmp\n\ngit clone -b testing/1.90 https://github.com/bincrafters/conan-cppcheck_installer.git\n\ncd conan-cppcheck_installer\n\nexport VERBOSE=1\nexport CONAN_REVISIONS_ENABLED=1\nexport CONAN_VERBOSE_TRACEBACK=1\nexport CONAN_PRINT_RUN_COMMANDS=1\nexport CONAN_LOGGING_LEVEL=10\n\n# NOTE: change `build_type=Debug` to `build_type=Release` in production\n# NOTE: use --build=missing if you got error `ERROR: Missing prebuilt package`\ncmake -E time \\\n  conan create . conan/stable \\\n  -s build_type=Release\n\n# clean build cache\nconan remove \"*\" --build --force\n```\n\nUsage (runs cmake with `-DENABLE_CPPCHECK=ON`):\n\n```bash\n# creates local build in separate folder and runs cmake targets\n# NOTE: -DCLEAN_OLD=\"OFF\" to keep generated html report\ncmake -DCPPCHECK=\"ON\" -DCLEAN_OLD=\"OFF\" -P tools/run_tool.cmake\n```\n\n```bash\n# `index.html` must exist\n# find $PWD -name index.html\n```\n\nOpen 'index.html' to see the results.\n\n## For contibutors: vue ui\n\nDesktop application that provides a single context to manage and run multiple scripts.\n\nSimplifies setup of local dev environment; this avoids opening a lot of shell terminals.\n\nYou can add custom commands in `package.json` or `plugin/vue-cli-plugin/ui.js`:\n\n```bash\n# Before: Install Latest Node.js and NPM\n# see https://tecadmin.net/install-latest-nodejs-npm-on-ubuntu/\nnode --version\nnpm --version\n```\n\nBuild your project via npm:\n\n```bash\nnpm install\n```\n\n```bash\nsudo npm install -g @vue/cli\nsudo vue ui --dev --port 8061\n```\n\nOpen `http://localhost:8061/`.\n\nImport project directory.\n\nSelect `Tasks`, like build/test...\n\nTasks may be changed in `package.json`.\n\nNOTE: We use `package.json` only for tasks. Conan is controlled by a file called conanfile.txt.\n\nUseful links:\n\n- https://cli.vuejs.org/dev-guide/ui-api.html#ui-files\n- https://github.com/Dewep/GCE\n- https://github.com/supnate/command-pad\n\n## For contibutors: gdbinit\n\nWe use `.gdbinit` add 'add-auto-load-safe-path .'\n\nFor more details about `.gdbinit`, read: [https://metricpanda.com/tips-for-productive-debugging-with-gdb](https://metricpanda.com/tips-for-productive-debugging-with-gdb)\n\nFor more details about `gdb`, read: [http://www.yolinux.com/TUTORIALS/GDB-Commands.html](http://www.yolinux.com/TUTORIALS/GDB-Commands.html)\n\nGDB debugging session can be automated like so:\n\n```bash\n# see https://gist.github.com/williballenthin/8bd6e29ad8504b9cb308039f675ee889\ngdb \\\n  -ex \"run\" \\\n  -ex \"set pagination off\" \\\n  -ex \"bt\" \\\n  -ex \"set confirm off\" \\\n  -ex \"quit\" \\\n  --args \\\n  ${APP_EXE} \\\n  ${APP_CMD_ARGS}\n```\n\n## For contibutors: valgrind\n\nMake sure you use `Debug` build with `-e flextool:enable_llvm_tools=True`.\n\nFor details, see:\n\n* [https://www.jetbrains.com/help/clion/memory-profiling-with-valgrind.html](https://www.jetbrains.com/help/clion/memory-profiling-with-valgrind.html)\n* [https://heeris.id.au/2016/valgrind-gdb/](https://heeris.id.au/2016/valgrind-gdb/)\n\nInstall valgrind:\n\n```bash\nsudo apt install valgrind  # Ubuntu, Debian, etc.\n# OR\nsudo yum install valgrind  # RHEL, CentOS, Fedora, etc.\n```\n\nNOTE: make sure you set `use_alloc_shim=False` and `enable_valgrind=True` (see below).\n\nRun valgrind via cmake:\n\n```bash\nexport VERBOSE=1\nexport CONAN_REVISIONS_ENABLED=1\nexport CONAN_VERBOSE_TRACEBACK=1\nexport CONAN_PRINT_RUN_COMMANDS=1\nexport CONAN_LOGGING_LEVEL=10\n\n# NOTE: set `use_alloc_shim=False` and `enable_valgrind=True` for valgrind support\ncmake -E time \\\n  conan install . \\\n  --install-folder local_build_valgrind \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_tools:build_type=Release \\\n  --profile clang12_compiler \\\n      -o flextool:enable_valgrind=True \\\n      -e flextool:enable_tests=True \\\n      -e flextool:enable_llvm_tools=True \\\n      -e abseil:enable_llvm_tools=True \\\n      -o chromium_base:enable_valgrind=True \\\n      -e chromium_base:enable_llvm_tools=True \\\n      -o chromium_base:use_alloc_shim=False \\\n      -o perfetto:is_hermetic_clang=False \\\n      -o basis:enable_valgrind=True \\\n      -e basis:enable_llvm_tools=True \\\n      -o flexlib:enable_valgrind=True \\\n      -e flexlib:enable_llvm_tools=True \\\n      -o flexlib:enable_clang_from_conan=False \\\n      -o chromium_tcmalloc:use_alloc_shim=False \\\n      --build chromium_base \\\n      --build chromium_tcmalloc \\\n      --build basis \\\n      --build flexlib\n\ncd ~/flextool\n\n# see section about `conan editable mode`\ncd local_build_valgrind\n\n# optional\n# remove old CMakeCache\n(rm CMakeCache.txt || true)\n\n# remove old build artifacts\nrm -rf flextool\nrm -rf bin\nfind . -iname '*.o' -exec rm {} \\;\nfind . -iname '*.a' -exec rm {} \\;\nfind . -iname '*.dll' -exec rm {} \\;\nfind . -iname '*.lib' -exec rm {} \\;\n\n# NOTE: -DENABLE_VALGRIND=ON\ncmake .. \\\n  -DCMAKE_VERBOSE_MAKEFILE=TRUE \\\n  -DENABLE_VALGRIND=ON \\\n  -DENABLE_TESTS=TRUE \\\n  -DBASE_NEED_GEN_BUILD_DATE=FALSE \\\n  -DENABLE_DOCTEST=ON \\\n  -DENABLE_VALGRIND_TESTS=TRUE \\\n  -DBUILD_SHARED_LIBS=FALSE \\\n  -DCONAN_AUTO_INSTALL=OFF \\\n  -DCMAKE_BUILD_TYPE=Debug\n\n# NOTE: to run some tests under valgrind\n# use `-DENABLE_VALGRIND_TESTS=TRUE`\ncmake -E time cmake --build . \\\n  --target flextool-gmock_run_valgrind\n\n# Cmake will print valgrind command that was executed.\n# You can copy executed command and add custom command-line arguments:\n#   --gtest_filter=ToolsSanityTest.DISABLED_ValgrindTest \\\n#   --gtest_also_run_disabled_tests\n\n# search for valgrind log file\nfind $PWD -name *valgrind*.log\n```\n\nTo find leaks, you can seach for `definitely lost` in log file.\n\nNOTE: you can add valgrind suppressions in `cmake/valgrind.cfg`.\n\nNOTE: compile program with a debug flag to run under valgrind.\n\nNOTE: use `valgrind --tool=helgrind` to detect potential deadlocks and data races.\n\nNOTE: use `valgrind --tool=massif --massif-out-file=massif_file --stacks=true` to measure size of heap.\nSee also: https://kde.org/applications/development/org.kde.massif-visualizer\n\nFor details, see: https://stackoverflow.com/a/44989219\n\nTODO: try to build with valgrind and clang 10 https://stackoverflow.com/questions/40509986/valgrind-reporting-mismatched-free-delete-delete\n\nTODO: valgrind may not support chromium base, FIXME. And remove GTEST_NO_SUITE\n\n## For contibutors: clang-tidy\n\nMake sure you use `Debug` build with `-e flextool:enable_llvm_tools=True`\n\nInstall clang-tidy:\n\n```bash\nsudo apt-get install clang-tidy  # Ubuntu, Debian, etc.\n# OR\nsudo yum install clang-tidy  # RHEL, CentOS, Fedora, etc.\n```\n\nUsage (runs cmake with `-DENABLE_CLANG_TIDY=ON`):\n\n```bash\n# creates local build in separate folder and runs cmake targets\ncmake -DCLANG_TIDY=\"ON\" -DCLEAN_OLD=\"ON\" -P tools/run_tool.cmake\n```\n\n## For contibutors: scan-build\n\nMake sure you use `Debug` build with `-e flextool:enable_llvm_tools=True`\n\nFor details, see: [https://chromium.googlesource.com/chromium/src.git/+/master/docs/clang_static_analyzer.md](https://chromium.googlesource.com/chromium/src.git/+/master/docs/clang_static_analyzer.md)\nand [https://clang-analyzer.llvm.org/scan-build.html](https://clang-analyzer.llvm.org/scan-build.html)\n\nThe program ccc-analyzer acts like a fake compiler, forwarding its command line arguments over to the compiler to perform regular compilation and clang to perform static analysis.\n\nRunning configure typically generates makefiles that have hardwired paths to the compiler, and by running configure through scan-build that path is set to ccc-analyzer.\n\n```bash\n# must exist\nccc-analyzer -v\n\n# must exist\nc++-analyzer -v\n\n# must exist\nscan-build -v\n\nexport VERBOSE=1\nexport CONAN_REVISIONS_ENABLED=1\nexport CONAN_VERBOSE_TRACEBACK=1\nexport CONAN_PRINT_RUN_COMMANDS=1\nexport CONAN_LOGGING_LEVEL=10\n\ncmake -E time \\\n  conan install . \\\n  --install-folder local_build_scan_build \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_tools:build_type=Release \\\n  --profile clang12_compiler \\\n      -e flextool:enable_tests=True \\\n      -e flextool:enable_llvm_tools=True\n\ncmake -E time \\\n  conan source . \\\n  --source-folder local_build_scan_build \\\n  --install-folder local_build_scan_build\n\n# see section about `conan editable mode`\ncd local_build_scan_build\n\n# NOTE: change `build_type=Debug` to `build_type=Release` in production\nexport build_type=Debug\n\n# optional\n# remove old CMakeCache\n(rm CMakeCache.txt || true)\n\n# NOTE: changed CMAKE_C_COMPILER to ccc-analyzer (!!!)\n# configure via cmake\nscan-build \\\n  --use-cc=clang-10 \\\n  --use-c++=clang++-10 \\\n  -o ./scanbuildout/ \\\n  cmake .. \\\n  -DCMAKE_VERBOSE_MAKEFILE=TRUE \\\n  -DCMAKE_C_COMPILER=ccc-analyzer \\\n  -DCMAKE_CXX_COMPILER=c++-analyzer \\\n  -DENABLE_TESTS=FALSE \\\n  -DBASE_NEED_GEN_BUILD_DATE=FALSE \\\n  -DENABLE_DOCTEST=OFF \\\n  -DBUILD_SHARED_LIBS=FALSE \\\n  -DCONAN_AUTO_INSTALL=OFF \\\n  -DCMAKE_BUILD_TYPE=${build_type}\n\n# remove old build artifacts\n(make clean || true)\nrm -rf bin\n\n# NOTE: requires project configured in debug build\n# disable other static analyzers\n# run from build directory\nscan-build \\\n  -maxloop 8 \\\n  -enable-checker alpha.security.taint.TaintPropagation \\\n  -enable-checker alpha.core.BoolAssignment \\\n  -enable-checker alpha.core.CastSize \\\n  -enable-checker alpha.core.DynamicTypeChecker \\\n  -enable-checker alpha.core.FixedAddr \\\n  -enable-checker alpha.core.IdenticalExpr \\\n  -enable-checker alpha.core.PointerArithm \\\n  -enable-checker alpha.core.PointerSub \\\n  -enable-checker alpha.core.SizeofPtr \\\n  -enable-checker alpha.core.TestAfterDivZero \\\n  -enable-checker alpha.deadcode.UnreachableCode \\\n  -enable-checker alpha.security.ArrayBoundV2 \\\n  -enable-checker alpha.security.MallocOverflow \\\n  -enable-checker alpha.security.ReturnPtrRange \\\n  -enable-checker alpha.unix.PthreadLock \\\n  -enable-checker alpha.unix.Stream \\\n  -enable-checker alpha.unix.cstring.BufferOverlap \\\n  -enable-checker alpha.unix.cstring.NotNullTerminated \\\n  -enable-checker alpha.unix.cstring.OutOfBounds \\\n  -enable-checker nullability.NullableDereferenced \\\n  -enable-checker optin.performance.Padding \\\n  -enable-checker security.insecureAPI.rand \\\n  -enable-checker security.insecureAPI.strcpy \\\n  --use-cc=clang-10 \\\n  --use-c++=clang++-10 \\\n  -o ./scanbuildout/ \\\n  make \\\n  -j8\n```\n\nOpen resulting `scanbuildout/...../index.html` file\n\n## For contibutors: cppclean\n\nMake sure you use `Debug` build with `-e flextool:enable_llvm_tools=True`\n\nFor details, see: [https://github.com/myint/cppclean](https://github.com/myint/cppclean)\n\nInstallation:\n\n```bash\npip install --index-url=https://pypi.python.org/simple/ --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --upgrade cppclean\n```\n\nUsage (runs cmake with `-DENABLE_CPPCLEAN=ON`):\n\n```bash\n# creates local build in separate folder and runs cmake targets\ncmake -DCPPCLEAN=\"ON\" -DCLEAN_OLD=\"ON\" -P tools/run_tool.cmake\n```\n\nNOTE: cppclean requires file encoding to be: `UTF-8 without BOM` (ascii)\n\n## For contibutors: IWYU\n\nMake sure you use `Debug` build with `-e flextool:enable_llvm_tools=True`\n\ninclude-what-you-use (IWYU) is a project intended to optimise includes.\n\nIt will calculate the required headers and add / remove includes as appropriate.\n\nFor details, see: [https://include-what-you-use.org/](https://include-what-you-use.org/)\n\nUsage (runs cmake with `-DENABLE_IWYU=ON`):\n\n```bash\n# creates local build in separate folder and runs cmake targets\ncmake -DIWYU=\"ON\" -DCLEAN_OLD=\"ON\" -P tools/run_tool.cmake\n```\n\nCODESTYLE: use `// IWYU pragma: associated` in C++ source files.\n\nNOTE: Read about IWYU Pragmas: [https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md](https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md)\n\nNOTE: don't use \"bits/\" or \"/details/*\" includes, add them to mappings file (.imp)\n\nFor details, see:\n\n* https://llvm.org/devmtg/2010-11/Silverstein-IncludeWhatYouUse.pdf\n* https://github.com/include-what-you-use/include-what-you-use/tree/master/docs\n* https://github.com/hdclark/Ygor/blob/master/artifacts/20180225_include-what-you-use/iwyu_how-to.txt\n\n## For contibutors: ccache\n\nUse `-DUSE_CCACHE=ON`\n\n```bash\ngcc -v\nexport CC=gcc\nexport CXX=g++\n# NOTE: -DUSE_CCACHE=ON\ncmake .. \\\n  -DCMAKE_VERBOSE_MAKEFILE=TRUE \\\n  -DUSE_CCACHE=ON \\\n  -DENABLE_TESTS=FALSE \\\n  -DBASE_NEED_GEN_BUILD_DATE=FALSE \\\n  -DENABLE_DOCTEST=OFF \\\n  -DBUILD_SHARED_LIBS=FALSE \\\n  -DCONAN_AUTO_INSTALL=OFF \\\n  -DCMAKE_BUILD_TYPE=Debug\n```\n\nFor details, see: [https://www.virag.si/2015/07/use-ccache-with-cmake-for-faster-compilation/](https://www.virag.si/2015/07/use-ccache-with-cmake-for-faster-compilation/)\n\nTo get the most out of ccache, put something like this in: `~/.ccache/ccache.conf`:\n\n```bash\nmax_size = 50.0G  # or whatever cache size you prefer; default is 5G; 0 means unlimited\nbase_dir = /home/yourname  # or wherever you keep your source files\n```\n\nNote: `base_dir` is required for ccache to share cached compiles of the same file across different repositories / paths; it will only do this for paths under `base_dir`.\nSo this option is required for effective use of ccache with git worktrees (described below).\n\nYou must not set `base_dir` to \"/\", or anywhere that contains system headers (according to the ccache docs).\n\n## For contibutors: GOLD linker\n\nInstallation:\n\n```bash\nsudo apt-get install ccache\n\n# On OS X use homebrew:\n# brew install ccache\n\nccache --version\n```\n\nUse `-DUSE_LD_GOLD=ON`\n\n```bash\ngcc -v\nexport CC=gcc\nexport CXX=g++\n# NOTE: -DUSE_LD_GOLD=ON\ncmake .. \\\n  -DCMAKE_VERBOSE_MAKEFILE=TRUE \\\n  -DUSE_LD_GOLD=ON \\\n  -DENABLE_TESTS=FALSE \\\n  -DBASE_NEED_GEN_BUILD_DATE=FALSE \\\n  -DENABLE_DOCTEST=OFF \\\n  -DBUILD_SHARED_LIBS=FALSE \\\n  -DCONAN_AUTO_INSTALL=OFF \\\n  -DCMAKE_BUILD_TYPE=Debug\n```\n\nFor details, see: [https://cristianadam.eu/20170709/speeding-up-cmake/](https://cristianadam.eu/20170709/speeding-up-cmake/)\n\nNOTE: gold not threaded by default, configure with \"--enable-threads\"\n\nNOTE: lld threaded by default, may be faster than gold\n\n## For contibutors: oclint\n\nMake sure you use `Debug` build with `-e flextool:enable_llvm_tools=True`\n\nFor details, see: https://oclint-docs.readthedocs.io/en/stable/devel/codingstandards.html\n\nInstallation:\n\n```bash\ncd ~\nwget --no-check-certificate https://github.com/oclint/oclint/releases/download/v0.13.1/oclint-0.13.1-x86_64-linux-4.4.0-112-generic.tar.gz\n# mirror 1: http://github.strcpy.cn/oclint/oclint/releases/download/v0.13.1/oclint-0.13.1-x86_64-linux-4.4.0-112-generic.tar.gz\n# mirror 2: http://archives.oclint.org/releases/0.8/oclint-0.8.1-x86_64-linux-3.13.0-35-generic.tar.gz\ntar -xzvf oclint-0.13.1-x86_64-linux-4.4.0-112-generic.tar.gz\nrm -rf oclint-0.13.1-x86_64-linux-4.4.0-112-generic.tar.gz\nexport OCLINT_HOME=~/oclint-0.13.1\nexport PATH=$OCLINT_HOME/bin:$PATH\noclint -version\n```\n\nUsage (runs cmake with `-DENABLE_OCLINT=ON`):\n\n```bash\n# NOTE: -DCLEAN_OLD=\"OFF\" to keep generated html report\n# creates local build in separate folder and runs cmake targets\ncmake -DOCLINT=\"ON\" -DCLEAN_OLD=\"OFF\" -P tools/run_tool.cmake\n```\n\n```bash\n# `report.html` must exist\n# find $PWD -name report.html\n```\n\nOpen report.html\n\nSee oclint tutorial: [http://docs.oclint.org/en/stable/intro/tutorial.html](http://docs.oclint.org/en/stable/intro/tutorial.html)\n\nSee list of oclint rules at: [https://oclint-docs.readthedocs.io/en/stable/rules/](https://oclint-docs.readthedocs.io/en/stable/rules/)\n\nNOTE: you can suppress oclint warnings [http://docs.oclint.org/en/stable/howto/suppress.html#oclint-comment](http://docs.oclint.org/en/stable/howto/suppress.html#oclint-comment)\n\n## For contibutors: clang-format\n\nFor details, see: [https://clang.llvm.org/docs/ClangFormat.html](https://clang.llvm.org/docs/ClangFormat.html)\n\nUsage (runs cmake with `-DENABLE_CLANG_FORMAT=ON`):\n\n```bash\n# creates local build in separate folder and runs cmake targets\ncmake -DCLANG_FORMAT=\"ON\" -DCLEAN_OLD=\"ON\" -P tools/run_tool.cmake\n```\n\nWe use `.clang-format` file. For details, see: [https://clang.llvm.org/docs/ClangFormatStyleOptions.html](https://clang.llvm.org/docs/ClangFormatStyleOptions.html)\n\nNOTE: we use `DisableFormat`, so clang-format will change only include order based on `SortIncludes`.\n\nUnfortunately, `clang-format` is not configurable enough, so it can be used only to sort includes. See: https://stackoverflow.com/a/32191189\n\n## For contibutors: uncrustify\n\nWe use uncrustify bacause clang-format and astyle [do not support a lot of options](https://dev.to/voins/does-anybody-know-a-good-working-c-formatting-tool-2lpi).\n\nFor details, see: [https://patrickhenson.com/2018/06/07/uncrustify-configuration.html](https://patrickhenson.com/2018/06/07/uncrustify-configuration.html)\n\nInstallation:\n\n```bash\ncd ~\ngit clone https://github.com/uncrustify/uncrustify.git\ncd uncrustify\nmkdir build\ncd build\ncmake -DCMAKE_BUILD_TYPE=Release ..\ncmake --build .\nexport UNCRUSTIFY_HOME=~/uncrustify/build\nexport PATH=$UNCRUSTIFY_HOME:$PATH\n# OR sudo make install\n\nuncrustify --version\n```\n\nUsage (runs cmake with `-DENABLE_UNCRUSTIFY=ON`):\n\n```bash\n# creates local build in separate folder and runs cmake targets\ncmake -DUNCRUSTIFY=\"ON\" -DCLEAN_OLD=\"ON\" -P tools/run_tool.cmake\n```\n\nWe use `uncrustify.cfg` file. For details, see: [https://patrickhenson.com/2018/06/07/uncrustify-configuration.html](https://patrickhenson.com/2018/06/07/uncrustify-configuration.html)\n\nTo get a list of all available options use:\n\n```bash\nuncrustify --show-config\n```\n\nUncrustify has a lot of configurable options. You'll probably need Universal Indent GUI (in Konstantin's reply) as well to configure it: http://universalindent.sourceforge.net/\n\nUse comments containing `/* *INDENT-OFF* */` and `/* *INDENT-ON* */` to disable processing of parts of the source file.\n\nSee `disable_processing_cmt` from `uncrustify.cfg`:\n\n```ini\n# Specify the marker used in comments to disable processing of part of the\n# file.\n# The comment should be used alone in one line.\n#\n# Default:  *INDENT-OFF*\ndisable_processing_cmt          = \" *INDENT-OFF*\"      # string\n\n# Specify the marker used in comments to (re)enable processing in a file.\n# The comment should be used alone in one line.\n#\n# Default:  *INDENT-ON*\nenable_processing_cmt           = \" *INDENT-ON*\"     # string\n```\n\nYou can integrate `uncrustify` with IDE:\n\n* QT Creator: [https://doc.qt.io/qtcreator/creator-beautifier.html](https://doc.qt.io/qtcreator/creator-beautifier.html)\n* Visual Studio Code: [https://marketplace.visualstudio.com/items?itemName=LaurentTreguier.uncrustify](https://marketplace.visualstudio.com/items?itemName=LaurentTreguier.uncrustify)\n\n## HOW TO BUILD WITH SANITIZERS ENABLED\n\nSee https://github.com/blockspacer/llvm_9_installer#how-to-use-with-sanitizers\n\n## For contibutors: build using clang 10 from conan\n\nRequires `enable_llvm_tools=True`, `compile_with_llvm_tools=True`, and `llvm_tools:build_type=Release`:\n\n```bash\n-s llvm_tools:build_type=Release \\\n  -e flextool:enable_llvm_tools=True \\\n  -e flextool:compile_with_llvm_tools=True \\\n  -o llvm_tools:include_what_you_use=True \\\n  ...\n```\n\n* `enable_llvm_tools` installs clang 10 from conan\n* `compile_with_llvm_tools` sets cmake variables required to use clang 10 from conan\n\nRun `conan install` or `conan create` with:\n\n```bash\n# OR create conan profile https://docs.conan.io/en/latest/reference/profiles.html\n-s compiler=clang \\\n  -s compiler.version=10 \\\n  -s compiler.libcxx=libc++\n```\n\nNOTE: Change of compiler may require rebuild of all deps (`--build=missing`).\n\nExample in case of local build:\n\n```bash\nexport CC=$(find ~/.conan/data/llvm_tools/master/conan/stable/package/ -path \"*bin/clang\" | head -n 1)\n\nexport CXX=$(find ~/.conan/data/llvm_tools/master/conan/stable/package/ -path \"*bin/clang++\" | head -n 1)\n\nexport VERBOSE=1\nexport CONAN_REVISIONS_ENABLED=1\nexport CONAN_VERBOSE_TRACEBACK=1\nexport CONAN_PRINT_RUN_COMMANDS=1\nexport CONAN_LOGGING_LEVEL=10\n\n# NOTE: NO `--profile` argument cause we use `CXX` env. var\n# NOTE: you may want to re-build `cling_conan` with clang 10\ncmake -E time \\\n  conan install . \\\n  --install-folder local_build_clang_10 \\\n  -s build_type=Debug \\\n  -s cling_conan:build_type=Release \\\n  -s llvm_tools:build_type=Release \\\n      --build missing \\\n      --build cascade \\\n      -s cling_conan:compiler=clang \\\n      -s cling_conan:compiler.version=10 \\\n      -s cling_conan:compiler.libcxx=libstdc++11 \\\n      -o llvm_tools:include_what_you_use=True \\\n      -s llvm_tools:compiler=clang \\\n      -s llvm_tools:compiler.version=10 \\\n      -s llvm_tools:compiler.libcxx=libstdc++11 \\\n      -e flextool:enable_tests=True \\\n      -e flextool:enable_llvm_tools=True \\\n      -e flextool:compile_with_llvm_tools=True \\\n      -e boost:enable_llvm_tools=True \\\n      -e boost:compile_with_llvm_tools=True \\\n      -s compiler=clang \\\n      -s compiler.version=10 \\\n      -s compiler.libcxx=libc++\n\ncmake -E time \\\n  conan source . \\\n  --source-folder local_build_clang_10 \\\n  --install-folder local_build_clang_10\n\n# remove old CMakeCache\n(rm local_build_clang_10/CMakeCache.txt || true)\n\n# see section about `conan editable mode`\nconan build . \\\n  --build-folder local_build_clang_10 \\\n  --source-folder local_build_clang_10 \\\n  --install-folder local_build_clang_10\n```\n\nPerform checks:\n\n```bash\n# check that `libcpp` symbol exists\nnm -an EXECUTABLE_PATH | grep libcpp\n\n# list linked dynamic libs\nldd EXECUTABLE_PATH\n```\n\n## For contibutors: doxygen\n\n`MCSS_ROOT_DIR_FOR_DOCS` must point to `m.css` sources like below:\n\n```bash\ncd ~\n\ngit clone https://github.com/mosra/m.css.git\n\npip3 install jinja2 Pygments\n\nsudo apt install \\\n    texlive-base \\\n    texlive-latex-extra \\\n    texlive-fonts-extra \\\n    texlive-fonts-recommended\n\nsudo apt-get install doxygen\n\nsudo apt install python3-pip\n\n# /usr/bin/python must point to python3\n/usr/bin/python --version\n\n# NOTE: switch to python3 for doxygen or use -DPYTHON_EXECUTABLE=/usr/bin/python3\nalias python='/usr/bin/python3'\n\n# You may need sudo here\npip3 install jinja2 Pygments\n\nsudo apt install \\\n    texlive-base \\\n    texlive-latex-extra \\\n    texlive-fonts-extra \\\n    texlive-fonts-recommended\n```\n\nUse cmake build with '--target doxyDoc' and `-DBUILD_DOXY_DOC=ON`\n\n```bash\ncd ~/flextool\n\n# see section about `conan editable mode`\ncd local_build_clang_10\n\n# optional\n# remove old CMakeCache\n(rm CMakeCache.txt || true)\n\n# remove old build artifacts\nrm -rf flextool\nrm -rf bin\nfind . -iname '*.o' -exec rm {} \\;\nfind . -iname '*.a' -exec rm {} \\;\nfind . -iname '*.dll' -exec rm {} \\;\nfind . -iname '*.lib' -exec rm {} \\;\n\n# remove old build docs\nrm -rf doc-mcss\nrm -rf docs\n\ncmake -E make_directory \"doc-mcss\"\n\n# NOTE: you can change python version like so: -DPYTHON_EXECUTABLE=/usr/bin/python3\ncmake .. \\\n  -DCMAKE_VERBOSE_MAKEFILE=TRUE \\\n  -DMCSS_ROOT_DIR_FOR_DOCS=$HOME/m.css \\\n  -DPYTHON_EXECUTABLE=/usr/bin/python3 \\\n  -DENABLE_TESTS=TRUE \\\n  -DBASE_NEED_GEN_BUILD_DATE=FALSE \\\n  -DENABLE_DOCTEST=ON \\\n  -DBUILD_DOXY_DOC=ON \\\n  -DBUILD_SHARED_LIBS=FALSE \\\n  -DCONAN_AUTO_INSTALL=OFF \\\n  -DCMAKE_BUILD_TYPE=Debug \\\n  -DDOXY_ROOT_DIR=$PWD/doc-mcss \\\n  -DDOXY_DOC_COMMON_IMG_PATH=$PWD/.. \\\n  -DPROJECT_SOURCES_DIR_FOR_DOCS=$PWD/../src\n\ncmake -E time cmake --build . \\\n  --target doxyDoc_notheme\n\ncmake -E time cmake --build . \\\n  --target doxyDoc\n\n# Use to find index.html\nfind $PWD -name *.html\n```\n\nOpen doxyDoc/html/index.html\n\nNOTE: Document namespaces in docs/namespaces.dox\n\nNOTE: [Files, directories and symbols with no documentation are not present in the output at all](https://mcss.mosra.cz/doxygen/#troubleshooting)\n\nUsed [comments style](https://mcss.mosra.cz/doxygen/):\n\n```bash\n/**\n * @brief Path utils\n *\n * Example usage:\n *\n * @code{.cpp}\n * const ::fs::path workdir = storage::getThisBinaryDirectoryPath();\n * @endcode\n **/\n```\n\nSee:\n\n- [doxygen cheatsheet](http://www.agapow.net/programming/tools/doxygen-cheatsheet/)\n- [doxygen coding style](https://doc.magnum.graphics/magnum/coding-style.html#coding-style-documentation)\n\n## For contibutors: Fuzzing with AFL\n\nFor details, see: [https://afl-1.readthedocs.io/en/latest/index.html](https://afl-1.readthedocs.io/en/latest/index.html)\n\nNOTE: prefer github.com/google/AFL or aflplus.plus to not updated AFL from `lcamtuf.coredump.cx/afl`\n\nFuzzing is a Black Box software testing technique.\n\nFuzzing consists in finding implementation bugs using malformed/semi-malformed data injection in an automated fashion.\n\nFuzzer tries to modify the input so that it can reach as much lines of the program code as possible.\n\nTherefore, fuzzing allows the discovery of vulnerabilities lying in code paths that are hard to reach by normal usage.\n\nInstall + compile the source code using following commands:\n\n```bash\n# optional\n# sudo apt-get update\n\n# optional\n# sudo apt-get -y install autoconf automake bison build-essential \\\nca-certificates llvm-dev libtool libtool-bin \\\nlibglib2.0-dev make nasm wget\n\n# Tested with clang 10 and gcc 7\nsudo apt-get -y install clang-10 g++-7 gcc-7\n\nexport CXX=g++-7\nexport CC=gcc-7\nexport PATH=/usr/bin/:$PATH\n$CC -v\n\n\n# llvm-config binary that coresponds to the same clang you are using to compile\nexport LLVM_CONFIG=/usr/bin/llvm-config-10\n$LLVM_CONFIG --cxxflags\n\ncd ~\ngit clone -b v2.56b https://github.com/google/AFL.git --recursive\n\n# NOTE: original AFL not updated since November 2017,\n# so prefer `google/AFL.git` to `lcamtuf.coredump.cx/afl`\n# wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz\n# tar -xf afl-latest.tgz\n# rm afl-latest.tgz\n# cd afl*\n\ncd AFL\nmake\n# build llvm using the sample compiler as afl code uses\n# see https://groups.google.com/forum/#!topic/afl-users/1WqZpGXvYY0\nmake \\\n  -C llvm_mode \\\n  LLVM_CONFIG=$LLVM_CONFIG \\\n  CC=clang-10 \\\n  CXX=clang++-10\n#\n# optional\n# cd qemu_mode\n# ./build_qemu_support.sh\n# cd ..\n#\nmake \\\n  -C libdislocator\nmake \\\n  -C libtokencap\nsudo make install\n\n# OR add to PATH via export PATH=$PATH:...\n\n# do not forget to reset CC and LLVM_CONFIG\nunset CXX\nunset CC\nunset LLVM_CONFIG\n```\n\nWe compile code using the AFL compiler: `-DCMAKE_C_COMPILER=afl-clang-fast`, `-DCMAKE_CXX_COMPILER=afl-clang-fast++`, and `-DCMAKE_LINKER=afl-clang-fast`.\n\nTo verify if binary uses the AFL compiler: `nm BINARY_PATH | grep afl`\n\nTo build application with some sanitizers and debug information enabled: (`-DENABLE_ASAN=ON` etc.):\n\nNOTE: There are some things to consider when using Address Sanitizer. Even if ASan finds a memory access violation, it doesn't automatically crash the application.\nThis is a problem when using automated fuzzing tools because they usually try to detect segfaults by checking the return code.\nWe can, however, force ASan to crash software when an error happens with the environment variable ASAN_OPTIONS before fuzzing: `export ASAN_OPTIONS='abort_on_error=1'`\n\nNOTE: Disable custom memory allocation functions. This can hide memory access bugs and prevent the detection of memory access errors.\n\n```bash\n# see https://afl-1.readthedocs.io/en/latest/instrumenting.html\n\n# Setting AFL_HARDEN automatically adds code hardening options\n# when invoking the downstream compiler.\n# This includes -D_FORTIFY_SOURCE=2 and -fstack-protector-all.\n# NOTE: _FORTIFY_SOURCE not compatible with ASAN\n# export AFL_HARDEN=1\n\n# see https://aflplus.plus/docs/env_variables/\nexport AFL_EXIT_WHEN_DONE=1\n\n# By default, the wrapper appends -O3 to optimize builds.\nexport AFL_DONT_OPTIMIZE=1\n\n# or AFL_USE_MSAN, etc.\n# READ https://aflplus.plus/docs/notes_for_asan/\nNOTE: if you run several slaves only one should run the\n# target compiled with ASAN (and UBSAN, CFISAN),\n# the others should run the target with no sanitizers compiled in.\nexport AFL_USE_UBSAN=1\nexport AFL_USE_ASAN=1\n\n# AFL_PRELOAD causes AFL to set LD_PRELOAD for the target binary\n# without disrupting the afl-fuzz process itself.\n# This is useful, among other things, for bootstrapping libdislocator.so.\n\n# see __AFL_LOOP\n# export AFL_PERSISTENT=1\n\n# make sure you compile app with `-fsanitize=address` or `-fsanitize=memory` etc.\n```\n\nNOTE: Use `AFL_DONT_OPTIMIZE=1`; read: http://moyix.blogspot.com/2016/07/fuzzing-with-afl-is-an-art.html\n\nFor details, see: [Using ASAN with AFL](https://afl-1.readthedocs.io/en/latest/notes_for_asan.html)\n\nBefore fuzzing the program, we may require switching to root user to arrange the core_pattern. Login as root and type the following command:\n\n```bash\n# see https://afl-1.readthedocs.io/en/latest/tips.html#check-os-configuration\nsudo su\n# disable core dumps and CPU frequency scaling on your system (AFL will warn you if you should do this)\necho core \u003e/proc/sys/kernel/core_pattern\n# afl-fuzz will usually complain that you should change your `CPUFREQ` settings to performance because the automatic frequency scaling by the Linux kernel doesn't work well with afl.\necho performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor\nexit\n```\n\nNOTE: Do not run the fuzzer with root access\n\nNOTE: Get a solid environment for the fuzzer; never run the fuzzer on low configured hypervisors.\n\n`afl-fuzz` is used to run AFL. The actual syntax is as follows:\n\n```bash\n# see https://afl-1.readthedocs.io/en/latest/fuzzing.html#fuzzing-binaries\n# -i is a directory of files to use as fuzz input \"seeds\"\n# -o is a directory to write the results (including inputs that provoke crashes or hangs)\n# -m is the memory allowed to use. Example: -m500\n# You can use -m none to disable memory limit\n# -t is the maximum time that a run is allowed to take before being declared a \"hang\"\n# Timeout of 10 seconds:  -t 10000\n# @@ is fuzzer input file name\n# if you skip @@ it will pass the fuzzed file on the standard input\nAFL_PERSISTENT=1 afl-fuzz -i [TESTCASE DIR] -o [RESULT_DIR] [TARGET_BINARY] [BINARY_PARAMS] @@\n\n# Example 1: runs `tar` with arguments `xfJ @@ -C fuzz-garbage/ --force-local`\n# where @@ is fuzzer input file name\n ./afl-1.56b/afl-fuzz -i fuzz-input/ -o fuzz-state/ -t 10000 ~/tar-1.28/src/tar xfJ @@ -C fuzz-garbage/ --force-local\n\n# Example 2: server is dual core, so we can run one AFL instance per core\nAFL_PERSISTENT=1 afl-fuzz -i inputs -o multi_sync -M master ./fuzz_capstone\n# In another terminal\nAFL_PERSISTENT=1 afl-fuzz -i inputs -o multi_sync -S slave1 ./fuzz_capstone\n```\n\nTo understand AFL status screen, read: [https://afl-1.readthedocs.io/en/latest/user_guide.html#status-screen](https://afl-1.readthedocs.io/en/latest/user_guide.html#status-screen)\n\nNOTE: If `total paths` stays at 1 you probably have set up something wrong.\n\nNOTE: Prefer `-m none`. We use AddressSanitizer; this maps a lot of pages for the shadow memory, so we have to remove the memory limit to have it up and running.\n\nNOTE: With `-m none`, your fuzzed software may actually try to really allocate and use a lot of memory due to your fuzzed samples.\nThis may lead to random crashes in your system. You shouldn't do any important work while doing so.\n\nNOTE: you can try `ASAN_OPTIONS=hard_rss_limit_mb=2000` to avoid `-m none`. See: https://countuponsecurity.com/category/fuzzing/\n\nYou can write custom binary that will run using `afl-fuzz`. It may wrap function that you want to test like so:\n\n```cpp\n// harness is simply a C program that makes use of certain methods from\n// a library, allowing you to indirectly fuzz it\n\n#include \u003ccstdio\u003e\n#include \u003ccstdlib\u003e\n#include \u003cstring\u003e\n#include \u003ciostream\u003e\n#include \u003cifstream\u003e\n\nint main(int argc, char *argv[]) {\n{\n  // init resources here\n  if (argc \u003e 1) {\n    std::ifstream fin;\n    fin.open(argv[1]);\n    parse(fin); // custom logic\n  } else {\n    /// \\note requires AFL_PERSISTENT=1\n    // __AFL_LOOP is the way that we have to tell AFL\n    // that we want persistent mode.\n    // Each fuzzing iteration,\n    // instead of to fork and re-execute the target with a different input,\n    // is just an execution of this loop.\n    // Force AFL to run 1000 times,\n    // with 1000 different inputs fed to the library.\n    // After that, the process is restarted by AFL.\n    // This ensures we regularly replace the process to avoid memory leaks.\n    // see https://toastedcornflakes.github.io/articles/fuzzing_capstone_with_afl.html\n    while (__AFL_LOOP(1000)) {\n      parse(std::cin); // custom logic\n    }\n  }\n  // free resources here\n  return 0;\n}\n```\n\nNOTE: __AFL_LOOP() allows AFL to perform the fuzzing of the binary in process through some memory wizardry, as opposed to starting up a new process for every new testcase we want to test. Requires `AFL_PERSISTENT=1`.\n\nBy default, AFL forks a process every time it tests a different input. We can control AFL to run multiple fuzz cases in a single instance of the program, rather than reverting the program state back for every test sample. This will reduce the time spent in the kernel space and improve the fuzzing speed. This is called AFL_PERSISTENT mode. We can do that by including the __AFL_LOOP(1000) macro within our test harness.\n\nNOTE: you may be interested in __AFL_INIT; see for details: [https://robertheaton.com/2019/07/08/how-to-write-an-afl-wrapper-for-any-language/](https://robertheaton.com/2019/07/08/how-to-write-an-afl-wrapper-for-any-language/)\n\nLet the fuzzer run for few hours or days as it generates maximum code execution paths based on the test cases provided.\n\nStop fuzzing issuing `ctrl+c’ observing `total paths` and `uniq crashes` in the section `overall results` of AFL statistics screen.\n\nCreate dictionary that takes all of the constants and strings found in the program binary and adds them to the dictionary.\nSee for script code:[http://moyix.blogspot.com/2016/07/fuzzing-with-afl-is-an-art.html](http://moyix.blogspot.com/2016/07/fuzzing-with-afl-is-an-art.html)\n\n```bash\n#!/bin/bash\n\n# see http://moyix.blogspot.com/2016/07/fuzzing-with-afl-is-an-art.html\n\nobjdump -d \"${1}\" | grep -Eo '\\$0x[0-9a-f]+' | cut -c 2- | sort -u | while read const; do echo $const | python -c 'import sys, struct; sys.stdout.write(\"\".join(struct.pack(\"\u003cI\" if len(l) \u003c= 11 else \"\u003cQ\", int(l,0)) for l in sys.stdin.readlines()))' \u003e testcases/$const; done\ni=0; strings \"${1}\"| while read line; do echo -n \"$line\" \u003e testcases/string_${i} ; i=$[ $i + 1 ] ; done\n```\n\nYou need to create a dictionary in one of the two formats discussed in dictionaries/README.dictionaries and then point the fuzzer to it via the -x option in the command line.\nRead: [https://afl-1.readthedocs.io/en/latest/fuzzing.html#fuzzing-binaries](https://afl-1.readthedocs.io/en/latest/fuzzing.html#fuzzing-binaries) and [https://github.com/mirrorer/afl/blob/master/dictionaries/README.dictionaries](https://github.com/mirrorer/afl/blob/master/dictionaries/README.dictionaries)\n\nYou can also use `libtokencap` to create a dictionary; see: [https://github.com/mirrorer/afl/blob/master/libtokencap/README.tokencap](https://github.com/mirrorer/afl/blob/master/libtokencap/README.tokencap)\n\nWe can find the test cases which cause the crash in the `results` folder which we have created. On navigating to the folder `results`, we observe few folders get generated.\n\nNOTE: Keep the input data files small; under 1 kB is ideal.\n\nUse `afl-cmin` to minimize number of input data files.\n\nUse `afl-tmin` to minimize each input data file (removes any bytes that do not affect the code paths taken).\n\nUse `afl-ptmin` to run `afl-tmin` in parallel. For details, see: [https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/](https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/)\n\nTo reproduce found crash you can use `crashwalk` (it is gdb plugin), see: [https://ritcsec.wordpress.com/2018/05/10/vulnerability-discovery-by-fuzzing/](https://ritcsec.wordpress.com/2018/05/10/vulnerability-discovery-by-fuzzing/)\n\n```bash\napt-get install gdb golang\nmkdir src\ncd src\ngit clone https://github.com/jfoote/exploitable.git\ncd \u0026\u0026 mkdir go\nexport GOPATH=~/go\n# crashwalk installed in $GOPATH/bin/\ngo get -u github.com/bnagy/crashwalk/cmd/...\n\n# USAGE\n~/go/bin/cwtriage -root syncdir/fuzzer1/crashes/ -match id -- ~/parse @@\n```\n\nWhen you can not reproduce a crash found by afl-fuzz, the most likely cause is that you are not setting the same memory limit as used by the tool.\nRead: [https://afl-1.readthedocs.io/en/latest/fuzzing.html#fuzzing-binaries](https://afl-1.readthedocs.io/en/latest/fuzzing.html#fuzzing-binaries)\n\nNOTE: You can use `afl-cov` to quantify how well you are exercising the available code paths in the binary.\nFor details, see: [https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/](https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/)\n\nNOTE: putting the AFL working directory on a RAM disk, you can potentially gain some additional speed and avoid wearing out the disks at the same time.\nFor details, see: [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/)\n\n```bash\n# Fuzzing involves billions of reads and writes to the filesystem (!!!)\n# Use RAMdisks for input since, we don't want to destroy harddrives\n# Make a 1GB ramdisk file from which AFL can read input\nsudo mkdir -p /mnt/inputfiles\nsudo chown -R $USER:$(id -gn $USER) /mnt/inputfiles\nsudo mount -t tmpfs -o size=1024M tmpfs /mnt/inputfiles/\n```\n\nNOTE: `-fvisibility-inlines-hidden` flag MAY BREAK AFL INSTRUMENTATION\n\nAFL provides a crash exploration script in `experimental/crash_triage/triage_crashes.sh`\n\nWhen run, the triage script will cycle through each crash file in the `/out/crashes` directory and print the resulting crash data to the screen.\n\n`triage_crashes` usage: `./triage_crashes.sh ~/targets/out/ ~/targets/target-app/target-app_binary`\nFor details, see: [https://research.aurainfosec.io/hunting-for-bugs-101/](https://research.aurainfosec.io/hunting-for-bugs-101/)\n\nNOTE: Instrument with AFL just the libraries you actually want to stress-test right now, one at a time.\nLet the program use system-wide, non-instrumented libraries for any functionality you don’t actually want to fuzz.\n\nNOTE: you can enable `crash exploration mode` via `-C`; see: https://lcamtuf.blogspot.com/2014/11/afl-fuzz-crash-exploration-mode.html\n\nNOTE: AFL detects faults by checking for the first spawned process dying due to a signal (SIGSEGV, SIGABRT, etc). Programs that install custom handlers for these signals may need to have the relevant code commented out.\n\nFor details, see:\n\n* https://github.com/mykter/afl-training\n* https://www.loginsoft.com/blog/2018/02/02/discovering-vulnerabilities-with-afl-fuzzer/\n* https://www.youtube.com/watch?v=vzfhHjnycnE\n* https://gamozolabs.github.io/fuzzing/2018/09/16/scaling_afl.html\n* https://ritcsec.wordpress.com/2018/05/10/vulnerability-discovery-by-fuzzing/\n* https://github.com/Dor1s/libfuzzer-workshop/blob/master/lessons/01/Modern_Fuzzing_of_C_C%2B%2B_projects_slides_1-23.pdf\n* https://github.com/hbowden/nextgen/blob/master/CMakeLists.txt#L92\n* https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/\n* https://cs.anu.edu.au/courses/csprojects/19S1/reports/u6759601_report.pdf\n* https://www.fastly.com/blog/how-fuzz-server-american-fuzzy-lop\n\n## For contibutors: Fuzzing with libFuzzer\n\nlibFuzzer is part of the LLVM compiler infrastructure project and comes built-in with the clang compiler.\n\nThen libFuzzer can be linked to the desired driver by passing in `-fsanitize=fuzzer` during the linking stage.\n\nNOTE: `-fsanitize=fuzzer` links in the libFuzzer’s main() symbol.\n\nNOTE: In most cases you may want to combine libFuzzer with AddressSanitizer (ASAN), UndefinedBehaviorSanitizer (UBSAN), or both. You can also build with MemorySanitizer (MSAN), but support is experimental: `-fsanitize=undefined,address,fuzzer`.\n\nExecutable repeatedly calls the following function:\n\n```cpp\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  // DoStuffWithYourAPI(Data, Size);\n  return 0;\n}\n```\n\nUse `-fsanitize=address,fuzzer`. Note that you can change sanitizer (address, memory, thread, etc.).\n\nNOTE: if you suspect memory leaks in your target you should run libFuzzer with `-runs=N` or `-max_total_time=N`. If your target has massive leaks you will eventually run out of RAM. To protect your machine from OOM death you may use: `ASAN_OPTIONS=hard_rss_limit_mb=2000` (with AddressSanitizer).\n\nlibFuzzer requires seed corpus. For details, see: [https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md](https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md)\n\nFor details, see:\n\n* https://llvm.org/docs/LibFuzzer.html\n* https://medium.com/@levwalkin/compile-llvm-clang-libfuzzer-b61e82718430\n* https://github.com/Dor1s/libfuzzer-workshop\n* [https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md](https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md)\n\n## For contibutors: Prefer Clang To GCC\n\n* Clang supports thread safety annotations (GUARDED_BY)\n  1. Enable `-Wthread-safety-analysis`\n  2. Use `base/thread_annotations.h` https://github.com/chromium/chromium/blob/master/base/thread_annotations.h\n  For details, see:\n  - http://clang.llvm.org/docs/ThreadSafetyAnalysis.html\n  - see https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetime.pdf\n  - https://insights.sei.cmu.edu/sei_blog/2014/10/thread-safety-analysis-in-c-and-c.html\n\n* Clang fas first-class support for sanitizers.\n  See details about MSAN, ASAN, TSAN, etc. in docs.\n\n* Clang can be build with lifetime profile:\n  1. Build special branch of Clang https://github.com/mgehre/llvm-project\n  2. Enable `-Wlifetime`\n  For details, see:\n  - https://pspdfkit.com/blog/2020/the-cpp-lifetime-profile/\n  - https://herbsutter.com/2018/09/20/lifetime-profile-v1-0-posted/\n\n## LICENSE for open source components\n\nAll the open source components are used under their associated open source licences.\n\nUsed open source components:\n* icu\n* ced\n* boost\n* harfbuzz\n* boost.outcome\n* chromium (base)\n* libevent\n* modp_b64\n* tcmalloc\n* xdg_mime\n* xdg_user_dirs\n* dynamic_annotations\n* (Facebook) Folly\n* (Microsoft) GSL\n\nSee LICENSE files\n\n## LICENSE\n\nthe MIT license\n\nSee LICENSE for the full content of the licenses.\n\n## Disclaimer\n\nThat open source project based on the Google Chromium project.\n\nThis is not official Google product.\n\nPortions Copyright (c) Google Inc.\n\nSee LICENSE files.\n\n### Contributors List: Example Profile\n\n- I'm an example that you can copy, if you want :)\n- I work on many things like...\n- My hobbies include...\n\n### Contributors List\n\n#### A\n\n##### Anindita Basu\n\n- Technical writer\n- [twitter](https://twitter.com/anindita_basu)\n  [github](https://github.com/AninditaBasu)\n\n##### Anna Hayhurst\n\n- Junior Developer\n- [github](https://github.com/annahayhurst)\n\n#### C\n\n##### Cassio Espindola\n\n- Analyst Developer\n- [github](https://github.com/cassioesp)\n\n#### D\n\n##### Denis Trofimov\n\n- C++ Developer\n- [github](https://github.com/blockspacer)\n- [github](https://github.com/derofim)\n- [linkedin](https://www.linkedin.com/in/denis-trofimov-4335bb13b/)\n\n#### M\n\n##### Mohib Qureshi\n\n- Software Development Enthusiast\n- [github](https://github.com/mohibqureshi)\n\n#### Y\n\n##### Yousif Alebyary\n\n- Web/Mobile Developer.\n- [github](https://github.com/yousifm)\n\n##### Yves Mancera\n\n- Software Engineer\n- [github](https://github.com/yvesmh)\n","funding_links":[],"categories":["CMake"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockspacer%2Fflextool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblockspacer%2Fflextool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockspacer%2Fflextool/lists"}