[rkward] /: Somewhat experimental: Auto-lazy-install RKWard R package
Thomas Friedrichsmeier
null at kde.org
Mon Dec 30 13:43:13 GMT 2019
Git commit 8ecd26dcf2f42b748fcf2ca8259a8588e624e4d0 by Thomas Friedrichsmeier.
Committed on 30/12/2019 at 13:40.
Pushed by tfry into branch 'master'.
Somewhat experimental: Auto-lazy-install RKWard R package
This is so we can support switching to a different (compatible) R installation without re-installation of RKWard.
Needed on Mac, will be nice to have everywere.
Needs testing.
M +1 -1 doc/rkward/man-rkward.1.docbook
M +1 -0 rkward.kdev4
M +18 -3 rkward/rbackend/rkrbackend.cpp
M +12 -6 rkward/rbackend/rpackages/CMakeLists.txt
D +0 -36 rkward/rbackend/rpackages/rpackage_install.cmake.in
M +21 -1 rkward/rkward.cpp
https://commits.kde.org/rkward/8ecd26dcf2f42b748fcf2ca8259a8588e624e4d0
diff --git a/doc/rkward/man-rkward.1.docbook b/doc/rkward/man-rkward.1.docbook
index 8ff350ed..2b411c4a 100644
--- a/doc/rkward/man-rkward.1.docbook
+++ b/doc/rkward/man-rkward.1.docbook
@@ -80,7 +80,7 @@
</varlistentry>
<varlistentry>
<term><option>--r-executable</option> <replaceable>command</replaceable></term>
-<listitem><para>In the case of several R installations, specify the installation to use, ⪚ <filename>/usr/bin/R</filename>. Note that the &rkward; R library must have been installed to this installation of R, or startup will fail.</para></listitem>
+<listitem><para>In the case of several R installations, specify the installation to use, ⪚ <filename>/usr/bin/R</filename>. You can also use the string <replaceable>"auto"</replaceable>, in which case RKWard will try to find R at one of the known standard installation paths. <emphasis>NOTE</emphasis> that while RKWard will <emphasis>often</emphasis> work with newer versions of R, it will <emphasis>sometimes</emphasis> need to be re-compiled for that version, or it may be incompatible altogether.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--reuse</option></term>
diff --git a/rkward.kdev4 b/rkward.kdev4
index e9cfb7f4..a2b625a0 100644
--- a/rkward.kdev4
+++ b/rkward.kdev4
@@ -1,3 +1,4 @@
[Project]
+CreatedFrom=CMakeLists.txt
Manager=KDevCMakeManager
Name=rkward
diff --git a/rkward/rbackend/rkrbackend.cpp b/rkward/rbackend/rkrbackend.cpp
index d255a9b6..a96439e7 100644
--- a/rkward/rbackend/rkrbackend.cpp
+++ b/rkward/rbackend/rkrbackend.cpp
@@ -2,7 +2,7 @@
rkrbackend - description
-------------------
begin : Sun Jul 25 2004
- copyright : (C) 2004 - 2013 by Thomas Friedrichsmeier
+ copyright : (C) 2004 - 2019 by Thomas Friedrichsmeier
email : thomas.friedrichsmeier at kdemail.net
***************************************************************************/
@@ -1646,9 +1646,24 @@ void RKRBackend::initialize (const char *locale_dir) {
bool lib_load_fail = false;
bool sink_fail = false;
- if (!runDirectCommand ("library (\"rkward\")\n")) lib_load_fail = true;
+ // Try to load rkward package. If that fails, or is the wrong version, try to install
+ // rkward package, then load again.
+ QString libloc = RKRBackendProtocolBackend::dataDir () + "/.rkward_packages/" + QString::number (r_version / 10);
+ QString versioncheck = QString ("stopifnot(.rk.app.version==\"%1\")\n").arg (RKWARD_VERSION);
+ QString command = "local({\n"
+ " libloc <- " + RKRSharedFunctionality::quote (libloc) + "\n"
+ " if (!dir.exists (libloc)) dir.create(libloc, recursive=TRUE)\n"
+ " ok <- FALSE\n"
+ " suppressWarnings (try ({library (\"rkward\", lib.loc=libloc); " + versioncheck + "; ok <- TRUE}))\n"
+ " if (!ok) {\n"
+ " suppressWarnings (try (detach(\"package:rkward\")))\n"
+ " install.packages(normalizePath(paste(libloc, \"..\", c (\"rkward.tgz\", \"rkwardtests.tgz\"), sep=\"/\")), lib=libloc, repos=NULL)\n"
+ " library (\"rkward\", lib.loc=libloc)\n"
+ " }\n"
+ "})\n";
+ if (!runDirectCommand (command)) lib_load_fail = true;
RK_setupGettext (locale_dir); // must happen *after* package loading, since R will re-set it
- if (!runDirectCommand (QString ("stopifnot(.rk.app.version==\"%1\")\n").arg (RKWARD_VERSION))) lib_load_fail = true;
+ if (!runDirectCommand (versioncheck)) lib_load_fail = true;
if (!runDirectCommand (".rk.fix.assignments ()\n")) sink_fail = true;
// error/output sink and help browser
diff --git a/rkward/rbackend/rpackages/CMakeLists.txt b/rkward/rbackend/rpackages/CMakeLists.txt
index a503965f..0a6bd309 100644
--- a/rkward/rbackend/rpackages/CMakeLists.txt
+++ b/rkward/rbackend/rpackages/CMakeLists.txt
@@ -1,8 +1,14 @@
-INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
+MACRO(createRpackage name)
+ FILE(GLOB_RECURSE rkwardfiles${name} LIST_DIRECTORIES true CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${name}/*")
+ MESSAGE(STATUS ${rkwardfiles${name}})
+ ADD_CUSTOM_COMMAND(OUTPUT ${name}.tgz
+ COMMAND ${CMAKE_COMMAND} -E tar "cfz" "${CMAKE_CURRENT_BINARY_DIR}/${name}.tgz" "${name}"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS ${rkwardfiles${name}})
+ENDMACRO()
-CONFIGURE_FILE(
- "${CMAKE_CURRENT_SOURCE_DIR}/rpackage_install.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/rpackage_install.cmake"
- @ONLY)
+createRpackage(rkward)
+createRpackage(rkwardtests)
+ADD_CUSTOM_TARGET(rpackages ALL DEPENDS rkward.tgz rkwardtests.tgz)
-INSTALL(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/rpackage_install.cmake -DDESTDIR=${DESTDIR} -DBUILD_TIMESTAMP=${BUILD_TIMESTAMP})
+INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/rkward.tgz" "${CMAKE_CURRENT_BINARY_DIR}/rkwardtests.tgz" DESTINATION ${DATA_INSTALL_DIR}/rkward/rpackages)
diff --git a/rkward/rbackend/rpackages/rpackage_install.cmake.in b/rkward/rbackend/rpackages/rpackage_install.cmake.in
deleted file mode 100644
index 476a45de..00000000
--- a/rkward/rbackend/rpackages/rpackage_install.cmake.in
+++ /dev/null
@@ -1,36 +0,0 @@
-SET(DESTDIR $ENV{DESTDIR})
-SET(BUILD_TIMESTAMP "@BUILD_TIMESTAMP@")
-
-MESSAGE(STATUS "Installing R support packages")
-
-IF(NOT ${BUILD_TIMESTAMP} EQUAL "")
- SET (TIMESTAMPARG "--built-timestamp=${BUILD_TIMESTAMP}")
-ENDIF(NOT ${BUILD_TIMESTAMP} EQUAL "")
-
-IF(WIN32)
- SET(R_LIBDIR @R_LIBDIR@)
- IF(DESTDIR)
- # strip drive letter
- STRING(REGEX REPLACE "^.:." "" R_LIBDIR ${R_LIBDIR})
- SET(R_LIBDIR "${DESTDIR}/${R_LIBDIR}")
- FILE(MAKE_DIRECTORY "${R_LIBDIR}")
- ENDIF(DESTDIR)
- EXECUTE_PROCESS(
- COMMAND @R_EXECUTABLE@ CMD INSTALL ${TIMESTAMPARG} -c -l ${R_LIBDIR} "@CMAKE_CURRENT_SOURCE_DIR@/rkward" "@CMAKE_CURRENT_SOURCE_DIR@/rkwardtests"
- WORKING_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@"
- RESULT_VARIABLE R_LIB_INSTALL_EXIT_CODE
- )
-ELSE(WIN32)
- EXECUTE_PROCESS(
- COMMAND mkdir -p "@CMAKE_CURRENT_BINARY_DIR@/tmp" ${DESTDIR}/@R_LIBDIR@
- )
- EXECUTE_PROCESS(
- COMMAND env TMPDIR="@CMAKE_CURRENT_BINARY_DIR@/tmp" @R_EXECUTABLE@ CMD INSTALL ${TIMESTAMPARG} -c -l ${DESTDIR}/@R_LIBDIR@ "@CMAKE_CURRENT_SOURCE_DIR@/rkward" "@CMAKE_CURRENT_SOURCE_DIR@/rkwardtests"
- WORKING_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@"
- RESULT_VARIABLE R_LIB_INSTALL_EXIT_CODE
- )
-ENDIF(WIN32)
-
-IF(R_LIB_INSTALL_EXIT_CODE)
- MESSAGE (SEND_ERROR "Failed to install R support libraries. Please make sure you have the required permissions.")
-ENDIF(R_LIB_INSTALL_EXIT_CODE)
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index bb2f69cd..d32db527 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -360,9 +360,28 @@ void RKWardMainWindow::startR () {
RK_ASSERT (!RKGlobals::rInterface ());
// make sure our general purpose files directory exists
- bool ok = QDir ().mkpath (RKSettingsModuleGeneral::filesPath());
+ QString packages_path = RKSettingsModuleGeneral::filesPath() + "/.rkward_packages";
+ bool ok = QDir ().mkpath (packages_path);
RK_ASSERT (ok);
+ // Copy RKWard R source packages to general purpose files directory (if still needed).
+ // This may look redundant at first (since the package still needs to be installed from the
+ // backend. However, if frontend and backend are on different machines (eventually), only the
+ // filesPath is shared between both.
+ QStringList packages;
+ packages << "rkward.tgz" << "rkwardtests.tgz";
+ for (int i = 0; i < packages.size (); ++i) {
+ QString package = QDir (packages_path).absoluteFilePath (packages[i]);
+ if (RKSettingsModuleGeneral::rkwardVersionChanged ()) {
+ RK_DEBUG(APP, DL_INFO, "RKWard version changed. Discarding cached package at %s", qPrintable (package));
+ QFile::remove (package);
+ }
+ if (!QFileInfo (package).exists()) {
+ RK_DEBUG(APP, DL_INFO, "Copying rkward R source package to %s", qPrintable (package));
+ RK_ASSERT(QFile::copy (RKCommonFunctions::getRKWardDataDir () + "/rpackages/" + packages[i], package));
+ }
+ }
+
RKGlobals::rinter = new RInterface ();
new RObjectList ();
@@ -947,3 +966,4 @@ void RKWardMainWindow::setCaption (const QString &) {
KParts::MainWindow::setCaption (wcaption);
}
+
More information about the rkward-tracker
mailing list