Skip to content
Snippets Groups Projects
Commit 4a3c0753 authored by Mick Jordan's avatar Mick Jordan
Browse files

Merge pull request #484 in G/fastr from ~MICK.JORDAN_ORACLE.COM/fastr:bugfix/pkgsource to master

* commit '47fb5d4d':
  use FastR-unique file when validating R_HOME
  Handle missing R_HOME in graal shell in development mode
parents 6e41deb6 47fb5d4d
Branches
No related tags found
No related merge requests found
......@@ -35,6 +35,7 @@ import java.util.HashMap;
import java.util.Map;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.vm.PolyglotEngine;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
......@@ -67,8 +68,7 @@ public final class REnvVars implements RContext.ContextState {
envVars.put("R_SHARE_DIR", fileSystem.getPath(rHome, "share").toString());
String rLibsUserProperty = envVars.get("R_LIBS_USER");
if (rLibsUserProperty == null) {
String os = System.getProperty("os.name");
if (os.contains("Mac OS")) {
if (isMacOS()) {
rLibsUserProperty = "~/Library/R/%v/library";
} else {
rLibsUserProperty = "~/R/%p-library/%v";
......@@ -139,6 +139,11 @@ public final class REnvVars implements RContext.ContextState {
return val != null ? val : envVars.get(var.toUpperCase());
}
private static boolean isMacOS() {
String os = System.getProperty("os.name");
return os.contains("Mac OS");
}
private static final String R_HOME = "R_HOME";
/**
......@@ -146,6 +151,13 @@ public final class REnvVars implements RContext.ContextState {
*/
private static String rHome;
/**
* Returns a file that only exists in a FastR {@code R_HOME}.
*/
private static String markerFile() {
return "libjniboot." + (isMacOS() ? "dylib" : "so");
}
/**
* Returns the value of the {@code R_HOME} environment variable (setting it in the unusual case
* where it it is not set by the initiating shell scripts. This is called very early in the
......@@ -157,17 +169,11 @@ public final class REnvVars implements RContext.ContextState {
rHome = System.getenv(R_HOME);
Path rHomePath;
if (rHome == null) {
/*
* The only time this can happen legitimately is when run under the graalvm shell,
* which does not execute the shell script that normally sets R_HOME.
*/
rHomePath = getRHomePath();
} else {
rHomePath = Paths.get(rHome);
}
// Sanity check on the expected structure of an R_HOME
Path bin = rHomePath.resolve("bin");
if (!(Files.exists(bin) && Files.isDirectory(bin) && Files.exists(bin.resolve("R")))) {
if (!validateRHome(rHomePath, markerFile())) {
Utils.rSuicide("R_HOME is not set correctly");
}
rHome = rHomePath.toString();
......@@ -175,8 +181,36 @@ public final class REnvVars implements RContext.ContextState {
return rHome;
}
/**
* In the case where {@code R_HOME} is not set, which should only occur when FastR is invoked
* from a {@link PolyglotEngine} created by another language, we try to locate the
* {@code R_HOME} dynamically by using the location of this class. The logic varies depending on
* whether this class was stored in a {@code .jar} file or in a {@code .class} file in a
* directory.
*
* @return either a valid {@code R_HOME} or {@code null}
*/
private static Path getRHomePath() {
return Paths.get(REnvVars.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParent();
Path path = Paths.get(REnvVars.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParent();
String markerFile = markerFile();
while (path != null) {
if (validateRHome(path, markerFile)) {
return path;
}
path = path.getParent();
}
return path;
}
/**
* Sanity check on the expected structure of an {@code R_HOME}.
*/
private static boolean validateRHome(Path path, String markerFile) {
if (path == null) {
return false;
}
Path lib = path.resolve("lib");
return Files.exists(lib) && Files.isDirectory(lib) && Files.exists(lib.resolve(markerFile));
}
private void checkRHome() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment