184 lines
6.0 KiB
CMake
184 lines
6.0 KiB
CMake
# CMake module for R
|
|
# Borrows ideas from RStudio's FindLibR.cmake
|
|
#
|
|
# Defines the following:
|
|
# LIBR_FOUND
|
|
# LIBR_HOME
|
|
# LIBR_EXECUTABLE
|
|
# LIBR_INCLUDE_DIRS
|
|
# LIBR_LIB_DIR
|
|
# LIBR_CORE_LIBRARY
|
|
# and a cmake function to create R.lib for MSVC
|
|
#
|
|
# The following could be provided by user through cmake's -D options:
|
|
# LIBR_EXECUTABLE (for unix and win)
|
|
# R_VERSION (for win)
|
|
# R_ARCH (for win 64 when want 32 bit build)
|
|
#
|
|
# TODO:
|
|
# - someone to verify OSX detection,
|
|
# - possibly, add OSX detection based on current R in PATH or LIBR_EXECUTABLE
|
|
# - improve registry-based R_HOME detection in Windows (from a set of R_VERSION's)
|
|
|
|
|
|
# Windows users might want to change this to their R version:
|
|
if(NOT R_VERSION)
|
|
set(R_VERSION "3.4.1")
|
|
endif()
|
|
if(NOT R_ARCH)
|
|
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
|
set(R_ARCH "i386")
|
|
else()
|
|
set(R_ARCH "x64")
|
|
endif()
|
|
endif()
|
|
|
|
|
|
# Creates R.lib and R.def in the build directory for linking with MSVC
|
|
function(create_rlib_for_msvc)
|
|
# various checks and warnings
|
|
if(NOT WIN32 OR NOT MSVC)
|
|
message(FATAL_ERROR "create_rlib_for_msvc() can only be used with MSVC")
|
|
endif()
|
|
if(NOT EXISTS "${LIBR_LIB_DIR}")
|
|
message(FATAL_ERROR "LIBR_LIB_DIR was not set!")
|
|
endif()
|
|
find_program(GENDEF_EXE gendef)
|
|
find_program(DLLTOOL_EXE dlltool)
|
|
if(NOT GENDEF_EXE OR NOT DLLTOOL_EXE)
|
|
message(FATAL_ERROR "\nEither gendef.exe or dlltool.exe not found!\
|
|
\nDo you have Rtools installed with its MinGW's bin/ in PATH?")
|
|
endif()
|
|
# extract symbols from R.dll into R.def and R.lib import library
|
|
execute_process(COMMAND ${GENDEF_EXE}
|
|
"-" "${LIBR_LIB_DIR}/R.dll"
|
|
OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/R.def")
|
|
execute_process(COMMAND ${DLLTOOL_EXE}
|
|
"--input-def" "${CMAKE_CURRENT_BINARY_DIR}/R.def"
|
|
"--output-lib" "${CMAKE_CURRENT_BINARY_DIR}/R.lib")
|
|
endfunction(create_rlib_for_msvc)
|
|
|
|
|
|
# detection for OSX
|
|
if(APPLE)
|
|
|
|
find_library(LIBR_LIBRARIES R)
|
|
|
|
if(LIBR_LIBRARIES MATCHES ".*\\.framework")
|
|
set(LIBR_HOME "${LIBR_LIBRARIES}/Resources" CACHE PATH "R home directory")
|
|
set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory")
|
|
set(LIBR_EXECUTABLE "${LIBR_HOME}/R" CACHE PATH "R executable")
|
|
set(LIBR_LIB_DIR "${LIBR_HOME}/lib" CACHE PATH "R lib directory")
|
|
else()
|
|
get_filename_component(_LIBR_LIBRARIES "${LIBR_LIBRARIES}" REALPATH)
|
|
get_filename_component(_LIBR_LIBRARIES_DIR "${_LIBR_LIBRARIES}" DIRECTORY)
|
|
set(LIBR_EXECUTABLE "${_LIBR_LIBRARIES_DIR}/../bin/R")
|
|
execute_process(
|
|
COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())"
|
|
OUTPUT_VARIABLE LIBR_HOME)
|
|
set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory")
|
|
set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory")
|
|
set(LIBR_LIB_DIR "${LIBR_HOME}/lib" CACHE PATH "R lib directory")
|
|
endif()
|
|
|
|
# detection for UNIX & Win32
|
|
else()
|
|
|
|
# attempt to find R executable
|
|
if(NOT LIBR_EXECUTABLE)
|
|
find_program(LIBR_EXECUTABLE NAMES R R.exe)
|
|
endif()
|
|
|
|
if(UNIX)
|
|
|
|
if(NOT LIBR_EXECUTABLE)
|
|
message(FATAL_ERROR "Unable to locate R executable.\
|
|
\nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable")
|
|
endif()
|
|
|
|
# ask R for the home path
|
|
execute_process(
|
|
COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())"
|
|
OUTPUT_VARIABLE LIBR_HOME
|
|
)
|
|
# ask R for the include dir
|
|
execute_process(
|
|
COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home('include'))"
|
|
OUTPUT_VARIABLE LIBR_INCLUDE_DIRS
|
|
)
|
|
# ask R for the lib dir
|
|
execute_process(
|
|
COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home('lib'))"
|
|
OUTPUT_VARIABLE LIBR_LIB_DIR
|
|
)
|
|
|
|
# Windows
|
|
else()
|
|
# ask R for R_HOME
|
|
if(LIBR_EXECUTABLE)
|
|
execute_process(
|
|
COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home(),winslash='/'))"
|
|
OUTPUT_VARIABLE LIBR_HOME)
|
|
endif()
|
|
# if R executable not available, query R_HOME path from registry
|
|
if(NOT LIBR_HOME)
|
|
get_filename_component(LIBR_HOME
|
|
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${R_VERSION};InstallPath]"
|
|
ABSOLUTE)
|
|
if(NOT LIBR_HOME)
|
|
message(FATAL_ERROR "\nUnable to locate R executable.\
|
|
\nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable")
|
|
endif()
|
|
endif()
|
|
# set exe location based on R_ARCH
|
|
if(NOT LIBR_EXECUTABLE)
|
|
set(LIBR_EXECUTABLE "${LIBR_HOME}/bin/${R_ARCH}/R.exe")
|
|
endif()
|
|
# set other R paths based on home path
|
|
set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include")
|
|
set(LIBR_LIB_DIR "${LIBR_HOME}/bin/${R_ARCH}")
|
|
|
|
message(STATUS "LIBR_HOME [${LIBR_HOME}]")
|
|
message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]")
|
|
message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]")
|
|
message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]")
|
|
message(STATUS "LIBR_CORE_LIBRARY [${LIBR_CORE_LIBRARY}]")
|
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
if(WIN32 AND MSVC)
|
|
# create a local R.lib import library for R.dll if it doesn't exist
|
|
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/R.lib")
|
|
create_rlib_for_msvc()
|
|
endif()
|
|
endif()
|
|
|
|
# look for the core R library
|
|
find_library(LIBR_CORE_LIBRARY NAMES R
|
|
HINTS "${CMAKE_CURRENT_BINARY_DIR}" "${LIBR_LIB_DIR}" "${LIBR_HOME}/bin" "${LIBR_LIBRARIES}")
|
|
if(LIBR_CORE_LIBRARY-NOTFOUND)
|
|
message(STATUS "Could not find R core shared library.")
|
|
endif()
|
|
|
|
set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory")
|
|
set(LIBR_EXECUTABLE ${LIBR_EXECUTABLE} CACHE PATH "R executable")
|
|
set(LIBR_INCLUDE_DIRS ${LIBR_INCLUDE_DIRS} CACHE PATH "R include directory")
|
|
set(LIBR_LIB_DIR ${LIBR_LIB_DIR} CACHE PATH "R shared libraries directory")
|
|
set(LIBR_CORE_LIBRARY ${LIBR_CORE_LIBRARY} CACHE PATH "R core shared library")
|
|
|
|
# define find requirements
|
|
include(FindPackageHandleStandardArgs)
|
|
find_package_handle_standard_args(LibR DEFAULT_MSG
|
|
LIBR_HOME
|
|
LIBR_EXECUTABLE
|
|
LIBR_INCLUDE_DIRS
|
|
LIBR_LIB_DIR
|
|
LIBR_CORE_LIBRARY
|
|
)
|
|
|
|
if(LIBR_FOUND)
|
|
message(STATUS "Found R: ${LIBR_EXECUTABLE}")
|
|
endif()
|