Sane C++ Libraries
C++ Platform Abstraction Libraries
Plugin.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Containers/SmallVector.h"
5#include "../Containers/VectorMap.h"
6#include "../Foundation/Function.h"
7#include "../Strings/SmallString.h"
8#include "../Time/Time.h"
9#include "Internal/DynamicLibrary.h"
10
11namespace SC
12{
13struct PluginDefinition;
14struct PluginScanner;
15struct PluginFile;
16struct PluginIdentity;
17struct PluginDynamicLibrary;
18struct PluginCompiler;
19struct PluginCompilerEnvironment;
20struct PluginSysroot;
21struct PluginRegistry;
22using PluginIdentifier = SmallString<30>;
23} // namespace SC
24
27
30
33{
35};
36
39{
43
47 bool operator==(const PluginIdentity& other) const { return identifier == other.identifier; }
48};
49
52{
57
61
64 PluginFile& getMainPluginFile() { return files[pluginFileIndex]; }
65
68 const PluginFile& getMainPluginFile() const { return files[pluginFileIndex]; }
69
74 [[nodiscard]] static bool find(const StringView text, StringView& extracted);
75
80 [[nodiscard]] static bool parse(StringView text, PluginDefinition& pluginDefinition);
81
85 [[nodiscard]] Result getDynamicLibraryAbsolutePath(String& fullDynamicPath) const;
86
90 [[nodiscard]] Result getDynamicLibraryPDBAbsolutePath(String& fullDynamicPath) const;
91
92 private:
93 [[nodiscard]] static bool parseLine(StringIteratorASCII& iterator, StringView& key, StringView& value);
94
95 size_t pluginFileIndex = 0;
96 friend struct PluginScanner;
97};
98
101{
106 [[nodiscard]] static Result scanDirectory(const StringView directory, Vector<PluginDefinition>& definitions);
107};
108
111{
118 Result compile(const PluginDefinition& definition, const PluginSysroot& sysroot,
119 const PluginCompilerEnvironment& environment, String& compilerLog) const;
120
128 Result link(const PluginDefinition& definition, const PluginSysroot& sysroot,
129 const PluginCompilerEnvironment& environment, StringView executablePath, String& linkerLog) const;
130
132 enum class Type
133 {
134 ClangCompiler,
135 GnuCompiler,
136 MicrosoftCompiler
137 };
138 Type type = Type::ClangCompiler;
141
143
146
150 [[nodiscard]] static Result findBestCompiler(PluginCompiler& compiler);
151
152 private:
153 [[nodiscard]] Result compileFile(const PluginDefinition& definition, const PluginSysroot& sysroot,
154 const PluginCompilerEnvironment& compilerEnvironment, StringView sourceFile,
155 StringView objectFile, String& compilerLog) const;
156 struct Internal;
157};
158
161{
164
166
171 [[nodiscard]] static Result findBestSysroot(PluginCompiler::Type compiler, PluginSysroot& sysroot);
172};
173
176{
177 StringView cFlags;
178 StringView ldFlags;
179
180 private:
181 struct Internal;
182 friend struct PluginCompiler;
183};
186{
188 SystemDynamicLibrary dynamicLibrary;
192
196 template <typename T>
197 [[nodiscard]] bool queryInterface(T*& outInterface) const
198 {
199 if (pluginQueryInterface and instance != nullptr)
200 {
201 return pluginQueryInterface(instance, T::InterfaceHash, reinterpret_cast<void**>(&outInterface));
202 }
203 return false;
204 }
205
206 PluginDynamicLibrary() : lastLoadTime(Time::Absolute::now()) { numReloads = 0; }
207
208 private:
209 void* instance = nullptr;
210 bool (*pluginInit)(void*& instance) = nullptr;
211 bool (*pluginClose)(void* instance) = nullptr;
212
213 bool (*pluginQueryInterface)(void* instance, uint32_t hash, void** instanceInterface) = nullptr;
214
215 friend struct PluginRegistry;
216 [[nodiscard]] Result load(const PluginCompiler& compiler, const PluginSysroot& sysroot, StringView executablePath);
217 [[nodiscard]] Result unload();
218};
219
222{
227
229 enum class LoadMode
230 {
231 Load = 0,
232 Reload = 1,
233 };
234
242 [[nodiscard]] Result loadPlugin(const StringView identifier, const PluginCompiler& compiler,
243 const PluginSysroot& sysroot, StringView executablePath,
244 LoadMode loadMode = LoadMode::Load);
245
249 [[nodiscard]] Result unloadPlugin(const StringView identifier);
250
254 [[nodiscard]] Result removeAllBuildProducts(const StringView identifier);
255
259 [[nodiscard]] const PluginDynamicLibrary* findPlugin(const StringView identifier);
260
262 [[nodiscard]] size_t getNumberOfEntries() const { return libraries.size(); }
263
265 [[nodiscard]] const PluginIdentifier& getIdentifierAt(size_t index) const { return libraries.items[index].key; }
266
268 [[nodiscard]] const PluginDynamicLibrary& getPluginDynamicLibraryAt(size_t index)
269 {
270 return libraries.items[index].value;
271 }
272
278 Function<void(const PluginIdentifier&)> onPlugin);
279
280 private:
282};
283
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
@ Native
Encoding is UTF8.
Wraps function pointers, member functions and lambdas without ever allocating.
Definition: Function.h:50
Reads and holds CFLAGS and LDFLAGS environment variables, mainly to pass down sysroot location.
Definition: Plugin.h:176
Compiles a plugin to a dynamic library.
Definition: Plugin.h:111
SmallVector< StringNative< 256 >, 8 > includePaths
Path to include directories used to compile plugin.
Definition: Plugin.h:142
SmallVector< StringNative< 256 >, 8 > compilerIncludePaths
Path to compiler include directories.
Definition: Plugin.h:144
SmallVector< StringNative< 256 >, 8 > compilerLibraryPaths
Path to compiler library directories.
Definition: Plugin.h:145
StringNative< 256 > compilerPath
Path to the compiler.
Definition: Plugin.h:139
Type type
Compile Type.
Definition: Plugin.h:138
Result compile(const PluginDefinition &definition, const PluginSysroot &sysroot, const PluginCompilerEnvironment &environment, String &compilerLog) const
Compiles a Definition to an object file.
Type
Compiler type (clang/gcc/msvc)
Definition: Plugin.h:133
static Result findBestCompiler(PluginCompiler &compiler)
Look for best compiler on current system.
StringNative< 256 > linkerPath
Path to the linker.
Definition: Plugin.h:140
Result link(const PluginDefinition &definition, const PluginSysroot &sysroot, const PluginCompilerEnvironment &environment, StringView executablePath, String &linkerLog) const
Links a Definition into a dynamic library, with symbols from executablePath
Plugin description, category, dependencies, files and directory location.
Definition: Plugin.h:52
Result getDynamicLibraryAbsolutePath(String &fullDynamicPath) const
Gets absolute path of where compiled dynamic library will exist after plugin is compiled.
SmallString< 255 > description
Long description of plugin.
Definition: Plugin.h:54
SmallVector< PluginIdentifier, 8 > dependencies
Dependencies necessary to load this plugin.
Definition: Plugin.h:58
PluginIdentity identity
Uniquely identifier a plugin.
Definition: Plugin.h:53
static bool find(const StringView text, StringView &extracted)
Extracts the plugin definition (SC_BEGIN_PLUGIN / SC_END_PLUGIN) comment from a .cpp file.
const PluginFile & getMainPluginFile() const
Get main plugin file, holding plugin definition.
Definition: Plugin.h:68
SmallString< 255 > directory
Path to the directory holding the plugin.
Definition: Plugin.h:56
Result getDynamicLibraryPDBAbsolutePath(String &fullDynamicPath) const
Gets absolute path of where compiled Program Database File will exist after plugin is compiled.
SmallVector< PluginFile, 10 > files
Source files that compose this plugin.
Definition: Plugin.h:60
static bool parse(StringView text, PluginDefinition &pluginDefinition)
Parses an extracted plugin definition text.
SmallVector< SmallString< 10 >, 8 > build
Build options.
Definition: Plugin.h:59
SmallString< 10 > category
Category where plugin belongs to.
Definition: Plugin.h:55
PluginFile & getMainPluginFile()
Get main plugin file, holding plugin definition.
Definition: Plugin.h:64
A plugin dynamic library loaded from a SC::PluginRegistry.
Definition: Plugin.h:186
String lastErrorLog
Last error log of compiler / linker (if any)
Definition: Plugin.h:191
Time::Absolute lastLoadTime
Last time when this plugin was last loaded.
Definition: Plugin.h:189
SystemDynamicLibrary dynamicLibrary
System handle of plugin's dynamic library.
Definition: Plugin.h:188
PluginDefinition definition
Definition of the loaded plugin.
Definition: Plugin.h:187
uint32_t numReloads
Number of times that the plugin has been hot-reloaded.
Definition: Plugin.h:190
bool queryInterface(T *&outInterface) const
Try to obtain a given interface as exported by a plugin through SC_PLUGIN_EXPORT_INTERFACES macro.
Definition: Plugin.h:197
Holds path to a given plugin source file.
Definition: Plugin.h:33
SmallString< 255 > absolutePath
Absolute path to a plugin source file.
Definition: Plugin.h:34
Represents the unique signature / identity of a Plugin.
Definition: Plugin.h:39
bool operator==(const PluginIdentity &other) const
Compares two plugins on Identity::identifier.
Definition: Plugin.h:47
SmallString< 10 > version
Plugin version (x.y.z)
Definition: Plugin.h:42
PluginIdentifier identifier
Unique string identifying the plugin.
Definition: Plugin.h:40
SmallString< 30 > name
Plugin name.
Definition: Plugin.h:41
Holds a registry of plugins, loading and compiling them on the fly.
Definition: Plugin.h:222
LoadMode
Instructs loadPlugin to Load or Reload the plugin.
Definition: Plugin.h:230
Result unloadPlugin(const StringView identifier)
Unloads an already loaded plugin by its identifier.
Result loadPlugin(const StringView identifier, const PluginCompiler &compiler, const PluginSysroot &sysroot, StringView executablePath, LoadMode loadMode=LoadMode::Load)
Loads a plugin with given identifier, compiling it with given PluginCompiler.
size_t getNumberOfEntries() const
Returns the total number of registry entries (counting both loaded and unloaded plugins)
Definition: Plugin.h:262
Result removeAllBuildProducts(const StringView identifier)
Removes all temporary build products of the Plugin with given identifier.
const PluginDynamicLibrary * findPlugin(const StringView identifier)
Find a PluginDynamicLibrary in the registry with a given identifier.
const PluginDynamicLibrary & getPluginDynamicLibraryAt(size_t index)
Returns the PluginIdentifier corresponding to the index entry of the registry.
Definition: Plugin.h:268
const PluginIdentifier & getIdentifierAt(size_t index) const
Returns the PluginIdentifier corresponding to the index entry of the registry.
Definition: Plugin.h:265
Result replaceDefinitions(Vector< PluginDefinition > &&definitions)
Appends the definitions to registry.
void getPluginsToReloadBecauseOf(StringView relativePath, Time::Milliseconds tolerance, Function< void(const PluginIdentifier &)> onPlugin)
Enumerates all plugins that must be reloaded when relativePath is modified.
Scans a directory for PluginDefinition.
Definition: Plugin.h:101
static Result scanDirectory(const StringView directory, Vector< PluginDefinition > &definitions)
Scans a directory for PluginDefinition.
Holds include and library paths for a system toolchain, used to let plugins link to libc and libc++.
Definition: Plugin.h:161
SmallVector< StringNative< 256 >, 8 > includePaths
Path to system include directories.
Definition: Plugin.h:162
static Result findBestSysroot(PluginCompiler::Type compiler, PluginSysroot &sysroot)
Finds a reasonable sysroot for the given compiler.
SmallVector< StringNative< 256 >, 8 > libraryPaths
Path to system library directories.
Definition: Plugin.h:163
StringNative< 256 > isysroot
Path to sysroot include (optional)
Definition: Plugin.h:165
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition: Result.h:12
String with compile time configurable inline storage (small string optimization)
Definition: SmallString.h:21
A Vector that can hold up to N elements inline and > N on heap.
Definition: SmallVector.h:27
A non-modifiable owning string with associated encoding.
Definition: String.h:30
A string iterator for ASCII strings.
Definition: StringIterator.h:245
Non-owning view over a range of characters with UTF Encoding.
Definition: StringView.h:47
Absolute time represented with milliseconds since epoch.
Definition: Time.h:110
Type-safe wrapper of uint64 used to represent milliseconds.
Definition: Time.h:42
A contiguous sequence of heap allocated elements.
Definition: Vector.h:51
A map holding VectorMapItem key-value pairs in an unsorted Vector.
Definition: VectorMap.h:33