From 811a53fba24622df91831cafd3559ad9494de0e8 Mon Sep 17 00:00:00 2001 From: Romain Francois Date: Thu, 5 Oct 2023 15:31:19 +0200 Subject: [PATCH] use Rcpp and RInside --- CMakeLists.txt | 22 ++++++++++++++-------- cmake/FindR.cmake | 28 ++++++++++++++++++++++++++++ environment-dev.yml | 2 ++ include/xeus-r/xinterpreter.hpp | 3 +++ src/xinterpreter.cpp | 8 ++++---- 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a55794..1d0b430 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,10 +68,14 @@ if (NOT TARGET xeus AND NOT TARGET xeus-static) endif () find_package(R REQUIRED) -message(STATUS "R_INCLUDE_DIR = ${R_INCLUDE_DIR}") -message(STATUS "R_LDFLAGS = ${R_LDFLAGS}") -message(STATUS "R_LIBRARY_BLAS = ${R_LIBRARY_BLAS}") -message(STATUS "R_LIBRARY_LAPACK = ${R_LIBRARY_LAPACK}") +message(STATUS "R_INCLUDE_DIR = ${R_INCLUDE_DIR}") +message(STATUS "R_LDFLAGS = ${R_LDFLAGS}") +message(STATUS "R_LIBRARY_BLAS = ${R_LIBRARY_BLAS}") +message(STATUS "R_LIBRARY_LAPACK = ${R_LIBRARY_LAPACK}") +message(STATUS "R_RCPP_INCLUDE_DIR = ${R_RCPP_INCLUDE_DIR}") +message(STATUS "R_RCPP_LDFLAGS = ${R_RCPP_LDFLAGS}") +message(STATUS "R_RINSIDE_INCLUDE_DIR = ${R_RINSIDE_INCLUDE_DIR}") +message(STATUS "R_RINSIDE_LDFLAGS = ${R_RINSIDE_LDFLAGS}") # Flags # ===== @@ -85,7 +89,6 @@ endif () if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder") - CHECK_CXX_COMPILER_FLAG("-std=c++17" HAS_CPP_17_FLAG) if (HAS_CPP_17_FLAG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") @@ -199,7 +202,10 @@ macro(xeus_r_create_target target_name linkage output_name) PUBLIC $ $ - ${R_INCLUDE_DIR}) + ${R_INCLUDE_DIR} + ${R_RCPP_INCLUDE_DIR} + ${R_RINSIDE_INCLUDE_DIR} + ) if (XEUS_R_USE_SHARED_XEUS) set(XEUS_R_XEUS_TARGET xeus) @@ -215,7 +221,7 @@ macro(xeus_r_create_target target_name linkage output_name) endif () find_package(Threads) # TODO: add Threads as a dependence of xeus-static? - target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${R_LDFLAGS} ${R_LIBRARY_BLAS} ${R_LIBRARY_LAPACK}) + target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${R_LDFLAGS} ${R_LIBRARY_BLAS} ${R_LIBRARY_LAPACK} ${R_RCPP_LDFLAGS} ${R_RINSIDE_LDFLAGS}) endmacro() @@ -249,7 +255,7 @@ if (XEUS_R_BUILD_EXECUTABLE) target_compile_features(xr PRIVATE cxx_std_17) xeus_r_set_common_options(xr) xeus_r_set_kernel_options(xr) - target_link_libraries(xr PRIVATE xeus-zmq ${R_LDFLAGS} ${R_LIBRARY_BLAS} ${R_LIBRARY_LAPACK}) + target_link_libraries(xr PRIVATE xeus-zmq ${R_LDFLAGS} ${R_LIBRARY_BLAS} ${R_LIBRARY_LAPACK} ${R_RCPP_LDFLAGS} ${R_RINSIDE_LDFLAGS}) endif() diff --git a/cmake/FindR.cmake b/cmake/FindR.cmake index 1410095..97d9981 100644 --- a/cmake/FindR.cmake +++ b/cmake/FindR.cmake @@ -16,6 +16,10 @@ # R_LIBRARY_READLINE - Path to readline library # R_LIBRARIES - Array of: R_LIBRARY_BASE, R_LIBRARY_BLAS, R_LIBRARY_LAPACK, R_LIBRARY_BASE [, R_LIBRARY_READLINE] # R_LDFLAGS - R CMD config --ldflags +# R_RCPP_INCLUDE_DIR - Path to Rcpp include directory +# R_RCPP_LDFLAGS - Rscript -e "Rcpp:::LdFlags()" +# R_RINSIDE_INCLUDE_DIR - Rscript -e "RInside:::CxxFlags()" +# R_RINSIDE_LDFLAGS - Rscript -e "RInside:::LdFlags()" # # Variable search order: # 1. Attempt to locate and set R_COMMAND @@ -59,6 +63,30 @@ if(R_COMMAND) OUTPUT_STRIP_TRAILING_WHITESPACE) set(R_LDFLAGS ${R_LDFLAGS} CACHE PATH "R CMD config --ldflags") + execute_process(WORKING_DIRECTORY . + COMMAND ${R_SCRIPT_COMMAND} -e "cat(tools::file_path_as_absolute(base::system.file('include', package = 'Rcpp')))" + OUTPUT_VARIABLE R_RCPP_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(R_RCPP_INCLUDE_DIR ${R_RCPP_INCLUDE_DIR} CACHE PATH "Rcpp include directory") + + execute_process(WORKING_DIRECTORY . + COMMAND ${R_SCRIPT_COMMAND} -e "Rcpp:::LdFlags()" + OUTPUT_VARIABLE R_RCPP_LDFLAGS + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(R_RCPP_LDFLAGS ${R_RCPP_LDFLAGS} CACHE PATH "Rcpp:::LdFlags()") + + execute_process(WORKING_DIRECTORY . + COMMAND ${R_SCRIPT_COMMAND} -e "cat(tools::file_path_as_absolute(base::system.file('include', package = 'RInside')))" + OUTPUT_VARIABLE R_RINSIDE_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(R_RINSIDE_INCLUDE_DIR ${R_RINSIDE_INCLUDE_DIR} CACHE PATH "RInside include directory") + + execute_process(WORKING_DIRECTORY . + COMMAND ${R_SCRIPT_COMMAND} -e "RInside:::LdFlags()" + OUTPUT_VARIABLE R_RINSIDE_LDFLAGS + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(R_RINSIDE_LDFLAGS ${R_RINSIDE_LDFLAGS} CACHE PATH "RInside:::LdFlags()") + find_path(R_INCLUDE_DIR R.h HINTS ${R_ROOT_DIR} ${R_ROOT_DIR}/bin/${R_LIB_ARCH} PATHS /usr/local/lib /usr/local/lib64 /usr/share diff --git a/environment-dev.yml b/environment-dev.yml index 5b6fb88..9e3702b 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -12,6 +12,8 @@ dependencies: - cppzmq - xtl - r-base + - r-rcpp + - r-rinside # Test dependencies - pytest - jupyter_kernel_test>=0.4.3 diff --git a/include/xeus-r/xinterpreter.hpp b/include/xeus-r/xinterpreter.hpp index 28fb0ff..3f47fe1 100644 --- a/include/xeus-r/xinterpreter.hpp +++ b/include/xeus-r/xinterpreter.hpp @@ -23,6 +23,7 @@ #include "xeus_r_config.hpp" #include "xeus/xinterpreter.hpp" +#include "RInside.h" namespace nl = nlohmann; @@ -58,6 +59,8 @@ namespace xeus_r void shutdown_request_impl() override; + private: + RInside R; }; } diff --git a/src/xinterpreter.cpp b/src/xinterpreter.cpp index 1354997..9e6896d 100644 --- a/src/xinterpreter.cpp +++ b/src/xinterpreter.cpp @@ -18,6 +18,8 @@ #include "xeus-r/xinterpreter.hpp" +#include "RInside.h" + #define R_NO_REMAP #include "R.h" #include "Rinternals.h" @@ -64,9 +66,8 @@ SEXP try_parse(const std::string& code, int execution_counter) { } - interpreter::interpreter(int argc, char* argv[]) + interpreter::interpreter(int argc, char* argv[]) : R(argc, argv) { - Rf_initEmbeddedR(argc, argv); xeus::register_interpreter(this); } @@ -90,7 +91,7 @@ SEXP try_parse(const std::string& code, int execution_counter) { } UNPROTECT(1); // parsed - + // echo the code for now nl::json pub_data; pub_data["text/plain"] = code; @@ -159,7 +160,6 @@ SEXP try_parse(const std::string& code, int execution_counter) { } void interpreter::shutdown_request_impl() { - Rf_endEmbeddedR(0); std::cout << "Bye!!" << std::endl; }