[education/rkward] rkward/rbackend: Fix compilation on Windows

Thomas Friedrichsmeier null at kde.org
Fri May 10 17:04:24 BST 2024


Git commit ba2930659dea8cb633e7629224e3c634eb57ea77 by Thomas Friedrichsmeier.
Committed on 05/05/2024 at 12:37.
Pushed by tfry into branch 'master'.

Fix compilation on Windows

M  +29   -3    rkward/rbackend/rkrapi.cpp
M  +3    -1    rkward/rbackend/rkrapi.h
M  +5    -5    rkward/rbackend/rkrbackend.cpp
M  +3    -11   rkward/rbackend/rkrbackendprotocol_backend.cpp

https://invent.kde.org/education/rkward/-/commit/ba2930659dea8cb633e7629224e3c634eb57ea77

diff --git a/rkward/rbackend/rkrapi.cpp b/rkward/rbackend/rkrapi.cpp
index 50a6ec515..9918fe8a7 100644
--- a/rkward/rbackend/rkrapi.cpp
+++ b/rkward/rbackend/rkrapi.cpp
@@ -7,20 +7,46 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "rkrapi.h"
 
+#ifdef Q_OS_WIN
+#include <windows.h>
+#else
 #include <dlfcn.h>
+#endif
 
 #include "../debug.h"
 
-void RFn::init(void *dllinfo) {
-	// TODO: This is just proof/test of concept code!
+void RFn::init(const char* libname) {
+#if defined RK_DLOPEN_LIBRSO
+//#if defined(RTLD_DEEPBIND)  // causes hard fail on suse tumbleweed 05/2024
+//	RK_DEBUG(RBACKEND, DL_DEBUG, "Now loading R lib, dynamically (deepbind)");
+//	RFn::init(dlopen(RLIBNAME, RTLD_NOW | RTLD_DEEPBIND));
+//#else
+	RK_DEBUG(RBACKEND, DL_DEBUG, "Now loading R lib, dynamically (local)");
+#if defined(Q_OS_WIN)
+	auto dllinfo = LoadLibraryA(libname);
+#else
+	auto dllinfo = dlopen(libname, RTLD_NOW | RTLD_LOCAL);
+#endif
+	if (!dllinfo) {
+		RK_DEBUG(RBACKEND, DL_ERROR, "Failure loading R lib from '%s'", libname);
+	}
+//#endif
+
 	auto rfn = new RFn(); // we need a dummy object, even if we are only interested in the static members
 	auto meta = rfn->metaObject();
 	RK_DEBUG(RBACKEND, DL_DEBUG, "Loading %d symbols from R lib %p", meta->propertyCount() - meta->propertyOffset(), dllinfo);
 	for (int i = meta->propertyOffset(); i < meta->propertyCount(); ++i) {
 		auto prop = meta->property(i);
 		auto name = prop.name();
+#if defined(Q_OS_WIN)
+		auto symb = GetProcAddress(dllinfo, name);
+#else
 		auto symb = dlsym(dllinfo, name);
+#endif
 		RK_DEBUG(RBACKEND, DL_DEBUG, "Lookup of symbol %s in %p: %p", name, dllinfo, symb);
-		prop.write(rfn, QVariant::fromValue(symb)); // NOTE: Qt refuses to write nullptr as value, but that's already the initial value of each member
+		prop.write(rfn, QVariant::fromValue((void*) symb)); // NOTE: Qt refuses to write nullptr as value, but that's already the initial value of each member
 	}
+#else
+	RK_DEBUG(RBACKEND, DL_DEBUG, "R lib already linked");
+#endif
 }
diff --git a/rkward/rbackend/rkrapi.h b/rkward/rbackend/rkrapi.h
index 7693e2cb7..f67038060 100644
--- a/rkward/rbackend/rkrapi.h
+++ b/rkward/rbackend/rkrapi.h
@@ -280,6 +280,8 @@ IMPORT_R_API(R_DefParams);
 IMPORT_R_API(R_SetParams);
 IMPORT_R_API(R_setStartTime);
 IMPORT_R_API(R_set_command_line_arguments);
+IMPORT_R_API(getRUser);
+IMPORT_R_API(get_R_HOME);
 IMPORT_R_API(UserBreak);
 #endif
 
@@ -289,7 +291,7 @@ IMPORT_R_API(R_GE_maskType);
 #endif
 
 public:
-	static void init(void* dllinfo);
+	static void init(const char* dllname);
 };
 
 #endif
