From 8039ae1b900ff7a00d2edca24540af378ca899b7 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 1 Feb 2025 15:13:13 +0100 Subject: [PATCH] build: Make ImHex fully compile with MSVC and Clang CL This does NOT make ImHex work yet. However it can now be compiled --- cmake/build_helpers.cmake | 2 +- lib/external/libwolv | 2 +- lib/external/pattern_language | 2 +- lib/libimhex/CMakeLists.txt | 1 + .../include/hex/api/workspace_manager.hpp | 7 ++--- lib/libimhex/source/api/workspace_manager.cpp | 14 +++++++--- lib/third_party/imgui/CMakeLists.txt | 7 ++++- .../include/imgui_impl_opengl3_loader.h | 8 ++++++ .../imgui/imgui/include/imconfig.h | 16 ++++++++++++ .../imgui/imnodes/include/imnodes_internal.h | 2 +- .../imgui/imnodes/source/imnodes.cpp | 2 +- main/forwarder/CMakeLists.txt | 8 +++++- main/gui/CMakeLists.txt | 4 +++ main/gui/source/messaging/common.cpp | 2 +- main/gui/source/stacktrace.cpp | 21 ++++++++++----- main/gui/source/window/win_window.cpp | 26 +++++++++++++------ .../content/views/view_data_processor.hpp | 2 +- .../builtin/source/content/achievements.cpp | 2 +- 18 files changed, 95 insertions(+), 33 deletions(-) diff --git a/cmake/build_helpers.cmake b/cmake/build_helpers.cmake index c49917401..5c9008adc 100644 --- a/cmake/build_helpers.cmake +++ b/cmake/build_helpers.cmake @@ -585,7 +585,7 @@ macro(setupCompilerFlags target) # Disable some warnings set(IMHEX_C_CXX_FLAGS "-Wno-array-bounds -Wno-deprecated-declarations -Wno-unknown-pragmas") elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set(IMHEX_CXX_FLAGS "/EHsc") + set(IMHEX_CXX_FLAGS "/DWIN32 /D_WINDOWS /GR /EHsc") endif() if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") diff --git a/lib/external/libwolv b/lib/external/libwolv index 9d38dd5b4..ba8fb9c84 160000 --- a/lib/external/libwolv +++ b/lib/external/libwolv @@ -1 +1 @@ -Subproject commit 9d38dd5b48e429d4f1d7c71dc2684a6ab42b6f92 +Subproject commit ba8fb9c842b218fdf747df64940e4467421fcc17 diff --git a/lib/external/pattern_language b/lib/external/pattern_language index 82ce31275..506b867e5 160000 --- a/lib/external/pattern_language +++ b/lib/external/pattern_language @@ -1 +1 @@ -Subproject commit 82ce31275b124082fc2a32e83f7ac3e122ffadda +Subproject commit 506b867e512f1cbf5ab21f92a7250e2c20b52f94 diff --git a/lib/libimhex/CMakeLists.txt b/lib/libimhex/CMakeLists.txt index f505d9d93..0e3b1d0af 100644 --- a/lib/libimhex/CMakeLists.txt +++ b/lib/libimhex/CMakeLists.txt @@ -138,6 +138,7 @@ if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD) target_link_options(libimhex PRIVATE -Wl,--export-all-symbols) endif() target_link_libraries(libimhex PRIVATE Netapi32.lib) + target_compile_definitions(libimhex PRIVATE EXPORT_SYMBOLS=1) elseif (APPLE) find_library(FOUNDATION NAMES Foundation) target_link_libraries(libimhex PUBLIC ${FOUNDATION}) diff --git a/lib/libimhex/include/hex/api/workspace_manager.hpp b/lib/libimhex/include/hex/api/workspace_manager.hpp index 608df2d9c..c7900a985 100644 --- a/lib/libimhex/include/hex/api/workspace_manager.hpp +++ b/lib/libimhex/include/hex/api/workspace_manager.hpp @@ -24,8 +24,8 @@ namespace hex { static void removeWorkspace(const std::string &name); - static const auto& getWorkspaces() { return *s_workspaces; } - static const auto& getCurrentWorkspace() { return s_currentWorkspace; } + static const std::map& getWorkspaces(); + static const std::map::iterator& getCurrentWorkspace(); static void reset(); static void reload(); @@ -34,9 +34,6 @@ namespace hex { private: WorkspaceManager() = default; - - static AutoReset> s_workspaces; - static decltype(s_workspaces)::Type::iterator s_currentWorkspace, s_previousWorkspace, s_workspaceToRemove; }; } \ No newline at end of file diff --git a/lib/libimhex/source/api/workspace_manager.cpp b/lib/libimhex/source/api/workspace_manager.cpp index 655e8dd31..d276c13e2 100644 --- a/lib/libimhex/source/api/workspace_manager.cpp +++ b/lib/libimhex/source/api/workspace_manager.cpp @@ -14,10 +14,10 @@ namespace hex { - AutoReset> WorkspaceManager::s_workspaces; - decltype(WorkspaceManager::s_workspaces)::Type::iterator WorkspaceManager::s_currentWorkspace = s_workspaces->end(); - decltype(WorkspaceManager::s_workspaces)::Type::iterator WorkspaceManager::s_previousWorkspace = s_workspaces->end(); - decltype(WorkspaceManager::s_workspaces)::Type::iterator WorkspaceManager::s_workspaceToRemove = s_workspaces->end(); + AutoReset> s_workspaces; + decltype(s_workspaces)::Type::iterator s_currentWorkspace = s_workspaces->end(); + decltype(s_workspaces)::Type::iterator s_previousWorkspace = s_workspaces->end(); + decltype(s_workspaces)::Type::iterator s_workspaceToRemove = s_workspaces->end(); void WorkspaceManager::createWorkspace(const std::string& name, const std::string &layout) { s_currentWorkspace = s_workspaces->insert_or_assign(name, Workspace { @@ -174,7 +174,13 @@ namespace hex { } } + const std::map& WorkspaceManager::getWorkspaces() { + return *s_workspaces; + } + const std::map::iterator& WorkspaceManager::getCurrentWorkspace() { + return s_currentWorkspace; + } } diff --git a/lib/third_party/imgui/CMakeLists.txt b/lib/third_party/imgui/CMakeLists.txt index b29e9ced2..91078ffdc 100644 --- a/lib/third_party/imgui/CMakeLists.txt +++ b/lib/third_party/imgui/CMakeLists.txt @@ -13,4 +13,9 @@ add_subdirectory(imnodes) add_subdirectory(backend) add_subdirectory(ColorTextEditor) -set(IMGUI_LIBRARIES imgui_imgui imgui_cimgui imgui_implot imgui_implot3d imgui_imnodes imgui_backend imgui_color_text_editor PARENT_SCOPE) \ No newline at end of file +set(IMGUI_LIBRARIES imgui_imgui imgui_cimgui imgui_implot imgui_implot3d imgui_imnodes imgui_backend imgui_color_text_editor) +set(IMGUI_LIBRARIES ${IMGUI_LIBRARIES} PARENT_SCOPE) + +foreach (LIBRARY IN LISTS IMGUI_LIBRARIES) + target_compile_definitions(${LIBRARY} PRIVATE EXPORT_SYMBOLS=1) +endforeach () \ No newline at end of file diff --git a/lib/third_party/imgui/backend/include/imgui_impl_opengl3_loader.h b/lib/third_party/imgui/backend/include/imgui_impl_opengl3_loader.h index fc8ef19b8..913384c01 100644 --- a/lib/third_party/imgui/backend/include/imgui_impl_opengl3_loader.h +++ b/lib/third_party/imgui/backend/include/imgui_impl_opengl3_loader.h @@ -5011,8 +5011,16 @@ typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, #endif #ifndef GL3W_API +#ifdef _MSC_VER +#if EXPORT_SYMBOLS == 1 +#define GL3W_API __declspec(dllexport) +#else +#define GL3W_API __declspec(dllimport) +#endif +#else #define GL3W_API #endif +#endif #ifndef __gl_h_ #define __gl_h_ diff --git a/lib/third_party/imgui/imgui/include/imconfig.h b/lib/third_party/imgui/imgui/include/imconfig.h index 5efa45a16..f43d905f0 100644 --- a/lib/third_party/imgui/imgui/include/imconfig.h +++ b/lib/third_party/imgui/imgui/include/imconfig.h @@ -32,6 +32,22 @@ namespace hex::log::impl { //#define IMGUI_API __declspec( dllexport ) //#define IMGUI_API __declspec( dllimport ) +#if EXPORT_SYMBOLS == 1 + #define IMGUI_API __declspec(dllexport) + #define IMGUI_IMPL_API __declspec(dllexport) + #define IMPLOT_API __declspec(dllexport) + #define IMPLOT_IMPL_API __declspec(dllexport) + #define IMPLOT3D_API __declspec(dllexport) + #define IMPLOT3D_IMPL_API __declspec(dllexport) +#else + #define IMGUI_API __declspec(dllimport) + #define IMGUI_IMPL_API __declspec(dllimport) + #define IMPLOT_API __declspec(dllimport) + #define IMPLOT_IMPL_API __declspec(dllimport) + #define IMPLOT3D_API __declspec(dllimport) + #define IMPLOT3D_IMPL_API __declspec(dllimport) +#endif + //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions. diff --git a/lib/third_party/imgui/imnodes/include/imnodes_internal.h b/lib/third_party/imgui/imnodes/include/imnodes_internal.h index 593ab4997..3cffdf642 100644 --- a/lib/third_party/imgui/imnodes/include/imnodes_internal.h +++ b/lib/third_party/imgui/imnodes/include/imnodes_internal.h @@ -17,7 +17,7 @@ struct ImNodesContext; -extern ImNodesContext* GImNodes; +IMGUI_API extern ImNodesContext* GImNodes; // [SECTION] internal enums diff --git a/lib/third_party/imgui/imnodes/source/imnodes.cpp b/lib/third_party/imgui/imnodes/source/imnodes.cpp index 7689cb10b..a08a77927 100644 --- a/lib/third_party/imgui/imnodes/source/imnodes.cpp +++ b/lib/third_party/imgui/imnodes/source/imnodes.cpp @@ -31,7 +31,7 @@ #define sscanf sscanf_s #endif -ImNodesContext* GImNodes = NULL; +IMGUI_API ImNodesContext* GImNodes = NULL; namespace IMNODES_NAMESPACE { diff --git a/main/forwarder/CMakeLists.txt b/main/forwarder/CMakeLists.txt index 9a04c3517..a77947bd1 100644 --- a/main/forwarder/CMakeLists.txt +++ b/main/forwarder/CMakeLists.txt @@ -10,4 +10,10 @@ add_dependencies(imhex_all main-forwarder) set_target_properties(main-forwarder PROPERTIES OUTPUT_NAME "imhex" RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../.. -) \ No newline at end of file +) + +if (WIN32) + if (MSVC) + target_link_options(main-forwarder PRIVATE /MANIFEST:NO) + endif() +endif() \ No newline at end of file diff --git a/main/gui/CMakeLists.txt b/main/gui/CMakeLists.txt index 05b71c287..4723c5925 100644 --- a/main/gui/CMakeLists.txt +++ b/main/gui/CMakeLists.txt @@ -61,6 +61,10 @@ target_compile_definitions(main PRIVATE IMHEX_PROJECT_NAME="${PROJECT_NAME}") target_link_libraries(main PRIVATE libromfs-imhex libimhex libwolv ${LIBBACKTRACE_LIBRARIES} LLVMDemangle) if (WIN32) target_link_libraries(main PRIVATE usp10 wsock32 ws2_32 Dwmapi.lib Winmm.lib) + + if (MSVC) + target_link_options(main PRIVATE /MANIFEST:NO /ENTRY:mainCRTStartup) + endif() else () target_link_libraries(main PRIVATE pthread) diff --git a/main/gui/source/messaging/common.cpp b/main/gui/source/messaging/common.cpp index d2ca48269..1e31ab33c 100644 --- a/main/gui/source/messaging/common.cpp +++ b/main/gui/source/messaging/common.cpp @@ -28,7 +28,7 @@ namespace hex::messaging { }); EventNativeMessageReceived::subscribe([](const std::vector &rawData) { - ssize_t nullIndex = -1; + i64 nullIndex = -1; auto messageData = reinterpret_cast(rawData.data()); size_t messageSize = rawData.size(); diff --git a/main/gui/source/stacktrace.cpp b/main/gui/source/stacktrace.cpp index cdd8d0838..a08109504 100644 --- a/main/gui/source/stacktrace.cpp +++ b/main/gui/source/stacktrace.cpp @@ -47,12 +47,21 @@ namespace { ZeroMemory(&stackFrame, sizeof(STACKFRAME64)); image = IMAGE_FILE_MACHINE_AMD64; - stackFrame.AddrPC.Offset = context.Rip; - stackFrame.AddrPC.Mode = AddrModeFlat; - stackFrame.AddrFrame.Offset = context.Rsp; - stackFrame.AddrFrame.Mode = AddrModeFlat; - stackFrame.AddrStack.Offset = context.Rsp; - stackFrame.AddrStack.Mode = AddrModeFlat; + #if defined(_X86_) + stackFrame.AddrPC.Offset = context.Eip; + stackFrame.AddrPC.Mode = AddrModeFlat; + stackFrame.AddrFrame.Offset = context.Esp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + stackFrame.AddrStack.Offset = context.Esp; + stackFrame.AddrStack.Mode = AddrModeFlat; + #else + stackFrame.AddrPC.Offset = context.Rip; + stackFrame.AddrPC.Mode = AddrModeFlat; + stackFrame.AddrFrame.Offset = context.Rsp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + stackFrame.AddrStack.Offset = context.Rsp; + stackFrame.AddrStack.Mode = AddrModeFlat; + #endif while (true) { if (StackWalk64( diff --git a/main/gui/source/window/win_window.cpp b/main/gui/source/window/win_window.cpp index 1901d9026..80c298ed6 100644 --- a/main/gui/source/window/win_window.cpp +++ b/main/gui/source/window/win_window.cpp @@ -32,12 +32,22 @@ #include #include #include + #include + + #if !defined(STDIN_FILENO) + #define STDIN_FILENO 0 + #endif + + #if !defined(STDOUT_FILENO) + #define STDOUT_FILENO 1 + #endif + + #if !defined(STDERR_FILENO) + #define STDERR_FILENO 2 + #endif namespace hex { - template - using WinUniquePtr = std::unique_ptr, BOOL(*)(T)>; - static LONG_PTR s_oldWndProc; static float s_titleBarHeight; static Microsoft::WRL::ComPtr s_taskbarList; @@ -418,10 +428,10 @@ namespace hex { DropManager() = default; virtual ~DropManager() = default; - ULONG AddRef() override { return 1; } - ULONG Release() override { return 0; } + ULONG STDMETHODCALLTYPE AddRef() override { return 1; } + ULONG STDMETHODCALLTYPE Release() override { return 0; } - HRESULT QueryInterface(REFIID riid, void **ppvObject) override { + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override { if (riid == IID_IDropTarget) { *ppvObject = this; @@ -578,14 +588,14 @@ namespace hex { EventThemeChanged::subscribe([this]{ auto hwnd = glfwGetWin32Window(m_window); - static auto user32Dll = WinUniquePtr(LoadLibraryA("user32.dll"), FreeLibrary); + static auto user32Dll = LoadLibraryA("user32.dll"); if (user32Dll != nullptr) { using SetWindowCompositionAttributeFunc = BOOL(WINAPI*)(HWND, WINCOMPATTRDATA*); const auto setWindowCompositionAttribute = reinterpret_cast( reinterpret_cast( - GetProcAddress(user32Dll.get(), "SetWindowCompositionAttribute") + GetProcAddress(user32Dll, "SetWindowCompositionAttribute") ) ); diff --git a/plugins/builtin/include/content/views/view_data_processor.hpp b/plugins/builtin/include/content/views/view_data_processor.hpp index fea747c21..b269b16fc 100644 --- a/plugins/builtin/include/content/views/view_data_processor.hpp +++ b/plugins/builtin/include/content/views/view_data_processor.hpp @@ -22,7 +22,7 @@ namespace hex::plugin::builtin { ImNodesContext *ctx = ImNodes::CreateContext(); ctx->Style = ImNodes::GetStyle(); ctx->Io = ImNodes::GetIO(); - ctx->AttributeFlagStack = GImNodes->AttributeFlagStack; + ctx->AttributeFlagStack = ImNodes::GetCurrentContext()->AttributeFlagStack; return ctx; }(), [](ImNodesContext *ptr) { diff --git a/plugins/builtin/source/content/achievements.cpp b/plugins/builtin/source/content/achievements.cpp index 68401f533..e36a57037 100644 --- a/plugins/builtin/source/content/achievements.cpp +++ b/plugins/builtin/source/content/achievements.cpp @@ -202,7 +202,7 @@ namespace hex::plugin::builtin { AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.modify_byte.name"); }); - EventPatchCreated::subscribe([](const u8 *, u8, PatchKind) { + EventPatchCreated::subscribe([](const u8 *, u64, PatchKind) { AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.create_patch.name"); });