mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Added pycmake folder.
This commit is contained in:
parent
eae6afff80
commit
076ea3db77
168
python/pycmake/FindPythonModule.cmake
Normal file
168
python/pycmake/FindPythonModule.cmake
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# Copyright (C) 2016 Statoil ASA, Norway.
|
||||||
|
#
|
||||||
|
# This file is part of ERT - Ensemble based Reservoir Tool.
|
||||||
|
#
|
||||||
|
# ERT is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE.
|
||||||
|
#
|
||||||
|
# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||||
|
# for more details
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The basic assumption of this package is PEP 396 -- Module Version Numbers as
|
||||||
|
# layed out in https://www.python.org/dev/peps/pep-0396/
|
||||||
|
|
||||||
|
# Unfortunately, not all Python modules expose a version number, like inspect.
|
||||||
|
# Other Python modules expose several version numbers, e.g. one for the
|
||||||
|
# underlying software and one for the python packaging, like SQLite and PyQt.
|
||||||
|
|
||||||
|
cmake_minimum_required (VERSION 2.8.1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# try import python module, if success, check its version, store as PY_module.
|
||||||
|
# the module is imported as-is, hence the case (e.g. PyQt4) must be correct.
|
||||||
|
#
|
||||||
|
# if given a second argument, the accessor, we call accessor on the module
|
||||||
|
# instead of the default __version__.
|
||||||
|
#
|
||||||
|
# (Yes, accessor could potentially be a function like "os.delete_everything()".)
|
||||||
|
macro(python_module_version module)
|
||||||
|
set(PY_VERSION_ACCESSOR "__version__")
|
||||||
|
set(PY_module_name ${module})
|
||||||
|
|
||||||
|
if(${PY_module_name} STREQUAL "PyQt4")
|
||||||
|
set(PY_module_name "PyQt4.Qt")
|
||||||
|
endif()
|
||||||
|
if(${PY_module_name} STREQUAL "PyQt4.Qt")
|
||||||
|
set(PY_VERSION_ACCESSOR "PYQT_VERSION_STR")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${PY_module_name} STREQUAL "serial")
|
||||||
|
set(PY_VERSION_ACCESSOR "VERSION")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${PY_module_name} STREQUAL "sqlite")
|
||||||
|
set(PY_VERSION_ACCESSOR "version")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# ARGUMENTS: module accessor
|
||||||
|
set (extra_macro_args ${ARGN})
|
||||||
|
list(LENGTH extra_macro_args num_extra_args)
|
||||||
|
if (${num_extra_args} GREATER 0)
|
||||||
|
list(GET extra_macro_args 0 accessor)
|
||||||
|
set(PY_VERSION_ACCESSOR ${accessor})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
|
||||||
|
"# set module's version to py_mv and print it
|
||||||
|
import ${PY_module_name} as py_m
|
||||||
|
py_mv = '0.0.0' # output if no accessor is found
|
||||||
|
if hasattr(py_m, '${PY_VERSION_ACCESSOR}'):
|
||||||
|
py_mv = py_m.${PY_VERSION_ACCESSOR}
|
||||||
|
print(py_mv)
|
||||||
|
"
|
||||||
|
RESULT_VARIABLE _${module}_fail # error code 0 if module is importable
|
||||||
|
OUTPUT_VARIABLE _${module}_version # module.accessor or "0.0.0" if no such
|
||||||
|
ERROR_VARIABLE stderr_output
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if(NOT _${module}_fail)
|
||||||
|
set(PY_${module} ${_${module}_version})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
unset(PY_VERSION_ACCESSOR)
|
||||||
|
unset(PY_module_name)
|
||||||
|
unset(extra_macro_args)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# If we find the correct module and new enough version, set PY_package, where
|
||||||
|
# "package" is the given argument to the version we found else, display warning
|
||||||
|
# and do not set any variables.
|
||||||
|
macro(python_module package)
|
||||||
|
|
||||||
|
# ARGUMENTS: package package_req module_version version_req accessor
|
||||||
|
set (extra_macro_args ${ARGN})
|
||||||
|
# Did we get any optional args?
|
||||||
|
list(LENGTH extra_macro_args num_extra_args)
|
||||||
|
if (${num_extra_args} GREATER 0)
|
||||||
|
list(GET extra_macro_args 0 package_req)
|
||||||
|
else()
|
||||||
|
set(package_req "REQUIRED") # requirement not set, is required
|
||||||
|
endif ()
|
||||||
|
if (${num_extra_args} GREATER 1)
|
||||||
|
list(GET extra_macro_args 1 module_version)
|
||||||
|
else()
|
||||||
|
set(module_version "0.0.0") # module_version not set, 0.0.0 is ok
|
||||||
|
endif ()
|
||||||
|
if (${num_extra_args} GREATER 2)
|
||||||
|
list(GET extra_macro_args 2 version_req)
|
||||||
|
else()
|
||||||
|
set(version_req "MINIMUM") # version requirement not set, is minimum
|
||||||
|
endif ()
|
||||||
|
if (${num_extra_args} GREATER 3)
|
||||||
|
list(GET extra_macro_args 3 accessor)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Setting warning/error output level
|
||||||
|
set(PY_MSG_ERR SEND_ERROR)
|
||||||
|
set(PY_MSG_WARN WARNING)
|
||||||
|
if(${package_req} STREQUAL "QUIET")
|
||||||
|
set(PY_MSG_ERR STATUS)
|
||||||
|
set(PY_MSG_WARN STATUS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# We are done expanding the optional arguments
|
||||||
|
|
||||||
|
python_module_version(${package} ${accessor})
|
||||||
|
|
||||||
|
# package not found in system
|
||||||
|
if(NOT DEFINED PY_${package})
|
||||||
|
if(${package_req} STREQUAL "OPTIONAL")
|
||||||
|
message(${PY_MSG_WARN} "Could not find Python module " ${package})
|
||||||
|
else()
|
||||||
|
message(${PY_MSG_ERR} "Could not find Python module " ${package})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
else()
|
||||||
|
# package found in system
|
||||||
|
|
||||||
|
if (${version_req} STREQUAL "EXACT" AND NOT ${PY_${package}} VERSION_EQUAL ${module_version})
|
||||||
|
message(${PY_MSG_ERR} "Python module ${package} not exact. "
|
||||||
|
"Wanted EXACT ${module_version}, found ${PY_${package}}")
|
||||||
|
elseif (${version_req} STREQUAL "OPTIONAL" AND ${PY_${package}} VERSION_LESS ${module_version})
|
||||||
|
message(${PY_MSG_WARN} "Python module ${package} too old. "
|
||||||
|
"Wanted ${module_version}, found ${PY_${package}}")
|
||||||
|
elseif (${version_req} STREQUAL "MINIMUM" AND ${PY_${package}} VERSION_LESS ${module_version})
|
||||||
|
message(${PY_MSG_ERR} "Python module ${package} too old. "
|
||||||
|
"Wanted MINIMUM ${module_version}, found ${PY_${package}}")
|
||||||
|
else()
|
||||||
|
if(NOT DEFINED accessor)
|
||||||
|
message(STATUS "Found ${package}. "
|
||||||
|
"${PY_${package}} >= ${module_version}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Found ${package}. "
|
||||||
|
"${PY_${package}} >= ${module_version} (" ${accessor} ")")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
unset(package_req)
|
||||||
|
unset(module_version)
|
||||||
|
unset(version_req)
|
||||||
|
unset(accessor)
|
||||||
|
unset(extra_macro_args)
|
||||||
|
set(PY_MSG_ERR)
|
||||||
|
set(PY_MSG_WARN)
|
||||||
|
endmacro()
|
93
python/pycmake/PythonPackage.cmake
Normal file
93
python/pycmake/PythonPackage.cmake
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# Copyright (C) 2016 Statoil ASA, Norway.
|
||||||
|
#
|
||||||
|
# pymake is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pymake is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE.
|
||||||
|
#
|
||||||
|
# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||||
|
# for more details
|
||||||
|
|
||||||
|
# This module exports the following functions:
|
||||||
|
# * to_path_list(var path)
|
||||||
|
# which takes a list of paths and constructs a valid PYTHONPATH string,
|
||||||
|
# regardless of platform (path1:path2 for unix, path1;path2 for windows)
|
||||||
|
#
|
||||||
|
# * add_python_package(package_name package_path python_files) where
|
||||||
|
# which takes a package name, a path and the series of python files that
|
||||||
|
# makes that package. It exports the cmake target package_${package_name}
|
||||||
|
# in copies all ${python_files} sources to python/${package_path}, and
|
||||||
|
# sets up so you can install with `make install`.
|
||||||
|
#
|
||||||
|
# * add_python_test(testname python_test_file)
|
||||||
|
# which sets up a test target (using pycmake_test_runner.py, distributed
|
||||||
|
# with this module) and registeres it with ctest.
|
||||||
|
#
|
||||||
|
# * add_python_example(example testname test_file [args...])
|
||||||
|
# which sets up an example program which will be run with the arguments
|
||||||
|
# [args...] (can be empty) Useful to make sure some program runs
|
||||||
|
# correctly with the given arguments, and which will report as a unit
|
||||||
|
# test failure.
|
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_LIST_DIR}/pycmake_test_runner.py ${CMAKE_BINARY_DIR}/python/tests/pycmake_test_runner.py COPYONLY)
|
||||||
|
|
||||||
|
function(to_path_list var path1)
|
||||||
|
if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
|
||||||
|
set(sep "\\;")
|
||||||
|
else()
|
||||||
|
set(sep ":")
|
||||||
|
endif()
|
||||||
|
set(result "${path1}") # First element doesn't require separator at all...
|
||||||
|
foreach(path ${ARGN})
|
||||||
|
set(result "${result}${sep}${path}") # .. but other elements do.
|
||||||
|
endforeach()
|
||||||
|
set(${var} "${result}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
if (EXISTS "/etc/debian_version")
|
||||||
|
set( PYTHON_PACKAGE_PATH "dist-packages")
|
||||||
|
else()
|
||||||
|
set( PYTHON_PACKAGE_PATH "site-packages")
|
||||||
|
endif()
|
||||||
|
set(PYTHON_INSTALL_PREFIX "lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/${PYTHON_PACKAGE_PATH}" CACHE STRING "Subdirectory to install Python modules in")
|
||||||
|
|
||||||
|
function(add_python_package PACKAGE_NAME PACKAGE_PATH PYTHON_FILES)
|
||||||
|
add_custom_target(package_${PACKAGE_NAME} ALL)
|
||||||
|
|
||||||
|
foreach (file ${PYTHON_FILES})
|
||||||
|
add_custom_command(TARGET package_${PACKAGE_NAME}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/python/${PACKAGE_PATH}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${file} ${CMAKE_BINARY_DIR}/python/${PACKAGE_PATH}
|
||||||
|
)
|
||||||
|
endforeach ()
|
||||||
|
set_target_properties(package_${PACKAGE_NAME} PROPERTIES PACKAGE_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX}/${PACKAGE_PATH})
|
||||||
|
install(FILES ${PYTHON_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX}/${PACKAGE_PATH})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(add_python_test TESTNAME PYTHON_TEST_FILE arg)
|
||||||
|
configure_file(${PYTHON_TEST_FILE} ${PYTHON_TEST_FILE} COPYONLY)
|
||||||
|
|
||||||
|
add_test(NAME ${TESTNAME}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/python/tests
|
||||||
|
COMMAND python pycmake_test_runner.py ${PYTHON_TEST_FILE} ${arg}
|
||||||
|
)
|
||||||
|
|
||||||
|
to_path_list(pythonpath "${CMAKE_BINARY_DIR}/python" "$ENV{PYTHONPATH}")
|
||||||
|
set_tests_properties(${TESTNAME} PROPERTIES ENVIRONMENT "PYTHONPATH=${pythonpath}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(add_python_example TESTNAME PYTHON_TEST_FILE)
|
||||||
|
configure_file(${PYTHON_TEST_FILE} ${PYTHON_TEST_FILE} COPYONLY)
|
||||||
|
|
||||||
|
add_test(NAME ${TESTNAME}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/examples
|
||||||
|
COMMAND python ${PYTHON_TEST_FILE} ${ARGN}
|
||||||
|
)
|
||||||
|
to_path_list(pythonpath "${CMAKE_BINARY_DIR}/python" "$ENV{PYTHONPATH}")
|
||||||
|
set_tests_properties(${TESTNAME} PROPERTIES ENVIRONMENT "PYTHONPATH=${pythonpath}")
|
||||||
|
endfunction()
|
||||||
|
|
48
python/pycmake/pycmake_test_runner.py
Normal file
48
python/pycmake/pycmake_test_runner.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import inspect
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import imp
|
||||||
|
|
||||||
|
try:
|
||||||
|
from unittest2 import TextTestRunner, TestLoader, TestCase
|
||||||
|
except ImportError:
|
||||||
|
from unittest import TextTestRunner, TestLoader, TestCase
|
||||||
|
|
||||||
|
|
||||||
|
def runTestCase(tests, verbosity=0):
|
||||||
|
test_result = TextTestRunner(verbosity=verbosity).run(tests)
|
||||||
|
|
||||||
|
if len(test_result.errors) or len(test_result.failures):
|
||||||
|
test_result.printErrors()
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getTestClassFromModule(module_path):
|
||||||
|
test_module = imp.load_source('test', module_path)
|
||||||
|
for name, obj in inspect.getmembers(test_module):
|
||||||
|
if inspect.isclass(obj) and issubclass(obj, TestCase) and not obj == TestCase:
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def getTestsFromModule(module_path):
|
||||||
|
klass = getTestClassFromModule(module_path)
|
||||||
|
if klass is None:
|
||||||
|
raise UserWarning("No tests classes found in: '%s'" % module_path)
|
||||||
|
|
||||||
|
loader = TestLoader()
|
||||||
|
return loader.loadTestsFromTestCase(klass)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_module = sys.argv[1]
|
||||||
|
argv = []
|
||||||
|
|
||||||
|
tests = getTestsFromModule(test_module)
|
||||||
|
|
||||||
|
# Set verbosity to 2 to see which test method in a class that fails.
|
||||||
|
if runTestCase(tests, verbosity=0):
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
Loading…
Reference in New Issue
Block a user