diff --git a/rkward/rbackend/rkrbackend.cpp b/rkward/rbackend/rkrbackend.cpp
index a7a5c07c6..372bcc450 100644
--- a/rkward/rbackend/rkrbackend.cpp
+++ b/rkward/rbackend/rkrbackend.cpp
@@ -71,15 +71,15 @@ void RK_scheduleIntr () {
 	RK_DEBUG (RBACKEND, DL_DEBUG, "interrupt scheduled");
 	RKRBackend::repl_status.interrupted = true;
 #ifdef Q_OS_WIN
-	UserBreak = 1;
+	ROb(UserBreak) = 1;
 #else
-	RKSignalSupport::callOldSigIntHandler ();
+	RKSignalSupport::callOldSigIntHandler();
 #endif
 }
 
 void RK_doIntr () {
 	RK_scheduleIntr ();
-	RFn::R_CheckUserInterrupt ();
+	RFn::R_CheckUserInterrupt();
 }
 
 void RKRBackend::scheduleInterrupt () {
@@ -776,8 +776,8 @@ void RKRBackend::setupCallbacks () {
 	RFn::R_DefParams(&RK_R_Params);
 
 // IMPORTANT: see also the #ifndef QS_WS_WIN-portion!
-	RK_R_Params.rhome = get_R_HOME ();
-	RK_R_Params.home = getRUser ();
+	RK_R_Params.rhome = RFn::get_R_HOME();
+	RK_R_Params.home = RFn::getRUser();
 	RK_R_Params.CharacterMode = RGui;
 	RK_R_Params.ShowMessage = RShowMessage;
 #if R_VERSION < R_Version(4, 2, 0)
diff --git a/rkward/rbackend/rkrbackendprotocol_backend.cpp b/rkward/rbackend/rkrbackendprotocol_backend.cpp
index 2314c3032..8f4a7d721 100644
--- a/rkward/rbackend/rkrbackendprotocol_backend.cpp
+++ b/rkward/rbackend/rkrbackendprotocol_backend.cpp
@@ -20,7 +20,6 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include <QUrl>
 
 #include <iostream>
-#include <dlfcn.h>
 
 #include "rkbackendtransmitter.h"
 #include "rktransmitter.h"
@@ -113,26 +112,19 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 		// TODO: Should rather take the libname from CMake
 		// maybe we also want to accept an absolute path specified on command line from the frontend
-#ifdef RK_DLOPEN_LIBRSO
 #ifdef Q_OS_WIN
 #	define RLIBNAME "R.dll"
 #else
 #	define RLIBNAME "libR.so"
 #endif
-//#if defined(RTLD_DEEPBIND)
-//		RK_DEBUG(RBACKEND, DL_DEBUG, "Now loading R lib, dynamically (deepbind)");
-//		RFn::init(dlopen(RLIBNAME, RTLD_NOW | RTLD_DEEPBIND));
-//#else
-		RK_DEBUG(RBACKEND, DL_DEBUG, "Now loading R lib, dynamically (local)");
-		RFn::init(dlopen(RLIBNAME, RTLD_NOW | RTLD_LOCAL));
-//#endif
-#endif
+		RFn::init(RLIBNAME);
+
 		RKRBackendTransmitter transmitter (servername, token);
 		RKRBackendProtocolBackend::p_transmitter = &transmitter;
 		RKRBackendProtocolBackend backend (data_dir, rkd_server_name);
 		transmitter.start ();
 		RKRBackend::this_pointer->run (locale_dir);
-		// NOTE:: Since some unknown version of R (4.3.0 at the latest, but probabably much earlier), run_Rmainloop() does not return, it will
+		// NOTE:: Since some unknown version of R (4.3.0 at the latest, but probably much earlier), run_Rmainloop() does not return, it will
 		//        eventually exit, instead.
 		RKRBackendProtocolBackend::doExit();
 	}



More information about the rkward-tracker mailing list