Attached is my initial attempt to check for the existence of python modules and 
R packages. 

In the case of python, I need to be able to check for a specific version of 
python (find corresponding executable, libraries, and headers) and check for 
modules in that version of python. This is not possible with the 
FindPythonInterp.cmake and FindPythonLibs.cmake. The location of modules is 
returned. I also return the location where new modules should be installed. 

The FindR module is much simpler, mostly because I know much less about R. I 
did add a function to install an R module in the default location for a user’s 
R packages, if it’s not already installed.

I realize this code is somewhat UNIX-biased, but perhaps adding Windows support 
is not too difficult. If anyone has ideas to improve this code, please let me 
know.
-- 
Mark


# This code sets the following variables:
# PYTHON_EXEC         - path to python executable
# PYTHON_LIBRARIES    - path to the python library
# PYTHON_INCLUDE_DIRS - path to where Python.h is found
# PTYHON_SITE_MODULES - path to site-packages
# PYTHON_ARCH         - name of architecture to be used for platform-specific 
#                       binary modules
# PYTHON_VERSION      - version of python
#
# You can optionally include the version number when using this package 
# like so:
#       find_package(python 2.6)
#
# This code defines a helper function find_python_module(). It can be used 
# like so:
#       find_python_module(numpy)
# If numpy is found, the variable PY_NUMPY contains the location of the numpy 
# module. If the module is required add the keyword "REQUIRED":
#       find_python_module(numpy REQUIRED)

find_program(PYTHON_EXEC "python${Python_FIND_VERSION}" 
        DOC "Location of python executable to use")
string(REGEX REPLACE "/bin/python${Python_FIND_VERSION}$" "" PYTHON_PREFIX
        "${PYTHON_EXEC}")
execute_process(COMMAND "${PYTHON_EXEC}" "-c"
        "import sys; print '%d.%d' % (sys.version_info[0],sys.version_info[1])"
        OUTPUT_VARIABLE PYTHON_VERSION
        OUTPUT_STRIP_TRAILING_WHITESPACE)
find_library(PYTHON_LIBRARIES "python${PYTHON_VERSION}" PATHS 
"${PYTHON_PREFIX}" 
        PATH_SUFFIXES "lib" "lib/python${PYTHON_VERSION}/config" 
        DOC "Python libraries" NO_DEFAULT_PATH)
find_path(PYTHON_INCLUDE_DIRS "Python.h"
        PATHS "${PYTHON_PREFIX}/include/python${PYTHON_VERSION}"
        DOC "Python include directories" NO_DEFAULT_PATH)
execute_process(COMMAND "${PYTHON_EXEC}" "-c" 
        "from distutils.sysconfig import get_python_lib; print get_python_lib()"
        OUTPUT_VARIABLE PYTHON_SITE_MODULES
        OUTPUT_STRIP_TRAILING_WHITESPACE)

function(find_python_module module)
        string(TOUPPER ${module} module_upper)
        if(NOT PY_${module_upper})
                if(ARGC GREATER 1 AND ARGV1 STREQUAL "REQUIRED")
                        set(${module}_FIND_REQUIRED TRUE)
                endif()
                # A module's location is usually a directory, but for binary 
modules
                # it's a .so file.
                execute_process(COMMAND "${PYTHON_EXEC}" "-c" 
                        "import re, ${module}; print 
re.compile('/__init__.py.*').sub('',${module}.__file__)"
                        RESULT_VARIABLE _${module}_status 
                        OUTPUT_VARIABLE _${module}_location
                        ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
                if(NOT _${module}_status)
                        set(PY_${module_upper} ${_${module}_location} CACHE 
STRING 
                                "Location of Python module ${module}")
                endif(NOT _${module}_status)
        endif(NOT PY_${module_upper})
        find_package_handle_standard_args(PY_${module} DEFAULT_MSG 
PY_${module_upper})
endfunction(find_python_module)

set(PYTHON_ARCH "unknown")
if(APPLE)
        set(PYTHON_ARCH "darwin")
else(APPLE)
        if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
                if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
                        set(PYTHON_ARCH "linux2")
                else(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
                        set(PYTHON_ARCH "linux")
                endif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
        else(CMAKE_SYSTEM_NAME STREQUAL "Linux")
                if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
                        set(PYTHON_ARCH "windows")
                endif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
        endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
endif(APPLE)

find_package_handle_standard_args(Python DEFAULT_MSG 
        PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS PYTHON_SITE_MODULES)


===============================================================

# This code sets the following variables
# R_EXEC      - path to R executable
# R_LIBS_USER - path to directory of user's R packages (defined only if R is 
found) 
#
# It also defines the following help functions if R is found:
# FIND_R_PACKAGE(package)            - sets R_<PACKAGE> to ON if package is 
installed 
# INSTALL_R_PACKAGE(package)         - installs package in ${R_LIBS_USER}
# FIND_OR_INSTALL_R_PACKAGE(package) - finds package and installs it, if not 
found

find_program(R_EXEC R)

if(R_EXEC)
        # R_LIBS_USER is always defined within R, even if it is not explicitly 
set by the user
        execute_process(COMMAND "${R_EXEC}" "--slave" "-e" 
                "print(Sys.getenv(\"R_LIBS_USER\"))"
                OUTPUT_VARIABLE _rlibsuser
                OUTPUT_STRIP_TRAILING_WHITESPACE)
        string(REGEX REPLACE "[ ]*(R_LIBS_USER)[ ]*\n\"(.*)\"" "\\2"
                R_LIBS_USER ${_rlibsuser})
        
        function(find_r_package package)
                string(TOUPPER ${package} package_upper)
                if(NOT R_${package_upper})
                        if(ARGC GREATER 1 AND ARGV1 STREQUAL "REQUIRED")
                                set(${package}_FIND_REQUIRED TRUE)
                        endif()
                        execute_process(COMMAND "${R_EXEC}" "--slave" "-e" 
                                "library('${package}')"
                                RESULT_VARIABLE _${package}_status 
                                ERROR_QUIET OUTPUT_QUIET)
                        if(NOT _${package}_status)
                                set(R_${package_upper} TRUE CACHE BOOL 
                                        "Whether the R package ${package} is 
installed")
                        endif(NOT _${package}_status)
                endif(NOT R_${package_upper})
                find_package_handle_standard_args(R_${package} DEFAULT_MSG 
R_${package_upper})
        endfunction(find_r_package)
        
        function(install_r_package package)
                message(STATUS "Installing R package ${package}...")
                execute_process(COMMAND "${R_EXEC}" "--slave" "-e"
                        
"install.packages('${package}','${R_LIBS_USER}','http://cran.r-project.org')"
                        ERROR_QUIET OUTPUT_QUIET)
                message(STATUS "R package ${package} has been installed in 
${R_LIBS_USER}")
        endfunction(install_r_package)
        
        function(find_or_install_r_package package)
                find_r_package(${package})
                string(TOUPPER ${package} package_upper)
                if(NOT R_${package_upper})
                        install_r_package(${package})
                endif()
        endfunction(find_or_install_r_package)
endif(R_EXEC)

find_package_handle_standard_args(R DEFAULT_MSG R_EXEC)

-- 
Mark



_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to