1 ############################################################################## 2 # @file FindPythonModules.cmake 3 # @brief Find Python modules. 5 # @par Input/Output variables: 8 # @tp @b PythonModules_DIR @endtp 9 # <td>List of directories where Python modules are installed.</td> 13 # @par Input variables: 16 # @tp @b PythonModules_FIND_COMPONENTS @endtp 17 # <td>The @c COMPONENTS argument(s) of the find_package() command specifies 18 # the names of the Python modules to look for.</td> 21 # @tp @b PythonModules_FIND_OPTIONAL_COMPONENTS @endtp 22 # <td>The @c OPTIONAL_COMPONENTS argument(s) of the find_package() command 23 # specifies the names of the Python modules which are not necessarily 24 # required, but should be searched as well.</td> 27 # @tp @b PYTHON_EXECUTABLE @endtp 28 # <td>Path to the Python interpreter. Should be set by first looking 29 # for the Python interpreter, i.e., find_packages(PythonInterp). 30 # If set, this module first tries to execute the Python interpreter, 31 # import the respective Python module, and then derive the search path 32 # from the @c __file__ attribute of the loaded Python module. 33 # Otherwise, or if this fails, it looks either for a package 34 # @c __init__.py file inside a subdirectory named after the specified 35 # Python module or a @c .py module file in each directory listed in 36 # the @c PYTHONPATH.</td> 39 # @tp @b PYTHONPATH @endtp 40 # <td>Search path for Python modules. If this CMake variable is undefined, 41 # the corresponding environment variable is used instead if set. 42 # Only absolute paths in the @c PYTHONPATH are considered.</td> 46 # @par Output variables: 49 # @tp @b PythonModules_FOUND @endtp 50 # <td>Whether all specified Python modules were found.</td> 53 # @tp @b PythonModules_<module>_FOUND @endtp 54 # <td>Whether the Python module <module%gt; was found.</td> 57 # @tp @b PythonModules_<module>_PATH @endtp 58 # <td>Absolute path of the directory containing the Python module named <module%gt;.</td> 61 # @tp @b PythonModules_<module> @endtp 62 # <td>Import target for module named <module>. The location of the 63 # target is @c PythonModules_<module>_PATH.</tr> 66 # @tp @b PythonModules_PYTHONPATH @endtp 67 # <td>The @c PYTHONPATH setting required for the found Python module(s), i.e., 68 # The directories that have to be added to the Python search path. 69 # To support the use of this CMake module more than once with different 70 # arguments to the find_package() command, e.g., with and without the 71 # @c REQUIRED argument, the directories containing the found Python 72 # modules are appended to any existing directories in 73 # @c PythonModules_PYTHONPATH if not already listed.</td> 77 # @ingroup CMakeFindModules 78 ############################################################################## 80 #============================================================================= 81 # Copyright 2011-2012 University of Pennsylvania 82 # Copyright 2013-2016 Andreas Schuh <andreas.schuh.84@gmail.com> 84 # Distributed under the OSI-approved BSD License (the "License"); 85 # see accompanying file Copyright.txt for details. 87 # This software is distributed WITHOUT ANY WARRANTY; without even the 88 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 89 # See the License for more information. 90 #============================================================================= 91 # (To distribute this file outside of CMake, substitute the full 92 # License text for the above reference.) 94 include (CMakeParseArguments)
96 # ---------------------------------------------------------------------------- 97 ## @brief Find Python module. 99 # If the @c PYTHON_EXECUTABLE variable is set, this function at first tries 100 # to launch the Python interpreter, import the named Python module, and then 101 # determines the search path for the Python module from the @c __file__ 102 # attribute of the loaded module. Otherwise, or if this fails, it looks for 103 # the Python module in the directories listed in the @c PYTHONPATH variable 104 # if defined. If this variable is not defined, the @c PYTHONPATH environment 105 # variable is used instead. 107 # @param [in] CACHEVAR Name of CMake cache variable which stores path of 108 # directory of the Python module. If not set or if 109 # the cache entry contains space characters only or 110 # ends in the string NOTFOUND, this function looks for 111 # the specified Python module. Otherwise, it does nothing 112 # and leaves the cache entry unmodified. 113 # @param [in] ARGN The remaining arguments are parsed and the following 118 # @tp @b NAME module @endtp 119 # <td>Name of the Python module.</td> 122 # @tp @b PYTHON_EXECUTABLE python @endtp 123 # <td>Full path of the Python interpreter executable. If not specified 124 # the global PYTHON_EXECUTABLE CMake variable/cache entry is used.</td> 127 # @tp @b PATH dir1 [dir2...] @endtp 128 # <td>Directories where to look for Python module.</td> 131 # @tp @b NO_PYTHONPATH @endtp 132 # <td>Do not consider the @c PYTHONPATH environment variable.</td> 135 # @tp @b NO_DEFAULT_PATH @endtp 136 # <td>Do not look in any default path such as the directories listed by the 137 # @c PYTHONPATH environment variable.</td> 141 # @returns Sets the named cache variable of type @c PATH to the absolute path 142 # of the directory containing the specified Python @p MODULE if found, 143 # or the string "<MODULE%gt;-NOTFOUND" otherwise. 145 #
do nothing
if path of module already known from previous run
146 if (DEFINED ${CACHEVAR} AND NOT ${CACHEVAR} MATCHES
"NOTFOUND$")
150 CMAKE_PARSE_ARGUMENTS (
152 "NO_DEFAULT_PATH;NO_PYTHONPATH" 153 "PYTHON_EXECUTABLE;NAME" 158 message (
"basis_find_python_module(): Missing NAME argument!")
160 if (ARGN_UNPARSED_ARGUMENTS)
163 if (NOT ARGN_PYTHON_EXECUTABLE) 164 set (ARGN_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}
") 166 if (ARGN_NO_DEFAULT_PATH) 167 set (ARGN_NO_PYTHONPATH TRUE) 168 set (ARGN_PYTHON_EXECUTABLE) 170 # set initial value of cache entry 171 if (${CACHEVAR} MATCHES "^ *$
") 172 set (${CACHEVAR} "${ARGN_NAME}-NOTFOUND
" CACHE PATH "Directory containing ${ARGN_NAME} Python module/package.
" FORCE) 174 set (${CACHEVAR} "${ARGN_NAME}-NOTFOUND
" CACHE PATH "Directory containing ${ARGN_NAME} Python module/package.
") 176 # 1. search specified paths 177 foreach (P ${ARGN_PATH}) # ignore empty entries 178 if (IS_ABSOLUTE "${P}
") 179 if (EXISTS "${P}/${ARGN_NAME}.py
" OR EXISTS "${P}/${ARGN_NAME}/__init__.py
" OR 180 EXISTS "${P}/${ARGN_NAME}.pyc
" OR EXISTS "${P}/${ARGN_NAME}/__init__.pyc
") 181 set_property (CACHE ${CACHEVAR} PROPERTY VALUE "${P}
") 186 # 2. get __file__ attribute of module loaded in Python 187 if (ARGN_PYTHON_EXECUTABLE) 188 set (IMPORT_SITE_ERROR FALSE) 189 # 2a. try it with -E option -- the preferred way to run Python 191 COMMAND "${ARGN_PYTHON_EXECUTABLE}
" -E -c "import ${ARGN_NAME}; print ${ARGN_NAME}.__file__
" 192 RESULT_VARIABLE STATUS 195 OUTPUT_STRIP_TRAILING_WHITESPACE 197 if (ERROR MATCHES "'import site' failed|ImportError: No module named site
") 198 set (IMPORT_SITE_ERROR TRUE) 200 # 2b. try it without -E option 201 if (NOT STATUS EQUAL 0) 203 COMMAND "${ARGN_PYTHON_EXECUTABLE}
" -c "import ${ARGN_NAME}; print ${ARGN_NAME}.__file__
" 204 RESULT_VARIABLE STATUS 207 OUTPUT_STRIP_TRAILING_WHITESPACE 209 if (ERROR MATCHES "'import site' failed|ImportError: No module named site
") 210 set (IMPORT_SITE_ERROR TRUE) 212 if (NOT STATUS EQUAL 0 AND ERROR MATCHES "ImportError: No module named site
") 213 set (PYTHONHOME "$ENV{PYTHONHOME}
") 214 unset (ENV{PYTHONHOME}) 216 COMMAND "${ARGN_PYTHON_EXECUTABLE}
" -c "import ${ARGN_NAME}; print ${ARGN_NAME}.__file__
" 217 RESULT_VARIABLE STATUS 220 OUTPUT_STRIP_TRAILING_WHITESPACE 222 if (ERROR MATCHES "'import site' failed|ImportError: No module named site
") 223 set (IMPORT_SITE_ERROR TRUE) 225 set (ENV{PYTHONHOME} "${PYTHONHOME}
") 229 if (P MATCHES "__init__\\.pyc?$
") 230 get_filename_component (P "${P}
" PATH) 231 get_filename_component (P "${P}
" PATH) 233 get_filename_component (P "${P}
" PATH) 235 set_property (CACHE ${CACHEVAR} PROPERTY VALUE "${P}
") 237 elseif (IMPORT_SITE_ERROR) 238 message (WARNING "Import of site module failed when running Python interpreter ${ARGN_PYTHON_EXECUTABLE}
" 239 " with and without -E option. Make sure that the Python interpreter
is installed properly
" 240 " and that the PYTHONHOME environment variable
is either not
set (recommended) or at
" 241 " least
set correctly
for this Python installation. Maybe you need to enable
this Python
" 242 " version first somehow
if more than one version of Python
is installed on your system?
" 243 " Otherwise,
set PYTHON_EXECUTABLE to the right Python interpreter executable (python).
") 246 # 3. search PYTHONPATH 247 if (NOT ARGN_NO_PYTHONPATH) 248 string (REPLACE ":
" ";
" PYTHONPATH "$ENV{PYTHONPATH}
") 249 foreach (P ${PYTHONPATH}) # ignore empty entries 250 if (IS_ABSOLUTE "${P}
") 251 if (EXISTS "${P}/${ARGN_NAME}.py
" OR EXISTS "${P}/${ARGN_NAME}/__init__.py
" OR 252 EXISTS "${P}/${ARGN_NAME}.pyc
" OR EXISTS "${P}/${ARGN_NAME}/__init__.pyc
") 253 set_property (CACHE ${CACHEVAR} PROPERTY VALUE "${P}
") 261 # ---------------------------------------------------------------------------- 262 # find Python modules 263 if (NOT PythonModules_FIND_COMPONENTS AND NOT PythonModules_FIND_OPTIONAL_COMPONENTS) 264 message (FATAL_ERROR "PythonModules: No (OPTIONAL_)COMPONENTS (i.
e., Python module names) specified!")
266 if (NOT DEFINED PythonModules_PYTHONPATH)
267 set (PythonModules_PYTHONPATH)
# PYTHONPATH of all found modules 270 macro (_PythonModules_find_python_modules ALL_FOUND)
271 set (${ALL_FOUND} TRUE)
272 foreach (_PythonModules_MODULE ${ARGN})
273 set (_PythonModules_VAR
"PythonModules_${_PythonModules_MODULE}_PATH")
274 set (_PythonModules_TGT
"PythonModules_${_PythonModules_MODULE}")
275 if (PythonModules_DIR)
277 ${_PythonModules_VAR}
278 NAME "${_PythonModules_MODULE}" 279 PATH
"${PythonModules_DIR}" 284 ${_PythonModules_VAR}
285 NAME "${_PythonModules_MODULE}" 286 PATH
"${PythonModules_DIR}" 289 mark_as_advanced (${_PythonModules_VAR})
290 if (${_PythonModules_VAR} MATCHES
"(^ *|NOTFOUND)$")
291 set (${ALL_FOUND} FALSE)
292 set (PythonModules_${_PythonModules_MODULE}_FOUND FALSE)
294 if (NOT TARGET ${_PythonModules_TGT})
295 add_library (${_PythonModules_TGT} UNKNOWN IMPORTED)
297 ${_PythonModules_TGT}
299 BASIS_TYPE
"SCRIPT_LIBRARY" 300 IMPORTED_LOCATION
"${${_PythonModules_VAR}}" 303 set (PythonModules_${_PythonModules_MODULE}_FOUND TRUE)
304 list (APPEND PythonModules_PYTHONPATH
"${${_PythonModules_VAR}}")
308 # optional first, as PythonModules_FOUND shall be reset to TRUE afterwards 309 _PythonModules_find_python_modules (PythonModules_FOUND ${PythonModules_FIND_OPTIONAL_COMPONENTS})
310 _PythonModules_find_python_modules (PythonModules_FOUND ${PythonModules_FIND_COMPONENTS})
311 #
remove duplicate paths in PYTHONPATH
312 if (PythonModules_PYTHONPATH)
313 list (REMOVE_DUPLICATES PythonModules_PYTHONPATH)
316 # ---------------------------------------------------------------------------- 317 # handle standard QUIET and REQUIRED arguments 318 if (NOT PythonModules_FOUND)
319 # list of modules that were not found 320 set (_PythonModules_MISSING)
321 foreach (_PythonModules_MODULE ${PythonModules_FIND_COMPONENTS})
322 if (NOT PythonModules_${_PythonModules_MODULE}_FOUND)
323 list (APPEND _PythonModules_MISSING
"${_PythonModules_MODULE}")
326 # hint on how to help finding the Python modules 328 if (PYTHON_EXECUTABLE)
331 set (
_PythonModules_HINT "Set PYTHON_EXECUTABLE, e.g., by searching for Python interpreter first")
338 set (
_PythonModules_HINT "${_PythonModules_HINT} the PythonModules_DIR variable. Alternatively,")
339 set (
_PythonModules_HINT "${_PythonModules_HINT} set the PythonModules_<module>_PATH variable(s)")
340 set (
_PythonModules_HINT "${_PythonModules_HINT} instead or the PYTHONPATH environment variable.")
341 set (
_PythonModules_HINT "${_PythonModules_HINT} Unset PythonModules_DIR if you chose an alternative")
342 set (
_PythonModules_HINT "${_PythonModules_HINT} option and before rerunning CMake again.")
344 string (REPLACE
";" ", " ${_PythonModules_MISSING}
"${_PythonModules_MISSING}")
345 message (FATAL_ERROR
"Could NOT find the following Python modules:\n${_PythonModules_MISSING}\n${_PythonModules_HINT}")
348 # ---------------------------------------------------------------------------- 349 # common <Pkg>_DIR variable 350 if (NOT PythonModules_DIR)
353 "${PythonModules_PYTHONPATH}" 355 "Directory or list of directories separated by ; of installed Python modules." 360 # ---------------------------------------------------------------------------- 362 unset (_PythonModules_MODULE)
363 unset (_PythonModules_VAR)
364 unset (_PythonModules_VARS)
function set_target_properties(in ARGN)
Set target property.
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.
function add_library(in TARGET_UID, in ARGN)
Add library target.
cmake _PythonModules_HINT
function basis_find_python_module(in CACHEVAR, in ARGN)
Find Python module.