diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .gitmodules | 4 | ||||
-rw-r--r-- | CMakeLists.txt | 25 | ||||
-rw-r--r-- | LICENSE | 22 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | cmake/FindNorthstarPluginABI.cmake | 12 | ||||
-rw-r--r-- | cmake/R2plugin.cmake | 191 | ||||
-rw-r--r-- | cmake/utils.cmake | 25 | ||||
m--------- | deps/NorthstarLauncher | 0 | ||||
-rw-r--r-- | src/CMakeLists.txt | 18 | ||||
-rw-r--r-- | src/init.cpp | 12 | ||||
-rw-r--r-- | src/internal/logging.h | 45 | ||||
-rw-r--r-- | src/plugin.h | 14 |
13 files changed, 370 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e6f024f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "deps/NorthstarLauncher"] + path = deps/NorthstarLauncher + url = https://github.com/R2Northstar/NorthstarLauncher + branch = 300521638f6600f23bfea433e8069c049af42388 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d3d04dd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.21.1) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(utils) +include(R2plugin) + +if(CMAKE_POLICY_DEFAULT_CMP0017 OR CMAKE_POLICY_DEFAULT_CMP0020) + # touch these to remove warnings +endif() + +project(SouthRPC VERSION 0.1.0) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif() + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_FLAGS "-fpermissive") + +set(CMAKE_SHARED_LIBRARY_PREFIX "") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +add_subdirectory(src) @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) Jan Drögehoff + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd4434b --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# South-RPC diff --git a/cmake/FindNorthstarPluginABI.cmake b/cmake/FindNorthstarPluginABI.cmake new file mode 100644 index 0000000..08518f2 --- /dev/null +++ b/cmake/FindNorthstarPluginABI.cmake @@ -0,0 +1,12 @@ + +if (NorthstarPluginABI_FOUND) + return() +endif() + +set(NS_LAUNCHER_DIR "${PROJECT_SOURCE_DIR}/deps/NorthstarLauncher" CACHE STRING "Path to NorthstarLauncher Dependency") +check_init_submodule(${NS_LAUNCHER_DIR}) + +set(NS_DLL_DIR "${NS_LAUNCHER_DIR}/NorthstarDLL") +set(NS_PLUG_DIR "${NS_DLL_DIR}/plugins") + +set(NorthstarPluginABI_FOUND) diff --git a/cmake/R2plugin.cmake b/cmake/R2plugin.cmake new file mode 100644 index 0000000..bb9dac0 --- /dev/null +++ b/cmake/R2plugin.cmake @@ -0,0 +1,191 @@ +## CMake extension for creating R2Northstar V2 Plugins + +cmake_minimum_required( VERSION 3.21.1) + +if(CMAKE_POLICY_DEFAULT_CMP0017 OR CMAKE_POLICY_DEFAULT_CMP0020) + # touch these to remove warnings +endif() +cmake_policy(SET CMP0057 NEW) + +project(R2plugin) + +find_package(spdlog REQUIRED) +find_package(NorthstarPluginABI REQUIRED) + +if (NOT WIN32) + message(FATAL_ERROR "Northstar Plugins can only be compiled for Windows") +elseif (NOT "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64") + message(FATAL_ERROR "Northstar Plugins can only be build for x86_64") +endif () + +if (__R2PLUGIN_CMAKE_INCLUDED) + return() +endif() +set(__R2PLUGIN_CMAKE_INCLUDED TRUE) + +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CheckLinkerFlag) + +macro(check_compiler_flags CHECK_FUNC FLAGS OUTPUT) + foreach(flag ${${FLAGS}}) + string(REPLACE "+" "P" VAR_NAME ${flag}) + string(TOUPPER ${VAR_NAME} VAR_NAME) + set(flag "-${flag}") + cmake_language(CALL ${CHECK_FUNC} "${flag}" "${VAR_NAME}") + + if(${${VAR_NAME}}) + list(APPEND ${OUTPUT} "${flag}") + endif() + endforeach() +endmacro() + +macro(check_linker_flags LANG FLAGS OUTPUT) + foreach(flag ${${FLAGS}}) + string(REPLACE "+" "P" VAR_NAME ${flag}) + string(TOUPPER ${VAR_NAME} VAR_NAME) + set(flag "-${flag}") + check_linker_flag("${LANG}" "${flag}" "${VAR_NAME}") + + if(${${VAR_NAME}}) + list(APPEND ${OUTPUT} "${flag}") + endif() + endforeach() +endmacro() + + +list(APPEND + C_FLAGS +) + +list(APPEND + C_LINK_FLAGS + static + static-libgcc +) + +list(APPEND + CXX_FLAGS + ${C_FLAGS} +) + +list(APPEND + CXX_LINK_FLAGS + ${C_LINK_FLAGS} + static-libstdc++ +) + + +get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) + +if("C" IN_LIST languages) + check_compiler_flags(check_c_compiler_flag C_FLAGS C_FLAGS_LIST) + list(JOIN C_FLAGS_LIST " " C_FLAGS) + set(PLUGIN_C_FLAGS "${PLUGIN_C_FLAGS} ${C_FLAGS}") + + check_linker_flags("C" C_LINK_FLAGS C_LINK_FLAGS_LIST) + list(JOIN C_LINK_FLAGS_LIST " " PLUGIN_C_LINK_FLAGS) +endif() +if("CXX" IN_LIST languages) + check_compiler_flags(check_cxx_compiler_flag CXX_FLAGS CXX_FLAGS_LIST) + list(JOIN CXX_FLAGS_LIST " " CXX_FLAGS) + set(PLUGIN_CXX_FLAGS "${PLUGIN_CXX_FLAGS} ${CXX_FLAGS}") + + check_linker_flags("C" CXX_LINK_FLAGS CXX_LINK_FLAGS_LIST) + list(JOIN CXX_LINK_FLAGS_LIST " " PLUGIN_CXX_LINK_FLAGS) +endif() + +set(RESOURCE_TEMPLATE +" +#define IDR_RCDATA1 101 +IDR_RCDATA1 RCDATA \"manifest.json\" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK \"StringFileInfo\" + BEGIN + BLOCK \"040904b0\" + BEGIN + VALUE \"CompanyName\", \"Northstar\" + VALUE \"FileDescription\", \"Northstar Plugin\" + VALUE \"FileVersion\", \"1.0.0.0\" + VALUE \"ProductName\", \"Northstar Plugin\" + VALUE \"ProductVersion\", \"1.0.0.0\" + END + END + BLOCK \"VarFileInfo\" + BEGIN + VALUE \"Translation\", 0x409, 1200 + END +END +") + +set(MANIFEST_TEMPLATE + "{ + \"description\": \"\", + \"api_version\": \"2\", + \"version\": \"0\", + \"run_on_server\": false, + \"run_on_client\": false + }" +) + +list(APPEND + REQUIRED_MANIFEST_KEYS + name + displayname + description + api_version + version + run_on_server + run_on_client +) +macro(plugin_manifest TARGET KEY VALUE) + if (NOT ${TARGET}_MANIFEST) + set(${TARGET}_MANIFEST "${MANIFEST_TEMPLATE}") + + # set default name to target name + string(JSON ${TARGET}_MANIFEST SET "${${TARGET}_MANIFEST}" name "\"${TARGET}\"") + + # set default version to project version + string(JSON ${TARGET}_MANIFEST SET "${${TARGET}_MANIFEST}" version "\"${CMAKE_PROJECT_VERSION}\"") + endif() + + if ("${VALUE}" STREQUAL ON) + set(JSON_VALUE "true") + elseif ("${VALUE}" STREQUAL OFF) + set(JSON_VALUE "false") + else() + set(JSON_VALUE "\"${VALUE}\"") + endif() + + string(JSON ${TARGET}_MANIFEST SET "${${TARGET}_MANIFEST}" "${KEY}" "${JSON_VALUE}") +endmacro() + +macro(plugin_link TARGET) + if("C" IN_LIST languages) + target_link_libraries(${TARGET} ${PLUGIN_C_LINK_FLAGS}) + endif() + if("CXX" IN_LIST languages) + target_link_libraries(${TARGET} ${PLUGIN_CXX_LINK_FLAGS}) + endif() + target_link_libraries(${TARGET} spdlog::spdlog_header_only) + target_include_directories(${TARGET} PRIVATE ${NS_DLL_DIR}) + target_include_directories(${TARGET} PRIVATE ${NS_PLUG_DIR}) + + string(JSON PLUGIN_NAME GET "${${TARGET}_MANIFEST}" name) + target_compile_definitions(${TARGET} PRIVATE PLUGIN_NAME=\"${PLUGIN_NAME}\") + + set(MANIFEST_DIR "${CMAKE_BINARY_DIR}/${TARGET}_plugin/") + file(MAKE_DIRECTORY "${MANIFEST_DIR}") + file(WRITE "${MANIFEST_DIR}/manifest.json" "${${TARGET}_MANIFEST}") + file(WRITE "${MANIFEST_DIR}/manifest.rc" "${RESOURCE_TEMPLATE}") + target_sources(${TARGET} PUBLIC "${MANIFEST_DIR}/manifest.rc") +endmacro() diff --git a/cmake/utils.cmake b/cmake/utils.cmake new file mode 100644 index 0000000..a0e0ee9 --- /dev/null +++ b/cmake/utils.cmake @@ -0,0 +1,25 @@ + +# Check if a dependency exist before trying to init git submodules +function(check_init_submodule path) + file(GLOB DIR_CONTENT path) + list(LENGTH DIR_CONTENT CONTENT_COUNT) + if (CONTENT_COUNT EQUAL 0) + if (NOT EXISTS "${PROJECT_SOURCE_DIR}/.git") + message(FATAL_ERROR "Failed to find third party dependency in '${path}'") + endif() + + find_package(Git QUIET) + if (NOT Git_FOUND) + message(FATAL_ERROR "Failed to find Git, third party dependency could not be setup at `${path}") + endif() + + message(STATUS "Setting up dependencies as git submodules") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE GIT_SUBMOD_RESULT) + + if(NOT GIT_SUBMOD_RESULT EQUAL "0") + message(FATAL_ERROR "Initializing Git submodules failed with ${GIT_SUBMOD_RESULT}") + endif() + endif() +endfunction() diff --git a/deps/NorthstarLauncher b/deps/NorthstarLauncher new file mode 160000 +Subproject 07e76e3a8e2738dbb7a1d5a6aeaa908a838f5a0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..44ae5d4 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,18 @@ + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +find_package(spdlog REQUIRED) + +plugin_manifest(SouthRPC name "South-RPC") +plugin_manifest(SouthRPC displayname "South RPC") +plugin_manifest(SouthRPC description "Implements JSON-RPC Bridge for Northstar over TCP/IP") +plugin_manifest(SouthRPC run_on_server OFF) +plugin_manifest(SouthRPC run_on_client ON) + +add_library(SouthRPC SHARED + ${CMAKE_CURRENT_SOURCE_DIR}/init.cpp +) + +target_precompile_headers(SouthRPC PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/plugin.h) + +plugin_link(SouthRPC) diff --git a/src/init.cpp b/src/init.cpp new file mode 100644 index 0000000..856af41 --- /dev/null +++ b/src/init.cpp @@ -0,0 +1,12 @@ +// Needed to bootstrap plugin abi +#include "plugin.h" +#include "internal/logging.h" + +extern "C" __declspec(dllexport) +void PLUGIN_INIT(PluginInitFuncs* funcs, PluginNorthstarData* data) +{ + spdlog::default_logger()->sinks().pop_back(); + spdlog::default_logger()->sinks().push_back(std::make_shared<PluginSink>(funcs->logger)); + + spdlog::info(PLUGIN_NAME " succesfully initialised!"); +} diff --git a/src/internal/logging.h b/src/internal/logging.h new file mode 100644 index 0000000..ad6de6b --- /dev/null +++ b/src/internal/logging.h @@ -0,0 +1,45 @@ +#ifndef LOGGING_H +#define LOGGING_H + +#include <iostream> + +#include "plugin.h" +#include "spdlog/sinks/base_sink.h" + +using spdlog_base_sink = spdlog::sinks::base_sink<std::mutex>; + +class PluginSink : public spdlog_base_sink +{ +public: + + PluginSink(loggerfunc_t logger): spdlog_base_sink() + { + this->ns_logger_ = logger; + } + + void sink_it_(const spdlog::details::log_msg& in_msg) override + { + LogMsg msg{}; + std::string payload(in_msg.payload.data(), in_msg.payload.size()); + msg.level = (int)in_msg.level; + msg.msg = payload.c_str(); + msg.timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(in_msg.time.time_since_epoch()).count(); + msg.source.file = in_msg.source.filename; + msg.source.func = in_msg.source.funcname; + msg.source.line = in_msg.source.line; + this->ns_logger_(&msg); + } + + void flush_() override + { + std::cout << std::flush; + } + +protected: + loggerfunc_t ns_logger_; + + // sink log level - default is all + spdlog::level_t level_{ spdlog::level::trace }; +}; + +#endif
\ No newline at end of file diff --git a/src/plugin.h b/src/plugin.h new file mode 100644 index 0000000..c346cee --- /dev/null +++ b/src/plugin.h @@ -0,0 +1,14 @@ +#ifndef PLUGIN_H +#define PLUGIN_H + +// Needed to bootstrap plugin abi +#include <windef.h> +#include <mutex> +#include <optional> +#include <map> +#include <unordered_map> +#include "spdlog/spdlog.h" + +#include "plugin_abi.h" + +#endif |