1
0
mirror of synced 2024-09-25 03:58:27 +02:00

build/plugin: Make plugins no longer depend on their file name

This commit is contained in:
WerWolv 2022-01-23 23:28:56 +01:00
parent b3a8d02d19
commit 541c0d7547
6 changed files with 85 additions and 53 deletions

View File

@ -16,15 +16,25 @@ macro(addVersionDefines)
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGIT_COMMIT_HASH=\"\\\"${GIT_COMMIT_HASH}\"\\\"")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGIT_BRANCH=\"\\\"${GIT_BRANCH}\"\\\"")
endif()
add_compile_definitions(GIT_COMMIT_HASH="${GIT_COMMIT_HASH}" GIT_BRANCH="${GIT_BRANCH}")
endif ()
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} -DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR} -DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH} ")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DRELEASE -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}\"\\\"")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}-Debug\"\\\"")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DRELEASE -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}-ReleaseWithDebugInfo\"\\\"")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DRELEASE -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}-ReleaseMinimumSize\"\\\"")
add_compile_definitions(
$<$<CONFIG:Release>:IMHEX_VERSION="${PROJECT_VERSION}">
$<$<CONFIG:Debug>:IMHEX_VERSION="${PROJECT_VERSION}-Debug">
$<$<CONFIG:RelWithDebInfo>:IMHEX_VERSION="${PROJECT_VERSION}-ReleaseWithDebugInfo">
$<$<CONFIG:MinSizeRel>:IMHEX_VERSION="${PROJECT_VERSION}-ReleaseMinimumSize">
)
add_compile_definitions(
$<$<CONFIG:Release>:RELEASE>
$<$<CONFIG:Debug>:DEBUG>
$<$<CONFIG:RelWithDebInfo>:RELEASE>
$<$<CONFIG:MinSizeRel>:RELEASE>
)
endmacro()
macro(configurePython)
@ -49,30 +59,30 @@ macro(configurePython)
endif ()
list(JOIN PYTHON_VERSION_MAJOR_MINOR "." PYTHON_VERSION_MAJOR_MINOR)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -DPYTHON_VERSION_MAJOR_MINOR=\"\\\"${PYTHON_VERSION_MAJOR_MINOR}\"\\\"")
add_compile_definitions(PYTHON_VERSION_MAJOR_MINOR="${PYTHON_VERSION_MAJOR_MINOR}")
endmacro()
# Detect current OS / System
macro(detectOS)
if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_WINDOWS")
add_compile_definitions(OS_WINDOWS)
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
set(MAGIC_INSTALL_LOCATION "magic")
elseif(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_MACOS")
elseif (APPLE)
add_compile_definitions(OS_MACOS)
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
set(MAGIC_INSTALL_LOCATION "magic")
elseif(UNIX AND NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_LINUX")
elseif (UNIX AND NOT APPLE)
add_compile_definitions(OS_LINUX)
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_LIBDIR "lib")
set(PLUGINS_INSTALL_LOCATION "share/imhex/plugins")
set(MAGIC_INSTALL_LOCATION "share/imhex/magic")
else()
else ()
message(FATAL_ERROR "Unknown / unsupported system!")
endif()
endmacro()
@ -80,9 +90,9 @@ endmacro()
# Detect 32 vs. 64 bit system
macro(detectArch)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DARCH_64_BIT")
add_compile_definitions(ARCH_64_BIT)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DARCH_32_BIT")
add_compile_definitions(ARCH_32_BIT)
endif()
endmacro()

View File

@ -8,13 +8,10 @@
#define IMHEX_PLUGIN_SETUP(name, author, description) IMHEX_PLUGIN_SETUP_IMPL(IMHEX_PLUGIN_NAME, name, author, description)
#define IMHEX_PLUGIN_SETUP_IMPL(namespaceName, name, author, description) \
namespace hex::plugin::namespaceName::internal { \
[[gnu::visibility("default")]] void initializePlugin(); \
\
[[gnu::visibility("default")]] const char* getPluginName() { return name; } \
[[gnu::visibility("default")]] const char* getPluginAuthor() { return author; } \
[[gnu::visibility("default")]] const char* getPluginDescription() { return description; } \
[[gnu::visibility("default")]] void setImGuiContext(ImGuiContext *ctx) { ImGui::SetCurrentContext(ctx); GImGui = ctx; } \
} \
void hex::plugin::namespaceName::internal::initializePlugin()
#define IMHEX_PLUGIN_SETUP_IMPL(namespaceName, name, author, description) \
extern "C" [[gnu::visibility("default")]] const char* getPluginName() { return name; } \
extern "C" [[gnu::visibility("default")]] const char* getPluginAuthor() { return author; } \
extern "C" [[gnu::visibility("default")]] const char* getPluginDescription() { return description; } \
extern "C" [[gnu::visibility("default")]] const char* getCompatibleVersion() { return IMHEX_VERSION; } \
extern "C" [[gnu::visibility("default")]] void setImGuiContext(ImGuiContext *ctx) { ImGui::SetCurrentContext(ctx); GImGui = ctx; } \
extern "C" [[gnu::visibility("default")]] void initializePlugin()

View File

@ -22,33 +22,39 @@ namespace hex {
[[nodiscard]] std::string getPluginName() const;
[[nodiscard]] std::string getPluginAuthor() const;
[[nodiscard]] std::string getPluginDescription() const;
[[nodiscard]] std::string getCompatibleVersion() const;
void setImGuiContext(ImGuiContext *ctx) const;
[[nodiscard]] const fs::path& getPath() const;
[[nodiscard]] bool isLoaded() const;
private:
using InitializePluginFunc = void(*)();
using GetPluginNameFunc = const char*(*)();
using GetPluginAuthorFunc = const char*(*)();
using GetPluginDescriptionFunc = const char*(*)();
using GetCompatibleVersionFunc = const char*(*)();
using SetImGuiContextFunc = void(*)(ImGuiContext*);
void *m_handle = nullptr;
fs::path m_path;
mutable bool m_initialized = false;
InitializePluginFunc m_initializePluginFunction = nullptr;
GetPluginNameFunc m_getPluginNameFunction = nullptr;
GetPluginAuthorFunc m_getPluginAuthorFunction = nullptr;
GetPluginDescriptionFunc m_getPluginDescriptionFunction = nullptr;
GetCompatibleVersionFunc m_getCompatibleVersionFunction = nullptr;
SetImGuiContextFunc m_setImGuiContextFunction = nullptr;
template<typename T>
[[nodiscard]] auto getPluginFunction(const std::string &pluginName, const std::string &symbol) {
return reinterpret_cast<T>(this->getPluginFunction(pluginName, symbol));
[[nodiscard]] auto getPluginFunction(const std::string &symbol) {
return reinterpret_cast<T>(this->getPluginFunction(symbol));
}
private:
[[nodiscard]] void* getPluginFunction(const std::string &pluginName, const std::string &symbol);
[[nodiscard]] void* getPluginFunction(const std::string &symbol);
};
class PluginManager {

View File

@ -7,13 +7,6 @@
namespace hex {
// hex::plugin::<pluginName>::internal::initializePlugin()
constexpr auto InitializePluginSymbol = "_ZN3hex6plugin{0}{1}8internal16initializePluginEv";
constexpr auto GetPluginNameSymbol = "_ZN3hex6plugin{0}{1}8internal13getPluginNameEv";
constexpr auto GetPluginAuthorSymbol = "_ZN3hex6plugin{0}{1}8internal15getPluginAuthorEv";
constexpr auto GetPluginDescriptionSymbol = "_ZN3hex6plugin{0}{1}8internal20getPluginDescriptionEv";
constexpr auto SetImGuiContextSymbol = "_ZN3hex6plugin{0}{1}8internal15setImGuiContextEP12ImGuiContext";
Plugin::Plugin(const fs::path &path) : m_path(path) {
this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY);
@ -24,11 +17,12 @@ namespace hex {
auto pluginName = fs::path(path).stem().string();
this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>(pluginName, InitializePluginSymbol);
this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>(pluginName, GetPluginNameSymbol);
this->m_getPluginAuthorFunction = getPluginFunction<GetPluginAuthorFunc>(pluginName, GetPluginAuthorSymbol);
this->m_getPluginDescriptionFunction = getPluginFunction<GetPluginDescriptionFunc>(pluginName, GetPluginDescriptionSymbol);
this->m_setImGuiContextFunction = getPluginFunction<SetImGuiContextFunc>(pluginName, SetImGuiContextSymbol);
this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>("initializePlugin");
this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>("getPluginName");
this->m_getPluginAuthorFunction = getPluginFunction<GetPluginAuthorFunc>("getPluginAuthor");
this->m_getPluginDescriptionFunction = getPluginFunction<GetPluginDescriptionFunc>("getPluginDescription");
this->m_getCompatibleVersionFunction = getPluginFunction<GetCompatibleVersionFunc>("getCompatibleVersion");
this->m_setImGuiContextFunction = getPluginFunction<SetImGuiContextFunc>("setImGuiContext");
}
Plugin::Plugin(Plugin &&other) noexcept {
@ -39,6 +33,7 @@ namespace hex {
this->m_getPluginNameFunction = other.m_getPluginNameFunction;
this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction;
this->m_getPluginDescriptionFunction = other.m_getPluginDescriptionFunction;
this->m_getCompatibleVersionFunction = other.m_getCompatibleVersionFunction;
this->m_setImGuiContextFunction = other.m_setImGuiContextFunction;
other.m_handle = nullptr;
@ -46,6 +41,7 @@ namespace hex {
other.m_getPluginNameFunction = nullptr;
other.m_getPluginAuthorFunction = nullptr;
other.m_getPluginDescriptionFunction = nullptr;
other.m_getCompatibleVersionFunction = nullptr;
other.m_setImGuiContextFunction = nullptr;
}
@ -55,12 +51,20 @@ namespace hex {
}
bool Plugin::initializePlugin() const {
const auto requestedVersion = getCompatibleVersion();
if (requestedVersion != IMHEX_VERSION) {
log::error("Refused to load plugin '{}' which was built for a different version of ImHex: '{}'", this->m_path.filename().string(), requestedVersion);
return false;
}
if (this->m_initializePluginFunction != nullptr) {
this->m_initializePluginFunction();
return true;
} else {
return false;
}
this->m_initialized = true;
return true;
}
std::string Plugin::getPluginName() const {
@ -84,6 +88,13 @@ namespace hex {
return "";
}
std::string Plugin::getCompatibleVersion() const {
if (this->m_getCompatibleVersionFunction != nullptr)
return this->m_getCompatibleVersionFunction();
else
return "";
}
void Plugin::setImGuiContext(ImGuiContext *ctx) const {
if (this->m_setImGuiContextFunction != nullptr)
this->m_setImGuiContextFunction(ctx);
@ -93,12 +104,15 @@ namespace hex {
return this->m_path;
}
void* Plugin::getPluginFunction(const std::string &pluginName, const std::string &symbol) {
auto symbolName = hex::format(symbol.data(), pluginName.length(), pluginName.data());
return dlsym(this->m_handle, symbolName.c_str());
bool Plugin::isLoaded() const {
return this->m_initialized;
}
void* Plugin::getPluginFunction(const std::string &symbol) {
return dlsym(this->m_handle, symbol.c_str());
}
bool PluginManager::load(const fs::path &pluginFolder) {
if (!fs::exists(pluginFolder))

View File

@ -715,11 +715,12 @@ namespace hex {
const auto &plugins = PluginManager::getPlugins();
if (!plugins.empty()) {
if (ImGui::BeginTable("plugins", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_SizingFixedFit, ImVec2((ImGui::GetContentRegionAvail().x * 5) / 6, ImGui::GetTextLineHeightWithSpacing() * 5))) {
if (ImGui::BeginTable("plugins", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_SizingFixedFit, ImVec2((ImGui::GetContentRegionAvail().x * 5) / 6, ImGui::GetTextLineHeightWithSpacing() * 5))) {
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.welcome.plugins.plugin"_lang);
ImGui::TableSetupColumn("hex.welcome.plugins.author"_lang);
ImGui::TableSetupColumn("hex.welcome.plugins.desc"_lang);
ImGui::TableSetupColumn("hex.welcome.plugins.plugin"_lang, ImGuiTableColumnFlags_WidthStretch, 0.2);
ImGui::TableSetupColumn("hex.welcome.plugins.author"_lang, ImGuiTableColumnFlags_WidthStretch, 0.2);
ImGui::TableSetupColumn("hex.welcome.plugins.desc"_lang, ImGuiTableColumnFlags_WidthStretch, 0.6);
ImGui::TableSetupColumn("##loaded", ImGuiTableColumnFlags_WidthFixed, ImGui::GetTextLineHeight());
ImGui::TableHeadersRow();
@ -728,13 +729,17 @@ namespace hex {
while (clipper.Step()) {
for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
const auto &plugin = plugins[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted((plugins[i].getPluginName() + " ").c_str());
ImGui::TextUnformatted(plugin.getPluginName().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted((plugins[i].getPluginAuthor() + " ").c_str());
ImGui::TextUnformatted(plugin.getPluginAuthor().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugins[i].getPluginDescription().c_str());
ImGui::TextUnformatted(plugin.getPluginDescription().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.isLoaded() ? ICON_VS_CHECK : ICON_VS_CLOSE);
}
}

View File

@ -15,7 +15,7 @@ namespace hex::plugin::windows {
IMHEX_PLUGIN_SETUP("Windows", "WerWolv", "Windows-only features") {
using namespace hex::plugin::windows;
ContentRegistry::Views::add<ViewTTYConsole>();
hex::ContentRegistry::Views::add<ViewTTYConsole>();
registerLanguageEnUS();
registerLanguageZhCN();