diff --git a/tools/generate-plugin.sh b/tools/generate-plugin.sh new file mode 100755 index 0000000000000000000000000000000000000000..a99f6976013582125f678a705a7a337dc5c3ac2d --- /dev/null +++ b/tools/generate-plugin.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +BOLD='\e[1m' +RESET='\e[0m' + +GREEN='\e[92m' +RED='\e[91m' +YELLOW='\e[93m' + +echo -ne ${BOLD} +echo -e "---------------------" +echo -e "pugs plugin generator" +echo -e "---------------------" +echo -e ${RESET} + +CURRENT_DIR="$(pwd -P)" +SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +PUGS_DIR="$(dirname ${SCRIPT_DIR})" + +if [[ "${CURRENT_DIR}" =~ "${PUGS_DIR}" ]] +then + echo -e ${RED}"Aborting..."${RESET} + echo -e "run this script outside of pugs sources" + exit 1 +fi + +NAME_RE='^[A-Z][a-zA-Z0-9]*$' + +echo " Plugin name must fulfill the following constrains:" +echo " - be a single word that starts by an upper case," +echo " - contains only letters or numbers," +echo " and preferably separate words with caps." +echo +echo " ex.: MyFirstPlugin" +echo + +while [[ ! "${PLUGIN_NAME}" =~ $NAME_RE ]] +do + echo -n "Give plugin name: " + read -r PLUGIN_NAME + + if [[ ! "${PLUGIN_NAME}" =~ $NAME_RE ]] + then + echo -e ${RED}" invalid name!"${RESET} + echo + unset PLUGIN_NAME + fi + +done + +PLUGIN_UP="${PLUGIN_NAME^^}" +PLUGIN_LOW="${PLUGIN_NAME,,}" +echo +echo -e "creating plugin ${YELLOW}${PLUGIN_NAME}${RESET} in directory ${YELLOW}${PLUGIN_LOW}${RESET}" +echo + +if [[ -e ${PLUGIN_LOW} ]] +then + echo -e ${RED}"Aborting..."${RESET} + echo -e "directory \"${PLUGIN_LOW}\" ${YELLOW}already exists${RESET}!" + exit 1 +fi + + +mkdir "${PLUGIN_LOW}" +mkdir "${PLUGIN_LOW}/cmake" + +cp "${PUGS_DIR}"/cmake/CheckNotInSources.cmake "${PLUGIN_LOW}"/cmake/ +cp "${PUGS_DIR}"/tools/plugin-template/FindPugs.cmake "${PLUGIN_LOW}"/cmake/ +cp "${PUGS_DIR}"/.gitignore "${PLUGIN_LOW}" +cp "${PUGS_DIR}"/.clang-format "${PLUGIN_LOW}" +cat "${PUGS_DIR}"/tools/plugin-template/CMakeLists.txt-template | sed s/_PLUGIN_NAME_/${PLUGIN_NAME}/g | sed s/_PLUGIN_LOW_/${PLUGIN_LOW}/g | sed s/_PLUGIN_UP_/${PLUGIN_UP}/g > "${PLUGIN_LOW}"/CMakeLists.txt +cat "${PUGS_DIR}"/tools/plugin-template/Module.hpp-template | sed s/_PLUGIN_NAME_/${PLUGIN_NAME}/g | sed s/_PLUGIN_LOW_/${PLUGIN_LOW}/g | sed s/_PLUGIN_UP_/${PLUGIN_UP}/g > "${PLUGIN_LOW}"/${PLUGIN_NAME}Module.hpp +cat "${PUGS_DIR}"/tools/plugin-template/Module.cpp-template | sed s/_PLUGIN_NAME_/${PLUGIN_NAME}/g | sed s/_PLUGIN_LOW_/${PLUGIN_LOW}/g | sed s/_PLUGIN_UP_/${PLUGIN_UP}/g > "${PLUGIN_LOW}"/${PLUGIN_NAME}Module.cpp +cat "${PUGS_DIR}"/tools/plugin-template/README.md-template | sed s/_PLUGIN_NAME_/${PLUGIN_NAME}/g | sed s/_PLUGIN_LOW_/${PLUGIN_LOW}/g | sed s/_PLUGIN_UP_/${PLUGIN_UP}/g > "${PLUGIN_LOW}"/README.md + +(cd "${PLUGIN_LOW}"; git init -q) +(cd "${PLUGIN_LOW}"; git add .) +(cd "${PLUGIN_LOW}"; git commit -m "init" -q) + +echo -e ${GREEN}"Creation finished successfully!"${RESET} diff --git a/tools/plugin-template/CMakeLists.txt-template b/tools/plugin-template/CMakeLists.txt-template new file mode 100644 index 0000000000000000000000000000000000000000..ae56000c37ed40cf18def1262e67554e0f5ee302 --- /dev/null +++ b/tools/plugin-template/CMakeLists.txt-template @@ -0,0 +1,95 @@ +cmake_minimum_required (VERSION 3.19) + +project("_PLUGIN_LOW_") + +# CMake utils +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +# Forbids in-source builds +include(CheckNotInSources) + +# use PkgConfig to find packages +find_package(PkgConfig REQUIRED) +find_package(Pugs REQUIRED) + +# ----------------------------------------------------- +# dynamic libraries + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +link_libraries("-rdynamic") +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + +#------------------------------------------------------ + +set(CMAKE_CONFIGURATION_TYPES "Release;Debug;Coverage" CACHE STRING INTERNAL FORCE ) + +#------------------------------------------------------ + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +#------------------------------------------------------ + +set(PUGS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +set(PUGS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") + +# Add new build types +set(CMAKE_CXX_FLAGS_COVERAGE + "-g -O0 --coverage" + CACHE STRING "Flags used by the C++ compiler during coverage builds." + FORCE ) +set(CMAKE_C_FLAGS_COVERAGE + "-g -O0 --coverage" + CACHE STRING "Flags used by the C compiler during coverage builds." + FORCE ) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "--coverage" + CACHE STRING "Flags used for linking binaries during coverage builds." + FORCE ) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "--coverage" + CACHE STRING "Flags used by the shared libraries linker during coverage builds." + FORCE ) +mark_as_advanced( + CMAKE_CXX_FLAGS_COVERAGE + CMAKE_C_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) + +if(CMAKE_BUILD_TYPE) + string(REGEX MATCH "^(Release|Debug|Coverage)$" VALID_BUILD_TYPE "${CMAKE_BUILD_TYPE}") + if(NOT VALID_BUILD_TYPE) + message(FATAL_ERROR "Invalid CMAKE_BUILD_TYPE: '${CMAKE_BUILD_TYPE}'") + endif() +endif() + +# Default build type is Release +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build: Release Debug Coverage." + FORCE) +endif() + +#------------------------------------------------------ +# default build shared libraries +if (NOT BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS ON CACHE STRING "" FORCE) +endif() + +#------------------------------------------------------ + +# Checks if compiler version is compatible with Pugs sources +set(GNU_CXX_MIN_VERSION "10.0.0") +set(CLANG_CXX_MIN_VERSION "11.0.0") + +#------------------------------------------------------ +# Change Kokkos namespace to avoid conflicts +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKokkos=InlineKokkos") + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}") +include_directories(SYSTEM "${PUGS_PREFIX_PATH}/include") +include_directories(SYSTEM "${PUGS_PREFIX_PATH}/include/kokkos") +include_directories(SYSTEM "${PUGS_PREFIX_PATH}/include/tao/") + +add_library(_PLUGIN_NAME_ + _PLUGIN_NAME_Module.cpp +) diff --git a/tools/plugin-template/FindPugs.cmake b/tools/plugin-template/FindPugs.cmake new file mode 100644 index 0000000000000000000000000000000000000000..6269bed8a9055339894cdd9fa9e63b2b479c9b70 --- /dev/null +++ b/tools/plugin-template/FindPugs.cmake @@ -0,0 +1,10 @@ +# Finds for the pugs installation directory + +find_path(PUGS_PREFIX_PATH include/utils/pugs_version.hpp + HINTS + $ENV{PUGS_INSTALL_DIR} + /usr/local/pugs + NO_DEFAULT_PATH +) + +find_package_handle_standard_args(Pugs REQUIRED_VARS PUGS_PREFIX_PATH ) diff --git a/tools/plugin-template/Module.cpp-template b/tools/plugin-template/Module.cpp-template new file mode 100644 index 0000000000000000000000000000000000000000..dd264e03631590e3cf0db152779e2118df86d474 --- /dev/null +++ b/tools/plugin-template/Module.cpp-template @@ -0,0 +1,28 @@ +#include <_PLUGIN_NAME_Module.hpp> + +#include <language/modules/ModuleRepository.hpp> +#include <language/utils/BuiltinFunctionEmbedder.hpp> + +_PLUGIN_NAME_Module::_PLUGIN_NAME_Module() : BuiltinModule(false) +{ + // Simple hello world example + this->_addBuiltinFunction("_PLUGIN_LOW__hello", std::function( + + []() -> void { std::cout << "_PLUGIN_NAME_: Hello world\n"; } + + )); +} + +void +_PLUGIN_NAME_Module::registerOperators() const +{ + // Kept empty for basic use +} + +void +_PLUGIN_NAME_Module::registerCheckpointResume() const +{ + // kept empty for basic use +} + +ModuleRepository::Subscribe<_PLUGIN_NAME_Module> _PLUGIN_LOW__module; diff --git a/tools/plugin-template/Module.hpp-template b/tools/plugin-template/Module.hpp-template new file mode 100644 index 0000000000000000000000000000000000000000..757e3b5e650390251d15515cfdcf26a9c970a102 --- /dev/null +++ b/tools/plugin-template/Module.hpp-template @@ -0,0 +1,22 @@ +#ifndef _PLUGIN_UP__MODULE_HPP +#define _PLUGIN_UP__MODULE_HPP + +#include <language/modules/BuiltinModule.hpp> + +class _PLUGIN_NAME_Module : public BuiltinModule +{ + public: + std::string_view + name() const final + { + return "_PLUGIN_LOW_"; + } + + void registerOperators() const final; + void registerCheckpointResume() const final; + + _PLUGIN_NAME_Module(); + ~_PLUGIN_NAME_Module() = default; +}; + +#endif // _PLUGIN_UP__MODULE_HPP diff --git a/tools/plugin-template/README.md-template b/tools/plugin-template/README.md-template new file mode 100644 index 0000000000000000000000000000000000000000..d89c74f974696b95dc875e5357007b5b67fba557 --- /dev/null +++ b/tools/plugin-template/README.md-template @@ -0,0 +1,67 @@ +`pugs`'s plugin `_PLUGIN_NAME_` +=============================== + +# Building `_PLUGIN_NAME_` + +## `pugs` installation + +Building this plugin requires an **installed** version of `pugs`. +`pugs` follows standard `cmake` installation recipes. + +Before building `pugs` one should define its installation directory. +In the `pugs` compilation directory one should execute +```shell +cmake -DCMAKE_INSTALL_PREFIX=pugs_install_dir ... +``` +where `pugs_install_dir` is the chosen installation directory. + +Then one simply runs +```shell +make install +``` + +## building the plugin `_PLUGIN_NAME_` + +> **Warning**:<br> +> Building `_PLUGIN_NAME_` in its source directory is +> **forbidden**. Trying to do so will result in a failure. However it +> generally leaves some garbage files in the source directory, namely +> the `CMakeCache.txt` and the `CMakeFiles` directory. `CMake` itself +> is not able to remove them, to avoid the risk of compilation issues, +> one has to dot it manually... + +In the build directory one runs +```shell +PUGS_INSTALL_DIR=pugs_install_dir cmake _PLUGIN_LOW__dir +``` +where `pugs_install_dir` has the same value as above and `_PLUGIN_LOW__dir` +is the directory that contains this `README.md` file. + +Then to build the plugin, one runs +```shell +make +``` + +If anything runs fine, the dynamic library `lib_PLUGIN_NAME_.so` is +built. + +# Using `_PLUGIN_NAME_` + +In order to use the created plugin, one simply has to give the +location of `lib_PLUGIN_NAME_.so` to `pugs`. This is done by means of +environment variables. There are two possibilities: +- `PUGS_PLUGIN` contains a semicolumn separated list of plugin + libraries, +- `PUGS_PLUGIN_DIR` contains a semicolumn separated list of path to + plugin libraries. + +Example +```shell +export PUGS_PLUGIN="/pathtoplugin/lib_PLUGIN_NAME_.so" +``` +or +```shell +export PUGS_PLUGIN_DIR="/pathtoplugin1;/pathtoplugin2" +``` + +Then one launches `pugs` classically.