From 0ec53b0e2cd0713fa3e0fbe538eb1c89fe4e59d2 Mon Sep 17 00:00:00 2001
From: Jonathan Scruggs <j.scruggs@gmail.com>
Date: Thu, 28 Sep 2017 16:42:25 +0100
Subject: [PATCH 2/2] oiio/RB-1.7: Make python and boost detection more generic

* Fix boost and python detection for certain systems.
* Clean up boost and python detection.
* Remove redundant code.

Backported from:
https://github.com/OpenImageIO/oiio/commit/fca7ed62bd679a8221147dcddb23a516796dab90
---
 CMakeLists.txt                   |  38 +------------
 src/cmake/externalpackages.cmake |  61 +-------------------
 src/python/CMakeLists.txt        | 119 ++++++++++++++++-----------------------
 3 files changed, 53 insertions(+), 165 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 635c61f4..0f80959a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -181,9 +181,7 @@ set (USE_OPENGL ON CACHE BOOL "Include OpenGL support")
 set (USE_QT ON CACHE BOOL "Include Qt support")
 set (FORCE_OPENGL_1 OFF CACHE BOOL "Force iv to use OpenGL's fixed pipeline")
 set (USE_PYTHON ON CACHE BOOL "Build the Python bindings")
-set (USE_PYTHON3 OFF CACHE BOOL "Build the Python3 bindings")
-set (PYTHON_VERSION 2.6)
-set (PYTHON3_VERSION 3.2)
+set (PYTHON_VERSION "2.7" CACHE STRING "Target version of python to find")
 set (PYLIB_INCLUDE_SONAME OFF CACHE BOOL "If ON, soname/soversion will be set for Python module library")
 set (PYLIB_LIB_PREFIX OFF CACHE BOOL "If ON, prefix the Python module with 'lib'")
 set (USE_FIELD3D ON CACHE BOOL "Use Field3D if found")
