InstallPythonPackage.cmake 4.6 KB
Newer Older
Dion Haefner's avatar
Dion Haefner committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
# This cmake module provides macros that install python packages into the virtualenv
# that is shared by all dune modules that depend on dune-python.
#
# .. cmake_function:: dune_install_python_package
#
#    .. cmake_param:: PATH
#       :required:
#       :single:
#
#       Relative path to the given python package source code.
#
#    .. cmake_param:: MAJOR_VERSION
#       :single:
#
#       Set to "2" or "3" if your python package only works with
#       python2 or python3. This will restrict the installation process to that
#       python version.
#
#    .. cmake_param:: NO_PIP
#       :option:
#
#       Instead of :code:`pip -e`, `python setup.py develop` will be used as
#       the installation command.
#
#    .. cmake_param:: NO_EDIT
#       :option:
#
#       Will drop :code:`pip`s :code:`-e` option (or switch :code:`develop` to :code:`install`).
#       Only use this option if your package is incompatible with :code:`-e`.
#
#    Installs the python package located at path into the virtualenv used by dune-python
#    The package at the given location is expected to be a pip installable package.
#    Also marks the given python package for global installation during :code:`make install`.
#    By default, the python package will then be installed into the system-wide site-packages
#    location. If you do not want to install it there, or you do not have permission to,
#    you may optionally set :ref:`DUNE_PYTHON_INSTALL_USER` to a username. The
#    packages will then be installed in the home directory of that user.
#    This is done through pips :code:`--user` option. Installation in arbitrary locations is not
#    supported to minimize :code:`PYTHONPATH` issues.
#
# .. cmake_variable:: DUNE_PYTHON_INSTALL_USER
#
#    dune-python only supports two ways of globally installing python packages during
#    :code:`make install`:
#
#    * Into standard system paths (default)
#    * Into the standard python path of a users home directory (through :code:`pip --user`)
#
#    Set this variable to a username to use the latter.
#

include(CheckPythonPackage)

function(dorie_install_python_package)
  # Parse Arguments
  set(OPTION NO_PIP NO_EDIT QUIET)
  set(SINGLE PATH MAJOR_VERSION)
  set(MULTI)
  include(CMakeParseArguments)
  cmake_parse_arguments(PYINST "${OPTION}" "${SINGLE}" "${MULTI}" ${ARGN})
  if(PYINST_UNPARSED_ARGUMENTS)
    message(WARNING "Unparsed arguments in dune_install_python_package: This often indicates typos!")
  endif()

  # apply defaults
  if(NOT PYINST_MAJOR_VERSION)
    set(PYINST_MAJOR_VERSION 2 3)
  endif()

  # check for available pip packages
  check_python_package(PACKAGE pip
                       INTERPRETER ${PYTHON2_EXECUTABLE}
                       RESULT PIP2_FOUND)
  check_python_package(PACKAGE pip
                       INTERPRETER ${PYTHON3_EXECUTABLE}
                       RESULT PIP3_FOUND)

  # Construct the installation command strings from the given options
  if(PYINST_NO_PIP)
    if(PYINST_NO_EDIT)
      set(INST_COMMAND install)
    else()
      set(INST_COMMAND develop)
    endif()
    set(VENV_INSTALL_COMMAND python setup.py ${INST_COMMAND})
  else()
    set(EDIT_OPTION)
    if(NOT PYINST_NO_EDIT)
      set(EDIT_OPTION -e)
    endif()
    if(PYINST_QUIET)
      set(EDIT_OPTION "-q ${EDIT_OPTION}")
    endif()
    set(VENV_INSTALL_COMMAND python -m pip install ${EDIT_OPTION} .)
  endif()

  # Construct the interpreter options for global installation
  if(PYINST_NO_PIP)
    set(SYSTEM_INSTALL_OPTIONS setup.py install)
    if(DUNE_PYTHON_INSTALL_USER)
      message("Error message: Incompatible options - NO_PIP and DUNE_PYTHON_INSTALL_USER")
    endif()
  else()
    set(USER_STRING "")
    if(DUNE_PYTHON_INSTALL_USER)
      set(USER_STRING --user ${DUNE_PYTHON_INSTALL_USER})
    endif()
    set(SYSTEM_INSTALL_OPTIONS -m pip install ${USER_STRING} .)
  endif()

  # iterate over the given interpreters
  foreach(version ${PYINST_MAJOR_VERSION})
    # install the package into the virtual env
    execute_process(COMMAND ${CMAKE_BINARY_DIR}/dune-env-${version} ${VENV_INSTALL_COMMAND}
                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${PYINST_PATH})

    # define a rule on how to install the package during make install
    if(PIP${version}_FOUND)
      install(CODE "execute_process(COMMAND ${PYTHON${version}_EXECUTABLE} ${SYSTEM_INSTALL_OPTIONS}
                                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${PYINST_PATH})
                   ")
    else()
      install(CODE "message(FATAL_ERROR \"You need the python${version} package pip installed on the host system to install a module that contains python code\")")
    endif()
  endforeach()
endfunction()