NeuronRobotics / nrjavaserial

A Java Serial Port system. This is a fork of the RXTX project that uses in jar loading of the native code.
Other
344 stars 142 forks source link

Compile the Windows natives with MSVC #206

Open MrDOS opened 3 years ago

MrDOS commented 3 years ago

The 32- and 64-bit Windows native libraries are 355 KB and 396 KB, respectively. This is pretty absurd; the native libraries for all other platforms are in the 60-90 KB range. I suspect the Windows libraries would be much smaller if they were compiled by MSVC instead of GCC.

fwolter commented 3 years ago

I noticed that too when dealing with the libgcc_s_seh-1 dependency. Maybe it's (also) this Structured Exception Handling support which lets the dll grow. I was wondering why a C program needs SEH at all. But I found no way to disable it.

MrDOS commented 3 years ago

After searching-and-replacing all instances of the WIN32 symbol with _WIN32, and replacing #ifndef _TIMESPEC_DEFINED in windows/win32termios.h with #if !defined _TIMESPEC_DEFINED && defined _CRT_NO_TIME_T, the objects compile and link with the VS 2019 toolchain:

C:\nrjavaserial\src\main\c>mkdir build\windows\x86_64
C:\nrjavaserial\src\main\c>cl /I "C:\Program Files\AdoptOpenJDK\jdk-8.0.252.09-hotspot\include" /I include /I include\target /I include\windows /I include\windows\win32 /Fobuild\windows\x86_64\fuserImp.obj /c src\fuserImp.c
C:\nrjavaserial\src\main\c>cl /I "C:\Program Files\AdoptOpenJDK\jdk-8.0.252.09-hotspot\include" /I include /I include\target /I include\windows /I include\windows\win32 /Fobuild\windows\x86_64\SerialImp.obj /c src\SerialImp.c
C:\nrjavaserial\src\main\c>cl /I "C:\Program Files\AdoptOpenJDK\jdk-8.0.252.09-hotspot\include" /I include /I include\target /I include\windows /I include\windows\win32 /Fobuild\windows\x86_64\termios.obj /c src\windows\termios.c
C:\nrjavaserial\src\main\c>mkdir resources\native\windows\x86_64
C:\nrjavaserial\src\main\c>cl /LD /Feresources\native\windows\x86_64\libNRJavaSerial.dll build\windows\x86_64\fuserImp.obj build\windows\x86_64\SerialImp.obj build\windows\x86_64\termios.obj
C:\nrjavaserial\src\main\c>dir resources\native\windows\x86_64
...
2021-01-21  18:09           199,680 libNRJavaSerial.dll

None of the functions are marked with __declspec(dllexport), so without having tried it, I have no expectation that the produced DLL would actually function. And 195 KB isn't as much of an improvement as I'd hoped for. But still, I think this is the right idea.

MrDOS commented 3 years ago

Actually, all of the JNI function declarations in src/main/c/include/target/*.h invoke the JNIEXPORT and JNICALL macros:

JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_open
  (JNIEnv *, jobject, jstring);

...which are defined in $JAVA_HOME/include/win32/jni_md.h as __declspec(dllexport) and __stdcall, respectively. So all the JNI functions are correctly marked for export from the DLL. I fired up a test and the JVM seems to load the library and call into it okay, although I haven't passed any data through it yet.