FindPython3: how to specify local installation directory for Python module?

include(GNUInstallDirs)
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
...
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mymodule.py
          DESTINATION ${Python3_SITELIB})

installs to /usr/lib/python3/dist-packages/.

How to install to /usr/local/lib/python3/dist-packages/?

Is there a way to base the solution on ${CMAKE_INSTALL_LIBDIR}?

1 Like

I usually do something like:

if (NOT CMAKE_INSTALL_PYTHON_LIBDIR)
  set(CMAKE_INSTALL_PYTHON_LIBDIR
    "${CMAKE_INSTALL_LIBDIR}/python${major}.${minor}/site-packages")
endif ()

Distributors can then override with whatever their preferred layout is. And whatever the spelling for the major and minor variables are.

The variable CMAKE_INSTALL_PYTHON_LIBDIR is meant to be set by the user? It is not defined by CMake? Shouldn’t it be better called <my_project>_INSTALL_PYTHON_LIBDIR?

The version variables are defined by FindPython3.

Promising idea from https://stackoverflow.com/a/40006251/1017348:

  COMMAND "${Python3_EXECUTABLE}" -c "from distutils import sysconfig as sc;print(sc.get_python_lib(prefix='', plat_specific=True))"
  OUTPUT_VARIABLE PYTHON_SITE
  OUTPUT_STRIP_TRAILING_WHITESPACE)

Under Debian this yields PYTHON_SITE=lib/python3/dist-packages. A relative path, since the prefix is supplied by CMAKE_INSTALL_PREFIX=/usr/local. Unfortunately though, /usr/local/lib/python3/dist-packages is not in sys.path. We’d rather need /usr/local/lib/python3.${minor}/dist-packages.

So the above is close, but not quite the solution.

I named it that in order to follow GNUInstallDirs naming patterns (it keeps all of the destinations beside each other in the cache). And yes, if the default is not sufficient, the user should set it. You can use fancier logic to get the default (such as the Python code from your SO link).

Yes, I’m aware, I was just being lazy :slight_smile: .