From 9e2f51ef2502239486683b2f647c446502f4b109 Mon Sep 17 00:00:00 2001 From: Roberto Di Remigio Date: Fri, 28 Aug 2015 19:13:03 +0200 Subject: [PATCH] Python interpreter and libraries/headers detection. - The user can now pass its own interpreter. - Development libraries and headers can be requested. - Travis-CI switched to new container-based workers. --- .travis.yml | 38 ++++++--- modules/python.cmake | 9 -- modules/python_interpreter.cmake | 36 ++++++++ modules/python_libs.cmake | 85 +++++++++++++++++++ test/python_interpreter/cmake/autocmake.cfg | 14 +++ test/python_interpreter/src/CMakeLists.txt | 1 + test/python_interpreter/src/example.cpp | 7 ++ .../cmake/autocmake.cfg | 14 +++ .../src/CMakeLists.txt | 1 + .../python_interpreter_custom/src/example.cpp | 7 ++ test/python_libs/cmake/autocmake.cfg | 17 ++++ test/python_libs/src/CMakeLists.txt | 2 + test/python_libs/src/example.cpp | 11 +++ test/python_libs_custom/cmake/autocmake.cfg | 17 ++++ test/python_libs_custom/src/CMakeLists.txt | 2 + test/python_libs_custom/src/example.cpp | 11 +++ test/test.py | 18 ++++ 17 files changed, 267 insertions(+), 23 deletions(-) delete mode 100644 modules/python.cmake create mode 100644 modules/python_interpreter.cmake create mode 100644 modules/python_libs.cmake create mode 100644 test/python_interpreter/cmake/autocmake.cfg create mode 100644 test/python_interpreter/src/CMakeLists.txt create mode 100644 test/python_interpreter/src/example.cpp create mode 100644 test/python_interpreter_custom/cmake/autocmake.cfg create mode 100644 test/python_interpreter_custom/src/CMakeLists.txt create mode 100644 test/python_interpreter_custom/src/example.cpp create mode 100644 test/python_libs/cmake/autocmake.cfg create mode 100644 test/python_libs/src/CMakeLists.txt create mode 100644 test/python_libs/src/example.cpp create mode 100644 test/python_libs_custom/cmake/autocmake.cfg create mode 100644 test/python_libs_custom/src/CMakeLists.txt create mode 100644 test/python_libs_custom/src/example.cpp diff --git a/.travis.yml b/.travis.yml index f745587..1158330 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,29 @@ +sudo: false language: cpp -install: - # update, clean - - sudo apt-get update - - sudo apt-get clean - - sudo apt-get autoclean - # compilers - - sudo apt-get install g++ cmake gfortran - # libraries for static linking - - sudo apt-get install binutils-gold libc6-dev libpthread-stubs0-dev - # math libraries - - sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev - # MPI - - sudo apt-get install openmpi-bin libopenmpi-dev +addons: + apt: + packages: + # Compilers + - g++ + - gfortran + - cmake + # Libraries for static linking + - binutils-gold + - libc6-dev + - libpthread-stubs0-dev + # Math libraries + - libblas-dev + - liblapack-dev + - libatlas-base-dev + # MPI + - openmpi-bin + - libopenmpi-dev + # Python library, development version + - libpython2.7 +before_script: + - export PATH=$HOME/.local/bin:$PATH # PEP8 and py.test - - sudo pip install pytest pep8 + - pip install pytest pep8 --user `whoami` script: # test PEP8 conformity - pep8 --ignore=E501 update.py diff --git a/modules/python.cmake b/modules/python.cmake deleted file mode 100644 index dbc6507..0000000 --- a/modules/python.cmake +++ /dev/null @@ -1,9 +0,0 @@ -#.rst: -# -# Detects Python interpreter. -# -# Variables defined:: -# -# PYTHON_EXECUTABLE - -find_package(PythonInterp REQUIRED) diff --git a/modules/python_interpreter.cmake b/modules/python_interpreter.cmake new file mode 100644 index 0000000..a726da9 --- /dev/null +++ b/modules/python_interpreter.cmake @@ -0,0 +1,36 @@ +#.rst: +# +# Detects Python interpreter. +# +# Variables used:: +# +# PYTHON_INTERPRETER - User-set path to the Python interpreter +# +# Variables defined:: +# +# PYTHONINTERP_FOUND - Was the Python executable found +# PYTHON_EXECUTABLE - path to the Python interpreter +# PYTHON_VERSION_STRING - Python version found e.g. 2.5.2 +# PYTHON_VERSION_MAJOR - Python major version found e.g. 2 +# PYTHON_VERSION_MINOR - Python minor version found e.g. 5 +# PYTHON_VERSION_PATCH - Python patch version found e.g. 2 +# +# autocmake.cfg configuration:: +# +# docopt: --python= The Python interpreter (development version) to use. [default: '']. +# define: '-DPYTHON_INTERPRETER="%s"' % arguments['--python'] + +if("${PYTHON_INTERPRETER}" STREQUAL "") + find_package(PythonInterp REQUIRED) +else() + if(NOT EXISTS "${PYTHON_INTERPRETER}") + find_program(PYTHON_EXECUTABLE NAMES ${PYTHON_INTERPRETER}) + if (NOT EXISTS "${PYTHON_EXECUTABLE}") + set(PYTHONINTERP_FOUND FALSE) + endif() + else() + set(PYTHONINTERP_FOUND TRUE) + set(PYTHON_EXECUTABLE "${PYTHON_INTERPRETER}") + endif() +endif() +find_package(PythonInterp REQUIRED) diff --git a/modules/python_libs.cmake b/modules/python_libs.cmake new file mode 100644 index 0000000..2379709 --- /dev/null +++ b/modules/python_libs.cmake @@ -0,0 +1,85 @@ +#.rst: +# +# Detects Python libraries and headers. +# Detection is done basically by hand as the proper CMake package +# will not find libraries and headers matching the interpreter version. +# +# Dependencies:: +# python_interpreter - Sets the Python interpreter for headers and libraries detection +# +# Variables used:: +# +# PYTHONINTERP_FOUND - Was the Python executable found +# +# Variables defined:: +# +# PYTHONLIBS_FOUND - have the Python libs been found +# PYTHON_LIBRARIES - path to the python library +# PYTHON_INCLUDE_DIRS - path to where Python.h is found +# PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8) + +if(PYTHONINTERP_FOUND) + # Get Python include path from Python interpreter + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c + "import distutils.sysconfig, sys; sys.stdout.write(distutils.sysconfig.get_python_inc())" + OUTPUT_VARIABLE _PYTHON_INCLUDE_PATH + RESULT_VARIABLE _PYTHON_INCLUDE_RESULT) + # Get Python library path from interpreter + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c + "from distutils.sysconfig import get_config_var; import sys; sys.stdout.write(get_config_var('LIBDIR'))" + OUTPUT_VARIABLE _PYTHON_LIB_PATH + RESULT_VARIABLE _PYTHON_LIB_RESULT) + + set(PYTHON_INCLUDE_DIR ${_PYTHON_INCLUDE_PATH} CACHE PATH "Path to a directory") + set(_PYTHON_VERSION "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") + set(_PYTHON_VERSION_NO_DOTS "${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") + + find_library(PYTHON_LIBRARY + NAMES + python${_PYTHON_VERSION_NO_DOTS} + python${_PYTHON_VERSION}mu + python${_PYTHON_VERSION}m + python${_PYTHON_VERSION}u + python${_PYTHON_VERSION} + NO_DEFAULT_PATH + HINTS + "${_PYTHON_LIB_PATH}" + DOC "Path to Python library file." + ) + if (NOT EXISTS "${PYTHON_LIBRARY}") + # redo with default paths + find_library(PYTHON_LIBRARY + NAMES + python${_PYTHON_VERSION_NO_DOTS} + python${_PYTHON_VERSION}mu + python${_PYTHON_VERSION}m + python${_PYTHON_VERSION}u + python${_PYTHON_VERSION} + HINTS + "${_PYTHON_LIB_PATH}" + DOC "Path to Python library file." + ) + endif() + + mark_as_advanced(CLEAR PYTHON_EXECUTABLE) + mark_as_advanced(FORCE PYTHON_LIBRARY) + mark_as_advanced(FORCE PYTHON_INCLUDE_DIR) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PythonLibs + REQUIRED_VARS + PYTHON_LIBRARY + PYTHON_INCLUDE_DIR + PYTHON_EXECUTABLE) + +if(NOT PYTHONLIBS_FOUND) + message(FATAL_ERROR "Could NOT find PythonLibs") +endif() + +# Hook-up script variables to cache variables +set(PYTHON_LIBRARIES ${PYTHON_LIBRARY}) +set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIR}) + +include_directories(SYSTEM ${PYTHON_INCLUDE_DIRS}) +link_directories(${PYTHON_LIBRARIES}) diff --git a/test/python_interpreter/cmake/autocmake.cfg b/test/python_interpreter/cmake/autocmake.cfg new file mode 100644 index 0000000..1ced495 --- /dev/null +++ b/test/python_interpreter/cmake/autocmake.cfg @@ -0,0 +1,14 @@ +[project] +name: example + +[cxx] +source: ../../../modules/cxx.cmake + +[python_interpreter] +source: ../../../modules/python_interpreter.cmake + +[default_build_paths] +source: ../../../modules/default_build_paths.cmake + +[src] +source: ../../../modules/src.cmake diff --git a/test/python_interpreter/src/CMakeLists.txt b/test/python_interpreter/src/CMakeLists.txt new file mode 100644 index 0000000..2d487d5 --- /dev/null +++ b/test/python_interpreter/src/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(example example.cpp) diff --git a/test/python_interpreter/src/example.cpp b/test/python_interpreter/src/example.cpp new file mode 100644 index 0000000..fc43d52 --- /dev/null +++ b/test/python_interpreter/src/example.cpp @@ -0,0 +1,7 @@ +#include + +int main() +{ + std::cout << "PASSED"; + return 0; +} diff --git a/test/python_interpreter_custom/cmake/autocmake.cfg b/test/python_interpreter_custom/cmake/autocmake.cfg new file mode 100644 index 0000000..1ced495 --- /dev/null +++ b/test/python_interpreter_custom/cmake/autocmake.cfg @@ -0,0 +1,14 @@ +[project] +name: example + +[cxx] +source: ../../../modules/cxx.cmake + +[python_interpreter] +source: ../../../modules/python_interpreter.cmake + +[default_build_paths] +source: ../../../modules/default_build_paths.cmake + +[src] +source: ../../../modules/src.cmake diff --git a/test/python_interpreter_custom/src/CMakeLists.txt b/test/python_interpreter_custom/src/CMakeLists.txt new file mode 100644 index 0000000..2d487d5 --- /dev/null +++ b/test/python_interpreter_custom/src/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(example example.cpp) diff --git a/test/python_interpreter_custom/src/example.cpp b/test/python_interpreter_custom/src/example.cpp new file mode 100644 index 0000000..fc43d52 --- /dev/null +++ b/test/python_interpreter_custom/src/example.cpp @@ -0,0 +1,7 @@ +#include + +int main() +{ + std::cout << "PASSED"; + return 0; +} diff --git a/test/python_libs/cmake/autocmake.cfg b/test/python_libs/cmake/autocmake.cfg new file mode 100644 index 0000000..a451db6 --- /dev/null +++ b/test/python_libs/cmake/autocmake.cfg @@ -0,0 +1,17 @@ +[project] +name: example + +[cxx] +source: ../../../modules/cxx.cmake + +[python_interpreter] +source: ../../../modules/python_interpreter.cmake + +[python_libs] +source: ../../../modules/python_libs.cmake + +[default_build_paths] +source: ../../../modules/default_build_paths.cmake + +[src] +source: ../../../modules/src.cmake diff --git a/test/python_libs/src/CMakeLists.txt b/test/python_libs/src/CMakeLists.txt new file mode 100644 index 0000000..f0e97ea --- /dev/null +++ b/test/python_libs/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(example example.cpp) +target_link_libraries(example ${PYTHON_LIBRARIES}) diff --git a/test/python_libs/src/example.cpp b/test/python_libs/src/example.cpp new file mode 100644 index 0000000..ca12cc4 --- /dev/null +++ b/test/python_libs/src/example.cpp @@ -0,0 +1,11 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + Py_SetProgramName(argv[0]); /* optional but recommended */ + Py_Initialize(); + PyRun_SimpleString("print('PASSED')\n"); + Py_Finalize(); + return 0; +} diff --git a/test/python_libs_custom/cmake/autocmake.cfg b/test/python_libs_custom/cmake/autocmake.cfg new file mode 100644 index 0000000..a451db6 --- /dev/null +++ b/test/python_libs_custom/cmake/autocmake.cfg @@ -0,0 +1,17 @@ +[project] +name: example + +[cxx] +source: ../../../modules/cxx.cmake + +[python_interpreter] +source: ../../../modules/python_interpreter.cmake + +[python_libs] +source: ../../../modules/python_libs.cmake + +[default_build_paths] +source: ../../../modules/default_build_paths.cmake + +[src] +source: ../../../modules/src.cmake diff --git a/test/python_libs_custom/src/CMakeLists.txt b/test/python_libs_custom/src/CMakeLists.txt new file mode 100644 index 0000000..f0e97ea --- /dev/null +++ b/test/python_libs_custom/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(example example.cpp) +target_link_libraries(example ${PYTHON_LIBRARIES}) diff --git a/test/python_libs_custom/src/example.cpp b/test/python_libs_custom/src/example.cpp new file mode 100644 index 0000000..ca12cc4 --- /dev/null +++ b/test/python_libs_custom/src/example.cpp @@ -0,0 +1,11 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + Py_SetProgramName(argv[0]); /* optional but recommended */ + Py_Initialize(); + PyRun_SimpleString("print('PASSED')\n"); + Py_Finalize(); + return 0; +} diff --git a/test/test.py b/test/test.py index 526bb39..7bccaf8 100644 --- a/test/test.py +++ b/test/test.py @@ -193,3 +193,21 @@ def test_fc_lapack(): @skip_on_windows def test_fc_lapack_static(): configure_build_and_exe('fc_lapack', 'python setup.py --fc=gfortran --static --cmake-options="-DMATH_LIB_SEARCH_ORDER=\'ATLAS;MKL\'"') + + +def test_python_interpreter(): + configure_build_and_exe('python_interpreter', 'python setup.py --cxx=g++') + + +def test_python_interpreter_custom(): + python_executable = sys.executable + configure_build_and_exe('python_interpreter_custom', 'python setup.py --cxx=g++ --python={}'.format(python_executable)) + + +def test_python_libs(): + configure_build_and_exe('python_libs', 'python setup.py --cxx=g++') + + +def test_python_libs_custom(): + python_executable = sys.executable + configure_build_and_exe('python_libs_custom', 'python setup.py --cxx=g++ --python={}'.format(python_executable))