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 : [email protected] ***************************************************************************/ @@ -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); } +
