diff options
-rw-r--r-- | host/CMakeLists.txt | 33 | ||||
-rw-r--r-- | host/cmake/Modules/UHDPython.cmake | 180 | ||||
-rw-r--r-- | host/docs/build.dox.in | 6 | ||||
-rw-r--r-- | host/docs/pythonapi.dox | 8 | ||||
-rw-r--r-- | host/python/CMakeLists.txt | 2 |
5 files changed, 160 insertions, 69 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 2d2e465d1..916138ee9 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -6,11 +6,6 @@ # ######################################################################## -#if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) -# message(FATAL_ERROR "Prevented in-tree built. This is bad practice.") -#endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) - -######################################################################## # Project setup ######################################################################## # NOTE! If you change the version in the following line, also change @@ -38,6 +33,7 @@ set(MSVC_MIN_VERSION_READABLE "14.0") # This Python version gets used for Python API (if requested) as well as # all the build-time Python scripts set(PYTHON_MIN_VERSION "2.7") +set(PYTHON3_MIN_VERSION "3.5") # Other deps set(BOOST_MIN_VERSION "1.58") set(NUMPY_MIN_VERSION "1.7") @@ -279,15 +275,6 @@ if(WIN32) endif(WIN32) ######################################################################## -# Choose a version of Python -######################################################################## -option(ENABLE_PYTHON3 "Enable Python 3. Default is Python 2" OFF) -set(PYBIND11_PYTHON_VERSION 2.7) -if(${ENABLE_PYTHON3}) - set(PYBIND11_PYTHON_VERSION 3) -endif() - -######################################################################## # Setup Boost ######################################################################## message(STATUS "") @@ -327,7 +314,6 @@ set(Boost_ADDITIONAL_VERSIONS "1.64" "1.65" "1.66" "1.67" "1.68" "1.69" ) -#Python API requirements message(STATUS "Looking for optional Boost components...") find_package(Boost ${BOOST_MIN_VERSION} OPTIONAL_COMPONENTS ${BOOST_OPTIONAL_COMPONENTS}) @@ -352,18 +338,11 @@ include(UHDLog) ######################################################################## # Check Python Modules ######################################################################## -find_package(PythonInterp ${PYBIND11_PYTHON_VERSION}) -find_package(PythonLibs ${PYBIND11_PYTHON_VERSION}) include(UHDPython) -set(PYTHON_VERSION "platform.python_version() >= '2.7' and platform.python_version() < '3.0'") -if(${ENABLE_PYTHON3}) - set(PYTHON_VERSION "platform.python_version() >= '3.0'") -endif() - PYTHON_CHECK_MODULE( - "Python version ${PYBIND11_PYTHON_VERSION} or greater" - "platform" ${PYTHON_VERSION} + "Python version ${PYTHON_MIN_VERSION} or greater" + "platform" "platform.python_version() >= '${PYTHON_MIN_VERSION}'" HAVE_PYTHON_PLAT_MIN_VERSION ) @@ -385,8 +364,6 @@ PYTHON_CHECK_MODULE( HAVE_PYTHON_MODULE_NUMPY ) -set(PYTHON_ADDITIONAL_VERSIONS 2.7 3.4 3.5) - ######################################################################## # Create Uninstall Target ######################################################################## @@ -415,9 +392,9 @@ UHD_INSTALL(FILES LIBUHD_REGISTER_COMPONENT("LibUHD" ENABLE_LIBUHD ON "Boost_FOUND;HAVE_PYTHON_PLAT_MIN_VERSION;HAVE_PYTHON_MODULE_MAKO" OFF ON) LIBUHD_REGISTER_COMPONENT("LibUHD - C API" ENABLE_C_API ON "ENABLE_LIBUHD" OFF OFF) if(WIN32) - LIBUHD_REGISTER_COMPONENT("LibUHD - Python API" ENABLE_PYTHON_API OFF "ENABLE_LIBUHD;HAVE_PYTHON_MODULE_NUMPY;PythonLibs_FOUND" OFF OFF) + LIBUHD_REGISTER_COMPONENT("LibUHD - Python API" ENABLE_PYTHON_API OFF "ENABLE_LIBUHD;HAVE_PYTHON_MODULE_NUMPY;HAVE_PYTHON_LIBS" OFF OFF) else() - LIBUHD_REGISTER_COMPONENT("LibUHD - Python API" ENABLE_PYTHON_API ON "ENABLE_LIBUHD;HAVE_PYTHON_MODULE_NUMPY;PythonLibs_FOUND" OFF OFF) + LIBUHD_REGISTER_COMPONENT("LibUHD - Python API" ENABLE_PYTHON_API ON "ENABLE_LIBUHD;HAVE_PYTHON_MODULE_NUMPY;HAVE_PYTHON_LIBS" OFF OFF) endif(WIN32) LIBUHD_REGISTER_COMPONENT("Examples" ENABLE_EXAMPLES ON "ENABLE_LIBUHD" OFF OFF) LIBUHD_REGISTER_COMPONENT("Utils" ENABLE_UTILS ON "ENABLE_LIBUHD" OFF OFF) diff --git a/host/cmake/Modules/UHDPython.cmake b/host/cmake/Modules/UHDPython.cmake index 5ac2d991b..a93761131 100644 --- a/host/cmake/Modules/UHDPython.cmake +++ b/host/cmake/Modules/UHDPython.cmake @@ -1,6 +1,7 @@ # # Copyright 2010-2011 Ettus Research LLC # Copyright 2018 Ettus Research, a National Instruments Company +# Copyright 2019 Ettus Research, a National Instruments Company # # SPDX-License-Identifier: GPL-3.0-or-later # @@ -9,62 +10,121 @@ if(NOT DEFINED INCLUDED_UHD_PYTHON_CMAKE) set(INCLUDED_UHD_PYTHON_CMAKE TRUE) ######################################################################## -# Setup Python +# Setup Python Part 1: Find the interpreters ######################################################################## message(STATUS "") -message(STATUS "Configuring the python interpreter...") +message(STATUS "Configuring the Python interpreter...") #this allows the user to override PYTHON_EXECUTABLE if(PYTHON_EXECUTABLE) - set(PYTHONINTERP_FOUND TRUE) +endif(PYTHON_EXECUTABLE) -#otherwise if not set, try to automatically find it -else(PYTHON_EXECUTABLE) - - #use the built-in find script - if(ENABLE_PYTHON3) - find_package(PythonInterp 3.0) - else(ENABLE_PYTHON3) - find_package(PythonInterp 2.0) - endif(ENABLE_PYTHON3) - - #and if that fails use the find program routine - if(NOT PYTHONINTERP_FOUND) - if(ENABLE_PYTHON3) - find_program(PYTHON_EXECUTABLE NAMES python3 python3.5 python3.6) - else(ENABLE_PYTHON3) - find_program(PYTHON_EXECUTABLE NAMES python2 python2.7) - endif(ENABLE_PYTHON3) - - if(PYTHON_EXECUTABLE) - set(PYTHONINTERP_FOUND TRUE) - endif(PYTHON_EXECUTABLE) - endif(NOT PYTHONINTERP_FOUND) +# We always try to find Py3k first. Once we only support Py3k we can remove +# most of this. +if(NOT PYTHONINTERP_FOUND) + find_package(Python3 ${PYTHON3_MIN_VERSION} QUIET) + if(Python3_Interpreter_FOUND) + set(PYTHON_MIN_VERSION ${PYTHON3_MIN_VERSION}) + set(PYTHON_VERSION ${Python3_VERSION}) + set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) + set(PYTHONINTERP_FOUND TRUE) + endif(Python3_Interpreter_FOUND) +endif(NOT PYTHONINTERP_FOUND) -endif(PYTHON_EXECUTABLE) +if(NOT PYTHONINTERP_FOUND) + find_package(PythonInterp ${PYTHON3_MIN_VERSION} QUIET) + if(PYTHONINTERP_FOUND) + set(PYTHON_MIN_VERSION ${PYTHON3_MIN_VERSION}) + set(PYTHON_VERSION ${PYTHON_VERSION_STRING}) + endif(PYTHONINTERP_FOUND) +endif(NOT PYTHONINTERP_FOUND) -#make the path to the executable appear in the cmake gui -set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH - "python buildtime interpreter") +# Next, try and find Py2k. +if(NOT PYTHONINTERP_FOUND) + find_package(Python2 ${PYTHON_MIN_VERSION} QUIET) + if(Python2_Interpreter_FOUND) + set(PYTHON_VERSION ${Python2_VERSION}) + set(PYTHON_EXECUTABLE ${Python2_EXECUTABLE}) + set(PYTHONINTERP_FOUND TRUE) + endif(Python2_Interpreter_FOUND) +endif(NOT PYTHONINTERP_FOUND) -message(STATUS "Python interpreter: ${PYTHON_EXECUTABLE}") -message(STATUS "Override with: -DPYTHON_EXECUTABLE=<path-to-python>") +if(NOT PYTHONINTERP_FOUND) + find_package(PythonInterp ${PYTHON_MIN_VERSION} QUIET) + set(PYTHON_VERSION ${PYTHON_VERSION_STRING}) +endif(NOT PYTHONINTERP_FOUND) +# If that fails, try using the build-in find program routine. +if(NOT PYTHONINTERP_FOUND) + message(STATUS "Attempting to find Python without CMake...") + find_program(PYTHON_EXECUTABLE NAMES python3 python3.5 python3.6 python3.7 python3.8) + if(PYTHON_EXECUTABLE) + set(PYTHONINTERP_FOUND TRUE) + set(PYTHON_MIN_VERSION ${PYTHON3_MIN_VERSION}) + endif(PYTHON_EXECUTABLE) +endif(NOT PYTHONINTERP_FOUND) + +if(NOT PYTHONINTERP_FOUND) + message(STATUS "Attempting to find Python without CMake...") + find_program(PYTHON_EXECUTABLE NAMES python2 python2.7) + if(PYTHON_EXECUTABLE) + set(PYTHONINTERP_FOUND TRUE) + endif(PYTHON_EXECUTABLE) +endif(NOT PYTHONINTERP_FOUND) + +if(NOT PYTHON_VERSION) + message(STATUS "Manually determining build Python version...") + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " +from __future__ import print_function +import sys +print('{}.{}.{}'.format( + sys.version_info.major, + sys.version_info.minor, + sys.version_info.micro))" + OUTPUT_VARIABLE PYTHON_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif(NOT PYTHON_VERSION) + +# If we still haven't found a Python interpreter, then we're done. if(NOT PYTHONINTERP_FOUND) message(FATAL_ERROR "Error: Python interpreter required by the build system.") endif(NOT PYTHONINTERP_FOUND) +if(NOT PYTHON_EXECUTABLE) + message(FATAL_ERROR "Error: Python interpreter required by the build system.") +endif(NOT PYTHON_EXECUTABLE) + +#make the path to the executable appear in the cmake gui +set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH + "python buildtime interpreter") + +message(STATUS "Python interpreter: ${PYTHON_EXECUTABLE} Version: ${PYTHON_VERSION}") +message(STATUS "Override with: -DPYTHON_EXECUTABLE=<path-to-python>") #this allows the user to override RUNTIME_PYTHON_EXECUTABLE if(NOT RUNTIME_PYTHON_EXECUTABLE) #default to the buildtime interpreter set(RUNTIME_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE}) + set(RUNTIME_PYTHON_VERSION ${PYTHON_VERSION}) endif(NOT RUNTIME_PYTHON_EXECUTABLE) +if(NOT RUNTIME_PYTHON_VERSION) + message(STATUS "Manually determining runtime Python version...") + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " +from __future__ import print_function +import sys +print('{}.{}.{}'.format( + sys.version_info.major, + sys.version_info.minor, + sys.version_info.micro))" + OUTPUT_VARIABLE RUNTIME_PYTHON_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif(NOT RUNTIME_PYTHON_VERSION) + #make the path to the executable appear in the cmake gui set(RUNTIME_PYTHON_EXECUTABLE ${RUNTIME_PYTHON_EXECUTABLE} CACHE FILEPATH "python runtime interpreter") -message(STATUS "Python runtime interpreter: ${RUNTIME_PYTHON_EXECUTABLE}") +message(STATUS "Python runtime interpreter: ${RUNTIME_PYTHON_EXECUTABLE} Version: ${RUNTIME_PYTHON_VERSION}") message(STATUS "Override with: -DRUNTIME_PYTHON_EXECUTABLE=<path-to-python>") macro(PYTHON_CHECK_MODULE desc mod cmd have) @@ -97,4 +157,60 @@ exit(0) endif() endmacro(PYTHON_CHECK_MODULE) +############################################################################### +# Part 2: Python Libraries +############################################################################### +# The libraries must match the RUNTIME_PYTHON_EXECUTABLE's version. +# - Figure out version +# - See if Python3_LIBRARIES is already set (or Python2_LIBRARIES) +if(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) + message(STATUS "Finding Python Libraries...") + find_package(PythonLibs ${RUNTIME_PYTHON_VERSION} EXACT QUIET) + if(RUNTIME_PYTHON_VERSION VERSION_LESS 3) + if(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) + find_package(Python3 ${RUNTIME_PYTHON_VERSION} + EXACT + QUIET + COMPONENTS Interpreter Development) + if(Python3_Development_FOUND) + set(PYTHON_LIBRARIES ${Python3_LIBRARIES}) + set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) + endif(Python3_Development_FOUND) + endif(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) + else(RUNTIME_PYTHON_VERSION VERSION_LESS 3) + if(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) + find_package(Python2 ${RUNTIME_PYTHON_VERSION} + EXACT + QUIET + COMPONENTS Interpreter Development) + if(Python2_Development_FOUND) + set(PYTHON_LIBRARIES ${Python2_LIBRARIES}) + set(PYTHON_INCLUDE_DIRS ${Python2_INCLUDE_DIRS}) + endif(Python2_Development_FOUND) + endif(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) + endif(RUNTIME_PYTHON_VERSION VERSION_LESS 3) + if(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) + message(STATUS "Could not find Python Libraries.") + endif(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) +endif(NOT PYTHON_LIBRARIES OR NOT PYTHON_INCLUDE_DIRS) + +if(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS) + set(HAVE_PYTHON_LIBS TRUE) + message(STATUS "Python Libraries: ${PYTHON_LIBRARIES}") + message(STATUS "Python include directories: ${PYTHON_INCLUDE_DIRS}") +else(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS) + set(HAVE_PYTHON_LIBS FALSE) +endif(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS) + +if(NOT PYTHON_LIBRARY) + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} CACHE FILEPATH + "Python libraries") + mark_as_advanced(PYTHON_LIBRARIES) +endif(NOT PYTHON_LIBRARY) +if(NOT PYTHON_INCLUDE_DIR) + set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} CACHE FILEPATH + "Python include dirs") + mark_as_advanced(PYTHON_INCLUDE_DIRS) +endif(NOT PYTHON_INCLUDE_DIR) + endif(NOT DEFINED INCLUDED_UHD_PYTHON_CMAKE) diff --git a/host/docs/build.dox.in b/host/docs/build.dox.in index 9e4f91ce4..1d9d9a0fe 100644 --- a/host/docs/build.dox.in +++ b/host/docs/build.dox.in @@ -220,10 +220,8 @@ extensions: \subsection cmake_win Generate the project with CMake -- Enable Python3 option in the CMake list if the version of installed Python is >=3, otherwise go to the next step. - - Go to the source code: `<uhd-repo-path>/host`. - - Open 'CMakeLists.txt'. - - Find 'ENABLE_PYTHON3' option and set it to 'ON', e.g. 'option(ENABLE_PYTHON3 "Enable Python 3. Default is Python 2" ON)'. +- Make sure the version of Python that CMake detects matches the version you + want it to be (check the PYTHON_VERSION variable) - Open the CMake GUI. - Set the path to the source code: `<uhd-repo-path>/host`. - Set the path to the build directory (this may require creating the folder \build\): `<uhd-repo-path>/host/build`. diff --git a/host/docs/pythonapi.dox b/host/docs/pythonapi.dox index 3f73c3a74..c8f504049 100644 --- a/host/docs/pythonapi.dox +++ b/host/docs/pythonapi.dox @@ -14,16 +14,16 @@ provide that functionality. On Windows, these headers always get installed when using the binary installers provided on https://www.python.org/downloads/windows/. If CMake can't find the Python headers or library, specify -the `PYTHON_INCLUDE_DIRS` and/or `PYTHON_LIBRARY` CMake variables manually. +the `PYTHON_INCLUDE_DIR` and/or `PYTHON_LIBRARY` CMake variables manually. \subsection python_install_2v3 Python 2 vs. 3 The Python API supports both Python 2 and 3, but if you have both versions installed, CMake might require some hints which version is the desired one. -To force Python 3, UHD has a CMake variable `ENABLE_PYTHON3`. If you set it, -e.g., by running `cmake -DENABLE_PYTHON3=ON`, it will force the usage of -Python 3. +To force a particular version, it helps to set `-DPYTHON_EXECUTABLE=/usr/bin/python3`, +or whatever interpreter you are expecting. The variables PYTHON_LIBRARY and +PYTHON_INCLUDE_DIR may also need to be set. \subsection python_install_windows Installing on Windows diff --git a/host/python/CMakeLists.txt b/host/python/CMakeLists.txt index 7aae1dfeb..5598dda24 100644 --- a/host/python/CMakeLists.txt +++ b/host/python/CMakeLists.txt @@ -36,7 +36,7 @@ target_include_directories(pyuhd PUBLIC ${PYBIND11_INCLUDE_DIR} ) -target_link_libraries(pyuhd ${Boost_LIBRARIES} ${PYTHON_LIBRARY} uhd) +target_link_libraries(pyuhd ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} uhd) # Copy pyuhd library to the staging directory if(WIN32) set(PYUHD_LIBRARY_NAME libpyuhd.pyd) |