Open Enchufa2 opened 2 years ago
Thanks for reaching out. I agree with you although I only compile a minimalistic version of VTK to get readers and writers for vtk and VTP formats. I'll give it some more thoughts for future versions.
Would pkgconfig
auto detect an already existing VTK build up on those Linux systems?
I don't think that VTK ships any pc files. cmake does have a module to find VTK. Or you could just check for the necessary files in standard locations. Which libraries and headers does riot need?
riot needs to be able to link to the following:
-lvtkIOXML -lvtkIOXMLParser -lvtkIOCore -lvtkIOLegacy \
-lvtkCommonExecutionModel -lvtkCommonDataModel -lvtkCommonTransforms \
-lvtkCommonMath -lvtkCommonMisc -lvtkCommonSystem -lvtkCommonCore \
-lvtkdoubleconversion -lvtkexpat -lvtklz4 -lvtklzma \
-lvtkpugixml -lvtksys -lvtkzlib
BTW, TinyXML2 is also part of Fedora. So another find_package(TinyXML2)
should detect it too.
Thanks! I use cmake
for building VTK. I have no CMakeLists.txt
anywhere. Where would you suggest I add find_package(VTK)
then?
The idea would be to add a src/CMakeLists.txt
file, then call cmake from configure
or src/Makevars
. There seems to be some packages using this approach. One example here.
It might be a good idea. Otherwise it boils down to looking into usr/local/
, doesn't it?
Nope, it's not that easy, because each Linux distribution has a preferred path for libraries. Fedora puts everything under /usr/lib64
. But e.g. Ubuntu has a very different path (something like /usr/lib/x86_64-...
). So if cmake does this for you, it's much much easier.
I have a first draft of the CMakeLists.txt
but when running the R CMD INSTALL
, it fails to find the VTK headers. Are you familiar with this? Can you help please?
cmake_minimum_required(VERSION 3.12)
project(riot)
set(CMAKE_MODULE_PATH
${CMAKE_SOURCE_DIR}/cmake
${CMAKE_MODULE_PATH}
)
message(STATUS ${CMAKE_MODULE_PATH})
message(STATUS ${CMAKE_SOURCE_DIR})
find_package(LibR)
if(${LIBR_FOUND})
else()
message(FATAL_ERROR "No R...")
endif()
message(STATUS ${CMAKE_SOURCE_DIR})
execute_process(
COMMAND ${LIBR_EXECUTABLE} "--slave" "-e" "stopifnot(require('Rcpp'));cat(Rcpp:::Rcpp.system.file('include'))"
OUTPUT_VARIABLE LIBRCPP_INCLUDE_DIRS
)
include_directories(BEFORE ${LIBR_INCLUDE_DIRS})
message(STATUS ${LIBR_INCLUDE_DIRS})
include_directories(BEFORE ${LIBRCPP_INCLUDE_DIRS})
message(STATUS ${LIBRCPP_INCLUDE_DIRS})
find_package(VTK COMPONENTS CommonCore QUIET)
if (NOT VTK_FOUND)
find_package(VTK COMPONENTS vtkCommonCore QUIET)
if (NOT VTK_FOUND)
message("NO_EXISTING_VTK")
return ()
endif()
endif()
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
find_package(VTK COMPONENTS
CommonCore
CommonDataModel
CommonExecutionModel
CommonMath
CommonMisc
CommonSystem
CommonTransforms
IOCore
IOLegacy
IOXML
IOXMLParser
doubleconversion
expat
lz4
lzma
pugixml
vtksys
zlib
)
if (NOT VTK_FOUND)
message("Skipping ${PROJECT_NAME}: ${VTK_NOT_FOUND_MESSAGE}")
return ()
endif()
add_library(vtk INTERFACE)
target_link_libraries(vtk INTERFACE ${VTK_LIBRARIES})
add_custom_target(riot ALL
COMMAND find ${CMAKE_SOURCE_DIR} -name "*.o" -exec rm "{}" "\;"
COMMAND find ${CMAKE_SOURCE_DIR} -name "*.so" -exec rm "{}" "\;"
COMMAND ${LIBR_EXECUTABLE} "--slave" "-e" "\"stopifnot(require(roxygen2));roxygenize('${CMAKE_SOURCE_DIR}',roclets=c('rd','collate','namespace'))\""
COMMAND ${LIBR_EXECUTABLE} CMD INSTALL "${CMAKE_SOURCE_DIR}"
)
add_dependencies(riot vtk)
with the following FindLibR.cmake
file listed under cmake/
:
#
# FindLibR.cmake
#
# Copyright (C) 2009-11 by RStudio, Inc.
#
# This program is licensed to you under the terms of version 3 of the
# GNU Affero General Public License. This program is distributed WITHOUT
# ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
# AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
#
#
# LIBR_FOUND
# LIBR_HOME
# LIBR_INCLUDE_DIRS
# LIBR_DOC_DIR
# LIBR_LIBRARIES
# detection for OSX (look for R framework)
if(APPLE)
find_library(LIBR_LIBRARIES R)
if(LIBR_LIBRARIES)
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_DOC_DIR "${LIBR_HOME}/doc" CACHE PATH "R doc directory")
set(LIBR_EXECUTABLE "${LIBR_HOME}/R" CACHE PATH "R executable")
endif()
# detection for UNIX & Win32
else()
# Find R executable and paths (UNIX)
if(UNIX)
# find executable
find_program(LIBR_EXECUTABLE R)
if(LIBR_EXECUTABLE-NOTFOUND)
message(STATUS "Unable to locate R executable")
endif()
# ask R for the home path
if(NOT LIBR_HOME)
execute_process(
COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home())"
OUTPUT_VARIABLE LIBR_HOME
)
if(LIBR_HOME)
set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory")
endif()
endif()
# ask R for the include dir
if(NOT LIBR_INCLUDE_DIRS)
execute_process(
COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('include'))"
OUTPUT_VARIABLE LIBR_INCLUDE_DIRS
)
if(LIBR_INCLUDE_DIRS)
set(LIBR_INCLUDE_DIRS ${LIBR_INCLUDE_DIRS} CACHE PATH "R include directory")
endif()
endif()
# ask R for the doc dir
if(NOT LIBR_DOC_DIR)
execute_process(
COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('doc'))"
OUTPUT_VARIABLE LIBR_DOC_DIR
)
if(LIBR_DOC_DIR)
set(LIBR_DOC_DIR ${LIBR_DOC_DIR} CACHE PATH "R doc directory")
endif()
endif()
# ask R for the lib dir
if(NOT LIBR_LIB_DIR)
execute_process(
COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('lib'))"
OUTPUT_VARIABLE LIBR_LIB_DIR
)
endif()
# Find R executable and paths (Win32)
else()
# find the home path
if(NOT LIBR_HOME)
# read home from the registry
get_filename_component(LIBR_HOME
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R;InstallPath]"
ABSOLUTE CACHE)
# print message if not found
if(NOT LIBR_HOME)
message(STATUS "Unable to locate R home (not written to registry)")
endif()
endif()
# set other R paths based on home path
set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory")
set(LIBR_DOC_DIR "${LIBR_HOME}/doc" CACHE PATH "R doc directory")
# set library hint path based on whether we are doing a special session 64 build
if(LIBR_FIND_WINDOWS_64BIT)
set(LIBRARY_ARCH_HINT_PATH "${LIBR_HOME}/bin/x64")
else()
set(LIBRARY_ARCH_HINT_PATH "${LIBR_HOME}/bin/i386")
endif()
endif()
# look for the R executable
find_program(LIBR_EXECUTABLE R
HINTS ${LIBRARY_ARCH_HINT_PATH} ${LIBR_HOME}/bin)
if(LIBR_EXECUTABLE-NOTFOUND)
message(STATUS "Unable to locate R executable")
endif()
# look for the core R library
find_library(LIBR_CORE_LIBRARY NAMES R
HINTS ${LIBR_LIB_DIR} ${LIBRARY_ARCH_HINT_PATH} ${LIBR_HOME}/bin)
if(LIBR_CORE_LIBRARY)
set(LIBR_LIBRARIES ${LIBR_CORE_LIBRARY})
else()
message(STATUS "Could not find libR shared library.")
endif()
# look for lapack
find_library(LIBR_LAPACK_LIBRARY NAMES Rlapack
HINTS ${LIBR_LIB_DIR} ${LIBRARY_ARCH_HINT_PATH} ${LIBR_HOME}/bin)
if(LIBR_LAPACK_LIBRARY)
set(LIBR_LIBRARIES ${LIBR_LIBRARIES} ${LIBR_LAPACK_LIBRARY})
if(UNIX)
set(LIBR_LIBRARIES ${LIBR_LIBRARIES} gfortran)
endif()
endif()
# look for blas
find_library(LIBR_BLAS_LIBRARY NAMES Rblas
HINTS ${LIBR_LIB_DIR} ${LIBRARY_ARCH_HINT_PATH} ${LIBR_HOME}/bin)
if(LIBR_BLAS_LIBRARY)
set(LIBR_LIBRARIES ${LIBR_LIBRARIES} ${LIBR_BLAS_LIBRARY})
endif()
# look for rgraphapp on win32
if(WIN32)
find_library(LIBR_GRAPHAPP_LIBRARY NAMES Rgraphapp
HINTS ${LIBR_LIB_DIR} ${LIBRARY_ARCH_HINT_PATH} ${LIBR_HOME}/bin)
if(LIBR_GRAPHAPP_LIBRARY)
set(LIBR_LIBRARIES ${LIBR_LIBRARIES} ${LIBR_GRAPHAPP_LIBRARY})
endif()
endif()
# cache LIBR_LIBRARIES
if(LIBR_LIBRARIES)
set(LIBR_LIBRARIES ${LIBR_LIBRARIES} CACHE PATH "R runtime libraries")
endif()
endif()
# define find requirements
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibR DEFAULT_MSG
LIBR_HOME
LIBR_EXECUTABLE
LIBR_INCLUDE_DIRS
LIBR_LIBRARIES
LIBR_DOC_DIR
)
if(LIBR_FOUND)
message(STATUS "Found R: ${LIBR_HOME}")
endif()
# mark low-level variables from FIND_* calls as advanced
mark_as_advanced(
LIBR_CORE_LIBRARY
LIBR_LAPACK_LIBRARY
LIBR_BLAS_LIBRARY
)
It works for me in Fedora with vtk-devel installed:
$ ls .
cmake CMakeLists.txt
$ cmake -B build
-- /home/user/tmp/cmake
-- /home/user/tmp
-- Found R: /usr/lib64/R
-- /home/user/tmp
Loading required package: Rcpp
-- /usr/include/R
-- /usr/local/lib/R/library/Rcpp/include
-- VTK_VERSION: 9.1.0
-- Found Threads: TRUE
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.12")
-- Found EXPAT: /usr/lib64/libexpat.so (found version "2.5.0")
-- Found double-conversion: /usr/lib64/libdouble-conversion.so
-- Found LZ4: /usr/lib64/liblz4.so (found version "1.9.3")
-- Found LZMA: /usr/lib64/liblzma.so (found version "5.2.5")
-- Found utf8cpp: /usr/include/utf8cpp
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/tmp/build
Could you please put everything together in a separate branch here for testing?
Yes i will do that. But the Cmake command run you show also works on my Mac. It's the subsequent make command that throws errors.
I cannot test your setup without the changes required to the configure file, that's why I am asking for a new branch with this stuff, so that I can directly clone, checkout the branch and run R CMD INSTALL
there. :)
It is taking me too much time at the moment. I think I will release without this feature unless you think you can contribute. Thanks for your time anyway and happy new year!
Not at this moment, sorry! :)
I will probably close this issue. Detecting an existing VTK build
Hence, I prefer to have control over the compilation.
There is already no compilation happening on Windows.
On macOS and Linux, I now ship a shrunk version of latest stable VTK source files which weighs 3.6MB
and builds from that with cmake
.
You mean that you bundle it? But this is not on CRAN yet, right? Bundling is fine. The issue is with downloading things at build time.
Exactly. Not yet on CRAN, submitted but I have not heard from them yet. If all goes well, I'll close this issue when v1.1.1 reaches CRAN.
Compiling vtk is a huge undertaking, but there are Linux distributions that already have it in their official repos (e.g., Fedora). Would it be possible to detect an existing installation and avoid the compilation altogether?