From 33b66746334b579daadd0a824c48668616779f22 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Fri, 4 Aug 2023 11:30:05 +0300 Subject: [PATCH 01/37] Get Rhome and libR from preferences when provided --- Project.toml | 1 + src/RCall.jl | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index 6ecf7a4b..ac1dc617 100644 --- a/Project.toml +++ b/Project.toml @@ -11,6 +11,7 @@ DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Missings = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +Preferences = "21216c6a-2e73-6563-6e65-726566657250" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Requires = "ae029012-a4dd-5104-9daa-d747884805df" diff --git a/src/RCall.jl b/src/RCall.jl index 80b3fde3..960be929 100644 --- a/src/RCall.jl +++ b/src/RCall.jl @@ -1,6 +1,7 @@ __precompile__() module RCall +using Preferences using Requires using Dates using Libdl @@ -29,11 +30,20 @@ export RObject, robject, rcopy, rparse, rprint, reval, rcall, rlang, rimport, @rimport, @rlibrary, @rput, @rget, @var_str, @R_str -const depfile = joinpath(dirname(@__FILE__),"..","deps","deps.jl") -if isfile(depfile) - include(depfile) +@static if @has_preference("Rhome") || @has_preference("libR") + @static if !(@has_preference("Rhome") && @has_preference("libR")) + error("RCall: Either both Rhome and libR must be set or neither of them") + end + const Rhome = @load_preference("Rhome") + const libR = @load_preference("libR") + const conda_provided_r = false else - error("RCall not properly installed. Please run Pkg.build(\"RCall\")") + const depfile = joinpath(dirname(@__FILE__),"..","deps","deps.jl") + if isfile(depfile) + include(depfile) + else + error("RCall not properly installed. Please run Pkg.build(\"RCall\")") + end end include("types.jl") From 902c5d644bdcbfe5015a6d555f15cd9320aab829 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Fri, 4 Aug 2023 11:33:29 +0300 Subject: [PATCH 02/37] Allow installing package without R installation This is in case the user wants to specify and installation via Preferences.jl after installation. An error message is printed at import time if no installation is available. --- deps/build.jl | 37 ++++++++++++++++++++++++++----------- src/setup.jl | 7 +++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index 2bd34622..ddc82d22 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -25,6 +25,7 @@ try @info "Using previously configured R at $Rhome with libR in $libR." else Rhome = get(ENV, "R_HOME", "") + libR = nothing if Rhome == "*" # install with Conda @info "Installing R via Conda. To use a different R installation,"* @@ -48,22 +49,36 @@ try try Rhome = WinReg.querykey(WinReg.HKEY_CURRENT_USER, "Software\\R-Core\\R", "InstallPath"); catch; end end - else - if !isdir(Rhome) - error("R_HOME is not a directory.") - end end - isempty(Rhome) && error("R cannot be found. Set the \"R_HOME\" environment variable to re-run Pkg.build(\"RCall\").") - libR = locate_libR(Rhome) + if !isempty(Rhome) && !isdir(Rhome) + error("R_HOME is not a directory.") + end + + if !isempty(Rhome) + libR = locate_libR(Rhome) + end end - @info "Using R at $Rhome and libR at $libR." - if DepFile.Rhome != Rhome || DepFile.libR != libR + if isempty(Rhome) + @info ( + "No R installation found. " * + "You will not be able to import RCall without " * + "providing values for its preferences Rhome and libR." + ) open(depfile, "w") do f - println(f, "const Rhome = \"", escape_string(Rhome), '"') - println(f, "const libR = \"", escape_string(libR), '"') - println(f, "const conda_provided_r = $(conda_provided_r)") + println(f, "const Rhome = \"\"") + println(f, "const libR = \"\"") + println(f, "const conda_provided_r = nothing") + end + else + @info "Using R at $Rhome and libR at $libR." + if DepFile.Rhome != Rhome || DepFile.libR != libR + open(depfile, "w") do f + println(f, "const Rhome = \"", escape_string(Rhome), '"') + println(f, "const libR = \"", escape_string(libR), '"') + println(f, "const conda_provided_r = $(conda_provided_r)") + end end end end diff --git a/src/setup.jl b/src/setup.jl index 9ef691f3..f7f603fb 100644 --- a/src/setup.jl +++ b/src/setup.jl @@ -171,6 +171,13 @@ end include(joinpath(dirname(@__FILE__),"..","deps","setup.jl")) function __init__() + if Rhome == "" + error( + "No R installation was detected as RCall installation time. " * + "Please provided the location of R by setting the Rhome and libR preferences or " * + "else set R_HOME='*' and rerun Pkg.build(\"RCall\") to use Conda.jl." + ) + end validate_libR(libR) # Check if R already running From 92ffbabe5a0abdee9dac7cb0a778a450c4661dbc Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Fri, 4 Aug 2023 14:42:33 +0300 Subject: [PATCH 03/37] Add docs for Preferences based R customization --- docs/src/installation.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index e022a5a6..e60d274f 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -8,6 +8,27 @@ Pkg.add("RCall") ## Customizing the R installation +There are two ways to configure the R installation used by RCall.jl: + + * [Using Julia's Preferences system](#Customizing-the-R-installation-using-Julia's-Preferences-system) + * [At install time, using the `R_HOME` environment variable](#Customizing-the-R-installation-at-install-time) + +Should you experience problems with any of these methods, please [open an issue](https://github.com/JuliaStats/RCall.jl/issues/new). + +### Customizing the R installation using Julia's Preferences system + +In this case the appropriate paths are provided with RCall's `Rhome` and `libR` preferences. You can change these in different ways using [Julia's Preferences system](https://docs.julialang.org/en/v1/manual/code-loading/#preferences). For example, you can add the following to a `LocalPreferences.toml` file in the same directory as a project's `Project.toml` file: + +```toml +[RCall] +Rhome = "/path/to/env/lib/R" +libR = "/path/to/env/lib/R/lib/libR.so" +``` + +When these preferences are set, they take precedence over the R installation configured at installation time. + +### Customizing the R installation at install time + The RCall build script (run by `Pkg.add`) will check for an existing R installation by looking in the following locations, in order. @@ -29,8 +50,6 @@ Pkg.build("RCall") When `R_HOME` is set to `"*"`, RCall.jl will automatically install R for you using [Conda](https://github.com/JuliaPy/Conda.jl). -Should you experience problems with any of these methods, please [open an issue](https://github.com/JuliaStats/RCall.jl/issues/new). - ## Standard installations If you want to install R yourself, rather than relying on the automatic Conda installation, you can use one of the following options: From ce9756b6d29485de546a1dee23da3be33b257d39 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Thu, 14 Sep 2023 14:38:29 +0300 Subject: [PATCH 04/37] Only precompile when Rhome is set --- src/RCall.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/RCall.jl b/src/RCall.jl index 960be929..c03bfe51 100644 --- a/src/RCall.jl +++ b/src/RCall.jl @@ -46,6 +46,8 @@ else end end +__precompile__(Rhome != "") + include("types.jl") include("Const.jl") include("methods.jl") From ed5ff4f5a4a715056b35525b5e3851908de247e8 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Thu, 14 Sep 2023 14:38:35 +0300 Subject: [PATCH 05/37] Add compat entry for Preferences --- Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Project.toml b/Project.toml index ac1dc617..8a1aa2b9 100644 --- a/Project.toml +++ b/Project.toml @@ -25,6 +25,7 @@ Conda = "1.4" DataFrames = "0.21, 0.22, 1.0" DataStructures = "0.5, 0.6, 0.7, 0.8, 0.9, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18" Missings = "0.2, 0.3, 0.4, 1.0" +Preferences = "1" Requires = "0.5.2, 1" StatsModels = "0.6, 0.7" WinReg = "0.2, 0.3, 1" From 75b836a1b5903a1f0ad0f8796607e7424ea72303 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Thu, 14 Sep 2023 14:40:41 +0300 Subject: [PATCH 06/37] Add note about current downsides of installation time R configuration --- docs/src/installation.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/installation.md b/docs/src/installation.md index e60d274f..a0442914 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -50,6 +50,10 @@ Pkg.build("RCall") When `R_HOME` is set to `"*"`, RCall.jl will automatically install R for you using [Conda](https://github.com/JuliaPy/Conda.jl). +!!! note "Installation time R installation is shared" + + When the R installation is configured at installation time, the absolute path to the R installation is currently hard-coded into the RCall.jl package, which can be shared between projects. This may cause problems if you are using different R installations for different projects which end up using the same RCall.jl installation. In this case, please [use the Preferences system instead](#Customizing-the-R-installation-at-install-time) which keeps different copies of the compiled RCall for different R installations. + ## Standard installations If you want to install R yourself, rather than relying on the automatic Conda installation, you can use one of the following options: From 258be88908200eb5cb5fcaeed4fa596f96da3733 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Fri, 15 Sep 2023 08:49:17 +0300 Subject: [PATCH 07/37] Update docs/src/installation.md Co-authored-by: Phillip Alday --- docs/src/installation.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index a0442914..694bf81d 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -25,7 +25,8 @@ Rhome = "/path/to/env/lib/R" libR = "/path/to/env/lib/R/lib/libR.so" ``` -When these preferences are set, they take precedence over the R installation configured at installation time. +!!! note + When these preferences are set, they take precedence over the R installation configured at installation time. ### Customizing the R installation at install time From 229da8823440cbd53063f55e8ccc7a1316676987 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Sat, 16 Sep 2023 11:27:26 +0300 Subject: [PATCH 08/37] Add additional note about switching to preference based Rlib config --- docs/src/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 694bf81d..55337c77 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -51,9 +51,9 @@ Pkg.build("RCall") When `R_HOME` is set to `"*"`, RCall.jl will automatically install R for you using [Conda](https://github.com/JuliaPy/Conda.jl). -!!! note "Installation time R installation is shared" +!!! note "Install-time R installation is shared" - When the R installation is configured at installation time, the absolute path to the R installation is currently hard-coded into the RCall.jl package, which can be shared between projects. This may cause problems if you are using different R installations for different projects which end up using the same RCall.jl installation. In this case, please [use the Preferences system instead](#Customizing-the-R-installation-at-install-time) which keeps different copies of the compiled RCall for different R installations. + When the R installation is configured at RCall.jl install time, the absolute path to the R installation is currently hard-coded into the RCall.jl package, which can be shared between projects. This may cause problems if you are using different R installations for different projects which end up using the same copy of RCall.jl. In this case, please [use the Preferences system instead](#Customizing-the-R-installation-at-install-time) which keeps different copies of the compiled RCall for different R installations. You do not need to rebuild RCall.jl manually for this, simply setting the relevant preferences will trigger rebuilds as necessary. ## Standard installations From 9da8881dc163fb331e8dc7edb64cb04895cfc1ab Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Tue, 3 Oct 2023 09:50:57 +0300 Subject: [PATCH 09/37] Add _ option for R_HOME to explicitly unset it --- deps/build.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deps/build.jl b/deps/build.jl index ddc82d22..8d35c96d 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -36,6 +36,8 @@ try Conda.add("r-base>=3.4.0,<5") # greater than or equal to 3.4.0 AND strictly less than 5.0 Rhome = joinpath(Conda.LIBDIR, "R") libR = locate_libR(Rhome) + elseif Rhome == "_" + Rhome = "" else if isempty(Rhome) try Rhome = readchomp(`R RHOME`); catch; end From 545cea1f585b45f25820531b2b22cdc6a027a01b Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Tue, 3 Oct 2023 13:48:17 +0300 Subject: [PATCH 10/37] Add docs for installing with R_HOME=_ --- docs/src/installation.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 55337c77..04808850 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -51,9 +51,11 @@ Pkg.build("RCall") When `R_HOME` is set to `"*"`, RCall.jl will automatically install R for you using [Conda](https://github.com/JuliaPy/Conda.jl). +When `R_HOME` is set to `"_"`, you opt out of all attempts to automatically locate R. RCall.jl will not be importable until you set a location for R [using the Preferences system](#Customizing-the-R-installation-using-Julia's-Preferences-system). + !!! note "Install-time R installation is shared" - When the R installation is configured at RCall.jl install time, the absolute path to the R installation is currently hard-coded into the RCall.jl package, which can be shared between projects. This may cause problems if you are using different R installations for different projects which end up using the same copy of RCall.jl. In this case, please [use the Preferences system instead](#Customizing-the-R-installation-at-install-time) which keeps different copies of the compiled RCall for different R installations. You do not need to rebuild RCall.jl manually for this, simply setting the relevant preferences will trigger rebuilds as necessary. + When the R installation is configured at RCall.jl install time, the absolute path to the R installation is currently hard-coded into the RCall.jl package, which can be shared between projects. This may cause problems if you are using different R installations for different projects which end up using the same copy of RCall.jl. In this case, please [use the Preferences system instead](#Customizing-the-R-installation-using-Julia's-Preferences-system) which keeps different copies of the compiled RCall for different R installations. You do not need to rebuild RCall.jl manually for this, simply setting the relevant preferences will trigger rebuilds as necessary. ## Standard installations From 8040b3e3f128b01ee09d0e31e133d3c5440d7f51 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Tue, 3 Oct 2023 13:52:54 +0300 Subject: [PATCH 11/37] Add installation tests --- Project.toml | 4 +- test/installation.jl | 148 +++++++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 2 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 test/installation.jl diff --git a/Project.toml b/Project.toml index 8a1aa2b9..3287a865 100644 --- a/Project.toml +++ b/Project.toml @@ -37,6 +37,8 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +CondaPkg = "992eb4ea-22a4-4c89-a5bb-47a3300528ab" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" [targets] -test = ["Dates", "AxisArrays", "REPL", "Test", "Random"] +test = ["Dates", "AxisArrays", "REPL", "Test", "Random", "CondaPkg", "Pkg"] diff --git a/test/installation.jl b/test/installation.jl new file mode 100644 index 00000000..60bede2f --- /dev/null +++ b/test/installation.jl @@ -0,0 +1,148 @@ +""" +This file is used to test installation of the RCall package. We rerun this +script in a new Julia process to get a clean environment without RCall so we +can test what happens without already having imported RCall. Tasks for the +Julia subprocess are passed using the SUBINTERPRETER_TASK environment +variable. +""" + +using Base.Filesystem: mktempdir +import Pkg + +rcall_dir = (@__DIR__) * "/../" + + +function mk_temp_proj() + temp_proj = mktempdir() + Pkg.activate(temp_proj) + Pkg.add("Pkg") + Pkg.activate() + return temp_proj +end + +function restart_in_proj(proj, args...) + julia_cmd = Base.julia_cmd() + cmd = `$(julia_cmd) --project=$(proj) $(@__FILE__) $(join(args, " "))` + return Base.run(cmd) +end + +function with_subinterpreter_task(func, task) + ENV["SUBINTERPRETER_TASK"] = task + func() + delete!(ENV, "SUBINTERPRETER_TASK") +end + +subinterpreter_task = get(ENV, "SUBINTERPRETER_TASK", "") + +# This is just to stop errors due to @test not being defined when we run in +# another project +@static if !(@isdefined Test) + macro test(ex) + ex + end +end + +if subinterpreter_task == "can_install_rcall_without_r" + ENV["R_HOME"] = "_" + Pkg.add(path=rcall_dir) + Pkg.build() + try + Base.require(Main, :RCall) + catch e + if !(e isa LoadError) + println(stderr, "Expected LoadError when running RCall but got $e") + exit(1) + end + exit(0) + end + println(stderr, "RCall unexpectedly loaded") + exit(1) +elseif subinterpreter_task == "can_install_conda" + ENV["R_HOME"] = "*" + Pkg.add(path=rcall_dir) + Pkg.build("RCall") + rcall = Base.require(Main, :RCall) + if occursin(r"/conda/3/([^/]+/)?lib/R", rcall.Rhome) + exit(0) + end + println(stderr, "Wrong Conda Rhome $(rcall.Rhome)") + exit(1) +elseif subinterpreter_task == "get_localpreference_toml" + CondaPkg = Base.require(Main, :CondaPkg) + Libdl = Base.require(Main, :Libdl) + function locate_libR(Rhome) + @static if Sys.iswindows() + libR = joinpath(Rhome, "bin", Sys.WORD_SIZE==64 ? "x64" : "i386", "R.dll") + else + libR = joinpath(Rhome, "lib", "libR.$(Libdl.dlext)") + end + return libR + end + condapkg_toml = joinpath(ARGS[1], "CondaPkg.toml") + open(condapkg_toml, "w") do io + write( + io, + """ + [deps] + r = "" + """ + ) + end + CondaPkg.resolve() + target_rhome = "$(CondaPkg.envdir())/lib/R" + localpreference_toml = joinpath(ARGS[1], "LocalPreferences.toml") + open(localpreference_toml, "w") do io + write( + io, + """ + [RCall] + Rhome = "$target_rhome" + libR = "$(locate_libR(target_rhome))" + """ + ) + end + exit(0) +elseif subinterpreter_task == "can_switch_to_condapkg" + rcall = Base.require(Main, :RCall) + if occursin("/.CondaPkg/env/lib/R", rcall.Rhome) + exit(0) + end + println(stderr, "Wrong RCall used $(rcall.Rhome)") + exit(1) +end + +@assert subinterpreter_task == "" + +# Test whether we can install RCall without R +rcall_without_r_proj = mk_temp_proj() +with_subinterpreter_task("can_install_rcall_without_r") do + process = restart_in_proj(rcall_without_r_proj) + @test process.exitcode == 0 +end + +# We want to guard this with a version check so we don't run into the following +# (non-widespread) issue on older versions of Julia: +# https://github.com/JuliaLang/julia/issues/34276 +@static if VERSION ≥ v"1.9" + # Test whether we can install RCall with Conda, and then switch to using + # Preferences + CondaPkg + conda_then_condapkg_proj = mk_temp_proj() + with_subinterpreter_task("can_install_conda") do + process = restart_in_proj(conda_then_condapkg_proj) + @test process.exitcode == 0 + end + + Pkg.activate(conda_then_condapkg_proj) + Pkg.add("CondaPkg") + Pkg.add("Libdl") + Pkg.activate() + with_subinterpreter_task("get_localpreference_toml") do + process = restart_in_proj(conda_then_condapkg_proj, conda_then_condapkg_proj) + @test process.exitcode == 0 + end + + with_subinterpreter_task("can_switch_to_condapkg") do + process = restart_in_proj(conda_then_condapkg_proj) + @test process.exitcode == 0 + end +end diff --git a/test/runtests.jl b/test/runtests.jl index 7e839d39..713cad89 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,8 @@ using RCall using Test +include("installation.jl") + # before RCall does anything const R_PPSTACKTOP_INITIAL = unsafe_load(cglobal((:R_PPStackTop, RCall.libR), Int)) @info "" R_PPSTACKTOP_INITIAL From d6770a579346ceb10055d6c33bc2a4f6368cc655 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Tue, 14 Nov 2023 10:53:50 +0200 Subject: [PATCH 12/37] Fix typo in src/setup.jl Co-authored-by: Phillip Alday --- src/setup.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup.jl b/src/setup.jl index f7f603fb..d420d31c 100644 --- a/src/setup.jl +++ b/src/setup.jl @@ -173,7 +173,7 @@ include(joinpath(dirname(@__FILE__),"..","deps","setup.jl")) function __init__() if Rhome == "" error( - "No R installation was detected as RCall installation time. " * + "No R installation was detected at RCall installation time. " * "Please provided the location of R by setting the Rhome and libR preferences or " * "else set R_HOME='*' and rerun Pkg.build(\"RCall\") to use Conda.jl." ) From 10a0020c88ca1c21d93878791777dcaf40972d2d Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Wed, 3 Jan 2024 13:05:01 +0200 Subject: [PATCH 13/37] Update test/installation.jl Co-authored-by: Phillip Alday --- test/installation.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/installation.jl b/test/installation.jl index 60bede2f..fc82855a 100644 --- a/test/installation.jl +++ b/test/installation.jl @@ -123,6 +123,7 @@ end # We want to guard this with a version check so we don't run into the following # (non-widespread) issue on older versions of Julia: # https://github.com/JuliaLang/julia/issues/34276 +# (related to incompatible libstdc++ versions) @static if VERSION ≥ v"1.9" # Test whether we can install RCall with Conda, and then switch to using # Preferences + CondaPkg From a1eb5616d70398bc306b00125c067a7065953d56 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Wed, 3 Jan 2024 13:05:13 +0200 Subject: [PATCH 14/37] Update test/runtests.jl Co-authored-by: Phillip Alday --- test/runtests.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 713cad89..875a961c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,9 @@ using RCall using Test -include("installation.jl") +@testset "installation" begin + include("installation.jl") +end # before RCall does anything const R_PPSTACKTOP_INITIAL = unsafe_load(cglobal((:R_PPStackTop, RCall.libR), Int)) From a563f91534aee976ef752d99bce32bfc7e8e7757 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 5 Jan 2024 23:58:56 -0600 Subject: [PATCH 15/37] installation test improvements --- Project.toml | 4 +- test/installation.jl | 155 +++--------------- test/installation/drop_preferences.jl | 18 ++ test/installation/install_conda.jl | 17 ++ test/installation/preferences_invalid_env.jl | 39 +++++ test/installation/rcall_without_r.jl | 21 +++ .../swap_to_prefs_and_condapkg.jl | 39 +++++ 7 files changed, 160 insertions(+), 133 deletions(-) create mode 100644 test/installation/drop_preferences.jl create mode 100644 test/installation/install_conda.jl create mode 100644 test/installation/preferences_invalid_env.jl create mode 100644 test/installation/rcall_without_r.jl create mode 100644 test/installation/swap_to_prefs_and_condapkg.jl diff --git a/Project.toml b/Project.toml index 3287a865..d2a56f4d 100644 --- a/Project.toml +++ b/Project.toml @@ -33,12 +33,12 @@ julia = "1" [extras] AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +CondaPkg = "992eb4ea-22a4-4c89-a5bb-47a3300528ab" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -CondaPkg = "992eb4ea-22a4-4c89-a5bb-47a3300528ab" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" [targets] test = ["Dates", "AxisArrays", "REPL", "Test", "Random", "CondaPkg", "Pkg"] diff --git a/test/installation.jl b/test/installation.jl index fc82855a..90f63519 100644 --- a/test/installation.jl +++ b/test/installation.jl @@ -1,123 +1,24 @@ -""" -This file is used to test installation of the RCall package. We rerun this -script in a new Julia process to get a clean environment without RCall so we -can test what happens without already having imported RCall. Tasks for the -Julia subprocess are passed using the SUBINTERPRETER_TASK environment -variable. -""" +# This file is used to test installation of the RCall package. We run +# a new Julia process in a temporary environment so that we +# can test what happens without already having imported RCall. -using Base.Filesystem: mktempdir -import Pkg +using Test -rcall_dir = (@__DIR__) * "/../" +const RCALL_DIR = dirname(@__DIR__) - -function mk_temp_proj() - temp_proj = mktempdir() - Pkg.activate(temp_proj) - Pkg.add("Pkg") - Pkg.activate() - return temp_proj -end - -function restart_in_proj(proj, args...) - julia_cmd = Base.julia_cmd() - cmd = `$(julia_cmd) --project=$(proj) $(@__FILE__) $(join(args, " "))` - return Base.run(cmd) -end - -function with_subinterpreter_task(func, task) - ENV["SUBINTERPRETER_TASK"] = task - func() - delete!(ENV, "SUBINTERPRETER_TASK") -end - -subinterpreter_task = get(ENV, "SUBINTERPRETER_TASK", "") - -# This is just to stop errors due to @test not being defined when we run in -# another project -@static if !(@isdefined Test) - macro test(ex) - ex - end +function test_installation(file, project=mktempdir()) + path = joinpath(@__DIR__, "installation", file) + cmd = `$(Base.julia_cmd()) --project=$(project) $(path)` + return @test success(Cmd(cmd; env=Dict("RCALL_DIR" => RCALL_DIR))) end -if subinterpreter_task == "can_install_rcall_without_r" - ENV["R_HOME"] = "_" - Pkg.add(path=rcall_dir) - Pkg.build() - try - Base.require(Main, :RCall) - catch e - if !(e isa LoadError) - println(stderr, "Expected LoadError when running RCall but got $e") - exit(1) - end - exit(0) - end - println(stderr, "RCall unexpectedly loaded") - exit(1) -elseif subinterpreter_task == "can_install_conda" - ENV["R_HOME"] = "*" - Pkg.add(path=rcall_dir) - Pkg.build("RCall") - rcall = Base.require(Main, :RCall) - if occursin(r"/conda/3/([^/]+/)?lib/R", rcall.Rhome) - exit(0) - end - println(stderr, "Wrong Conda Rhome $(rcall.Rhome)") - exit(1) -elseif subinterpreter_task == "get_localpreference_toml" - CondaPkg = Base.require(Main, :CondaPkg) - Libdl = Base.require(Main, :Libdl) - function locate_libR(Rhome) - @static if Sys.iswindows() - libR = joinpath(Rhome, "bin", Sys.WORD_SIZE==64 ? "x64" : "i386", "R.dll") - else - libR = joinpath(Rhome, "lib", "libR.$(Libdl.dlext)") - end - return libR +mktempdir() do dir + @testset "No R" begin + test_installation("rcall_without_r.jl", dir) end - condapkg_toml = joinpath(ARGS[1], "CondaPkg.toml") - open(condapkg_toml, "w") do io - write( - io, - """ - [deps] - r = "" - """ - ) + @testset "Preferences" begin + test_installation("swap_to_prefs_and_condapkg.jl", dir) end - CondaPkg.resolve() - target_rhome = "$(CondaPkg.envdir())/lib/R" - localpreference_toml = joinpath(ARGS[1], "LocalPreferences.toml") - open(localpreference_toml, "w") do io - write( - io, - """ - [RCall] - Rhome = "$target_rhome" - libR = "$(locate_libR(target_rhome))" - """ - ) - end - exit(0) -elseif subinterpreter_task == "can_switch_to_condapkg" - rcall = Base.require(Main, :RCall) - if occursin("/.CondaPkg/env/lib/R", rcall.Rhome) - exit(0) - end - println(stderr, "Wrong RCall used $(rcall.Rhome)") - exit(1) -end - -@assert subinterpreter_task == "" - -# Test whether we can install RCall without R -rcall_without_r_proj = mk_temp_proj() -with_subinterpreter_task("can_install_rcall_without_r") do - process = restart_in_proj(rcall_without_r_proj) - @test process.exitcode == 0 end # We want to guard this with a version check so we don't run into the following @@ -127,23 +28,15 @@ end @static if VERSION ≥ v"1.9" # Test whether we can install RCall with Conda, and then switch to using # Preferences + CondaPkg - conda_then_condapkg_proj = mk_temp_proj() - with_subinterpreter_task("can_install_conda") do - process = restart_in_proj(conda_then_condapkg_proj) - @test process.exitcode == 0 - end - - Pkg.activate(conda_then_condapkg_proj) - Pkg.add("CondaPkg") - Pkg.add("Libdl") - Pkg.activate() - with_subinterpreter_task("get_localpreference_toml") do - process = restart_in_proj(conda_then_condapkg_proj, conda_then_condapkg_proj) - @test process.exitcode == 0 - end - - with_subinterpreter_task("can_switch_to_condapkg") do - process = restart_in_proj(conda_then_condapkg_proj) - @test process.exitcode == 0 + mktempdir() do dir + @testset "Conda" begin + test_installation("install_conda.jl", dir) + end + @testset "Conda 2 Preferences" begin + test_installation("swap_to_prefs_and_condapkg.jl", dir) + end + @testset "Back 2 Conda" begin + test_installation("drop_preferences.jl", dir) + end end end diff --git a/test/installation/drop_preferences.jl b/test/installation/drop_preferences.jl new file mode 100644 index 00000000..7a77dfff --- /dev/null +++ b/test/installation/drop_preferences.jl @@ -0,0 +1,18 @@ +# Test removal of Rhome from preferences. +# +# If run after `install_conda.jl` and `swap_to_prefs_and_condapkg.jl` in the same enviroment, +# then it tests returning to the build status quo after removal of preferences. +# +# This file is meant to be run in an embedded process spawned by installation.jl. +@debug ENV["RCALL_DIR"] +using Preferences, UUIDs + +set_preferences!(UUID("6f49c342-dc21-5d91-9882-a32aef131414"), + "Rhome" => nothing, "libR" => nothing; force=true) + +RCall = Base.require(Main, :RCall) +if occursin(r"/conda/3/([^/]+/)?lib/R", RCall.Rhome) + exit(0) +end +println(stderr, "Wrong Conda Rhome $(rcall.Rhome)") +exit(1) diff --git a/test/installation/install_conda.jl b/test/installation/install_conda.jl new file mode 100644 index 00000000..35756fd6 --- /dev/null +++ b/test/installation/install_conda.jl @@ -0,0 +1,17 @@ +# Test installation of RCall when R is not present on the system and R_HOME="*", +# which leads to the autoinstallation of Conda.jl and R via Conda.jl +# +# This file is meant to be run in an embedded process spawned by installation.jl. +@debug ENV["RCALL_DIR"] + +using Pkg +ENV["R_HOME"] = "*" +Pkg.add(;path=ENV["RCALL_DIR"]) +Pkg.build("RCall") + +RCall = Base.require(Main, :RCall) +if occursin(r"/conda/3/([^/]+/)?lib/R", RCall.Rhome) + exit(0) +end +println(stderr, "Wrong Conda Rhome $(rcall.Rhome)") +exit(1) diff --git a/test/installation/preferences_invalid_env.jl b/test/installation/preferences_invalid_env.jl new file mode 100644 index 00000000..eb0a459c --- /dev/null +++ b/test/installation/preferences_invalid_env.jl @@ -0,0 +1,39 @@ +# Test using Rhome set in Preferences, with invalid R_HOME set at build time. +# +# If run after `install_conda.jl` in the same enviroment, then it will also test +# dynamically overriding the Rhome variable from the build step via preferences. +# +# This file is meant to be run in an embedded process spawned by installation.jl. +@debug ENV["RCALL_DIR"] + +using Pkg + +Pkg.add("CondaPkg") +Pkg.add("Libdl") +Pkg.add("Preferences") +Pkg.add("UUIDs") + +using CondaPkg, Libdl, Preferences, UUIDs + +function locate_libR(Rhome) + @static if Sys.iswindows() + libR = joinpath(Rhome, "bin", Sys.WORD_SIZE==64 ? "x64" : "i386", "R.dll") + else + libR = joinpath(Rhome, "lib", "libR.$(Libdl.dlext)") + end + return libR +end + +CondaPkg.add("r") +target_rhome = joinpath(CondaPkg.envdir(), "lib", "R") +set_preferences!(UUID("6f49c342-dc21-5d91-9882-a32aef131414"), + "Rhome" => target_rhome, "libR" => locate_libR(target_rhome)) +ENV["R_HOME"] = "_" +Pkg.add(;path=ENV["RCALL_DIR"]) +Pkg.build("RCall") +RCall = Base.require(Main, :RCall) +if occursin("/.CondaPkg/env/lib/R", RCall.Rhome) + exit(0) +end +println(stderr, "Wrong RCall used $(RCall.Rhome)") +exit(1) diff --git a/test/installation/rcall_without_r.jl b/test/installation/rcall_without_r.jl new file mode 100644 index 00000000..d4dba66b --- /dev/null +++ b/test/installation/rcall_without_r.jl @@ -0,0 +1,21 @@ +# Test installation of RCall when R_HOME specifies an invalid R home. +# +# This file is meant to be run in an embedded process spawned by installation.jl. +@debug ENV["RCALL_DIR"] + +using Pkg +ENV["R_HOME"] = "_" +Pkg.add(;path=ENV["RCALL_DIR"]) +Pkg.build("RCall") + +try + Base.require(Main, :RCall) +catch e + if !(e isa LoadError) + @error "Expected LoadError when running RCall but got $e" + exit(1) + end + exit(0) +end +@error "RCall unexpectedly loaded" +exit(1) diff --git a/test/installation/swap_to_prefs_and_condapkg.jl b/test/installation/swap_to_prefs_and_condapkg.jl new file mode 100644 index 00000000..14b72ca0 --- /dev/null +++ b/test/installation/swap_to_prefs_and_condapkg.jl @@ -0,0 +1,39 @@ +# Test using Rhome set in Preferences. +# +# If run after `install_conda.jl` in the same enviroment, then it will also test +# dynamically overriding the Rhome variable from the build step via preferences. +# +# This file is meant to be run in an embedded process spawned by installation.jl. +@debug ENV["RCALL_DIR"] + +using Pkg + +Pkg.add("CondaPkg") +Pkg.add("Libdl") +Pkg.add("Preferences") +Pkg.add("UUIDs") + +using CondaPkg, Libdl, Preferences, UUIDs + +function locate_libR(Rhome) + @static if Sys.iswindows() + libR = joinpath(Rhome, "bin", Sys.WORD_SIZE==64 ? "x64" : "i386", "R.dll") + else + libR = joinpath(Rhome, "lib", "libR.$(Libdl.dlext)") + end + return libR +end + +CondaPkg.add("r") +target_rhome = joinpath(CondaPkg.envdir(), "lib", "R") +set_preferences!(UUID("6f49c342-dc21-5d91-9882-a32aef131414"), + "Rhome" => target_rhome, "libR" => locate_libR(target_rhome)) +# We do NOT re-add RCall here because we're testing against the version already built with Conda +# Pkg.add(;path=ENV["RCALL_DIR"]) +# Pkg.build("RCall") +RCall = Base.require(Main, :RCall) +if occursin("/.CondaPkg/env/lib/R", RCall.Rhome) + exit(0) +end +println(stderr, "Wrong RCall used $(RCall.Rhome)") +exit(1) From b6306441577901bd1e545748e217399a06ab7251 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 6 Jan 2024 00:26:05 -0600 Subject: [PATCH 16/37] argh loadpath --- test/installation.jl | 46 +++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/test/installation.jl b/test/installation.jl index 90f63519..d09940d3 100644 --- a/test/installation.jl +++ b/test/installation.jl @@ -16,27 +16,33 @@ mktempdir() do dir @testset "No R" begin test_installation("rcall_without_r.jl", dir) end - @testset "Preferences" begin - test_installation("swap_to_prefs_and_condapkg.jl", dir) + # We want to guard this with a version check so we don't run into the following + # (non-widespread) issue on older versions of Julia: + # https://github.com/JuliaLang/julia/issues/34276 + # (related to incompatible libstdc++ versions) + @static if VERSION ≥ v"1.9" + @testset "Preferences" begin + test_installation("swap_to_prefs_and_condapkg.jl", dir) + end end end -# We want to guard this with a version check so we don't run into the following -# (non-widespread) issue on older versions of Julia: -# https://github.com/JuliaLang/julia/issues/34276 -# (related to incompatible libstdc++ versions) -@static if VERSION ≥ v"1.9" - # Test whether we can install RCall with Conda, and then switch to using - # Preferences + CondaPkg - mktempdir() do dir - @testset "Conda" begin - test_installation("install_conda.jl", dir) - end - @testset "Conda 2 Preferences" begin - test_installation("swap_to_prefs_and_condapkg.jl", dir) - end - @testset "Back 2 Conda" begin - test_installation("drop_preferences.jl", dir) - end - end +# Test whether we can install RCall with Conda, and then switch to using +# Preferences + CondaPkg +mktempdir() do dir + @testset "Conda" begin + test_installation("install_conda.jl", dir) + end + # We want to guard this with a version check so we don't run into the following + # (non-widespread) issue on older versions of Julia: + # https://github.com/JuliaLang/julia/issues/34276 + # (related to incompatible libstdc++ versions) + @static if VERSION ≥ v"1.9" + @testset "Conda 2 Preferences" begin + test_installation("swap_to_prefs_and_condapkg.jl", dir) + end + @testset "Back 2 Conda" begin + test_installation("drop_preferences.jl", dir) + end + end end From eb19da1ae78af2a260c133c8d7e5adcdee500945 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 6 Jan 2024 00:51:57 -0600 Subject: [PATCH 17/37] test debugging --- test/installation.jl | 47 ++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/test/installation.jl b/test/installation.jl index d09940d3..8e9b5d88 100644 --- a/test/installation.jl +++ b/test/installation.jl @@ -9,35 +9,44 @@ const RCALL_DIR = dirname(@__DIR__) function test_installation(file, project=mktempdir()) path = joinpath(@__DIR__, "installation", file) cmd = `$(Base.julia_cmd()) --project=$(project) $(path)` - return @test success(Cmd(cmd; env=Dict("RCALL_DIR" => RCALL_DIR))) -end - -mktempdir() do dir - @testset "No R" begin - test_installation("rcall_without_r.jl", dir) - end - # We want to guard this with a version check so we don't run into the following - # (non-widespread) issue on older versions of Julia: - # https://github.com/JuliaLang/julia/issues/34276 - # (related to incompatible libstdc++ versions) - @static if VERSION ≥ v"1.9" - @testset "Preferences" begin - test_installation("swap_to_prefs_and_condapkg.jl", dir) + cmd = Cmd(cmd; env=Dict("RCALL_DIR" => RCALL_DIR)) + @test mktemp() do file, io + try + result = run(pipeline(cmd; stdout=io, stderr=io)) + return success(result) + catch + @error open(f -> read(f, String), file) + return false + end end - end end -# Test whether we can install RCall with Conda, and then switch to using -# Preferences + CondaPkg mktempdir() do dir - @testset "Conda" begin - test_installation("install_conda.jl", dir) + @testset "No R" begin + test_installation("rcall_without_r.jl", dir) end # We want to guard this with a version check so we don't run into the following # (non-widespread) issue on older versions of Julia: # https://github.com/JuliaLang/julia/issues/34276 # (related to incompatible libstdc++ versions) @static if VERSION ≥ v"1.9" + @testset "Preferences" begin + test_installation("swap_to_prefs_and_condapkg.jl", dir) + end + end +end + +# We want to guard this with a version check so we don't run into the following +# issue on older versions of Julia: +# https://github.com/JuliaLang/julia/issues/34276 +# (related to incompatible libstdc++ versions) +@static if VERSION ≥ v"1.9" + # Test whether we can install RCall with Conda, and then switch to using + # Preferences + CondaPkg + mktempdir() do dir + @testset "Conda" begin + test_installation("install_conda.jl", dir) + end @testset "Conda 2 Preferences" begin test_installation("swap_to_prefs_and_condapkg.jl", dir) end From a054681fb5f841bb881b5d784c3eedb21f3584e3 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 6 Jan 2024 01:16:37 -0600 Subject: [PATCH 18/37] reduce verbosity --- test/installation/swap_to_prefs_and_condapkg.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/installation/swap_to_prefs_and_condapkg.jl b/test/installation/swap_to_prefs_and_condapkg.jl index 14b72ca0..1426c183 100644 --- a/test/installation/swap_to_prefs_and_condapkg.jl +++ b/test/installation/swap_to_prefs_and_condapkg.jl @@ -26,6 +26,7 @@ end CondaPkg.add("r") target_rhome = joinpath(CondaPkg.envdir(), "lib", "R") +set_preferences!(CondaPkg, "verbosity" => -1) set_preferences!(UUID("6f49c342-dc21-5d91-9882-a32aef131414"), "Rhome" => target_rhome, "libR" => locate_libR(target_rhome)) # We do NOT re-add RCall here because we're testing against the version already built with Conda From 1273c4b86e7b25a9df2f2b32d415bc392eebc019 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 6 Jan 2024 01:36:28 -0600 Subject: [PATCH 19/37] wow Conda --- test/installation/install_conda.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/installation/install_conda.jl b/test/installation/install_conda.jl index 35756fd6..2867f427 100644 --- a/test/installation/install_conda.jl +++ b/test/installation/install_conda.jl @@ -5,6 +5,18 @@ @debug ENV["RCALL_DIR"] using Pkg + +# workaround for +# https://stackoverflow.com/questions/75489624/dockerfile-problem-with-miniconda-on-arm64-macos +@static if Sys.isapple() && success(`md5sum $(@__FILE__)`) + try + run(`md5 $(@__FILE__)`) + catch ex + ex isa IOError || rethrow() + run(`ln -s "$which" md5sum /bin/md5`) + end +end + ENV["R_HOME"] = "*" Pkg.add(;path=ENV["RCALL_DIR"]) Pkg.build("RCall") From 5711d6b9aaba5a873ce73715fd962907199040f0 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 6 Jan 2024 13:52:26 -0600 Subject: [PATCH 20/37] try again --- test/installation/install_conda.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/installation/install_conda.jl b/test/installation/install_conda.jl index 2867f427..16aae374 100644 --- a/test/installation/install_conda.jl +++ b/test/installation/install_conda.jl @@ -11,8 +11,7 @@ using Pkg @static if Sys.isapple() && success(`md5sum $(@__FILE__)`) try run(`md5 $(@__FILE__)`) - catch ex - ex isa IOError || rethrow() + catch run(`ln -s "$which" md5sum /bin/md5`) end end From 086c24c3ffe16af432f70b3dec3f3b69aaa2f14d Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 6 Jan 2024 15:10:36 -0600 Subject: [PATCH 21/37] try again --- test/installation.jl | 16 +++++++++++----- test/installation/install_conda.jl | 10 ---------- test/installation/swap_to_prefs_and_condapkg.jl | 14 +++++++++----- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/test/installation.jl b/test/installation.jl index 8e9b5d88..381734e2 100644 --- a/test/installation.jl +++ b/test/installation.jl @@ -44,14 +44,20 @@ end # Test whether we can install RCall with Conda, and then switch to using # Preferences + CondaPkg mktempdir() do dir - @testset "Conda" begin - test_installation("install_conda.jl", dir) + # we run into weird issues with this on CI, + # but we know that seems to be an upstream issue with Conda.jl + @static if Sys.islinux() + @testset "Conda" begin + test_installation("install_conda.jl", dir) + end end - @testset "Conda 2 Preferences" begin + @testset "Swap to Preferences" begin test_installation("swap_to_prefs_and_condapkg.jl", dir) end - @testset "Back 2 Conda" begin - test_installation("drop_preferences.jl", dir) + @static if Sys.islinux() + @testset "Swap back from Preferences" begin + test_installation("drop_preferences.jl", dir) + end end end end diff --git a/test/installation/install_conda.jl b/test/installation/install_conda.jl index 16aae374..1d5dbf26 100644 --- a/test/installation/install_conda.jl +++ b/test/installation/install_conda.jl @@ -6,16 +6,6 @@ using Pkg -# workaround for -# https://stackoverflow.com/questions/75489624/dockerfile-problem-with-miniconda-on-arm64-macos -@static if Sys.isapple() && success(`md5sum $(@__FILE__)`) - try - run(`md5 $(@__FILE__)`) - catch - run(`ln -s "$which" md5sum /bin/md5`) - end -end - ENV["R_HOME"] = "*" Pkg.add(;path=ENV["RCALL_DIR"]) Pkg.build("RCall") diff --git a/test/installation/swap_to_prefs_and_condapkg.jl b/test/installation/swap_to_prefs_and_condapkg.jl index 1426c183..6f4c524d 100644 --- a/test/installation/swap_to_prefs_and_condapkg.jl +++ b/test/installation/swap_to_prefs_and_condapkg.jl @@ -15,6 +15,8 @@ Pkg.add("UUIDs") using CondaPkg, Libdl, Preferences, UUIDs +const RCALL_UUID = UUID("6f49c342-dc21-5d91-9882-a32aef131414") + function locate_libR(Rhome) @static if Sys.iswindows() libR = joinpath(Rhome, "bin", Sys.WORD_SIZE==64 ? "x64" : "i386", "R.dll") @@ -24,14 +26,16 @@ function locate_libR(Rhome) return libR end +set_preferences!(CondaPkg, "verbosity" => -1) CondaPkg.add("r") target_rhome = joinpath(CondaPkg.envdir(), "lib", "R") -set_preferences!(CondaPkg, "verbosity" => -1) -set_preferences!(UUID("6f49c342-dc21-5d91-9882-a32aef131414"), +# If RCall is already present, then +# we do NOT re-add RCall here because we're testing against the version already built with Conda +if !haskey(Pkg.dependencies(), RCALL_UUID) + Pkg.add(;path=ENV["RCALL_DIR"]) +end +set_preferences!(RCALL_UUID, "Rhome" => target_rhome, "libR" => locate_libR(target_rhome)) -# We do NOT re-add RCall here because we're testing against the version already built with Conda -# Pkg.add(;path=ENV["RCALL_DIR"]) -# Pkg.build("RCall") RCall = Base.require(Main, :RCall) if occursin("/.CondaPkg/env/lib/R", RCall.Rhome) exit(0) From ced63bbd6a638f927de5d712440ddba88bd44d6c Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Sun, 7 Jan 2024 17:48:00 +0200 Subject: [PATCH 22/37] Remove @static Rhome/libR preference + force and document access --- src/RCall.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/RCall.jl b/src/RCall.jl index c03bfe51..3868594e 100644 --- a/src/RCall.jl +++ b/src/RCall.jl @@ -30,8 +30,13 @@ export RObject, robject, rcopy, rparse, rprint, reval, rcall, rlang, rimport, @rimport, @rlibrary, @rput, @rget, @var_str, @R_str -@static if @has_preference("Rhome") || @has_preference("libR") - @static if !(@has_preference("Rhome") && @has_preference("libR")) +# These two preference get marked as compile-time preferences by being accessed +# here +const Rhome_set_as_preference = @has_preference("Rhome") +const libR_set_as_preference = @has_preference("libR") + +if Rhome_set_as_preference || libR_set_as_preference + if !(Rhome_set_as_preference && libR_set_as_preference) error("RCall: Either both Rhome and libR must be set or neither of them") end const Rhome = @load_preference("Rhome") From 238832836a47d1c19a848fd43a4ef9058f5cf257 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Mon, 8 Jan 2024 08:57:20 +0200 Subject: [PATCH 23/37] Refer to old R installation method as R_HOME-based as shorthand rather than install-time in docs --- docs/src/installation.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 04808850..425edfc4 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -11,7 +11,7 @@ Pkg.add("RCall") There are two ways to configure the R installation used by RCall.jl: * [Using Julia's Preferences system](#Customizing-the-R-installation-using-Julia's-Preferences-system) - * [At install time, using the `R_HOME` environment variable](#Customizing-the-R-installation-at-install-time) + * [At RCall.jl install time, or when manually re-building RCall.jl, using the `R_HOME` environment variable](#Customizing-the-R-installation-using-R_HOME) Should you experience problems with any of these methods, please [open an issue](https://github.com/JuliaStats/RCall.jl/issues/new). @@ -26,11 +26,11 @@ libR = "/path/to/env/lib/R/lib/libR.so" ``` !!! note - When these preferences are set, they take precedence over the R installation configured at installation time. + When these preferences are set, they take precedence over the R installation configured using the `R_HOME` environment variable when RCall.jl was last built. -### Customizing the R installation at install time +### Customizing the R installation using `R_HOME` -The RCall build script (run by `Pkg.add`) +The RCall build script (run by `Pkg.add(...)` or `Pkg.build(...)`) will check for an existing R installation by looking in the following locations, in order. @@ -53,7 +53,7 @@ When `R_HOME` is set to `"*"`, RCall.jl will automatically install R for you usi When `R_HOME` is set to `"_"`, you opt out of all attempts to automatically locate R. RCall.jl will not be importable until you set a location for R [using the Preferences system](#Customizing-the-R-installation-using-Julia's-Preferences-system). -!!! note "Install-time R installation is shared" +!!! note "R_HOME-based R installation is shared" When the R installation is configured at RCall.jl install time, the absolute path to the R installation is currently hard-coded into the RCall.jl package, which can be shared between projects. This may cause problems if you are using different R installations for different projects which end up using the same copy of RCall.jl. In this case, please [use the Preferences system instead](#Customizing-the-R-installation-using-Julia's-Preferences-system) which keeps different copies of the compiled RCall for different R installations. You do not need to rebuild RCall.jl manually for this, simply setting the relevant preferences will trigger rebuilds as necessary. From 4e686aace874f1179d99e2e1406f4528bb60e4e5 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Mon, 8 Jan 2024 08:58:24 +0200 Subject: [PATCH 24/37] Add cookbook snippet for usage with CondaPkg --- docs/src/installation.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/src/installation.md b/docs/src/installation.md index 425edfc4..082eae11 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -28,6 +28,24 @@ libR = "/path/to/env/lib/R/lib/libR.so" !!! note When these preferences are set, they take precedence over the R installation configured using the `R_HOME` environment variable when RCall.jl was last built. +Unlike [customizing the R installation using `R_HOME`](#Customizing-the-R-installation-using-R_HOME), the Preferences-based approach allows for each of your Julia projects using RCall.jl to use a different R installation. As such, it is appropriate for when you want to install and manage R with [CondaPkg](https://github.com/JuliaPy/CondaPkg.jl). Assuming that RCall and CondaPkg are installed, the following script will install a CondaPkg-managed R and set the correct Preferences so that RCall.jl will make use of it. + +``` +using Libdl +using RCall +using CondaPkg +using Preferences + +CondaPkg.add("r") +target_rhome = joinpath(CondaPkg.envdir(), "lib", "R") +if Sys.iswindows() + target_libr = joinpath(Rhome, "bin", Sys.WORD_SIZE==64 ? "x64" : "i386", "R.dll") +else + target_libr = joinpath(Rhome, "lib", "libR.$(Libdl.dlext)") +end +set_preferences!(RCall, "Rhome" => target_rhome, "libR" => target_libr) +``` + ### Customizing the R installation using `R_HOME` The RCall build script (run by `Pkg.add(...)` or `Pkg.build(...)`) From 9e3fd9f123387e7698095dd8f759678f650774e4 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Mon, 8 Jan 2024 09:04:50 +0200 Subject: [PATCH 25/37] Clarify precompile-abort case and print explanitory message in this case --- src/RCall.jl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/RCall.jl b/src/RCall.jl index 3868594e..b48467e4 100644 --- a/src/RCall.jl +++ b/src/RCall.jl @@ -1,4 +1,3 @@ -__precompile__() module RCall using Preferences @@ -51,7 +50,14 @@ else end end -__precompile__(Rhome != "") +if Rhome == "" + @info ( + "No R installation found by RCall.jl. " * + "Precompilation of RCall and all dependent packages postponed. " * + "Importing RCall will fail until an R installation is configured beforehand." + ) + __precompile__(false) +end include("types.jl") include("Const.jl") From 3e8e50390077ac0d92cde1b654ce1ee0c8ad1ea5 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Mon, 8 Jan 2024 16:23:04 -0600 Subject: [PATCH 26/37] potential fix for mac CI --- test/installation.jl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/installation.jl b/test/installation.jl index 381734e2..afc9b7e5 100644 --- a/test/installation.jl +++ b/test/installation.jl @@ -8,7 +8,13 @@ const RCALL_DIR = dirname(@__DIR__) function test_installation(file, project=mktempdir()) path = joinpath(@__DIR__, "installation", file) - cmd = `$(Base.julia_cmd()) --project=$(project) $(path)` + @static if Sys.isunix() + # this weird stub is necessary so that all the nested conda installation processes + # have access to the PATH + cmd = `sh -c $(Base.julia_cmd()) --project=$(project) $(path)` + else + cmd = `$(Base.julia_cmd()) --project=$(project) $(path)` + end cmd = Cmd(cmd; env=Dict("RCALL_DIR" => RCALL_DIR)) @test mktemp() do file, io try @@ -44,9 +50,8 @@ end # Test whether we can install RCall with Conda, and then switch to using # Preferences + CondaPkg mktempdir() do dir - # we run into weird issues with this on CI, - # but we know that seems to be an upstream issue with Conda.jl - @static if Sys.islinux() + # we run into weird issues with this on CI + @static if Sys.isunix() @testset "Conda" begin test_installation("install_conda.jl", dir) end @@ -54,7 +59,7 @@ end @testset "Swap to Preferences" begin test_installation("swap_to_prefs_and_condapkg.jl", dir) end - @static if Sys.islinux() + @static if Sys.isunix() @testset "Swap back from Preferences" begin test_installation("drop_preferences.jl", dir) end From 0a52d21520286ff6252359f923d2ee6b7834f033 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Mon, 8 Jan 2024 16:37:48 -0600 Subject: [PATCH 27/37] try something on windows --- test/installation.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/installation.jl b/test/installation.jl index afc9b7e5..9c8f4612 100644 --- a/test/installation.jl +++ b/test/installation.jl @@ -12,8 +12,10 @@ function test_installation(file, project=mktempdir()) # this weird stub is necessary so that all the nested conda installation processes # have access to the PATH cmd = `sh -c $(Base.julia_cmd()) --project=$(project) $(path)` + elseif Sys.iswindows() + cmd = `cmd /C $(Base.julia_cmd()) --project=$(project) $(path)` else - cmd = `$(Base.julia_cmd()) --project=$(project) $(path)` + error("What system are you on?!") end cmd = Cmd(cmd; env=Dict("RCALL_DIR" => RCALL_DIR)) @test mktemp() do file, io From 74b6120324868ae0c78b5b06d543d4d647300920 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 6 Jan 2024 15:23:05 -0600 Subject: [PATCH 28/37] patch bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 4cfc9436..339bdc64 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "RCall" uuid = "6f49c342-dc21-5d91-9882-a32aef131414" authors = ["Douglas Bates ", "Randy Lai ", "Simon Byrne "] -version = "0.14.0" +version = "0.14.1" [deps] CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" From d86f4d4f35f5db7e71d90ee650dbb0dfb6c74cb5 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Sun, 21 Jan 2024 20:07:23 +0200 Subject: [PATCH 29/37] Fix CondaPkg test to activate the environment --- test/installation/swap_to_prefs_and_condapkg.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/installation/swap_to_prefs_and_condapkg.jl b/test/installation/swap_to_prefs_and_condapkg.jl index 6f4c524d..466ee232 100644 --- a/test/installation/swap_to_prefs_and_condapkg.jl +++ b/test/installation/swap_to_prefs_and_condapkg.jl @@ -7,6 +7,7 @@ @debug ENV["RCALL_DIR"] using Pkg +using Base.Filesystem: joinpath Pkg.add("CondaPkg") Pkg.add("Libdl") @@ -36,8 +37,12 @@ if !haskey(Pkg.dependencies(), RCALL_UUID) end set_preferences!(RCALL_UUID, "Rhome" => target_rhome, "libR" => locate_libR(target_rhome)) -RCall = Base.require(Main, :RCall) -if occursin("/.CondaPkg/env/lib/R", RCall.Rhome) +RCall = nothing +CondaPkg.withenv() do + RCall = Base.require(Main, :RCall) +end +expected = joinpath("x", ".CondaPkg", "env", "lib", "R")[2:end] +if occursin(expected, RCall.Rhome) exit(0) end println(stderr, "Wrong RCall used $(RCall.Rhome)") From 6f47c4d6f8590155012b9af999b373d151038311 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Sun, 21 Jan 2024 20:08:50 +0200 Subject: [PATCH 30/37] Refer to RCall by uuid in CondaPkg example --- docs/src/installation.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 082eae11..8fd83178 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -32,9 +32,11 @@ Unlike [customizing the R installation using `R_HOME`](#Customizing-the-R-instal ``` using Libdl -using RCall using CondaPkg using Preferences +using UUIDs + +const RCALL_UUID = UUID("6f49c342-dc21-5d91-9882-a32aef131414") CondaPkg.add("r") target_rhome = joinpath(CondaPkg.envdir(), "lib", "R") @@ -43,7 +45,7 @@ if Sys.iswindows() else target_libr = joinpath(Rhome, "lib", "libR.$(Libdl.dlext)") end -set_preferences!(RCall, "Rhome" => target_rhome, "libR" => target_libr) +set_preferences!(RCALL_UUID, "Rhome" => target_rhome, "libR" => target_libr) ``` ### Customizing the R installation using `R_HOME` From 5d89f03376fcbb8e481319134edf70e2e401188f Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Sun, 21 Jan 2024 20:10:32 +0200 Subject: [PATCH 31/37] Proof preferences installation docs a bit --- docs/src/installation.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 8fd83178..9eabdb49 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -17,7 +17,7 @@ Should you experience problems with any of these methods, please [open an issue] ### Customizing the R installation using Julia's Preferences system -In this case the appropriate paths are provided with RCall's `Rhome` and `libR` preferences. You can change these in different ways using [Julia's Preferences system](https://docs.julialang.org/en/v1/manual/code-loading/#preferences). For example, you can add the following to a `LocalPreferences.toml` file in the same directory as a project's `Project.toml` file: +You can customize the R installation using [Julia's Preferences system](https://docs.julialang.org/en/v1/manual/code-loading/#preferences) by providing appropriate paths using RCall's `Rhome` and `libR` preferences. Julia's Preferences system allows these to be set in a few different ways. One possibility is to add the following to a `LocalPreferences.toml` file in the same directory as a project's `Project.toml` file: ```toml [RCall] @@ -28,7 +28,9 @@ libR = "/path/to/env/lib/R/lib/libR.so" !!! note When these preferences are set, they take precedence over the R installation configured using the `R_HOME` environment variable when RCall.jl was last built. -Unlike [customizing the R installation using `R_HOME`](#Customizing-the-R-installation-using-R_HOME), the Preferences-based approach allows for each of your Julia projects using RCall.jl to use a different R installation. As such, it is appropriate for when you want to install and manage R with [CondaPkg](https://github.com/JuliaPy/CondaPkg.jl). Assuming that RCall and CondaPkg are installed, the following script will install a CondaPkg-managed R and set the correct Preferences so that RCall.jl will make use of it. +#### Usage with CondaPkg (experimental) + +Unlike [customizing the R installation using `R_HOME`](#Customizing-the-R-installation-using-R_HOME), the Preferences-based approach allows for each of your Julia projects using RCall.jl to use a different R installation. As such, it is appropriate for when you want to install and manage R with [CondaPkg](https://github.com/JuliaPy/CondaPkg.jl). Assuming that RCall and CondaPkg are installed, the following script will install a CondaPkg-managed R and set the correct preferences so that RCall.jl will make use of it. ``` using Libdl From ac7ade39154849f921e16fe9deaeb5ed930e4dd5 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Sun, 21 Jan 2024 20:10:58 +0200 Subject: [PATCH 32/37] Add note about use with CondaPkg and making sure the environment is activate --- docs/src/installation.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/src/installation.md b/docs/src/installation.md index 9eabdb49..f4732404 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -50,6 +50,13 @@ end set_preferences!(RCALL_UUID, "Rhome" => target_rhome, "libR" => target_libr) ``` +!!! note + So that CondaPkg managed R finds the correct versions of its shared library dependencies, such as BLAS, you must arrange for the Conda environment to be active when `RCall` is imported so that native library loading paths are set up correctly. If you do not do so, it is still possible that things will appear to work correctly if compatible versions are available from elsewhere in your library loading path, but the resulting code can break in some environments and so is not portable. + + At the moment there are two options for arranging for this: + 1. Use `CondaPkg.activate!(ENV)` to permanently modify the environment + 2. Use `CondaPkg.withenv()`, in which case you will have to use `Base.require(Main, :RCall)` to import RCall rather than `using`. + ### Customizing the R installation using `R_HOME` The RCall build script (run by `Pkg.add(...)` or `Pkg.build(...)`) From bc86527e66e9dc4461190837e2d9ce7febe6f336 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sun, 21 Jan 2024 12:49:42 -0600 Subject: [PATCH 33/37] try forcing build on Windows --- test/installation/swap_to_prefs_and_condapkg.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/installation/swap_to_prefs_and_condapkg.jl b/test/installation/swap_to_prefs_and_condapkg.jl index 466ee232..c59bfc04 100644 --- a/test/installation/swap_to_prefs_and_condapkg.jl +++ b/test/installation/swap_to_prefs_and_condapkg.jl @@ -39,6 +39,7 @@ set_preferences!(RCALL_UUID, "Rhome" => target_rhome, "libR" => locate_libR(target_rhome)) RCall = nothing CondaPkg.withenv() do + Pkg.build("RCall") RCall = Base.require(Main, :RCall) end expected = joinpath("x", ".CondaPkg", "env", "lib", "R")[2:end] From 9d968d09a713ced07407b6a7d74e26ccbd858edb Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sun, 21 Jan 2024 13:04:18 -0600 Subject: [PATCH 34/37] scope --- test/installation/swap_to_prefs_and_condapkg.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/installation/swap_to_prefs_and_condapkg.jl b/test/installation/swap_to_prefs_and_condapkg.jl index c59bfc04..df1bbd10 100644 --- a/test/installation/swap_to_prefs_and_condapkg.jl +++ b/test/installation/swap_to_prefs_and_condapkg.jl @@ -38,9 +38,9 @@ end set_preferences!(RCALL_UUID, "Rhome" => target_rhome, "libR" => locate_libR(target_rhome)) RCall = nothing -CondaPkg.withenv() do +RCall = CondaPkg.withenv() do Pkg.build("RCall") - RCall = Base.require(Main, :RCall) + Base.require(Main, :RCall) end expected = joinpath("x", ".CondaPkg", "env", "lib", "R")[2:end] if occursin(expected, RCall.Rhome) From c130c7871ceb7c207a21c4b84692aae081179501 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sun, 21 Jan 2024 21:58:11 -0600 Subject: [PATCH 35/37] coverage --- src/setup.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/setup.jl b/src/setup.jl index 6bf88d23..4415955b 100644 --- a/src/setup.jl +++ b/src/setup.jl @@ -171,13 +171,12 @@ end include(joinpath(dirname(@__FILE__),"..","deps","setup.jl")) function __init__() - if Rhome == "" - error( + # This should actually error much sooner, but this is just in case + isempty(Rhome) && error( "No R installation was detected at RCall installation time. " * "Please provided the location of R by setting the Rhome and libR preferences or " * - "else set R_HOME='*' and rerun Pkg.build(\"RCall\") to use Conda.jl." - ) - end + "else set R_HOME='*' and rerun Pkg.build(\"RCall\") to use Conda.jl.") + validate_libR(libR) # Check if R already running From 01aa738912413abe6c3b27b94ea769feff9c9917 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Tue, 30 Jan 2024 20:24:38 +0200 Subject: [PATCH 36/37] Clarify the CondaPkg cookbook section --- docs/src/installation.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index f4732404..3a566cac 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -28,7 +28,7 @@ libR = "/path/to/env/lib/R/lib/libR.so" !!! note When these preferences are set, they take precedence over the R installation configured using the `R_HOME` environment variable when RCall.jl was last built. -#### Usage with CondaPkg (experimental) +#### (Experimental) Usage with CondaPkg Unlike [customizing the R installation using `R_HOME`](#Customizing-the-R-installation-using-R_HOME), the Preferences-based approach allows for each of your Julia projects using RCall.jl to use a different R installation. As such, it is appropriate for when you want to install and manage R with [CondaPkg](https://github.com/JuliaPy/CondaPkg.jl). Assuming that RCall and CondaPkg are installed, the following script will install a CondaPkg-managed R and set the correct preferences so that RCall.jl will make use of it. @@ -50,12 +50,19 @@ end set_preferences!(RCALL_UUID, "Rhome" => target_rhome, "libR" => target_libr) ``` -!!! note - So that CondaPkg managed R finds the correct versions of its shared library dependencies, such as BLAS, you must arrange for the Conda environment to be active when `RCall` is imported so that native library loading paths are set up correctly. If you do not do so, it is still possible that things will appear to work correctly if compatible versions are available from elsewhere in your library loading path, but the resulting code can break in some environments and so is not portable. +So that CondaPkg managed R finds the correct versions of its shared library dependencies, such as BLAS, you must arrange for the Conda environment to be active when `RCall` is imported so that native library loading paths are set up correctly. If you do not do so, it is still possible that things will appear to work correctly if compatible versions are available from elsewhere in your library loading path, but the resulting code can break in some environments and so is not portable. + +At the moment there are two options for arranging for this: +1. (Recommended) Use `CondaPkg.activate!(ENV)` to permanently modify the environment *before* loading RCall. +2. (Experimental) Use `CondaPkg.withenv()` to change the environment while loading RCall/R and R libraries using native code. After the `CondaPkg.withenv()` block, the Conda environment will no longer be active. This approach may be needed if you need to return to a unmodified environment after loading R. Note this approach has not been thouroughly tested and may not work with all R packages. - At the moment there are two options for arranging for this: - 1. Use `CondaPkg.activate!(ENV)` to permanently modify the environment - 2. Use `CondaPkg.withenv()`, in which case you will have to use `Base.require(Main, :RCall)` to import RCall rather than `using`. +```julia +RCall = CondaPkg.withenv() do + RCall = @eval using RCall + # Load all R libraries that may load native code from the Conda environment here + return RCall +end +``` ### Customizing the R installation using `R_HOME` From 12731054ab7e60fc3fde15a1215d100a533bb536 Mon Sep 17 00:00:00 2001 From: Frankie Robertson Date: Tue, 30 Jan 2024 20:25:17 +0200 Subject: [PATCH 37/37] Clarify the docs on R_HOME's special values --- docs/src/installation.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 3a566cac..28706457 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -77,7 +77,7 @@ in order. * Otherwise, on Windows, it looks in the [Windows registry](https://cran.r-project.org/bin/windows/base/rw-FAQ.html#Does-R-use-the-Registry_003f). To change which R installation is used for RCall, set the `R_HOME` environment variable -and run `Pkg.build("RCall")`. Once this is configured, RCall remembers the location +and run `Pkg.build("RCall")`. Once this is configured, RCall remembers the location of R in future updates, so you don't need to set `R_HOME` permanently. ```julia @@ -85,12 +85,15 @@ ENV["R_HOME"] = "....directory of R home...." Pkg.build("RCall") ``` -When `R_HOME` is set to `"*"`, RCall.jl will automatically install R for you using [Conda](https://github.com/JuliaPy/Conda.jl). +As well as being setting `R_HOME` to a path, it can also be set to certain special values: -When `R_HOME` is set to `"_"`, you opt out of all attempts to automatically locate R. RCall.jl will not be importable until you set a location for R [using the Preferences system](#Customizing-the-R-installation-using-Julia's-Preferences-system). +* When `R_HOME="*"`, RCall.jl will automatically install R for you using [Conda](https://github.com/JuliaPy/Conda.jl). +* When `R_HOME=""`, or is unset, RCall will try to locate `R_HOME` by asking the copy of R in your `PATH` and then --- on Windows only --- by checking the registry. +* When `R_HOME="_"`, you opt out of all attempts to automatically locate R. -!!! note "R_HOME-based R installation is shared" +In case no R installation is found or given at build time, the build will complete with a warning, but no error. RCall.jl will not be importable until you set a location for R [using the Preferences system](#Customizing-the-R-installation-using-Julia's-Preferences-system). +!!! note "R_HOME-based R installation is shared" When the R installation is configured at RCall.jl install time, the absolute path to the R installation is currently hard-coded into the RCall.jl package, which can be shared between projects. This may cause problems if you are using different R installations for different projects which end up using the same copy of RCall.jl. In this case, please [use the Preferences system instead](#Customizing-the-R-installation-using-Julia's-Preferences-system) which keeps different copies of the compiled RCall for different R installations. You do not need to rebuild RCall.jl manually for this, simply setting the relevant preferences will trigger rebuilds as necessary. ## Standard installations