Skip to content

Commit 75eb9ba

Browse files
committed
chore: optimize cross-platform compatibility
1 parent 4858019 commit 75eb9ba

File tree

6 files changed

+288
-38
lines changed

6 files changed

+288
-38
lines changed

native/CMakeLists.txt

Lines changed: 213 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,162 @@ set(CMAKE_C_STANDARD 11)
2020
#SET_OPTION(Plugin.SymbolResolver ON)
2121
#add_subdirectory(../libs/Dobby dobby)
2222

23-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-type -Wno-invalid-offsetof")
24-
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
25-
SET(CLANG_CXX_EXTRA_OPT "-Werror=unknown-warning-option -Werror=format-invalid-specifier -Werror=call-to-pure-virtual-from-ctor-dtor")
26-
SET(CLANG_C_EXTRA_OPT "-Werror=format-invalid-specifier")
23+
# =============================================================================
24+
# Cross-Platform Compiler Configuration
25+
# =============================================================================
26+
27+
# Detect compiler and set appropriate flags
28+
if (MSVC)
29+
# Microsoft Visual C++ Compiler
30+
message(STATUS "Configuring for MSVC compiler")
31+
32+
# Warning configuration for MSVC
33+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") # High warning level
34+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we4716") # Error on missing return (equivalent to -Werror=return-type)
35+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996") # Disable deprecated warnings (similar to -Wno-invalid-offsetof)
36+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4068") # Disable unknown pragma warnings
37+
38+
# Frame pointer configuration
39+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Oy-") # Keep frame pointers (equivalent to -fno-omit-frame-pointer)
40+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Oy-")
41+
42+
# Runtime library configuration
43+
if (CMAKE_BUILD_TYPE MATCHES Debug)
44+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MTd") # Static debug runtime
45+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MTd")
46+
else ()
47+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MT") # Static release runtime
48+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MT")
49+
endif ()
50+
51+
# Optimization flags for release builds
52+
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
53+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2") # Optimize for speed
54+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GL") # Whole program optimization
55+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LTCG") # Link-time code generation
56+
endif ()
57+
58+
# MSVC-specific definitions
59+
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Disable CRT security warnings
60+
add_definitions(-DNOMINMAX) # Prevent Windows.h from defining min/max macros
61+
add_definitions(-DWIN32_LEAN_AND_MEAN) # Reduce Windows header bloat
62+
63+
# Symbol visibility (MSVC uses __declspec instead of -fvisibility)
64+
# We'll handle exports manually to avoid auto-generation issues
65+
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF)
66+
67+
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
68+
# Clang Compiler
69+
message(STATUS "Configuring for Clang compiler")
70+
71+
# Clang-specific warning flags
72+
set(CLANG_CXX_EXTRA_OPT "-Werror=unknown-warning-option -Werror=format-invalid-specifier -Werror=call-to-pure-virtual-from-ctor-dtor")
73+
set(CLANG_C_EXTRA_OPT "-Werror=format-invalid-specifier")
74+
75+
# Base warning and error flags
76+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-type -Wno-invalid-offsetof")
77+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLANG_CXX_EXTRA_OPT}")
78+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CLANG_C_EXTRA_OPT}")
79+
80+
# Position Independent Code (not needed on Windows)
81+
if (NOT WIN32)
82+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
83+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
84+
endif ()
85+
86+
# Frame pointer configuration
87+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer")
88+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
89+
90+
# Virtual destructor warnings
91+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=non-virtual-dtor -Werror=delete-non-virtual-dtor")
92+
93+
# Symbol visibility
94+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=protected")
95+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=protected")
96+
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
97+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
98+
endif ()
99+
100+
# Static linking of standard libraries (Unix/Linux only)
101+
if (UNIX AND NOT APPLE)
102+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
103+
endif ()
104+
105+
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
106+
# GCC Compiler
107+
message(STATUS "Configuring for GCC compiler")
108+
109+
# Base warning and error flags
110+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-type -Wno-invalid-offsetof")
111+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=return-type")
112+
113+
# Position Independent Code (not needed on Windows)
114+
if (NOT WIN32)
115+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
116+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
117+
endif ()
118+
119+
# Frame pointer configuration
120+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer")
121+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
122+
123+
# Virtual destructor warnings
124+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=non-virtual-dtor -Werror=delete-non-virtual-dtor")
125+
126+
# Symbol visibility
127+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=protected")
128+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=protected")
129+
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
130+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
131+
endif ()
132+
133+
# Static linking of standard libraries (Unix/Linux only)
134+
if (UNIX AND NOT APPLE)
135+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
136+
endif ()
137+
27138
else ()
28-
SET(CLANG_CXX_EXTRA_OPT "")
29-
SET(CLANG_C_EXTRA_OPT "")
139+
# Unknown compiler - use minimal configuration
140+
message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}. Using minimal configuration.")
141+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer")
142+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
30143
endif ()
31144

