From c66eba3b50ffe7c93df36d4320d3d4b47f75bbc6 Mon Sep 17 00:00:00 2001 From: Stat1cV01D <1160915+Stat1cV01D@users.noreply.github.com> Date: Fri, 25 Jun 2021 15:18:11 +0700 Subject: [PATCH 1/4] Use external library loader --- .gitmodules | 3 ++ gm_dotnet_native/CMakeLists.txt | 5 +- .../dotnethelper-src/dotnethelper.cpp | 31 +++++------- gm_dotnet_native/external_includes/dynalo | 1 + gm_dotnet_native/src/gm_dotnet.cpp | 49 +++++++------------ 5 files changed, 40 insertions(+), 49 deletions(-) create mode 100644 .gitmodules create mode 160000 gm_dotnet_native/external_includes/dynalo diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..7983dcf8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dynalo"] + path = gm_dotnet_native/external_includes/dynalo + url = https://github.com/Stat1cV01D/dynalo.git diff --git a/gm_dotnet_native/CMakeLists.txt b/gm_dotnet_native/CMakeLists.txt index a7ffb4e3..a2ae11f2 100644 --- a/gm_dotnet_native/CMakeLists.txt +++ b/gm_dotnet_native/CMakeLists.txt @@ -25,7 +25,10 @@ add_library(gm_dotnet_native SHARED src/gm_dotnet.cpp dotnethelper-src/cleanup_f add_library(dotnethelper SHARED dotnethelper-src/dotnethelper.cpp dotnethelper-src/cleanup_function_type.h dotnethelper-src/LuaAPIExposure.h dotnethelper-src/LuaAPIExposure.cpp) #Set up external include libraries -include_directories ("${EXTERNAL_INCLUDES_PATH}") +include_directories ("${EXTERNAL_INCLUDES_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}") +add_subdirectory ("${EXTERNAL_INCLUDES_PATH}/dynalo") +target_link_libraries(gm_dotnet_native PUBLIC dynalo) +target_link_libraries(dotnethelper PUBLIC dynalo) #Set up compile definitions target_compile_definitions(gm_dotnet_native PUBLIC SEM_VERSION="${SEM_VERSION}") target_compile_definitions(dotnethelper PUBLIC SEM_VERSION="${SEM_VERSION}") diff --git a/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp b/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp index 60db6736..aca5a91a 100644 --- a/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp +++ b/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef WIN32 #include #else @@ -51,23 +52,13 @@ managed_main_fn managed_main = nullptr; const std::filesystem::path lua_bin_folder = _T("garrysmod/lua/bin"); const std::filesystem::path hostfxr_path = (lua_bin_folder / _T("dotnet/host/fxr") / NET_CORE_VERSION).make_preferred(); -#ifdef WIN32 -HMODULE hostfxr_library_handle = LoadLibraryW((hostfxr_path / _T("hostfxr.dll")).c_str()); -#elif __APPLE__ -void* hostfxr_library_handle = dlopen((hostfxr_path / "libhostfxr.dylib").c_str(), RTLD_LAZY | RTLD_LOCAL); -#elif __gnu_linux__ -void* hostfxr_library_handle = dlopen((hostfxr_path / "libhostfxr.so").c_str(), RTLD_LAZY); -#endif + +const dynalo::library hostfxr_library(hostfxr_path / dynalo::to_native_name("hostfxr")); template -bool LoadFunction(const char* function_name, T& out_func) +void load_hostfxr_function(const char* function_name, T& out_func) { -#ifdef WIN32 - out_func = reinterpret_cast(GetProcAddress(hostfxr_library_handle, function_name)); -#else - out_func = reinterpret_cast(dlsym(hostfxr_library_handle, function_name)); -#endif - return (out_func != nullptr); + out_func = hostfxr_library.get_function>(function_name); } hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line = nullptr; hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate = nullptr; @@ -161,11 +152,15 @@ extern "C" DYNAMIC_EXPORT cleanup_function_fn InitNetRuntime(GarrysMod::Lua::ILu if(managed_main == nullptr) { - if(!(LoadFunction("hostfxr_initialize_for_dotnet_command_line", hostfxr_initialize_for_dotnet_command_line) - && LoadFunction("hostfxr_get_runtime_delegate", hostfxr_get_runtime_delegate) - && LoadFunction("hostfxr_set_error_writer", hostfxr_set_error_writer))) + try + { + load_hostfxr_function("hostfxr_initialize_for_dotnet_command_line", hostfxr_initialize_for_dotnet_command_line); + load_hostfxr_function("hostfxr_get_runtime_delegate", hostfxr_get_runtime_delegate); + load_hostfxr_function("hostfxr_set_error_writer", hostfxr_set_error_writer); + } + catch (std::runtime_error ex) { - error_log_file << "Unable to load hostfxr library" << std::endl; + error_log_file << "Unable to load hostfxr library: " << ex.what() << std::endl; return nullptr; } diff --git a/gm_dotnet_native/external_includes/dynalo b/gm_dotnet_native/external_includes/dynalo new file mode 160000 index 00000000..a1adfd99 --- /dev/null +++ b/gm_dotnet_native/external_includes/dynalo @@ -0,0 +1 @@ +Subproject commit a1adfd9963959354a1a4ebac9da3f7f280bf6487 diff --git a/gm_dotnet_native/src/gm_dotnet.cpp b/gm_dotnet_native/src/gm_dotnet.cpp index 29c862bb..761627f9 100644 --- a/gm_dotnet_native/src/gm_dotnet.cpp +++ b/gm_dotnet_native/src/gm_dotnet.cpp @@ -10,22 +10,25 @@ #include #endif // WIN32 #include -#include "../dotnethelper-src/cleanup_function_type.h" - -typedef cleanup_function_fn (*InitNetRuntime_fn)(GarrysMod::Lua::ILuaBase* lua); +#include "dotnethelper-src/cleanup_function_type.h" +#include cleanup_function_fn cleanup_function = nullptr; +const std::filesystem::path lua_bin_folder("garrysmod/lua/bin"); + +#ifdef __gnu_linux__ +const dynalo::library liblinuxhelper(lua_bin_folder / "liblinuxhelper.so"); +#endif + +const dynalo::library dotnethelper(lua_bin_folder / dynalo::to_native_name("dotnethelper")); + //Invoked by Garry's Mod on module load GMOD_MODULE_OPEN() { - const std::filesystem::path lua_bin_folder("garrysmod/lua/bin"); - // On Linux, modify SIGSEGV handling #ifdef __gnu_linux__ - void *linux_helper_handle = dlopen((lua_bin_folder / "liblinuxhelper.so").c_str(), RTLD_LAZY); - void (*pointer_to_install_sigsegv)(void); - pointer_to_install_sigsegv = (void(*)())dlsym(linux_helper_handle, "install_sigsegv_handler"); + auto pointer_to_install_sigsegv = liblinuxhelper.get_function("install_sigsegv_handler"); pointer_to_install_sigsegv(); #endif @@ -36,36 +39,22 @@ GMOD_MODULE_OPEN() LUA->Call(1, 0); LUA->Pop(1); - InitNetRuntime_fn InitNetRuntime = nullptr; - const char InitNetRuntime_fn_name[] = "InitNetRuntime"; - -#ifdef WIN32 - HMODULE dotnethelper_handle = LoadLibraryW((lua_bin_folder / "dotnethelper.dll").make_preferred().c_str()); - if (dotnethelper_handle != nullptr) - InitNetRuntime = reinterpret_cast(GetProcAddress(dotnethelper_handle, InitNetRuntime_fn_name)); -#elif __APPLE__ - void* dotnethelper_handle = dlopen((lua_bin_folder / "libdotnethelper.dylib").c_str(), RTLD_LAZY); -#elif __gnu_linux__ - void* dotnethelper_handle = dlopen((lua_bin_folder / "libdotnethelper.so").c_str(), RTLD_LAZY); -#endif - -#ifndef WIN32 - InitNetRuntime = reinterpret_cast(dlsym(dotnethelper_handle, InitNetRuntime_fn_name)); -#endif - - if(InitNetRuntime == nullptr) + try { + auto InitNetRuntime = dotnethelper.get_function("InitNetRuntime"); + cleanup_function = InitNetRuntime(LUA); + } + catch(std::runtime_error e) + { + auto error_msg = std::string("::error::Unable to load dotnet helper library. ") + e.what(); LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); LUA->GetField(-1, "print"); - LUA->PushString("::error::Unable to load dotnet helper library."); + LUA->PushString(error_msg.c_str()); LUA->Call(1, 0); LUA->Pop(1); - return 0; } - cleanup_function = InitNetRuntime(LUA); - if(cleanup_function == nullptr) { LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); From 18ae933f4531cae23ab56d3fa5ec1dad87835b7f Mon Sep 17 00:00:00 2001 From: Stat1cV01D <1160915+Stat1cV01D@users.noreply.github.com> Date: Fri, 25 Jun 2021 15:18:37 +0700 Subject: [PATCH 2/4] Add missing return on error --- gm_dotnet_native/dotnethelper-src/dotnethelper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp b/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp index aca5a91a..de12b087 100644 --- a/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp +++ b/gm_dotnet_native/dotnethelper-src/dotnethelper.cpp @@ -194,6 +194,7 @@ extern "C" DYNAMIC_EXPORT cleanup_function_fn InitNetRuntime(GarrysMod::Lua::ILu if(runtime_environment_handle == nullptr) { error_log_file << "runtime_environment_handle is null" << std::endl; + return nullptr; } get_function_pointer_fn get_function_pointer = nullptr; int get_runtime_delegate_success_code = From d348c202c3b88cbd66ef534e64388899f66f4de0 Mon Sep 17 00:00:00 2001 From: Stat1cV01D <1160915+Stat1cV01D@users.noreply.github.com> Date: Fri, 25 Jun 2021 20:49:24 +0700 Subject: [PATCH 3/4] Add dynalo dependency notice --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 49cb83b1..c4cc6487 100644 --- a/README.md +++ b/README.md @@ -112,4 +112,6 @@ Gmod.NET is making use of or borrows code from the following projects: 4. [Libsodium](http://libsodium.org) by [Frank Denis](https://github.com/jedisct1) (ISC License) +5. [dynalo](https://github.com/Stat1cV01D/dynalo) originally by [maddouri](https://github.com/maddouri/dynalo) (MIT License) + See other copyright notices in the NOTICE file. From 657f3a40b068b79f10c841d808d90699a4df3cb3 Mon Sep 17 00:00:00 2001 From: Stat1cV01D <1160915+Stat1cV01D@users.noreply.github.com> Date: Fri, 25 Jun 2021 21:03:07 +0700 Subject: [PATCH 4/4] Make CI checkout with submodules --- .github/workflows/ci.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf4e380e..fe3a04df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2.0.0 + uses: actions/checkout@v2 + with: + submodules: 'true' - name: Setup .NET Core SDK uses: actions/setup-dotnet@v1.7.2 @@ -130,7 +132,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2.0.0 + uses: actions/checkout@v2 + with: + submodules: 'true' - name: Setup .NET Core SDK uses: actions/setup-dotnet@v1.7.2 @@ -232,7 +236,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2.0.0 + uses: actions/checkout@v2 + with: + submodules: 'true' - name: Setup .NET Core SDK uses: actions/setup-dotnet@v1.7.2 @@ -298,7 +304,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2.0.0 + uses: actions/checkout@v2 + with: + submodules: 'true' - name: Setup .NET Core SDK uses: actions/setup-dotnet@v1.7.2