diff options
-rw-r--r-- | host/CMakeLists.txt | 11 | ||||
-rw-r--r-- | host/cmake/Modules/UHDPython.cmake | 72 | ||||
-rw-r--r-- | host/python/CMakeLists.txt | 135 | ||||
-rw-r--r-- | host/utils/CMakeLists.txt | 199 |
4 files changed, 252 insertions, 165 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 7cd8f87d4..8281a98a0 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -441,6 +441,11 @@ endif(WIN32) LIBUHD_REGISTER_COMPONENT("Examples" ENABLE_EXAMPLES ON "ENABLE_LIBUHD" OFF OFF) LIBUHD_REGISTER_COMPONENT("Utils" ENABLE_UTILS ON "ENABLE_LIBUHD" OFF OFF) LIBUHD_REGISTER_COMPONENT("Tests" ENABLE_TESTS ON "ENABLE_LIBUHD" OFF OFF) +LIBUHD_REGISTER_COMPONENT( + "Python Module (Utils only)" + ENABLE_PYMOD_UTILS OFF + "HAVE_PYTHON_MODULE_NUMPY;HAVE_PYTHON_MODULE_MAKO;HAVE_PYTHON_MODULE_YAML" + OFF OFF) ######################################################################## # Add the subdirectories @@ -459,13 +464,13 @@ if(ENABLE_TESTS) add_subdirectory(tests) endif(ENABLE_TESTS) -if(ENABLE_UTILS) +if(ENABLE_UTILS OR ENABLE_PYMOD_UTILS) add_subdirectory(utils) -endif(ENABLE_UTILS) +endif(ENABLE_UTILS OR ENABLE_PYMOD_UTILS) add_subdirectory(docs) -if(ENABLE_PYTHON_API) +if(ENABLE_PYTHON_API OR ENABLE_PYMOD_UTILS) add_subdirectory(python) endif() diff --git a/host/cmake/Modules/UHDPython.cmake b/host/cmake/Modules/UHDPython.cmake index a15434b18..e53e63824 100644 --- a/host/cmake/Modules/UHDPython.cmake +++ b/host/cmake/Modules/UHDPython.cmake @@ -237,6 +237,78 @@ exit(0) endif() endmacro(PYTHON_CHECK_MODULE_VERSION) + +############################################################################### +# Install a Python module into a system/prefix/virtualenv location. +# +# - LIBTARGET: Is there a library target included in this module (e.g., pyuhd)? +# If so, state its name here. It will update RPATH on Linux/Unix +# systems. +# - MODULE: Name of module (e.g., 'uhd') +macro(PYTHON_INSTALL_MODULE) + cmake_parse_arguments( + _py_install_mod + "" "LIBTARGET;MODULE" "" + ${ARGN} + ) + + # Check if we're in a virtual environment -- the rules are a bit different + # there. + PYTHON_CHECK_MODULE( + "virtual environment" + "sys" + "sys.prefix != sys.base_prefix" + HAVE_PYTHON_VIRTUALENV + ) + + if(HAVE_PYTHON_VIRTUALENV) + message( + STATUS + "Python virtual environment detected -- Ignoring UHD_PYTHON_DIR.") + # In virtualenvs, let setuptools do its thing + install(CODE "message(\"Installing ${_py_install_mod_MODULE} Python module into venv via pip.\")") + install(CODE + "execute_process(COMMAND pip3 install . --force-reinstall WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") + else() + # Otherwise, use sysconfig to determine the correct relative path for Python + # packages, and install to our prefix + if(NOT DEFINED UHD_PYTHON_DIR) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c + # Avoid the posix_local install scheme + "import os,sysconfig;\ + install_scheme = 'posix_user';\ + platlib = sysconfig.get_path('platlib', scheme=install_scheme);\ + prefix = sysconfig.get_config_var('prefix');\ + print(os.path.relpath(platlib, prefix));" + OUTPUT_VARIABLE UHD_PYTHON_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif(NOT DEFINED UHD_PYTHON_DIR) + file(TO_CMAKE_PATH ${UHD_PYTHON_DIR} UHD_PYTHON_DIR) + + message( + STATUS + "Installing '${_py_install_mod_MODULE}' Python module to: " + "${CMAKE_INSTALL_PREFIX}/${UHD_PYTHON_DIR}") + # We use sysconfig (above) to figure out the destination path, and then + # we simply copy this module recursively into its final destination. + install(DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR}/${_py_install_mod_MODULE} + DESTINATION ${UHD_PYTHON_DIR} + COMPONENT pythonapi + ) + # On Linux/Unix systems, we must properly install the library file. + # install(DIRECTORY) will treat the .so file like any other file, which + # means it won't update its RPATH, and thus the RPATH would be stuck to the + # build directory. + if(UNIX AND _py_install_mod_LIBTARGET) + install(TARGETS ${_py_install_mod_LIBTARGET} + DESTINATION ${UHD_PYTHON_DIR}/${_py_install_mod_MODULE} + ) + endif() + endif(HAVE_PYTHON_VIRTUALENV) +endmacro(PYTHON_INSTALL_MODULE) + ############################################################################### # Part 2: Python Libraries ############################################################################### diff --git a/host/python/CMakeLists.txt b/host/python/CMakeLists.txt index c3ed35478..81deb0499 100644 --- a/host/python/CMakeLists.txt +++ b/host/python/CMakeLists.txt @@ -4,12 +4,63 @@ # SPDX-License-Identifier: GPL-3.0-or-later # -PYTHON_CHECK_MODULE( - "virtual environment" - "sys" - "sys.prefix != sys.base_prefix" - HAVE_PYTHON_VIRTUALENV -) +######################################################################## +# This file included, use CMake directory variables +######################################################################## + +# Global Python API constants +set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in") +set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") +set(TIMESTAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp") +# convert binary directory to native format to use in SETUP_PY file. +file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR} NATIVE_CURRENT_BINARY_DIR) +configure_file(${SETUP_PY_IN} ${SETUP_PY}) + +# If we're not in a virtual environment, then we need to figure out where to +# install the Python module. Do this here so we can use the value for UHD_PYTHON_DIR +# in the simulator. +if(NOT DEFINED UHD_PYTHON_DIR) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c + # Avoid the posix_local install scheme + "import os,sysconfig;\ + install_scheme = 'posix_prefix';\ + platlib = sysconfig.get_path('platlib', scheme=install_scheme);\ + prefix = sysconfig.get_config_var('prefix');\ + print(os.path.relpath(platlib, prefix));" + OUTPUT_VARIABLE UHD_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif(NOT DEFINED UHD_PYTHON_DIR) + +# If ENABLE_PYTHON_API is OFF, then we can skip most of the work and will just +# install a bunch of Python files. +if(NOT ENABLE_PYTHON_API AND ENABLE_PYMOD_UTILS) + # List of Python files that are part of the module but don't get + # generated during build time and don't require libpyuhd. + # Note: When adding Python files into uhd/, they don't get added to the + # dependency list until CMake is re-run. + file(GLOB_RECURSE PYUHD_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/uhd/dsp/*.py + ${CMAKE_CURRENT_SOURCE_DIR}/uhd/imgbuilder/*.py + ${CMAKE_CURRENT_SOURCE_DIR}/uhd/imgbuilder/*.mako + ) + # This copies the contents of host/python/uhd into the build directory. We will + # use that as a staging ground for installing the final module to the system. + # We make sure that we always have an up-to-date copy in here. + add_custom_command(OUTPUT ${TIMESTAMP_FILE} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/uhd/ + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/uhd/__init__.py + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/uhd/imgbuilder ${CMAKE_CURRENT_BINARY_DIR}/uhd/imgbuilder + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/uhd/dsp ${CMAKE_CURRENT_BINARY_DIR}/uhd/dsp + COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} -q build + COMMAND ${CMAKE_COMMAND} -E touch ${TIMESTAMP_FILE} + DEPENDS ${PYUHD_FILES}) + add_custom_target(pyuhd_library ALL DEPENDS ${TIMESTAMP_FILE}) + PYTHON_INSTALL_MODULE( + MODULE "uhd" + ) + return() +endif() + if(pybind11_FOUND) message(STATUS "Using Pybind11 from: ${pybind11_INCLUDE_DIR}") @@ -84,29 +135,6 @@ file(GLOB_RECURSE PYUHD_FILES ${CMAKE_CURRENT_SOURCE_DIR}/uhd/*.py ) -set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in") -set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") -set(TIMESTAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp") -# convert binary directory to native format to use in SETUP_PY file. -file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR} NATIVE_CURRENT_BINARY_DIR) -configure_file(${SETUP_PY_IN} ${SETUP_PY}) - - -# If we're not in a virtual environment, then we need to figure out where to -# install the Python module. Do this here so we can use the value for UHD_PYTHON_DIR -# in the simulator. -if(NOT DEFINED UHD_PYTHON_DIR) - execute_process(COMMAND ${PYTHON_EXECUTABLE} -c - # Avoid the posix_local install scheme - "import os,sysconfig;\ - install_scheme = 'posix_prefix';\ - platlib = sysconfig.get_path('platlib', scheme=install_scheme);\ - prefix = sysconfig.get_config_var('prefix');\ - print(os.path.relpath(platlib, prefix));" - OUTPUT_VARIABLE UHD_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE - ) -endif(NOT DEFINED UHD_PYTHON_DIR) - if(ENABLE_SIM) set(MPM_DEVICE "sim") # Whereever UHD Python gets installed, also install that from MPM. @@ -168,6 +196,9 @@ if(ENABLE_SIM) set(PYUHD_FILES ${PYUHD_FILES} copy_mpm_packages) endif(ENABLE_SIM) +# This copies the contents of host/python/uhd into the build directory. We will +# use that as a staging ground for installing the final module to the system. +# We make sure that we always have an up-to-date copy in here. add_custom_command(OUTPUT ${TIMESTAMP_FILE} COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/uhd ${CMAKE_CURRENT_BINARY_DIR}/uhd COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} -q build @@ -175,43 +206,9 @@ add_custom_command(OUTPUT ${TIMESTAMP_FILE} DEPENDS ${PYUHD_FILES}) add_custom_target(pyuhd_library ALL DEPENDS ${TIMESTAMP_FILE} pyuhd) -if(HAVE_PYTHON_VIRTUALENV) - message(STATUS "Python virtual environment detected -- Ignoring UHD_PYTHON_DIR.") - # In virtualenvs, let setuptools do its thing - install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} -q install --force)") -else() - # Otherwise, use sysconfig to determine the correct relative path for Python - # packages, and install to our prefix - if(NOT DEFINED UHD_PYTHON_DIR) - execute_process(COMMAND ${PYTHON_EXECUTABLE} -c - # Avoid the posix_local install scheme - "import os,sysconfig;\ - install_scheme = 'posix_user';\ - platlib = sysconfig.get_path('platlib', scheme=install_scheme);\ - prefix = sysconfig.get_config_var('prefix');\ - print(os.path.relpath(platlib, prefix));" - OUTPUT_VARIABLE UHD_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE - ) - endif(NOT DEFINED UHD_PYTHON_DIR) - file(TO_CMAKE_PATH ${UHD_PYTHON_DIR} UHD_PYTHON_DIR) - - message(STATUS "Utilizing the python install directory: ${CMAKE_INSTALL_PREFIX}/${UHD_PYTHON_DIR}") - # CMake will create an up-to-date copy of the entire Python module within - # the build directory. Use sysconfig (above) to figure out the destination - # path, and then we simply copy this module recursively into its final - # destination. - install(DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR}/uhd - DESTINATION ${UHD_PYTHON_DIR} - COMPONENT pythonapi - ) - # On Linux/Unix systems, we must properly install the library file, though. - # install(DIRECTORY) will treat the .so file like any other file, which - # means it won't update its RPATH, and thus the RPATH would be stuck to the - # build directory. - if(UNIX) - install(TARGETS pyuhd - DESTINATION ${UHD_PYTHON_DIR}/uhd - ) - endif(UNIX) -endif(HAVE_PYTHON_VIRTUALENV) + +# Now install the Python module from the build directory to the final destination. +PYTHON_INSTALL_MODULE( + MODULE "uhd" + LIBTARGET pyuhd +) diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index fcb4fd9b0..088c3b505 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -5,6 +5,100 @@ # SPDX-License-Identifier: GPL-3.0-or-later # + +######################################################################## +# First, only utilities which get installed with ENABLE_PYMOD_UTILS +######################################################################## +if(ENABLE_PYMOD_UTILS OR ENABLE_UTILS) + ### RFNoC Image Builder + set(CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/${PKG_DATA_DIR}") + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/rfnoc_image_builder.py" + "${CMAKE_CURRENT_BINARY_DIR}/rfnoc_image_builder" + ) + UHD_INSTALL(PROGRAMS + ${CMAKE_CURRENT_BINARY_DIR}/rfnoc_image_builder + RENAME rfnoc_image_builder + DESTINATION ${RUNTIME_DIR} + COMPONENT utilities + ) + + ### UHD Images downloader + # Configure the scripts + file(READ ${CMAKE_CURRENT_SOURCE_DIR}/../../images/manifest.txt CMAKE_MANIFEST_CONTENTS) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/uhd_images_downloader.py.in + ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py + @ONLY) + # TODO: FIXME when know how. + # This is a hack to force cmake regenerate uhd_images_downloader.py + # whenever manifest.txt file changed. + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/../../images/manifest.txt + ${CMAKE_CURRENT_SOURCE_DIR}/../../images/manifest.txt + COPYONLY) + + UHD_INSTALL(PROGRAMS + ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py + DESTINATION ${PKG_LIB_DIR}/utils + COMPONENT utilities + ) + # On Linux/Unix systems, also install into $PATH + if(LINUX) + UHD_INSTALL(PROGRAMS + ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py + RENAME uhd_images_downloader + DESTINATION ${RUNTIME_DIR} + COMPONENT utilities + ) + endif(LINUX) + if(NOT HAVE_PYTHON_MODULE_REQUESTS) + message(WARNING + "Python module `requests' not found -- uhd_images_downloader.py " + "will not work without it.") + message(WARNING + "You may be able to install this by running 'pip install requests'") + endif(NOT HAVE_PYTHON_MODULE_REQUESTS) + + ### USRP2 Card Burner + if(ENABLE_USRP2) + if(WIN32 AND UHD_RELEASE_MODE) #include dd.exe + file(DOWNLOAD + "http://files.ettus.com/dd.exe" + ${CMAKE_CURRENT_BINARY_DIR}/dd.exe + ) + UHD_INSTALL(FILES + ${CMAKE_CURRENT_BINARY_DIR}/dd.exe + DESTINATION ${PKG_LIB_DIR}/utils + COMPONENT utilities + ) + endif(WIN32 AND UHD_RELEASE_MODE) + if(LINUX) + UHD_INSTALL(PROGRAMS + usrp2_recovery.py + DESTINATION ${PKG_LIB_DIR}/utils + COMPONENT utilities + ) + UHD_INSTALL(PROGRAMS + usrp2_card_burner.py + RENAME usrp2_card_burner + DESTINATION ${RUNTIME_DIR} + COMPONENT utilities + ) + endif(LINUX) + UHD_INSTALL(PROGRAMS + usrp2_card_burner.py + DESTINATION ${PKG_LIB_DIR}/utils + COMPONENT utilities + ) + endif(ENABLE_USRP2) + +endif(ENABLE_PYMOD_UTILS OR ENABLE_UTILS) + +if(NOT ENABLE_UTILS) + return() +endif() + ######################################################################## # Utilities that get installed into the runtime path ######################################################################## @@ -27,27 +121,18 @@ foreach(util_source ${util_runtime_sources}) UHD_INSTALL(TARGETS ${util_name} RUNTIME DESTINATION ${RUNTIME_DIR} COMPONENT utilities) endforeach(util_source) -set(CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/${PKG_DATA_DIR}") -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/rfnoc_image_builder.py" - "${CMAKE_CURRENT_BINARY_DIR}/rfnoc_image_builder" -) -UHD_INSTALL(PROGRAMS - ${CMAKE_CURRENT_BINARY_DIR}/rfnoc_image_builder - RENAME rfnoc_image_builder - DESTINATION ${RUNTIME_DIR} - COMPONENT utilities -) -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/usrpctl.py" - "${CMAKE_CURRENT_BINARY_DIR}/usrpctl" -) -UHD_INSTALL(PROGRAMS - ${CMAKE_CURRENT_BINARY_DIR}/usrpctl - RENAME usrpctl - DESTINATION ${RUNTIME_DIR} - COMPONENT utilities -) +if(ENABLE_PYTHON_API) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/usrpctl.py" + "${CMAKE_CURRENT_BINARY_DIR}/usrpctl" + ) + UHD_INSTALL(PROGRAMS + ${CMAKE_CURRENT_BINARY_DIR}/usrpctl + RENAME usrpctl + DESTINATION ${RUNTIME_DIR} + COMPONENT utilities + ) +endif() ######################################################################## # Utilities that get installed into the share path @@ -111,78 +196,6 @@ foreach(util_source ${util_share_sources_py}) ) endforeach(util_source) -#UHD images downloader configuration -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/../../images/manifest.txt CMAKE_MANIFEST_CONTENTS) -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/uhd_images_downloader.py.in - ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py -@ONLY) -# TODO: FIXME when know how. -# This is a hack to force cmake regenerate uhd_images_downloader.py -# whenever manifest.txt file changed. -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/../../images/manifest.txt - ${CMAKE_CURRENT_SOURCE_DIR}/../../images/manifest.txt -COPYONLY) - -UHD_INSTALL(PROGRAMS - ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py - DESTINATION ${PKG_LIB_DIR}/utils - COMPONENT utilities -) - -if(LINUX) - UHD_INSTALL(PROGRAMS - ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py - RENAME uhd_images_downloader - DESTINATION ${RUNTIME_DIR} - COMPONENT utilities - ) -endif(LINUX) -if(NOT HAVE_PYTHON_MODULE_REQUESTS) - message(WARNING "Python module `requests' not found -- uhd_images_downloader.py will not work without it.") - message(WARNING "You may be able to install this by running 'pip install requests'") -endif(NOT HAVE_PYTHON_MODULE_REQUESTS) - -if(ENABLE_USRP2) - set(burners - usrp2_card_burner.py - ) - - if(WIN32 AND UHD_RELEASE_MODE) #include dd.exe - file(DOWNLOAD - "http://files.ettus.com/dd.exe" - ${CMAKE_CURRENT_BINARY_DIR}/dd.exe - ) - UHD_INSTALL(FILES - ${CMAKE_CURRENT_BINARY_DIR}/dd.exe - DESTINATION ${PKG_LIB_DIR}/utils - COMPONENT utilities - ) - endif(WIN32 AND UHD_RELEASE_MODE) - if(LINUX) - UHD_INSTALL(PROGRAMS - usrp2_recovery.py - DESTINATION ${PKG_LIB_DIR}/utils - COMPONENT utilities - ) - UHD_INSTALL(PROGRAMS - usrp2_card_burner.py - RENAME usrp2_card_burner - DESTINATION ${RUNTIME_DIR} - COMPONENT utilities - ) - endif(LINUX) - foreach(burner ${burners}) - UHD_INSTALL(PROGRAMS - ${burner} - DESTINATION ${PKG_LIB_DIR}/utils - COMPONENT utilities - ) - endforeach(burner ${burners}) - -endif(ENABLE_USRP2) - ######################################################################## # Other files that are not utilities or executables ######################################################################## |