32-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLANG_CXX_EXTRA_OPT} -fPIC -Werror=return-type -Wno-invalid-offsetof")
33-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CLANG_C_EXTRA_OPT} -fPIC -Werror=return-type")
145+
# =============================================================================
146+
# Platform-Specific Linker Configuration
147+
# =============================================================================
34148

35-
# default visibility protected, but for release build, inline hidden for c++ code to reduce binary size
36-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=protected")
37-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=protected")
38-
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
39-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
40-
endif ()
149+
if (UNIX AND NOT APPLE)
150+
# Linux-specific linker flags
151+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
152+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-allow-shlib-undefined,--no-undefined")
153+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs,-z,now,-z,relro")
41154

42-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384 -Wl,--no-allow-shlib-undefined,--no-undefined -Wl,-z,defs,-z,now,-z,relro")
155+
# Garbage collection for release builds
156+
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
157+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
158+
endif ()
43159

44-
# if we are releasing, ask linker to reduce the size of the binary, eg. remove unused code
45-
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
46-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
47-
endif ()
160+
elseif (APPLE)
161+
# macOS-specific linker flags
162+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error")
48163

49-
# add -fno-omit-frame-pointer -Werror=non-virtual-dtor -Werror=delete-non-virtual-dtor
50-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -Werror=non-virtual-dtor -Werror=delete-non-virtual-dtor")
51-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
164+
# Garbage collection for release builds
165+
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
166+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
167+
endif ()
52168

53-
# prefer static linking libstdc++ and libgcc
54-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
169+
elseif (WIN32)
170+
# Windows-specific linker flags
171+
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
172+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /OPT:REF /OPT:ICF")
173+
endif ()
174+
endif ()
175+
176+
# =============================================================================
177+
# External Dependencies
178+
# =============================================================================
55179

56180
add_subdirectory(../libs/fmt fmt)
57181

