diff --git a/CHANGES.md b/CHANGES.md index 08e6c6f3..44f9f811 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ # Imath Release Notes +* [Version 3.1.3](#version-313-september-2-2021) September 2, 2021 * [Version 3.1.2](#version-312-july-31-2021) July 31, 2021 * [Version 3.1.1](#version-311-july-20-2021) July 20, 2021 * [Version 3.1.0](#version-310-july-13-2021) July 13, 2021 @@ -11,6 +12,25 @@ * [Version 3.0.0-beta](#version-300-beta-march-15-2021) March 15, 2021 * [Inherited History from OpenEXR](#inherited-history-from-openexr) +## Version 3.1.3 (September 2, 2021) + +Patch release with miscellaneous fixes + +* \[[#204](https://github.com/AcademySoftwareFoundation/Imath/pull/204)\] +Fix undefined access of a vector when empty +* \[[#203](https://github.com/AcademySoftwareFoundation/Imath/pull/203)\] +Require sphinx 4.0.3 +* \[[#201](https://github.com/AcademySoftwareFoundation/Imath/pull/201)\] +Build sphinx/doxygen docs with CMake +* \[[#200](https://github.com/AcademySoftwareFoundation/Imath/pull/200)\] +Use PYIMATH_OVERRIDE_PYTHON_INSTALL_DIR to specify destination python modules +* \[[#199](https://github.com/AcademySoftwareFoundation/Imath/pull/199)\] +Guard `__has_attribute` for compilers that don't support it +* \[[#198](https://github.com/AcademySoftwareFoundation/Imath/pull/198)\] +Cuda safety fixes +* \[[#194](https://github.com/AcademySoftwareFoundation/Imath/pull/194)\] +Replace stray Imath:: with IMATH_INTERNAL_NAMESPACE:: + ## Version 3.1.2 (July 31, 2021) Patch release that fixes a Windows header issue. diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ebbe6d7..a0bec300 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ endif() # Imath version -project(Imath VERSION 3.1.2 LANGUAGES C CXX) +project(Imath VERSION 3.1.3 LANGUAGES C CXX) set(IMATH_VERSION_RELEASE_TYPE "" CACHE STRING "Extra version tag string for Imath build, such as -dev, -beta1, etc.") @@ -39,7 +39,7 @@ set(IMATH_VERSION_API "${Imath_VERSION_MAJOR}_${Imath_VERSION_MINOR}") # 3. API changed: CURRENT+1.0.0 # set(IMATH_LIBTOOL_CURRENT 29) -set(IMATH_LIBTOOL_REVISION 1) +set(IMATH_LIBTOOL_REVISION 2) set(IMATH_LIBTOOL_AGE 0) set(IMATH_LIB_VERSION "${IMATH_LIBTOOL_CURRENT}.${IMATH_LIBTOOL_REVISION}.${IMATH_LIBTOOL_AGE}") set(IMATH_LIB_SOVERSION ${IMATH_LIBTOOL_CURRENT}) @@ -73,6 +73,11 @@ if (PYTHON) add_subdirectory(src/python) endif() +option(DOCS "Set ON to build html documentation") +if (DOCS) + add_subdirectory(docs) +endif() + # If you want to use ctest to configure, build and # upload the results, cmake has builtin support for # submitting to CDash, or any server who speaks the @@ -107,3 +112,4 @@ endif() if(NOT IMATH_IS_SUBPROJECT) include(cmake/clang-format.cmake) endif() + diff --git a/INSTALL.md b/INSTALL.md index c8ecc438..3cbf63c8 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -56,18 +56,6 @@ install`` installs the header files in ``/usr/local/include``, the object libraries in ``/usr/local/lib``, and the executable programs in ``/usr/local/bin``. -## Python Bindings - -If you wish to install the optional python bindings included in this -repository, this must first be toggled on by appending -DPYTHON=ON to the -CMake command before compiling. - - % cmake $source_directory -DPYTHON=ON - -From here forward PyImath will be compiled until it is toggled back. Using: - - % cmake $source_directory -DPYTHON=OFF - ## Windows Quick Start Under Windows, if you are using a command line-based setup, such as @@ -81,6 +69,32 @@ can specify a local install directory to CMake via the % cmake .. -DCMAKE_INSTALL_PREFIX=$install_directory + +## Documentation + +The Imath documentation at +[imath.readthedocs.io](https://imath.readthedocs.io) is generated via +[Sphinx](https://www.sphinx-doc.org) with the +[Breathe](https://breathe.readthedocs.io) extension using information +extracted from header comments by [Doxgen](https://www.doxygen.nl). + +To build the documentation locally from the source headers and +``.rst`` files, set the CMake option ``DOCS=ON``. This adds +``Doxygen`` and ``Sphinx`` CMake targets. Local documentation +generation is off by default. + +Building the documentation requires that sphinx, breathe, and doxygen +are installed. + +## Python Bindings + +To build and install the optional Python bindings for Imath, set the +CMake option ``PYTHON=ON``. + +The Python bindings require that ``boost_python`` is installed. By +default, the bindings build for Python 3. To build with python 2, set +the CMake option ``USE_PYTHON2=ON``. + ## Library Names By default the installed libraries follow a pattern for how they are @@ -256,6 +270,23 @@ ways: ``IMATH_OUTPUT_SUBDIR`` Destination sub-folder of the include path for install. Default is ``Imath``. +``DOCS`` + Build the html documentation. Default is ``OFF``. + +``PYTHON`` + Build the optional Imath python bindings. Default is ``OFF``. + + The Python bindings require that ``boost_python`` is installed. + +``USE_PYTHON2`` If ``ON`` and ``PYTHON`` is also ``ON``, build the + bindings for Python 2. Default is ``OFF``, implying that the default + bindings are built for Python 3. + +``PYIMATH_OVERRIDE_PYTHON_INSTALL_DIR`` + Custom destination for installatation of ``imath.so`` and + ``imathnumpy.so`` modules. By default, they go into either + ``site-packages`` or ``dist-packages`. + To enable half-to-float conversion using the F16C SSE instruction set for g++ and clang when installing Imath, add the ``-mf16c`` compiler option: diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake new file mode 100644 index 00000000..89640a59 --- /dev/null +++ b/cmake/FindSphinx.cmake @@ -0,0 +1,12 @@ +#Look for an executable called sphinx-build +find_program(SPHINX_EXECUTABLE + NAMES sphinx-build + DOC "Path to sphinx-build executable") + +include(FindPackageHandleStandardArgs) + +#Handle standard arguments to find_package like REQUIRED and QUIET +find_package_handle_standard_args(Sphinx + "Failed to find sphinx-build executable" + SPHINX_EXECUTABLE) + diff --git a/config/ImathConfig.h.in b/config/ImathConfig.h.in index 8c2b572e..ec29c7fd 100644 --- a/config/ImathConfig.h.in +++ b/config/ImathConfig.h.in @@ -130,6 +130,13 @@ #endif +// On modern versions of gcc & clang, __has_attribute can test support for +// __attribute__((attr)). Make sure it's safe for other compilers. +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif + + // // Simple way to mark things as deprecated. // When we are sure that C++14 is our true minimum, then we can just diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt new file mode 100644 index 00000000..6845eeea --- /dev/null +++ b/docs/CMakeLists.txt @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright Contributors to the OpenEXR Project. + +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + +find_package(Doxygen REQUIRED) +find_package(Sphinx REQUIRED) + +set(DOXYGEN_INPUT_DIR ${PROJECT_SOURCE_DIR}/src/Imath) +set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doxygen) +set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/html/index.html) +set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) +set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + +set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}) +set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/sphinx) +set(SPHINX_INDEX_FILE ${SPHINX_BUILD}/index.html) + +configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) + +file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR}) + +add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE} + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} + MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} + COMMENT "Running doxygen" + VERBATIM) + +add_custom_target(Doxygen ALL DEPENDS ${DOXYGEN_INDEX_FILE}) + +add_custom_command(OUTPUT ${SPHINX_INDEX_FILE} + COMMAND + ${SPHINX_EXECUTABLE} -b html + # Tell Breathe where to find the Doxygen output + -Dbreathe_projects.Imath=${DOXYGEN_OUTPUT_DIR}/xml + ${SPHINX_SOURCE} ${SPHINX_BUILD} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${DOXYGEN_INDEX_FILE} + MAIN_DEPENDENCY conf.py + COMMENT "Generating documentation with Sphinx") + +add_custom_target(Sphinx ALL DEPENDS ${SPHINX_INDEX_FILE}) + +# Add an install target to install the docs +include(GNUInstallDirs) +install(DIRECTORY ${SPHINX_BUILD} +DESTINATION ${CMAKE_INSTALL_DOCDIR}) diff --git a/docs/Doxyfile b/docs/Doxyfile.in similarity index 82% rename from docs/Doxyfile rename to docs/Doxyfile.in index b64d3e81..c6b9f8ff 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile.in @@ -1,10 +1,13 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright Contributors to the OpenEXR Project. + PROJECT_NAME = "Imath" -XML_OUTPUT = doxyxml GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO -INPUT = ../src/Imath/ +INPUT = "@DOXYGEN_INPUT_DIR@" +OUTPUT_DIRECTORY = "@DOXYGEN_OUTPUT_DIR@" RECURSIVE = YES QUIET = YES JAVADOC_AUTOBRIEF = YES @@ -13,6 +16,7 @@ GENERATE_XML = YES DISTRIBUTE_GROUP_DOC = YES MACRO_EXPANSION = YES ENABLE_PREPROCESSING = YES +WARN_IF_UNDOCUMENTED = NO PREDEFINED = IMATH_CONSTEXPR14=constexpr \ IMATH_HOSTDEVICE= \ IMATH_INTERNAL_NAMESPACE=Imath \ diff --git a/docs/classes/half.rst b/docs/classes/half.rst index 88a15e0f..28a223dc 100644 --- a/docs/classes/half.rst +++ b/docs/classes/half.rst @@ -5,11 +5,13 @@ The half Class #include -``half`` is a 16-bit floating point number. See `The half Type`_ for -an explanation of the representation. +``half`` is a 16-bit floating point number. See :doc:`../float` for an +explanation of the representation. -Also, see `C-language half Conversion`_ for C-language support for -conversion between ``half`` and ``float``. +See :doc:`../functions/half_c` for C-language functions for conversion +between ``half`` and ``float``. Also, see :doc:`../half_conversion` +for information about building Imath with support for the F16C SSE +instruction set. Example: diff --git a/docs/conf.py b/docs/conf.py index 363bd070..ac32aec9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,8 +23,20 @@ # hack for readthedocs to cause it to run doxygen first # https://github.com/rtfd/readthedocs.org/issues/388 + on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if on_rtd: + + with open("Doxyfile.in", "r") as file: + filedata = file.read() + + doxygen_output_dir = "_build" + filedata = filedata.replace('@DOXYGEN_INPUT_DIR@', "../src/Imath") + filedata = filedata.replace('@DOXYGEN_OUTPUT_DIR@', "doxygen") + + with open("Doxyfile", "w") as file: + file.write(filedata) + from subprocess import call call('doxygen') @@ -44,7 +56,7 @@ ] # Breathe extension variables -breathe_projects = { "Imath": "doxyxml/" } +breathe_projects = { "Imath": "doxygen/xml" } breathe_default_project = "Imath" # Add any paths that contain templates here, relative to this directory. @@ -67,10 +79,19 @@ # |version| and |release|, also used in various other places throughout the # built documents. # +project_Imath_VERSION = "project(Imath VERSION " +release = None +for l in open ("../CMakeLists.txt"): + if l.startswith (project_Imath_VERSION): + release = l.split (' ')[2] + break +if release == None: + print ("Error in conf.py: can't find Imath VERSION in ../CMakeList.txt") + exit(-1) + +v = release.split('.') # The short X.Y version. -version = '3.1' -# The full version, including alpha/beta/rc tags. -release = '3.1.0' +version = "%s.%s" % (v[0], v[1]) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -148,7 +169,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +#html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied @@ -157,11 +178,11 @@ # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} @@ -218,7 +239,7 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'Imath.tex', 'Imath Documentation', - 'Cary Phillips', 'manual'), + 'Contributors to the OpenEXR Project', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -248,7 +269,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'imath', 'Imath Documentation', - ['Cary Phillips'], 1) + ['Contributors to the OpenEXR Project'], 1) ] # If true, show URL addresses after external links. @@ -262,7 +283,8 @@ # dir menu entry, description, category) texinfo_documents = [ ('index', 'Imath', 'Imath Documentation', - 'Cary Phillips', 'Imath', 'One line description of project.', + 'Contributors to the OpenEXR Project', 'Imath', + '2D and 3D vectors and matrices, half 16-bit floating-point type', 'Miscellaneous'), ] diff --git a/docs/index.rst b/docs/index.rst index 20cb09ee..54f2f1d7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,8 +1,5 @@ -.. Imath documentation master file, created by - sphinx-quickstart on Wed Apr 24 15:19:01 2019. - -Imath Technical Documentation -============================= +Imath |version| Technical Documentation +======================================= Imath is a basic, light-weight, and efficient C++ representation of 2D and 3D vectors and matrices and other simple but useful mathematical diff --git a/docs/requirements.txt b/docs/requirements.txt index cd6467ed..f9001d3c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,2 @@ breathe +sphinx == 4.0.3 diff --git a/src/Imath/ImathBox.h b/src/Imath/ImathBox.h index 653de3c7..7391dd7b 100644 --- a/src/Imath/ImathBox.h +++ b/src/Imath/ImathBox.h @@ -53,8 +53,8 @@ template class IMATH_EXPORT_TEMPLATE_TYPE Box /// @name Constructors /// Construct an empty bounding box. This initializes the mimimum to - /// `std::numeric_limits::max()` and the maximum to - /// `std::numeric_limits::lowest()`. + /// std::numeric_limits::max() and the maximum to + /// std::numeric_limits::lowest(). IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box() IMATH_NOEXCEPT; /// Construct a bounding box that contains a single point. @@ -401,8 +401,8 @@ template class IMATH_EXPORT_TEMPLATE_TYPE Box> /// Set the Box to be empty. A Box is empty if the mimimum is /// greater than the maximum. makeEmpty() sets the mimimum to - /// `numeric_limits::max()' and the maximum to - /// `numeric_limits::lowest()`. + /// std::numeric_limits::max() and the maximum to + /// std::numeric_limits::lowest(). IMATH_HOSTDEVICE void makeEmpty() IMATH_NOEXCEPT; /// Extend the Box to include the given point. @@ -662,8 +662,8 @@ template class IMATH_EXPORT_TEMPLATE_TYPE Box> /// Set the Box to be empty. A Box is empty if the mimimum is /// greater than the maximum. makeEmpty() sets the mimimum to - /// `numeric_limits::max()` and the maximum to - /// `numeric_limits::lowest()`. + /// std::numeric_limits::max() and the maximum to + /// std::numeric_limits::lowest(). IMATH_HOSTDEVICE void makeEmpty() IMATH_NOEXCEPT; /// Extend the Box to include the given point. diff --git a/src/Imath/ImathInterval.h b/src/Imath/ImathInterval.h index 089b9dc3..ae483a4a 100644 --- a/src/Imath/ImathInterval.h +++ b/src/Imath/ImathInterval.h @@ -104,8 +104,8 @@ template class IMATH_EXPORT_TEMPLATE_TYPE Interval IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool hasVolume() const IMATH_NOEXCEPT; /// Return true if the interval contains all points, false - /// otherwise. An infinite box has a mimimum of `numeric_limits::lowest()` - /// and a maximum of `numeric_limits::max()` + /// otherwise. An infinite box has a mimimum of std::numeric_limits::lowest() + /// and a maximum of std::numeric_limits::max() IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const IMATH_NOEXCEPT; /// @} diff --git a/src/Imath/ImathMatrix.h b/src/Imath/ImathMatrix.h index e034c31a..c1211fd6 100644 --- a/src/Imath/ImathMatrix.h +++ b/src/Imath/ImathMatrix.h @@ -2160,7 +2160,7 @@ Matrix33::operator*= (const Matrix33& v) IMATH_NOEXCEPT { // Avoid initializing with 0 values before immediately overwriting them, // and unroll all loops for the best autovectorization. - Matrix33 tmp(Imath::UNINITIALIZED); + Matrix33 tmp(IMATH_INTERNAL_NAMESPACE::UNINITIALIZED); tmp.x[0][0] = x[0][0] * v.x[0][0] + x[0][1] * v.x[1][0] + x[0][2] * v.x[2][0]; tmp.x[0][1] = x[0][0] * v.x[0][1] + x[0][1] * v.x[1][1] + x[0][2] * v.x[2][1]; @@ -2184,7 +2184,7 @@ Matrix33::operator* (const Matrix33& v) const IMATH_NOEXCEPT { // Avoid initializing with 0 values before immediately overwriting them, // and unroll all loops for the best autovectorization. - Matrix33 tmp(Imath::UNINITIALIZED); + Matrix33 tmp(IMATH_INTERNAL_NAMESPACE::UNINITIALIZED); tmp.x[0][0] = x[0][0] * v.x[0][0] + x[0][1] * v.x[1][0] + x[0][2] * v.x[2][0]; tmp.x[0][1] = x[0][0] * v.x[0][1] + x[0][1] * v.x[1][1] + x[0][2] * v.x[2][1]; diff --git a/src/Imath/ImathTypeTraits.h b/src/Imath/ImathTypeTraits.h index 7fe1e72f..4e8447d3 100644 --- a/src/Imath/ImathTypeTraits.h +++ b/src/Imath/ImathTypeTraits.h @@ -29,7 +29,7 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER /// An enable_if helper to be used in template parameters which results in /// much shorter symbols. -#define IMATH_ENABLE_IF(...) Imath::enable_if_t<(__VA_ARGS__), int> = 0 +#define IMATH_ENABLE_IF(...) IMATH_INTERNAL_NAMESPACE::enable_if_t<(__VA_ARGS__), int> = 0 #if IMATH_FOREIGN_VECTOR_INTEROP diff --git a/src/Imath/ImathVec.h b/src/Imath/ImathVec.h index c938b18c..d0a1baa9 100644 --- a/src/Imath/ImathVec.h +++ b/src/Imath/ImathVec.h @@ -872,6 +872,8 @@ typedef Vec4 V4d; // Normalize and length don't make sense for integer vectors, so disable them. //---------------------------------------------------------------------------- +/// @cond Doxygen_Suppress + // Vec2 template <> IMATH_HOSTDEVICE short Vec2::length() const IMATH_NOEXCEPT = delete; template <> IMATH_HOSTDEVICE const Vec2& Vec2::normalize() IMATH_NOEXCEPT = delete; @@ -953,6 +955,8 @@ template <> IMATH_HOSTDEVICE Vec4 Vec4::normalized() const IMA template <> Vec4 Vec4::normalizedExc() const = delete; template <> IMATH_HOSTDEVICE Vec4 Vec4::normalizedNonNull() const IMATH_NOEXCEPT = delete; +/// @endcond Doxygen_Suppress + //------------------------ // Implementation of Vec2: //------------------------ diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 8825289b..eb6be40c 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -31,7 +31,7 @@ find_package(Imath ${CMAKE_PROJECT_VERSION} REQUIRED CONFIG) # first make sure we find *some* python find_package(Python COMPONENTS Interpreter Development) if(NOT TARGET Python::Interpreter AND NOT TARGET Python::Python) - message(WARNING ": Unable to find any python interpreter or libraries, disabling PyImath") + message(WARNING "Unable to find any python interpreter or libraries, disabling PyImath") return() endif() @@ -43,13 +43,13 @@ option(USE_PYTHON2 "Whether to use Python 2.x or 3.x" OFF) if(USE_PYTHON2) find_package(Python2 COMPONENTS Interpreter Development) if(Python2_FOUND) - message(STATUS ": Found Python ${Python2_VERSION}") + message(STATUS "Found Python ${Python2_VERSION}") elseif(Python2::Python) - message(WARNING ": Found Python ${Python2_VERSION} development libraries, but no interpreter") + message(WARNING "Found Python ${Python2_VERSION} development libraries, but no interpreter") elseif(Python2::Interpreter) - message(WARNING ": Found Python ${Python2_VERSION} interpreter, but no development libraries") + message(WARNING "Found Python ${Python2_VERSION} interpreter, but no development libraries") else() - message(WARNING ": Unable to find Python2 interpreter or development libraries") + message(WARNING "Unable to find Python2 interpreter or development libraries") endif() set(PY_MAJOR_VERSION ${Python2_VERSION_MAJOR}) set(Python_VERSION_MAJOR ${Python2_VERSION_MAJOR}) @@ -59,13 +59,13 @@ if(USE_PYTHON2) else() find_package(Python3 COMPONENTS Interpreter Development) if(Python3_FOUND) - message(STATUS ": Found Python ${Python3_VERSION}") + message(STATUS "Found Python ${Python3_VERSION}") elseif(Python3::Python) - message(WARNING ": Found Python ${Python3_VERSION} development libraries, but no interpreter") + message(WARNING "Found Python ${Python3_VERSION} development libraries, but no interpreter") elseif(Python3::Interpreter) - message(WARNING ": Found Python ${Python3_VERSION} interpreter, but no development libraries") + message(WARNING "Found Python ${Python3_VERSION} interpreter, but no development libraries") else() - message(WARNING ": Unable to find Python3 interpreter or development libraries") + message(WARNING "Unable to find Python3 interpreter or development libraries") endif() set(PY_MAJOR_VERSION ${Python3_VERSION_MAJOR}) set(Python_VERSION_MAJOR ${Python3_VERSION_MAJOR}) @@ -75,7 +75,7 @@ else() endif() if (NOT Python2_FOUND AND NOT Python3_FOUND) - message(WARNING ": Disabling PyImath") + message(WARNING "Disabling PyImath") return() endif() @@ -84,41 +84,46 @@ endif() # Boost Python has some .. annoyances in that the python module # has version names attached to it function(PYIMATH_EXTRACT_REL_SITEARCH varname pyver pyexe pysitearch) - get_filename_component(_exedir ${pyexe} DIRECTORY) - # we do this such that cmake will canonicalize the slashes - # so the directory search will work under windows and unix - # consistently - get_filename_component(_basedir ${pysitearch} DIRECTORY) - get_filename_component(_basename ${pysitearch} NAME) - set(_basedir "${_basedir}/${_basename}") - string(FIND ${_basedir} ${_exedir} _findloc) - string(LENGTH ${_exedir} _elen) - while(_findloc EQUAL -1 AND _elen GREATER 0) - get_filename_component(_nexedir ${_exedir} DIRECTORY) - string(FIND ${_basedir} ${_nexedir} _findloc) - if (_nexedir STREQUAL _exedir) - message(WARNING "Unable to get parent directory for ${_exedir}, using absolute python site arch folder ${pysitearch}") - set(_elen -1) - break() - else() - set(_exedir ${_nexedir}) - endif() + if(PYIMATH_OVERRIDE_PYTHON_INSTALL_DIR) + set(${varname} ${PYIMATH_OVERRIDE_PYTHON_INSTALL_DIR} CACHE STRING "Destination sub-folder (relative) for the python ${pyver} modules") + message(STATUS "Will install to: ${PYIMATH_OVERRIDE_PYTHON_INSTALL_DIR}") + else() + get_filename_component(_exedir ${pyexe} DIRECTORY) + # we do this such that cmake will canonicalize the slashes + # so the directory search will work under windows and unix + # consistently + get_filename_component(_basedir ${pysitearch} DIRECTORY) + get_filename_component(_basename ${pysitearch} NAME) + set(_basedir "${_basedir}/${_basename}") + string(FIND ${_basedir} ${_exedir} _findloc) string(LENGTH ${_exedir} _elen) - endwhile() - math(EXPR _elen "${_elen}+1") - string(SUBSTRING ${_basedir} ${_elen} -1 _reldir) - if(APPLE) - # on macOS, set install path to user's python package directory - # so that elevated privileges are not necessary - execute_process( - COMMAND "${pyexe}" -c "if True: - import sysconfig - print(sysconfig.get_path('platlib', 'posix_user'))" - OUTPUT_VARIABLE _reldir - OUTPUT_STRIP_TRAILING_WHITESPACE) + while(_findloc EQUAL -1 AND _elen GREATER 0) + get_filename_component(_nexedir ${_exedir} DIRECTORY) + string(FIND ${_basedir} ${_nexedir} _findloc) + if (_nexedir STREQUAL _exedir) + message(WARNING "Unable to get parent directory for ${_exedir}, using absolute python site arch folder ${pysitearch}") + set(_elen -1) + break() + else() + set(_exedir ${_nexedir}) + endif() + string(LENGTH ${_exedir} _elen) + endwhile() + math(EXPR _elen "${_elen}+1") + string(SUBSTRING ${_basedir} ${_elen} -1 _reldir) + if(APPLE) + # on macOS, set install path to user's python package directory + # so that elevated privileges are not necessary + execute_process( + COMMAND "${pyexe}" -c "if True: + import sysconfig + print(sysconfig.get_path('platlib', 'posix_user'))" + OUTPUT_VARIABLE _reldir + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + set(${varname} ${_reldir} CACHE STRING "Destination sub-folder (relative) for the python ${pyver} modules") + message(STATUS "Will install to: ${_reldir}") endif() - set(${varname} ${_reldir} CACHE STRING "Destination sub-folder (relative) for the python ${pyver} modules") - message(STATUS " -> Will install to: ${_reldir}") endfunction() set(PYIMATH_BOOST_PY_COMPONENT "python${Python_VERSION_MAJOR}${Python_VERSION_MINOR}") @@ -174,7 +179,7 @@ elseif(NOT _pyimath_have_perver_boost) return() else() if(TARGET Boost::${PYIMATH_BOOST_PY_COMPONENT}) - message(STATUS " -> Found Python ${Python_VERSION_MAJOR} boost: Boost::${PYIMATH_BOOST_PY_COMPONENT}") + message(STATUS "Found Python ${Python_VERSION_MAJOR} boost: Boost::${PYIMATH_BOOST_PY_COMPONENT}") elseif(Boost_PYTHON_FOUND OR Boost_${PYIMATH_PY_UPPER}_FOUND) message(WARNING "Found boost for python ${Python_VERSION_MAJOR}, but FindBoost did not create an import library. If you believe this is wrong, check the cmake documentation and see if you need to set Boost_ROOT or Boost_NO_BOOST_CMAKE") return() diff --git a/src/python/PyImath/PyImathFixedVArray.cpp b/src/python/PyImath/PyImathFixedVArray.cpp index f927bb0f..d1733e67 100644 --- a/src/python/PyImath/PyImathFixedVArray.cpp +++ b/src/python/PyImath/PyImathFixedVArray.cpp @@ -309,7 +309,7 @@ FixedVArray::getitem (Py_ssize_t index) { const size_t i = canonical_index (index, _length); std::vector& data = _ptr[(_indices ? raw_ptr_index(i) : i) * _stride]; - return FixedArray(&data[0], data.size(), 1, _writable); + return FixedArray(data.empty() ? nullptr : &data[0], data.size(), 1, _writable); } template diff --git a/src/python/config/PyImathSetup.cmake b/src/python/config/PyImathSetup.cmake index 156d97dc..01a2154c 100644 --- a/src/python/config/PyImathSetup.cmake +++ b/src/python/config/PyImathSetup.cmake @@ -6,9 +6,7 @@ include(GNUInstallDirs) ######################## ## Target configuration -# TODO: Right now, we support compiling for multiple pythons at once -set(PYIMATH_OVERRIDE_PYTHON2_INSTALL_DIR "" CACHE STRING "Override the install location for any python 2.x modules compiled") -set(PYIMATH_OVERRIDE_PYTHON3_INSTALL_DIR "" CACHE STRING "Override the install location for any python 3.x modules compiled") +set(PYIMATH_OVERRIDE_PYTHON_INSTALL_DIR "" CACHE STRING "Override the install location for imath.so and imathnumpy.so modules") ######################## ## Build related options