@@ -373,32 +371,7 @@ include_directories (
 
 
 ###########################################################################
-# Set install paths for the python modules
-# TODO: Figure out how to get the correct python directory
-
-if (UNIX AND NOT SELF_CONTAINED_INSTALL_TREE)
-    # TODO: Figure out how to get the correct python directory
-    set (DEFAULT_PYLIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/python/site-packages")
-    set (DEFAULT_PYLIB3_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/python3/site-packages")
-else ()
-    # Here is the "self-contained install tree" case: the expectation here
-    # is that everything related to this project will go into its own
-    # directory, not into some standard system heirarchy.
-    set (DEFAULT_PYLIB_INSTALL_DIR "python")
-    set (DEFAULT_PYLIB3_INSTALL_DIR "python3")
-endif ()
-if (EXEC_INSTALL_PREFIX)
-    # Tack on an extra prefix to support multi-arch builds.
-    set (DEFAULT_PYLIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/${DEFAULT_PYLIB_INSTALL_DIR}")
-    set (DEFAULT_PYLIB3_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/${DEFAULT_PYLIB3_INSTALL_DIR}")
-endif ()
-# Set up cmake cache variables corresponding to the defaults deduced above, so
-# that the user can override them as desired:
-set (PYLIB_INSTALL_DIR ${DEFAULT_PYLIB_INSTALL_DIR} CACHE STRING
-     "Install location for python libraries (relative to CMAKE_INSTALL_PREFIX or absolute)")
-set (PYLIB3_INSTALL_DIR ${DEFAULT_PYLIB3_INSTALL_DIR} CACHE STRING
-     "Install location for python3 libraries (relative to CMAKE_INSTALL_PREFIX or absolute)")
-
+# Set default install options
 set (PLUGIN_SEARCH_PATH "" CACHE STRING "Default plugin search path")
 
 set (INSTALL_DOCS ON CACHE BOOL "Install documentation")
@@ -494,14 +467,9 @@ if (NOT EMBEDPLUGINS AND NOT BUILD_OIIOUTIL_ONLY)
     endforeach ()
 endif ()
 
-if (USE_PYTHON AND boost_PYTHON_FOUND AND NOT BUILD_OIIOUTIL_ONLY)
+if (USE_PYTHON AND NOT BUILD_OIIOUTIL_ONLY)
     add_subdirectory (src/python)
 endif ()
-if (USE_PYTHON3 AND boost_PYTHON_FOUND AND NOT BUILD_OIIOUTIL_ONLY)
-    #build the python3 module in a different binary directory since it will
-    #have the same name as the python2 module (e.g. OpenImageIO.so)
-    add_subdirectory (src/python src/python3)
-endif ()
 
 add_subdirectory (src/include)
 add_subdirectory (src/doc)
diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake
index 03faf7bd..b354cda0 100644
--- a/src/cmake/externalpackages.cmake
+++ b/src/cmake/externalpackages.cmake
@@ -116,10 +116,7 @@ if (NOT Boost_FIND_QUIETLY)
 endif ()
 
 if (NOT DEFINED Boost_ADDITIONAL_VERSIONS)
-  set (Boost_ADDITIONAL_VERSIONS "1.60" "1.59" "1.58" "1.57" "1.56"
-                                 "1.55" "1.54" "1.53" "1.52" "1.51" "1.50"
-                                 "1.49" "1.48" "1.47" "1.46" "1.45" "1.44"
-                                 "1.43" "1.43.0" "1.42" "1.42.0")
+  set (Boost_ADDITIONAL_VERSIONS "1.65.1" "1.65" "1.63" "1.62")
 endif ()
 if (LINKSTATIC)
     set (Boost_USE_STATIC_LIBS   ON)
@@ -131,51 +128,7 @@ if (BOOST_CUSTOM)
     # Boost_VERSION, Boost_INCLUDE_DIRS, Boost_LIBRARY_DIRS, Boost_LIBRARIES.
 else ()
     set (Boost_COMPONENTS filesystem regex system thread)
-    find_package (Boost 1.42 REQUIRED
-                  COMPONENTS ${Boost_COMPONENTS}
-                 )
-
-    # Try to figure out if this boost distro has Boost::python.  If we
-    # include python in the component list above, cmake will abort if
-    # it's not found.  So we resort to checking for the boost_python
-    # library's existance to get a soft failure.
-    find_library (my_boost_python_lib boost_python
-                  PATHS ${Boost_LIBRARY_DIRS} NO_DEFAULT_PATH)
-    mark_as_advanced (my_boost_python_lib)
-    if (NOT my_boost_python_lib AND Boost_SYSTEM_LIBRARY_RELEASE)
-        get_filename_component (my_boost_PYTHON_rel
-                                ${Boost_SYSTEM_LIBRARY_RELEASE} NAME
-                               )
-        string (REGEX REPLACE "^(lib)?(.+)_system(.+)$" "\\2_python\\3"
-                my_boost_PYTHON_rel ${my_boost_PYTHON_rel}
-               )
-        find_library (my_boost_PYTHON_LIBRARY_RELEASE
-                      NAMES ${my_boost_PYTHON_rel} lib${my_boost_PYTHON_rel}
-                      HINTS ${Boost_LIBRARY_DIRS}
-                      NO_DEFAULT_PATH
-                     )
-        mark_as_advanced (my_boost_PYTHON_LIBRARY_RELEASE)
-    endif ()
-    if (NOT my_boost_python_lib AND Boost_SYSTEM_LIBRARY_DEBUG)
-        get_filename_component (my_boost_PYTHON_dbg
-                                ${Boost_SYSTEM_LIBRARY_DEBUG} NAME
-                               )
-        string (REGEX REPLACE "^(lib)?(.+)_system(.+)$" "\\2_python\\3"
-                my_boost_PYTHON_dbg ${my_boost_PYTHON_dbg}
-               )
-        find_library (my_boost_PYTHON_LIBRARY_DEBUG
-                      NAMES ${my_boost_PYTHON_dbg} lib${my_boost_PYTHON_dbg}
-                      HINTS ${Boost_LIBRARY_DIRS}
-                      NO_DEFAULT_PATH
-                     )
-        mark_as_advanced (my_boost_PYTHON_LIBRARY_DEBUG)
-    endif ()
-    if (my_boost_python_lib OR
-        my_boost_PYTHON_LIBRARY_RELEASE OR my_boost_PYTHON_LIBRARY_DEBUG)
-        set (boost_PYTHON_FOUND ON)
-    else ()
-        set (boost_PYTHON_FOUND OFF)
-    endif ()
+    find_package (Boost 1.62 REQUIRED COMPONENTS ${Boost_COMPONENTS})
 endif ()
 
 # On Linux, Boost 1.55 and higher seems to need to link against -lrt
@@ -190,16 +143,6 @@ if (NOT Boost_FIND_QUIETLY)
     message (STATUS "Boost include dirs ${Boost_INCLUDE_DIRS}")
     message (STATUS "Boost library dirs ${Boost_LIBRARY_DIRS}")
     message (STATUS "Boost libraries    ${Boost_LIBRARIES}")
-    message (STATUS "Boost python found ${boost_PYTHON_FOUND}")
-endif ()
-if (NOT boost_PYTHON_FOUND)
-    # If Boost python components were not found, turn off all python support.
-    message (STATUS "Boost python support not found -- will not build python components!")
-    if (APPLE AND USE_PYTHON)
-        message (STATUS "   If your Boost is from Macports, you need the +python26 variant to get Python support.")
-    endif ()
-    set (USE_PYTHON OFF)
-    set (PYTHONLIBS_FOUND OFF)
 endif ()
 
 include_directories (SYSTEM "${Boost_INCLUDE_DIRS}")
diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt
index 81a4a890..e58d372d 100644
--- a/src/python/CMakeLists.txt
+++ b/src/python/CMakeLists.txt
@@ -1,54 +1,30 @@
-#if the CMAKE_CURRENT_BINARY_DIR is python3, then build the python3 module,
-#otherwise the python2 module
-string (REGEX MATCH "python3\$" _py3_subdir ${CMAKE_CURRENT_BINARY_DIR})
+# Attempt to find the desired version, but fall back to other
+# additional versions.
+find_package (PythonInterp ${PYTHON_VERSION} REQUIRED)
 
-if (_py3_subdir)
-    set (BUILD_PY3 ON)
-else ()
-    set (BUILD_PY3 OFF)
-endif ()
-
-if (NOT BOOST_CUSTOM AND NOT BUILD_PY3)
-    #Unset those, otherwise find_package(PythonLibs) will pick up old stuff
-    #if it has been run before
-    unset(Python_ADDITIONAL_VERSIONS)
-    unset(PYTHON_LIBRARY)
-    unset(PYTHON_LIBRARY CACHE)
-    unset(PYTHON_INCLUDE_DIR)
-    unset(PYTHON_INCLUDE_DIR CACHE)
-    unset(PYTHON_INCLUDE_PATH)
-    unset(PYTHON_INCLUDE_PATH CACHE)
-    find_package (PythonLibs ${PYTHON_VERSION} REQUIRED)
-    find_package (Boost 1.42 REQUIRED COMPONENTS python)
-elseif (BOOST_CUSTOM AND NOT BUILD_PY3)
-    find_package (PythonLibs ${PYTHON_VERSION} REQUIRED)
-else ()
-    #BOOST_CUSTOM is ignored for python3
+# The version that was found may not be the default or user
+# defined one.
+set (PYTHON_VERSION_FOUND ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
 
-    #Unset those, otherwise find_package(PythonLibs) will pick up old stuff
-    #if it has been run before
-    unset(PYTHON_LIBRARY)
-    unset(PYTHON_LIBRARY CACHE)
-    unset(PYTHON_INCLUDE_DIR)
-    unset(PYTHON_INCLUDE_DIR CACHE)
-    unset(PYTHON_INCLUDE_PATH)
-    unset(PYTHON_INCLUDE_PATH CACHE)
+if (NOT ${PYTHON_VERSION} EQUAL ${PYTHON_VERSION_FOUND} )
+    message (WARNING "The requested version ${PYTHON_VERSION} was not found.") 
+    message (WARNING "Using ${PYTHON_VERSION_FOUND} instead.")
+endif ()
 
-    #cmake 2.8 does not look for python 3.4
-    set(Python_ADDITIONAL_VERSIONS 3.4)
-    find_package (PythonInterp ${PYTHON3_VERSION} REQUIRED)
-    find_package (PythonLibs ${PYTHON3_VERSION} REQUIRED)
+find_package (PythonLibs ${PYTHON_VERSION_FOUND} REQUIRED)
 
-    #Finding the python3 component for boost is a little tricky, since it has
-    #different names on different systems. Try the most common ones
-    #(boost_python3, boost_python-py34, …).
-    foreach (_boost_py3_lib python3 python-py34 python-py33 python-py32)
-        find_package (Boost 1.42 QUIET COMPONENTS ${_boost_py3_lib})
-        string (TOUPPER ${_boost_py3_lib} boost_py3_lib_name)
-        if (Boost_${boost_py3_lib_name}_FOUND)
-            #Not the most beautiful thing to do, but that gets them included in
-            #the target_link_libraries(…) call farther down
-            set (Boost_PYTHON_LIBRARIES ${Boost_${boost_py3_lib_name}_LIBRARIES})
+if (NOT BOOST_CUSTOM)
+    # Finding the python component for boost is a little tricky, since it has
+    # different names on different systems. Try the most common ones.
+    foreach (_py_lib python-${PYTHON_VERSION_FOUND} python
+             python${PYTHON_VERSION_MAJOR}
+             python-py${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR})
+        find_package (Boost QUIET COMPONENTS ${_py_lib})
+        string (TOUPPER ${_py_lib} _py_lib_name)
+        if (Boost_${_py_lib_name}_FOUND)
+            # Not the most beautiful thing to do, but that gets them included in
+            # the target_link_libraries(…) call farther down
+            set (Boost_PYTHON_LIBRARIES ${Boost_${_py_lib_name}_LIBRARIES})
             break ()
         endif ()
     endforeach ()
@@ -58,18 +34,19 @@ if (APPLE)
 #    set (PYTHON_LIBRARIES /opt/local/lib)
 endif ()
 
+if (NOT DEFINED PYTHON_SITE_DIR)
+    set (PYTHON_SITE_DIR "${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_FOUND}/site-packages")
+endif ()
+
 # Disable some warnings for Clang, it's a little too picky with boost
 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
     add_definitions ("-Wno-array-bounds")
 endif ()
 
-if (BUILD_PY3)
-    set (target_name Py3OpenImageIO)
-else ()
-    set (target_name PyOpenImageIO)
-endif ()
+set (target_name PyOpenImageIO)
 
-if (BOOST_CUSTOM OR Boost_FOUND AND PYTHONLIBS_FOUND)
+# Test if automatically found or manually set with BOOST_CUSTOM
+if (DEFINED Boost_PYTHON_LIBRARIES)
 
     set (python_srcs py_imageinput.cpp py_imageoutput.cpp
          py_imagecache.cpp py_imagespec.cpp py_roi.cpp
@@ -81,8 +58,12 @@ if (BOOST_CUSTOM OR Boost_FOUND AND PYTHONLIBS_FOUND)
         message (STATUS "Python found ${PYTHONLIBS_FOUND} ")
         message (STATUS "Python include dirs ${PYTHON_INCLUDE_PATH}")
         message (STATUS "Python libraries    ${PYTHON_LIBRARIES}")
+        message (STATUS "Python site packages dir ${PYTHON_SITE_DIR}")
         message (STATUS "Python to include 'lib' prefix: ${PYLIB_LIB_PREFIX}")
         message (STATUS "Python to include SO version: ${PYLIB_INCLUDE_SONAME}")
+        message (STATUS "Python version ${PYTHON_VERSION_STRING}")
+        message (STATUS "Python version major: ${PYTHON_VERSION_MAJOR} minor: ${PYTHON_VERSION_MINOR}")
+        message (STATUS "Boost python libraries ${Boost_PYTHON_LIBRARIES}")
     endif ()
 
     include_directories (${PYTHON_INCLUDE_PATH} ${Boost_INCLUDE_DIRS})
@@ -91,7 +72,7 @@ if (BOOST_CUSTOM OR Boost_FOUND AND PYTHONLIBS_FOUND)
         target_link_libraries (${target_name} OpenImageIO ${Boost_LIBRARIES} ${Boost_PYTHON_LIBRARIES} ${CMAKE_DL_LIBS})
         set_target_properties (${target_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
     else ()
-        target_link_libraries (${target_name} OpenImageIO ${Boost_LIBRARIES} ${Boost_PYTHON_LIBRARIES} ${PYTHON_LIBRARIES} ${CMAKE_DL_LIBS})
+        target_link_libraries (${target_name} OpenImageIO ${SANITIZE_LIBRARIES} ${Boost_LIBRARIES} ${Boost_PYTHON_LIBRARIES} ${PYTHON_LIBRARIES} ${CMAKE_DL_LIBS})
     endif ()
 
     # Exclude the 'lib' prefix from the name
@@ -123,21 +104,17 @@ if (BOOST_CUSTOM OR Boost_FOUND AND PYTHONLIBS_FOUND)
                                SUFFIX ".pyd")
     endif()
     
-    if (BUILD_PY3)
-        install (TARGETS ${target_name}
-                 RUNTIME DESTINATION ${PYLIB3_INSTALL_DIR} COMPONENT user
-                 LIBRARY DESTINATION ${PYLIB3_INSTALL_DIR} COMPONENT user)
-    else ()
-        install (TARGETS ${target_name}
-                 RUNTIME DESTINATION ${PYLIB_INSTALL_DIR} COMPONENT user
-                 LIBRARY DESTINATION ${PYLIB_INSTALL_DIR} COMPONENT user)
-    endif ()
-elseif (BUILD_PY3)
-    if (NOT PYTHONLIBS_FOUND)
-        message (STATUS "Python3 libraries not found")
-    endif ()
-    if (NOT Boost_FOUND)
-        message (STATUS "Boost python3 component not found")
-    endif ()
-    set(USE_PYTHON3 OFF)
+    install (TARGETS ${target_name}
+             RUNTIME DESTINATION ${PYTHON_SITE_DIR} COMPONENT user
+             LIBRARY DESTINATION ${PYTHON_SITE_DIR} COMPONENT user)
+else ()
+    # If Boost python components were not found, turn off all python support.
+    message (STATUS "Boost python support not found!")
+    if (APPLE AND USE_PYTHON)
+        message (STATUS "   If your Boost is from Macports, you need the +python26 variant to get Python support.")
+     endif ()
+     if (BOOST_CUSTOM)
+        message (STATUS "   Please set the variable Boost_PYTHON_LIBRARIES to the location of the boost python libraries.")
+     endif ()
+     message (FATAL_ERROR "Python module cannot be built. Either disable python support or check your boost installation.")
 endif ()
-- 
2.14.2