@@ -62,6 +186,10 @@ target_compile_definitions(fmt-header-only INTERFACE FMT_STATIC_THOUSANDS_SEPARA
62186
# target_compile_options(dobby PRIVATE -fomit-frame-pointer)
63187
#endif ()
64188

189+
# =============================================================================
190+
# Target Definition
191+
# =============================================================================
192+
65193
add_library(
66194
jvmplant
67195
SHARED
@@ -83,5 +211,65 @@ target_link_libraries(
83211
jvmplant
84212
PRIVATE
85213
fmt-header-only
86-
# dobby
214+
# dobby
87215
)
216+
217+
# =============================================================================
218+
# Platform-Specific Library Dependencies
219+
# =============================================================================
220+
221+
if (WIN32)
222+
# Windows-specific libraries
223+
target_link_libraries(jvmplant PRIVATE
224+
kernel32
225+
user32
226+
advapi32
227+
shell32
228+
)
229+
elseif (UNIX)
230+
# Unix-specific libraries
231+
target_link_libraries(jvmplant PRIVATE
232+
${CMAKE_DL_LIBS} # Dynamic loading library (libdl)
233+
pthread # POSIX threads
234+
)
235+
endif ()
236+
237+
# =============================================================================
238+
# Compiler-Specific Target Properties
239+
# =============================================================================
240+
241+
if (MSVC)
242+
# MSVC-specific target properties
243+
set_target_properties(jvmplant PROPERTIES
244+
COMPILE_PDB_NAME "jvmplant"
245+
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
246+
# Disable automatic DLL export generation that's causing issues
247+
WINDOWS_EXPORT_ALL_SYMBOLS OFF
248+
)
249+
250+
# Generate debug information for release builds
251+
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
252+
set_target_properties(jvmplant PROPERTIES
253+
LINK_FLAGS "/DEBUG /PDBALTPATH:%_PDB%"
254+
)
255+
endif ()
256+
endif ()
257+
258+
# Set output directory for all configurations
259+
set_target_properties(jvmplant PROPERTIES
260+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
261+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
262+
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
263+
)
264+
265+
# =============================================================================
266+
# Build Information
267+
# =============================================================================
268+
269+
message(STATUS "Build configuration:")
270+
message(STATUS " Compiler: ${CMAKE_CXX_COMPILER_ID}")
271+
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
272+
message(STATUS " C++ Standard: ${CMAKE_CXX_STANDARD}")
273+
message(STATUS " C Standard: ${CMAKE_C_STANDARD}")
274+
message(STATUS " Platform: ${CMAKE_SYSTEM_NAME}")
275+
message(STATUS " Architecture: ${CMAKE_SYSTEM_PROCESSOR}")

native/include/jni.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <stdarg.h>
2727
#include <stdint.h>
28+
#include "platform_compat.h"
2829

2930
/* Primitive types that match up with Java equivalents. */
3031
typedef uint8_t jboolean; /* unsigned 8 bits */
@@ -771,7 +772,7 @@ struct _JNIEnv {
771772
CALL_STATIC_TYPE(jfloat, Float)
772773
CALL_STATIC_TYPE(jdouble, Double)
773774

774-
__attribute__((no_stack_protector))
775+
JVMPLANT_ATTRIBUTE_NO_STACK_PROTECTOR
775776
void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
776777
{
777778
va_list args;
@@ -1103,7 +1104,7 @@ jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
11031104
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
11041105

11051106
#define JNIIMPORT
1106-
#define JNIEXPORT __attribute__ ((visibility ("default")))
1107+
#define JNIEXPORT JVMPLANT_ATTRIBUTE_VISIBILITY_DEFAULT
11071108
#define JNICALL
11081109

11091110
/*

native/include/platform_compat.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#pragma once
2+
3+
// Cross-platform compatibility macros for attributes and compiler-specific features
4+
5+
#ifdef _MSC_VER
6+
// Microsoft Visual C++ Compiler
7+
#define JVMPLANT_ATTRIBUTE_NO_STACK_PROTECTOR
8+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_DEFAULT __declspec(dllexport)
9+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_HIDDEN
10+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_PROTECTED __declspec(dllexport)
11+
12+
// MSVC doesn't have __attribute__ syntax, so we define empty macros
13+
#define __attribute__(x)
14+
15+
// MSVC-specific pragmas for equivalent functionality
16+
#define JVMPLANT_PRAGMA_PUSH_WARNINGS __pragma(warning(push))
17+
#define JVMPLANT_PRAGMA_POP_WARNINGS __pragma(warning(pop))
18+
#define JVMPLANT_PRAGMA_DISABLE_WARNING(num) __pragma(warning(disable : num))
19+
20+
#elif defined(__GNUC__) || defined(__clang__)
21+
// GCC or Clang Compiler
22+
#define JVMPLANT_ATTRIBUTE_NO_STACK_PROTECTOR __attribute__((no_stack_protector))
23+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_DEFAULT __attribute__((visibility("default")))
24+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
25+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_PROTECTED __attribute__((visibility("protected")))
26+
27+
// GCC/Clang pragma support
28+
#define JVMPLANT_PRAGMA_PUSH_WARNINGS _Pragma("GCC diagnostic push")
29+
#define JVMPLANT_PRAGMA_POP_WARNINGS _Pragma("GCC diagnostic pop")
30+
#define JVMPLANT_PRAGMA_DISABLE_WARNING(name) _Pragma("GCC diagnostic ignored \"" #name "\"")
31+
32+
#else
33+
// Unknown compiler - define empty macros
34+
#define JVMPLANT_ATTRIBUTE_NO_STACK_PROTECTOR
35+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_DEFAULT
36+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_HIDDEN
37+
#define JVMPLANT_ATTRIBUTE_VISIBILITY_PROTECTED
38+
#define __attribute__(x)
39+
40+
#define JVMPLANT_PRAGMA_PUSH_WARNINGS
41+
#define JVMPLANT_PRAGMA_POP_WARNINGS
42+
#define JVMPLANT_PRAGMA_DISABLE_WARNING(x)
43+
#endif

native/openjdkvm/openjdkvm_hook_impl.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
#include <ranges>
1717
#include <unordered_map>
1818

19+
#include "platform_compat.h"
20+
1921
// for dlopen, dlsym, dlclose, LoadLibraryW, GetProcAddress, FreeLibrary
20-
#ifdef __WIN32
22+
#ifdef _WIN32
2123
#include <windows.h>
2224
#else
2325
#include <dlfcn.h>
@@ -44,7 +46,11 @@ class JObjectHolder {
4446
// failed to create global ref
4547
env->ExceptionDescribe();
4648
env->FatalError("Failed to create global reference");
49+
#ifdef _MSC_VER
50+
__assume(0);
51+
#else
4752
__builtin_unreachable();
53+
#endif
4854
}
4955
}
5056
}
@@ -169,7 +175,7 @@ static bool InitOpenJdkVmHookInfoLocked(JNIEnv* env, std::string& errorMsg) {
169175

170176
// find address of bytecode verification flags
171177
void* libjvmHandle = nullptr;
172-
#ifdef __WIN32
178+
#ifdef _WIN32
173179
libjvmHandle = GetModuleHandleW(L"jvm.dll");
174180
if (libjvmHandle == nullptr) {
175181
errorMsg = fmt::format("Failed to get handle of jvm.dll: {}", GetLastError());
@@ -193,7 +199,7 @@ static bool InitOpenJdkVmHookInfoLocked(JNIEnv* env, std::string& errorMsg) {
193199
return addr;
194200
};
195201
std::unique_ptr<void, std::function<void(void*)>> libjvmCloser(libjvmHandle, [](void* handle) {
196-
#ifdef __WIN32
202+
#ifdef _WIN32
197203
/* GetModuleHandleW does not need to be freed */
198204
#else
199205
dlclose(handle);

0 commit comments

Comments
 (0)