Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/blockspacer/CXXCTP
DEPRECATED. USE INSTEAD github.com/blockspacer/flextool
https://github.com/blockspacer/CXXCTP
clang cling cmake codestyle conan cplusplus cpp cpp11 cpp14 cpp17 libtooling llvm metaclasses preprocessor refactoring reflection serialization source-to-source static-analysis transpiling
Last synced: about 2 hours ago
JSON representation
DEPRECATED. USE INSTEAD github.com/blockspacer/flextool
- Host: GitHub
- URL: https://github.com/blockspacer/CXXCTP
- Owner: blockspacer
- License: mit
- Archived: true
- Created: 2019-08-28T16:49:04.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2020-05-05T20:19:00.000Z (over 4 years ago)
- Last Synced: 2024-09-27T06:42:14.233Z (about 2 months ago)
- Topics: clang, cling, cmake, codestyle, conan, cplusplus, cpp, cpp11, cpp14, cpp17, libtooling, llvm, metaclasses, preprocessor, refactoring, reflection, serialization, source-to-source, static-analysis, transpiling
- Language: C++
- Homepage:
- Size: 1.15 MB
- Stars: 59
- Watchers: 10
- Forks: 13
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
Add custom features to C++ language, like metaclasses, Rust-like traits, reflection and many more
A fully open source, powerful solution for modification and generation of C++ source code. Reduce the amount of boilerplate code in your C++ projects.
![Open Source Love](https://img.shields.io/badge/Open%20Source-%E2%9D%A4-pink.svg)
![First Timers Only](https://img.shields.io/badge/first--timers--only-friendly-blue.svg?style=flat)
![Up For Grabs](https://img.shields.io/badge/up--for--grabs-friendly-green.svg?style=flat)
![GitHub](https://img.shields.io/github/license/blockspacer/CXXCTP.svg)
![GitHub forks](https://img.shields.io/github/forks/blockspacer/CXXCTP.svg)
![GitHub issues](https://img.shields.io/github/issues/blockspacer/CXXCTP.svg)
![GitHub pull requests](https://img.shields.io/github/issues-pr/blockspacer/CXXCTP.svg)
![GitHub contributors](https://img.shields.io/github/contributors/blockspacer/CXXCTP.svg)
![GitHub commit activity the past week, 4 weeks, year](https://img.shields.io/github/commit-activity/w/blockspacer/CXXCTP.svg)
![GitHub last commit](https://img.shields.io/github/last-commit/blockspacer/CXXCTP.svg)
![GitHub top language](https://img.shields.io/github/languages/top/blockspacer/CXXCTP.svg)
![GitHub language count](https://img.shields.io/github/languages/count/blockspacer/CXXCTP.svg)
[![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)
[![license](https://img.shields.io/github/license/blockspacer/CXXCTP.svg?style=flat-square)](https://github.com/blockspacer/CXXCTP/master/LICENSE)
[![Total alerts](https://img.shields.io/lgtm/alerts/g/bsamseth/cpp-project.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/blockspacer/CXXCTP/alerts/)
[![Lines of Code](https://tokei.rs/b1/github/blockspacer/CXXCTP)](https://github.com/blockspacer/CXXCTP)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/blockspacer/CXXCTP.svg)](http://isitmaintained.com/project/blockspacer/CXXCTP "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/blockspacer/CXXCTP.svg)](http://isitmaintained.com/project/blockspacer/CXXCTP "Percentage of issues still open")# NOTE
This repo will be migrated to https://github.com/blockspacer/flextool as soon as possible
CXXCTP will be deprecated. Prefer flextool
# 🔗 Navigation
- [About CXXCTP](#about)
- [Usage Examples](#usage)
- [Cloning and setup](#cloning)
- [Developing with CXXCTP](#developing)
- [Tools used by CXXCTP](#tools)
- [How to contribute](#contribute)# 📚 About CXXCTP (CXX compile-time programming)
CXXCTP is a transpiler that extends C++ for new introspection, reflection and compile-time execution.
CXXCTP doesn't aim to create a predefined set of source code transformations. Users can share C++ scripts for source code transformation.
Suppose someone shared useful scripts like `interface.cxx` and `enum_to_json.cxx` to the open-source community. You can use them in your project just by placing them into the `ctp_scripts` folder.
Metaprogramming is an “art” of writing programs to treat other programs as their data. This means that a program could generate, read, analyse, and transform code or even itself to achieve a certain solution.
Note: This project is provided as it is, without any warranty (see License).
## Features
- C++ as compile-time scripting language (https://github.com/derofim/cling-cmake)
- Template engine with full C++ power (transpiles template to valid C++ code, supports Cling, etc.). https://github.com/blockspacer/CXTPL
- Ability to modify source files (implement metaclasses, transpile from C++X to C++Y etc.)
- Ability to create new files (separate generated class to .hpp and .cpp, etc.)
- Ability to check source files (implement style checks, design patterns, etc.)
- Ability to compile scripts (rules for code transformations) for maximum performance, not only interpret them in Cling.## Motivation
Why wouldn't you just extend clang since it also provides some experimental features (modules for instance)?
Clang is a compiler while this project is a transpiler, that transforms code to standardized c++ code without the need to modify llvm/assembly.
Because the tool's output is C++ code, you can compile transpiled code using emscripten, use static code analyzers, run code inside cling etc.
CXXCTP allows you to create and share scripts for
- source code check (like codestyle validation)
- source code transformation (like alphabetical sort of all public functions inside some class)
- compile-time programming (like retrieve source code modification rules from remote server and save them in some folder) etc.## Project status
In development, see examples. Currently supports only Linux.
Note that you can run Linux containers under Windows/Mac/etc.
# ⚙️ Usage examples
- enum_gen_hpp.cxtpl - (codegen) enum to string + reflection metadata.```cpp
// usage example from ReflShapeKind.hpp
enum class
$apply(
reflect_enum
)
ReflShapeKind0 : uint32_t {
Box = 3,
Sphere = 6,
};
```- typeclass_gen_cpp.cxtpl - (codegen) typeclasses. Supports combinations of multiple typeclasses and out-of-source method definitions (data and logic separation). Supports combinations of multiple typeclasses and out-of-source method definition (data and logic separation). See examples and https://twitter.com/TartanLlama/status/1159457033441165313
```cpp
// Usage example. NOTE: no inheritance & definition outside lib.
// in lib .h
struct drawable {
virtual void draw(const char* arg1) const noexcept = 0;
};
struct printable {
virtual void print(const char* arg1, const char* arg2) const noexcept = 0;
};
struct canvas3D {
std::string name3D;
};
struct canvas4D {
std::string name4D;
};
// in app .cpp
void draw(const canvas3D& data, const char* arg1){
std::cout << "drawing to canvas3D name = " << data.name3D << std::endl;
}
void draw(const canvas4D& data, const char* arg1){
std::cout << "drawing to canvas4D name = " << data.name4D << std::endl;
}
void print(const canvas3D& data, const char* arg1, const char* arg2){
std::cout << "printing to canvas3D name = " << data.name3D << std::endl;
}
void print(const canvas4D& data, const char* arg1, const char* arg2){
std::cout << "printing to canvas4D name = " << data.name4D << std::endl;
}
std::vector<_tc_combined_t> vec {
canvas3D{},
canvas4D{},
};
_tc_combined_t CVS = canvas4D{};
CVS.draw("");
CVS.print("", "");canvas3D cvs3D;
CVS = std::move(cvs3D);canvas4D cvs4D;
CVS = cvs4D; // copyCVS = vec.at(0); // to
```- parse-time/compile-time code execution (see examples)
```cpp
$export (
static int resultSomeInt = 2345;
)
$eval("#include ")
$exec(
printf("execkjljlk\n");
printf("execasdasd\n");
)
$set_embed("set_embed103",
printf("set_embed101\n");
printf("set_embed102\n");
)
$embed(
[&clangMatchResult, &clangRewriter, &clangDecl]() {
printf("embed01\n");
printf("embed02\n");
return new llvm::Optional{"embed03"};
}();
)
```- metaclasses. Supports combinations of multiple metaclasses (see examples).
```cpp
class
$apply(make_interface;make_removefuncbody;make_reflect)
SomeInterfaceName {
virtual ~SomeInterfaceName() = 0;
/*int f ( ) { // {}
int i = 6;
{
// {
// }
}
return i;
};*/
int foo();
virtual void foobar(int& arg1) = 0;
virtual inline void zoobar(int& arg2);
//int m_bar;
//int m_bar2 = 2;
};
```# 🖥️ Cloning and setup
```bash
git submodule sync --recursive
git fetch --recurse-submodules
git submodule update --init --recursive --depth 100 --progress
# or
git submodule update --force --recursive --init --remote
```## Install & use with Docker
Install and configure Docker: https://medium.com/@saniaky/configure-docker-to-use-a-host-proxy-e88bd988c0aa
Clone code (as above) and `cd` into cloned dir.
NOTE: You may want to build Docker image with `--build-arg NO_SSL="False"`. Read comments in Dockerfile.
```bash
# Give docker the rights to access X-server
sudo -E xhost +local:docker# build Dockerfile
sudo -E docker build --no-cache \
--build-arg GIT_WITH_OPENSSL="" \
--build-arg NO_SSL="False" \
-t cpp-docker-cxxctp .# Now let’s check if our image has been created.
sudo -E docker images# Run in container without leaving host terminal
sudo -E docker run -v "$PWD":/home/u/cxxctp -w /home/u/cxxctp cpp-docker-cxxctp CXXCTP_tool -version --version# Run a terminal in container
sudo -E docker run --rm -v "$PWD":/home/u/cxxctp -w /home/u/cxxctp -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix cpp-docker-cxxctp# type in container terminal
CXXCTP_tool -version --version
```## Develop with Docker
```bash
# Run a terminal in container
sudo -E docker run --rm -v "$PWD":/home/u/cxxctp -w /home/u/cxxctp -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix cpp-docker-cxxctp# An example of how to build (with Makefile generated from cmake) inside the container
# Mounts $PWD to /home/u/cxxctp and runs command
mkdir build
sudo -E docker run --rm -v "$PWD":/home/u/cxxctp -w /home/u/cxxctp/build cpp-docker-cxxctp cmake -DCONAN_AUTO_INSTALL=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE ..# Run resulting app in host OS:
# ./build/
```## Install conan - a crossplatform dependency manager for C++
```bash
pip install --index-url=https://pypi.python.org/simple/ --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org wheel \
&& \
pip install --index-url=https://pypi.python.org/simple/ --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org virtualenv \
&& \
pip install --index-url=https://pypi.python.org/simple/ --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org conan \
&& \
pip install --index-url=https://pypi.python.org/simple/ --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org conan_package_toolsconan profile new default --detect
# conan profile update settings.compiler.libcxx=libstdc++11 defaultconan remote list
conan search *boost* -r all
```Configure Proxies & cacert_path in `~/.conan/conan.conf`, see https://docs.conan.io/en/latest/reference/config_files/conan.conf.html#proxies
Configure conan clang profile to then use --profile clang:
```bash
/usr/bin/clang-6.0 -v
/usr/bin/clang++-6.0 -vnano ~/.conan/profiles/clang
[settings]
# We are building in Ubuntu Linux
os_build=Linux
os=Linux
arch_build=x86_64
arch=x86_64compiler=clang
compiler.version=6.0
compiler.libcxx=libstdc++11[env]
CC=/usr/bin/clang-6.0
CXX=/usr/bin/clang++-6.0
```And then `conan install ***** --profile clang`
```bash
/usr/bin/gcc -v
/usr/bin/g++ -vnano ~/.conan/profiles/gcc
[settings]
# We are building in Ubuntu Linux
os_build=Linux
os=Linux
arch_build=x86_64
arch=x86_64compiler=gcc
compiler.version=7
compiler.libcxx=libstdc++11[env]
CC=/usr/bin/gcc
CXX=/usr/bin/g++
```If you want to disable ssl (under proxy, etc.):
```bash
# see https://docs.conan.io/en/latest/reference/commands/misc/remote.html#conan-remote
conan remote update conan-center https://conan.bintray.com False
conan search boost* -r=conan-centerconan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
conan remote update bincrafters https://api.bintray.com/conan/bincrafters/public-conan False
conan search boost* -r=bincrafters
```If you want to set corp. cacert:
```bash
CONAN_CACERT_PATH=/path/to/ca-bundle.crt
file $CONAN_CACERT_PATH
```Useful links:
- https://ncona.com/2019/04/dependency-management-in-cpp-with-conan/
- https://blog.conan.io/2018/06/11/Transparent-CMake-Integration.html
- Conan https://blog.conan.io/2018/06/11/Transparent-CMake-Integration.html https://blog.conan.io/2018/12/03/Using-Facebook-Folly-with-Conan.html
- CONAN_PKG::cppzmq https://github.com/chaplin89/prontocpp/blob/master/CMakeLists.txt#L42
- https://github.com/conan-io/examples## Add conan remotes
To be able to add the list of dependency remotes please type the following command:
```bash
cmake -E time conan config install conan/remotes/
# OR:
# cmake -E time conan config install conan/remotes_disabled_ssl/
```## Dependencies
```bash
# NOTE: don't forget to re-run `conan install` after command below
# NOTE: change `build_type=Debug` to `build_type=Release` in production
cmake -DEXTRA_CONAN_OPTS="--profile;clang;-s;build_type=Debug;--build;missing" -P tools/buildConanThirdparty.cmake
```- type_safe
```bash
conan remote add Manu343726 https://api.bintray.com/conan/manu343726/conan-packages Falsegit clone http://github.com/foonathan/type_safe.git -b v0.2.1
cd type_safe
# NOTE: change `build_type=Debug` to `build_type=Release` in production
CONAN_REVISIONS_ENABLED=1 \
CONAN_VERBOSE_TRACEBACK=1 \
CONAN_PRINT_RUN_COMMANDS=1 \
CONAN_LOGGING_LEVEL=10 \
GIT_SSL_NO_VERIFY=true \
conan create . conan/stable -s build_type=Debug --profile clang --build missing
```- corrade
```bash
# NOTE: change `build_type=Debug` to `build_type=Release` in production
git clone http://github.com/mosra/corrade.git && cd corrade
CONAN_REVISIONS_ENABLED=1 \
CONAN_VERBOSE_TRACEBACK=1 \
CONAN_PRINT_RUN_COMMANDS=1 \
CONAN_LOGGING_LEVEL=10 \
GIT_SSL_NO_VERIFY=true \
conan create . magnum/stable -s build_type=Debug --profile clang --build missing -tf package/conan/test_package
```- MPI
```bash
sudo apt-get install openmpi-bin openmpi-common libopenmpi-dev
```- CMake
```bash
sudo -E apt-get purge -y cmake
bash scripts/install_cmake.sh
```Install CXTPL library https://github.com/blockspacer/CXTPL
Install CXTPL_tool https://github.com/blockspacer/CXTPL#how-to-build
## How to build
```bash
BEFORE install_cling.sh:
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install clang-6.0 libstdc++6 libstdc++-6-dev
sudo update-alternatives --config c++
sudo update-alternatives --config cc
sudo ldconfig
export CC=clang-6.0
export CXX=clang++-6.0
``````bash
# Build Cling into `cling-build` folder
cd scripts
bash install_cling.sh
```Install deps as in CXTPL https://github.com/blockspacer/CXTPL#how-to-build
```bash
export CC=clang-6.0
export CXX=clang++-6.0
cmake -E remove_directory build
cmake -E make_directory build
cmake -E remove_directory resources/cxtpl/generated
cmake -E make_directory resources/cxtpl/generated
# NOTE: change `build_type=Debug` to `build_type=Release` in production
CONAN_REVISIONS_ENABLED=1 \
CONAN_VERBOSE_TRACEBACK=1 \
CONAN_PRINT_RUN_COMMANDS=1 \
CONAN_LOGGING_LEVEL=10 \
GIT_SSL_NO_VERIFY=true \
cmake -E chdir build \
cmake -E time \
conan install \
-s build_type=Debug \
--build=missing \
--profile clang \
-o enable_tests=False \
-o openssl:shared=True \
..
cmake -E chdir build cmake -E time cmake -DCONAN_AUTO_INSTALL=OFF -DENABLE_CLING=TRUE -DBUILD_SHARED_LIBS=FALSE -DBUILD_EXAMPLES=FALSE -DALLOW_PER_PROJECT_CTP_SCRIPTS=TRUE -DBUNDLE_EXAMPLE_SCRIPTS=FALSE -DCMAKE_BUILD_TYPE=Debug -DENABLE_CXXCTP=TRUE ..
cmake -E chdir build cmake -E time cmake --build . -- -j6# you can install CXXCTP_tool:
sudo cmake -E chdir build make install# NOTE: You can also use the “-p” flag with CMAKE_EXPORT_COMPILE_COMMANDS. See https://variousburglarious.com/2018/02/18/include-paths-for-clang-tools/
# cmake -E chdir build ./tool/CXXCTP_tool -p=../example_compile_commands/# NOTE: runs CXXCTP_tool on multiple files and adds include paths by `-extra-arg=-I`
cmake -E chdir build ./tool/CXXCTP_tool -L .=DBG9 -extra-arg=-I$PWD/include -extra-arg=-I../resources ../examples/built_in/for_codegen/example_make_reflect.cpp# check generator output
file build/example_make_reflect.cpp.generated.cpp
```OR under gdb:
```bash
rm -rf *generated* ; clear && clear ; gdb ./CXXCTP -ex "run" -ex "bt" -ex "q"
```## How to build with Cling support
Use shared CXXCTP_core as SHARED library `-DBUILD_SHARED_LIBS=TRUE`.
Run bash scripts/install_folly.sh from https://github.com/blockspacer/CXTPL or patch folly manually for clang support (replace FOLLY_USE_JEMALLOC with FOLLY_ASSUME_NO_JEMALLOC) https://github.com/facebook/folly/issues/976
Use clang (NOT GCC!) before build and `-DENABLE_CLING=TRUE`:
```bash
export CC=clang-6.0
export CXX=clang++-6.0
sudo rm -rf examples/*/ctp_scripts/*/*/generated/
cmake -E remove_directory build
cmake -E make_directory build
cmake -E remove_directory resources/cxtpl/generated
cmake -E make_directory resources/cxtpl/generated
# NOTE: clang profile!
# NOTE: change `build_type=Debug` to `build_type=Release` in production
CONAN_REVISIONS_ENABLED=1 \
CONAN_VERBOSE_TRACEBACK=1 \
CONAN_PRINT_RUN_COMMANDS=1 \
CONAN_LOGGING_LEVEL=10 \
GIT_SSL_NO_VERIFY=true \
cmake -E chdir build \
cmake -E time \
conan install \
-s build_type=Debug \
--build=missing \
--profile clang \
-o enable_tests=False \
-o openssl:shared=True \
..
cmake -E chdir build cmake -E time cmake -DCONAN_AUTO_INSTALL=OFF -DENABLE_CLING=TRUE -DBUILD_SHARED_LIBS=TRUE -DALLOW_PER_PROJECT_CTP_SCRIPTS=TRUE -DBUILD_EXAMPLES=FALSE -DBUNDLE_EXAMPLE_SCRIPTS=FALSE -DCLEAN_CXXCTP_GEN=TRUE -DCMAKE_BUILD_TYPE=Debug -DENABLE_CXXCTP=TRUE ..
# OR cmake -E chdir build cmake -E time cmake -DCONAN_AUTO_INSTALL=OFF -DENABLE_CLING=TRUE -DBUILD_SHARED_LIBS=TRUE -DALLOW_PER_PROJECT_CTP_SCRIPTS=FALSE -DBUILD_EXAMPLES=FALSE -DBUNDLE_EXAMPLE_SCRIPTS=TRUE -DCLEAN_CXXCTP_GEN=TRUE -DCMAKE_BUILD_TYPE=Debug -DENABLE_CXXCTP=TRUE ..
cmake -E chdir build cmake -E time cmake --build . -- -j6
# you can install CXXCTP_tool:
sudo cmake -E chdir build make install
# check supported plugins
/usr/local/bin/CXXCTP_tool --plugins
```If you installed CXXCTP_tool - you can run examples:
```bash
# requires CXXCTP_tool
sudo cmake -E chdir build make install# use -DBUILD_EXAMPLES=TRUE
rm ./build/examples/simple/CXXCTP_tool_for_CXXCTP_example.log
cmake -E chdir build cmake -E time cmake -DCONAN_AUTO_INSTALL=OFF -DENABLE_CLING=TRUE -DBUILD_SHARED_LIBS=TRUE -DBUILD_EXAMPLES=TRUE -DBUNDLE_EXAMPLE_SCRIPTS=FALSE -DALLOW_PER_PROJECT_CTP_SCRIPTS=TRUE -DCMAKE_BUILD_TYPE=Debug -DENABLE_CXXCTP=TRUE ..
cmake -E chdir build cmake -E time cmake --build . -- -j6
cat ./build/examples/simple/CXXCTP_tool_for_CXXCTP_example.logCheck that `.log` find doesn`t contain errors
# run examples
build/bin/CXXCTP_example
```Don't forget to set Cling include paths by`-extra-arg=-I\$PWD/include`and library paths by`-extra-arg=-L\$PWD/build`and .so/.dll libs by`-extra-arg=-lCXXCTP_core`:
```bash
# NOTE: runs CXXCTP_tool on multiple files and adds include paths by `-extra-arg=-I`
cmake -E chdir build ./tool/CXXCTP_tool --ctp_scripts_paths=$PWD -L .=DBG9 -extra-arg=-I$PWD/include -extra-arg=-L$PWD/build -extra-arg=-lCXXCTP_core -extra-arg=-I../resources ../resources/ReflShapeKind.hpp ../resources/test_typeclass_base1.hpp ../resources/test_typeclass_instance1.hpp ../resources/test.cpp
```## How to add include paths or definitions for Cling
Use `-extra-arg` option of `CXXCTP_tool`:
```bash
-extra-arg=-I$PWD/include -extra-arg=-I$PWD/include/foo -extra-arg=-DMY_DEFINITION=1 -extra-arg=-DONE_MORE_DEFINITION=1
```Example:
```bash
cmake -E chdir build ./tool/CXXCTP_tool --ctp_scripts_paths=$PWD -L .=DBG9 -extra-arg=-I$PWD/include -extra-arg=-I../resources ../resources/ReflShapeKind.hpp ../resources/test_typeclass_base1.hpp ../resources/test_typeclass_instance1.hpp ../resources/test.cpp
```# ⌨️ Developing with CXXCTP
The following sections cover usage, custom rules and debugging for CXXCTP.
## Writing code that writes codeYou can write custom C++ scripts for source code transformation or use existing ones.
CXXCTP loads all C++ scripts from ctp_scripts folder in lexicographical order.
Example contents of ctp_scripts:
- 1_utils
- CXTPL_STD
- CXTPL_STD.hpp
- CXTPL_STD.cpp
- CXXCTP_STD
- CXXCTP_STD.hpp
- CXXCTP_STD.cpp
- 2_scripts
- make_interface
- make_interface.hpp
- make_interface.cpp
- typeclass
- typeclass.hpp
- typeclass.cppUtils must load before scripts (Cling related), so we added `1_`, `2_`, ... before folder names (see above).
You can use `#include`, use filesystem, access the internet, etc. in C++ scripts.
## Got error `libcling.so.5: cannot open shared object file: No such file or
directory`Install with `-DENABLE_CLING=TRUE -DINSTALL_CLING=TRUE` and set `LD_LIBRARY_PATH`
```bash
export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
sudo ldconfig
```## About CXXCTP code annotations
You can use C++ annotations to tell CXXCTP what actions it must execute.
Suppose we want to morph class into interface:
```cpp
// Source
class SomeInterfaceName {
int foo1() {
// ...
};
int foo();
virtual void foobar(int& arg1) = 0;
virtual void zoobar(int& arg2);
virtual ~SomeInterfaceName() = 0;
};// <== will be changed into ==>
// Result
class SomeInterfaceName {
virtual int foo1() = 0;
virtual int foo() = 0;
virtual void foobar(int& arg1) = 0;
virtual void zoobar(int& arg2) = 0;
virtual ~SomeInterfaceName() = 0;
};
```We can use `funccall` action to run C++ scripts for source code transformation. Let's suppose that script names are `make_interface` and `make_removefuncbody` (name as you want).
```cpp
__attribute__((annotate("{gen};{funccall};make_interface;make_removefuncbody")))
````{gen};` - keyword used in every CXXCTP annotation.
`{funccall};` - keyword used to tell CXXCTP what it must execute C++ scripts with cling.
`make_interface;make_removefuncbody` - two scripts what CXXCTP will execute.
Scripts will be executed from left (`make_interface`) to right (`make_removefuncbody`).
Usually you don't need to write long C++ annotations, just use C++ `#define` (or include built-in header with common defines):
```cpp
#define $apply(...) \
__attribute__((annotate("{gen};{funccall};" #__VA_ARGS__)))class
$apply(make_interface;
make_removefuncbody)
SomeInterfaceName {
virtual ~SomeInterfaceName() = 0;
int foo();
virtual void foobar(int& arg1) = 0;
virtual void zoobar(int& arg2);
};
```Using a similar approach you can apply multiple source code transformation steps to the same `class` / `struct` / etc.
## How to add custom code transformation rules
Create files with your function in `ctp_scripts`
Copy `custom_plugins.cmake.example` as `custom_plugins.cmake`
Append your script paths to `custom_plugins.cmake` via `add_ctp_plugin`:
```bash
# first arg - typeclass_instance - script function name
# second arg - script source file
# third arg - script header file
# last arg - path to CMakeLists.txt used to generate script-related files
add_ctp_plugin(
"typeclass_instance"
${CMAKE_CURRENT_SOURCE_DIR}/examples/simple/ctp_scripts/2_scripts/typeclass_instance/typeclass_instance.cpp
${CMAKE_CURRENT_SOURCE_DIR}/examples/simple/ctp_scripts/2_scripts/typeclass_instance/typeclass_instance.hpp
${CMAKE_CURRENT_SOURCE_DIR}/examples/simple/ctp_scripts/2_scripts/typeclass_instance
)
```Check that your function name exists in generated file `ctp_registry.cpp` (may be skipped in Cling / dev-mode)
Function signature for code transformation must be compatible with `cxxctp_callback`:
```cpp
typedef std::function& all_funcs_with_args)> cxxctp_callback;
```Detailed function signature:
- return value (const char\*) - used to replace original code, if needed.
- func_with_args - currently executed function from list `all_funcs_with_args` (see below)
- clang::ast_matchers::MatchFinder::MatchResult - see https://xinhuang.github.io/posts/2015-02-08-clang-tutorial-the-ast-matcher.html
- clang::Rewriter - see https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-3-rewriting-code-with-clang-tidy/
- clang::Decl - found by MatchFinder, see https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-2-examining-the-clang-ast-with-clang-query/
- std::vector - all arguments extracted from attribute. Example: \$apply(interface, foo_with_args(1, "2")) becomes two `parsed_func` - `interface` and `foo_with_args`.Think about function name as one of `__VA_ARGS__` from
```cpp
#define $apply(...) \
__attribute__((annotate("{gen};{funccall};" #__VA_ARGS__)))
```Example where `make_interface` and `make_removefuncbody` - two function names:
```cpp
$apply(make_interface;
make_removefuncbody)
```If you need code generation:
- Create template file (`.cxtpl`). Build your file using CXTPL_tool https://github.com/blockspacer/CXTPL
- Create all needed template arguments inside of your function. Names, types, etc. for arguments must be the same as in template (cause generated template is valid C++ code).
- Create variable `std::string cxtpl_output`, that will store result of template rendering with some arguments.
- Include file generation from template file (`.cxtpl`) inside of your function.## What is `.cxtpl`
`.cxtpl` is the file extension for the C++ template engine https://github.com/blockspacer/CXTPL
## How to add `.cxtpl` at compile-time (CMake)
Add your `.cxtpl` file into `Codegen_files.cmake`
NOTE:
In dev mode (like cling mode) it may be a good idea to generate files from templates using CXTPL_tool https://github.com/blockspacer/CXTPL
You can add generation rules into `Codegen_files.cmake` later in the release build.NOTE:
Don't forget to provide both `.cxtpl`and`.cxtpl.h` files with shared codegen rules (add to version control system).## How to use `.cxtpl` at runtime with Cling
You have two options:
- Generate a file from your `.cxtpl`, then include it into Cling C++ script. Similar to compile-time, but you can re-generate or change files without program recompilation. Note that it is possible to generate files and include them in your script; just split script into multiple includes.
- Generate a string from your `.cxtpl`, then run it in a separate Cling interpreter. In most cases you will use the first option.## How to use `.cxtpl` with CXXCTP
Pass reflection data into template engine.
Generate files from templates using CXTPL_tool https://github.com/blockspacer/CXTPL
In CXXCTP script (`.cpp`):
```cpp
// see ReflectAST.cpp
reflection::NamespacesTree m_namespaces;
// `node` from AST parser (libtooling)
reflection::ClassInfoPtr structInfo = reflector.ReflectClass(node, &m_namespaces);// ...
stuct Arguments {
// any custom arguments here ...
std::string arg1 = "arg1...";
std::string arg2 = "arg2...";
// reflection data here (ClassInfoPtr) ...
};// ...
std::map cxtpl_params;
{
cxtpl_params["Arguments"] =
std::make_any(Arguments{});
cxtpl_params["generator_path"] =
std::make_any("enum_gen_hpp.cxtpl");
cxtpl_params["generator_includes"] =
std::make_any>(
std::vector{});std::string cxtpl_output;
#include "../../resources/cxtpl/generated/enum_gen_hpp.cxtpl.cpp"
writeToFile(cxtpl_output, gen_hpp_name);
}
```In `.cxtpl` template:
```cpp
const auto arguments = std::any_cast(cxtpl_params.at("Arguments"));
std::cout << arguments.arg1;
```See `resources/cxtpl/enum_gen_hpp.cxtpl` as an example.
## How to use CXXCTP_tool
CXXCTP_tool wraps libtooling to add custom command-line options.
Options related to libtooling (type -help or --help):
```bash
Generic Options:-help - Display available options (-help-hidden for more)
-help-list - Display list of available options (-help-list-hidden for more)
-version - Display the version of this programUse override options:
-extra-arg= - Additional argument to append to the compiler command line
-extra-arg-before= - Additional argument to prepend to the compiler command line
-p= - Build path
```Options related to CXXCTP_tool (type --help, not -help):
`ctp_scripts_paths` - list of paths where toll will search for ctp_scripts subfolder
NOTE: `ctp_scripts_paths` requires `-DENABLE_CLING=TRUE`
`-L .=DBG9` is log configuration in format https://github.com/facebook/folly/blob/master/folly/logging/docs/Config.md
Example of log configuration that writes both into the file and console stream:
```bash
./build/bin/CXXCTP_tool -L ".:=INFO:default:console; default=file:path=y.log,async=true,sync_level=DBG9;console=stream:stream=stderr"
````--srcdir` to change current filesystem path for input files.
`--resdir` to change current filesystem path for output files.
Example (custom output dir):
```bash
# Remove old generated files
rm -rf gen
rm -rf build/*generated*`--version` to get tool version
`-version` to get clang version
# Build files to `gen/out` dir
mkdir -p gen/out
cmake -E chdir gen ../build/bin/CXXCTP_tool --resdir=$PWD/gen/out --ctp_scripts_paths=$PWD -L .=DBG9 -extra-arg=-I$PWD/include -extra-arg=-I../resources ../resources/ReflShapeKind.hpp ../resources/test_typeclass_base1.hpp ../resources/test_typeclass_instance1.hpp ../resources/test.cpp
```## How to debug `ctp_scripts`
Remove old build artifacts and generated files.
Bundle your scripts with `CXXCTP_tool` via `-DBUNDLE_EXAMPLE_SCRIPTS=TRUE`.
Make sure that your scripts (plugins) are added to `CXXCTP_tool` via `custom_plugins.cmake.example`.
Disable per-project scripts `-DALLOW_PER_PROJECT_CTP_SCRIPTS=FALSE`.
Check that your scripts (plugins) are in `build/tool/CXXCTP_tool --plugins`
Check that the system-installed version of `CXXCTP_tool` is the same as `build/tool/CXXCTP_tool` (by date/file hash)
Run `CXXCTP_tool` manually under `gdb`:
```bash
gdb -ex "r" -ex "bt" --args build/tool/CXXCTP_tool .........
```Check that all needed paths are in `-extra-arg=`.
Make a log to file in `DBG9` mode and check `.log` files.
## About libtooling
CXXCTP uses LibTooling to parse and modify C++.
LibTooling is a library to support writing standalone tools based on Clang.
Useful links:
- https://clang.llvm.org/extra/clang-rename.html
- Clang Tooling I (add override keyword) https://medium.com/@chichunchen844/clang-tooling-i-add-override-keyword-ddfdf6113b24
- llvm-clang-samples https://github.com/eliben/llvm-clang-samples/blob/master/src_clang/tooling_sample.cpp
- https://chromium.googlesource.com/chromium/src/+/master/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
- http://www.dreamlandcoder.com/system-security/how-i-learned/clang-libtool/
- https://jonasdevlieghere.com/understanding-the-clang-ast/
- http://swtv.kaist.ac.kr/courses/cs453-fall13/Clang%20tutorial%20v4.pdf
- https://meetingcpp.com/mcpp/slides/2019/Teaching%20Old%20Compilers%20New%20Tricks_%20Transpiling%20C++17%20to%20C++11.pdf
- https://gist.github.com/riyadparvez/a2c157b24579c6552466
- https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-3-rewriting-code-with-clang-tidy/
- http://blog.audio-tk.com/2018/03/20/writing-custom-checks-for-clang-tidy/
- https://meetingcpp.com/mcpp/slides/2018/Reflection2.pdf
- https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-223.pdf
- https://kevinaboos.wordpress.com/2013/07/30/clang-tips-and-tricks/
- https://eli.thegreenplace.net/tag/llvm-clang
- http://www.goldsborough.me/c++/clang/llvm/tools/2017/02/24/00-00-06-emitting_diagnostics_and_fixithints_in_clang_tools/
- https://www.amazon.com/Getting-Started-LLVM-Core-Libraries/dp/1782166920
- https://variousburglarious.com/tag/clang/## About cling
CXXCTP uses cling to execute C++ at compile-time.
You can use cling for hot code reload / REPL / Fast C++ prototyping / Scripting engine / JIT / etc.
Useful links:
- (how to add Cling into CMake project) https://github.com/derofim/cling-cmake
- https://github.com/root-project/cling/tree/master/www/docs/talks
- https://github.com/caiorss/C-Cpp-Notes/blob/master/Root-cern-repl.org### clang-format
```bash
sudo apt install clang-format
```Run based on `.clang-format` file:
```bash
find . -regex '.*\.\(cpp\|hpp\|cu\|c\|h\)' -exec clang-format -style=file -i {} \;
```Useful links:
- Create & use `.clang-format` file https://leimao.github.io/blog/Clang-Format-Quick-Tutorial/
- Integrate with your IDE ( QT instructions http://doc.qt.io/qtcreator/creator-beautifier.html ) Import .clang-format rules to IDE settings.Please read our [contributing](CONTRIBUTING.md) guidelines before making your pull request.
## Code of Conduct
Please note that this project is released with a [Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project, you agree to abide by its terms.
### Contributors List: Example Profile
- I'm an example that you can copy, if you want :)
- I work on many things like...
- My hobbies include...
- [![twitter-alt][twitter-img]](https://twitter.com/example)
[![facebook-alt][facebook-img]](https://facebook.com/example)
[![google-img][google-img]](https://plus.google.com/+Example)
[![tumblr-alt][tumblr-img]](https://example.tumblr.com)
[![dribbble-alt][dribbble-img]](https://dribbble.com/example)
[![github-alt][github-img]](https://github.com/example)
[![freeCodeCamp](imgs/freecodecamp.png)](https://www.freecodecamp.org/example)
[](https://www.linkedin.com/in/example/)### Contributors List 👌
#### A
##### Anindita Basu
- Technical writer
- [![twitter-alt][twitter-img]](https://twitter.com/anindita_basu)
[![github-alt][github-img]](https://github.com/AninditaBasu)##### Anna Hayhurst
- Junior Developer
- [![github-alt][github-img]](https://github.com/annahayhurst)#### C
##### Cássio Espíndola
- Analyst Developer
- [![github-alt][github-img]](https://github.com/cassioesp)#### D
##### Denis trofimov
- C++ Developer
- [![github-alt][github-img]](https://github.com/blockspacer)
- [![github-alt][github-img]](https://github.com/derofim)
- [](https://www.linkedin.com/in/denis-trofimov-4335bb13b/)#### M
##### Mohib Qureshi
- Software Development Enthusiast
- [![github-alt][github-img]](https://github.com/mohibqureshi)#### Y
##### Yousif Alebyary
- Web/Mobile Developer.
- [![github-alt][github-img]](https://github.com/yousifm)##### Yves Mancera
- Software Engineer
- [![github-alt][github-img]](https://github.com/yvesmh)## Standing on the Shoulders of Giants
That project possible because of [flexferrum's `autoprogrammer`](https://github.com/flexferrum/autoprogrammer).
Articles about flexferrum's `autoprogrammer` in media:
- [RUS] метаклассах по-русски https://habr.com/ru/article/448466/
- [RUS] Метаклассы в C++17 Фантастика? Реальность! https://assets.ctfassets.net/oxjq45e8ilak/55bGdX2PnYzmrpM8rwCjcE/791e7eee3236c2023e86e169faca8a0e/Sergei_Sadovnikov_Metaclasses_in_C___dream_Reality.pdf## LICENSE for open source components
All the open source components are used under their associated open source licences.
Used open source components:
* icu
* ced
* boost
* harfbuzz
* boost.outcome
* chromium (base)
* libevent
* modp_b64
* tcmalloc
* xdg_mime
* xdg_user_dirs
* dynamic_annotations
* (Facebook) Folly
* (Microsoft) GSLSee LICENSE files
### CMake Code style
CMake files pass style checks, can be fixed by running run-cmake-format.py from the root of the repository. This requires Python 3 and [cmake_format](https://github.com/cheshirekow/cmake_format) (note: this currently does not work on Windows)
Use autoformatter `cmake-format.py` and `run-cmake-format.py`
```bash
pip3 install cmake_format
python3 run-cmake-format.py
```To use cmake-format on a specific CMakeLists.txt file in the command line run
```bash
python3 -m cmake_format -c cmake-format.py -i CMakeLists.txt
```There is an official Visual Studio extension, details of which can be found [here](https://marketplace.visualstudio.com/items?itemName=cheshirekow.cmake-format).
Follow CMake StyleGuide https://github.com/ruslo/0
## Projects that use `.cxtpl`
- [SKG](https://github.com/blockspacer/skia-opengl-emscripten) C++ HTML/CSS UI.
# 📋 Similar projects
- https://github.com/cppreflect/metapp
- https://github.com/flexferrum/autoprogrammer/blob/8c9867d357450b99202dac81730851ffc8faa891/src/generators/pimpl_generator.cpp
- Clava https://github.com/specs-feup/clava
- Compile-time EXecution of C++ code https://github.com/MaliusArth/cex/blob/6f6e700a253b06c7ae6801e1a3c1f3d842931d77/tool/src/MatchCallbacks/AnnotatedFunctionCallback.cpp
- circle https://github.com/seanbaxter/circle/blob/master/examples/README.md
- SugarCpp https://github.com/curimit/SugarCpp
- ExtendedCpp https://github.com/reneeichhorn/extended-cpp
- https://github.com/dobkeratops/compiler
- transpiling_cpp17_to_cpp11 https://github.com/neobrain/cftf
- https://github.com/llvm-mirror/clang-tools-extra/blob/388528d/clang-tidy/add_new_check.py
- https://github.com/aantron/better-enums
- https://github.com/Neargye/magic_enum
- https://github.com/foonathan/standardese
- https://github.com/Leandros/metareflect/blob/0208fdd4fc0ea1081ae2ff4c3bfce161305a7423/README.md#run-the-metareflect-tool
- https://github.com/qtinuum/QtnProperty#overview
- https://github.com/p-ranav/pprint
- https://github.com/google/draco/blob/master/CMakeLists.txt#L715
- https://github.com/goto40/rpp/blob/ec8a4c4a3ac32dccee8c4e8ba97be8c2ba1c8f88/src/parser/common_parser.cpp#L21
- More https://gist.github.com/blockspacer/6f03933de4f9a6c920649713b056ba4a[twitter-alt]: Twitter
[facebook-alt]: Facebook
[google-alt]: Google+
[tumblr-alt]: Tumblr
[dribbble-alt]: Dribbble
[github-alt]: GitHub
[twitter-img]: https://i.imgur.com/wWzX9uB.png
[facebook-img]: https://i.imgur.com/fep1WsG.png
[google-img]: https://i.imgur.com/VlgBKQ9.png
[tumblr-img]: https://i.imgur.com/jDRp47c.png
[dribbble-img]: https://i.imgur.com/Vvy3Kru.png
[github-img]: https://i.imgur.com/9I6NRUm.png