Skip to content

Commit effbb49

Browse files
authored
Merge pull request #1358 from Idclip/boost_python_cmake_changes
Boost python CMake changes
2 parents 35e1f42 + 88b0fa9 commit effbb49

File tree

3 files changed

+84
-60
lines changed

3 files changed

+84
-60
lines changed

openvdb/openvdb/python/CMakeLists.txt

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -142,71 +142,94 @@ if(TARGET openvdb_shared AND NOT Boost_USE_STATIC_LIBS)
142142
set(Boost_USE_STATIC_LIBS OFF)
143143
endif()
144144

145-
# Boost python handling. Try to find the following named boost python libraries:
146-
# - boost_python{Python_VERSION_MAJOR}${Python_VERSION_MINOR}
147-
# - boost_python{Python_VERSION_MAJOR}
148-
# - boost_python
149-
# Prioritize the version suffixed library, failing if none exist.
150-
151-
find_package(Boost ${MINIMUM_BOOST_VERSION}
152-
QUIET COMPONENTS python${Python_VERSION_MAJOR}${Python_VERSION_MINOR}
153-
)
154-
find_package(Boost ${MINIMUM_BOOST_VERSION}
155-
QUIET COMPONENTS python${Python_VERSION_MAJOR}
156-
)
157-
find_package(Boost ${MINIMUM_BOOST_VERSION}
158-
QUIET COMPONENTS python
159-
)
145+
# Boost python cmake is a mess. Implementations provided by boost's config
146+
# cmake and kitware's module differ significantly and different cmake versions
147+
# also do slightly different things regarding the major/minor suffixing. We
148+
# previously attempted to handle all these cases by searching for boost_python
149+
# three times, prioritize the version suffixed library and falling back such:
150+
# - boost_python{Python_VERSION_MAJOR}${Python_VERSION_MINOR}
151+
# - boost_python{Python_VERSION_MAJOR}
152+
# - boost_python
153+
# This unfortunately fails as CMake sometimes creates an empty Boost::python
154+
# target on failed searches which stops subsequent searches. CMake also
155+
# sometimes just fails to find the suffixed versions regardless.
156+
#
157+
# Newer boost versions now seems to say that the suffixing is only required if
158+
# you have multiple boost installations, however the CMake implementation still
159+
# requires it. Boost specifically reads from Boost_PYTHON_VERSION and
160+
# Boost_PYTHON_VERSION_MAJOR variables. If the user has set these we just
161+
# search for the non suffixed versions. Note that users can also provide
162+
# Boost_NO_BOOST_CMAKE to skip the CMake implementation of FindBoost, though
163+
# this will impact other boost components.
164+
#
165+
# @todo just get rid of boost python and migrate to pybind asap.
160166

161-
if(TARGET Boost::python${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
162-
message(STATUS "Found boost_python${Python_VERSION_MAJOR}${Python_VERSION_MINOR}")
163-
list(APPEND OPENVDB_PYTHON_DEPS Boost::python${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
164-
elseif(TARGET Boost::python${Python_VERSION_MAJOR})
165-
message(STATUS "Found boost_python${Python_VERSION_MAJOR}")
166-
list(APPEND OPENVDB_PYTHON_DEPS Boost::python${Python_VERSION_MAJOR})
167-
elseif(TARGET Boost::python)
168-
message(STATUS "Found non-suffixed boost_python, assuming to be python version "
169-
"\"${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}\" compatible"
170-
)
171-
list(APPEND OPENVDB_PYTHON_DEPS Boost::python)
172-
else()
173-
message(FATAL_ERROR "Unable to find boost_python${Python_VERSION_MAJOR}${Python_VERSION_MINOR}, "
174-
"boost_python${Python_VERSION_MAJOR} or boost_python."
175-
)
167+
set(_REQUIRED_BOOST_COMPONENTS python)
168+
if(USE_NUMPY)
169+
list(APPEND _REQUIRED_BOOST_COMPONENTS numpy)
176170
endif()
177171

178-
# If boost >= 1.65, find the required numpy boost component and link that in.
179-
# Use the same system as above, first trying without the suffix, then with.
172+
if(Boost_PYTHON_VERSION OR
173+
Boost_PYTHON_VERSION_MAJOR)
174+
# Search for non-suffixed boost libraries
175+
find_package(Boost ${MINIMUM_BOOST_VERSION} COMPONENTS ${_REQUIRED_BOOST_COMPONENTS} REQUIRED)
176+
else()
177+
# Try to find matching boost components to the version of python detected
178+
list(TRANSFORM _REQUIRED_BOOST_COMPONENTS APPEND ${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
179+
180+
# Explicitly don't pass REQUIRED so we can provide the user a message with
181+
# instructions to circumvent the major/minor requirement.
182+
find_package(Boost ${MINIMUM_BOOST_VERSION} COMPONENTS ${_REQUIRED_BOOST_COMPONENTS})
183+
184+
# See if we found the target. If we didn't and CMake/Boost created a broken
185+
# aliased target, we can't try another search. Build an error message and stop.
186+
set(_BOOST_ERROR "")
187+
if(NOT TARGET Boost::python${Python_VERSION_MAJOR}${Python_VERSION_MINOR} AND TARGET Boost::python)
188+
list(APPEND _BOOST_ERROR "boost_python${Python_VERSION_MAJOR}${Python_VERSION_MINOR}")
189+
endif()
190+
if(USE_NUMPY AND NOT TARGET Boost::numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR} AND TARGET Boost::numpy)
191+
list(APPEND _BOOST_ERROR "boost_numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR}")
192+
endif()
180193

181-
if(USE_NUMPY)
182-
find_package(Boost ${MINIMUM_BOOST_VERSION}
183-
QUIET COMPONENTS numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR}
184-
)
185-
find_package(Boost ${MINIMUM_BOOST_VERSION}
186-
QUIET COMPONENTS numpy${Python_VERSION_MAJOR}
187-
)
188-
find_package(Boost ${MINIMUM_BOOST_VERSION}
189-
QUIET COMPONENTS numpy
190-
)
194+
if(_BOOST_ERROR)
195+
message(FATAL_ERROR "Unable to find versioned boost python libraries (${_BOOST_ERROR}). It's "
196+
"recommended that your installation of boost_python/boost_numpy match your python version "
197+
"exactly.\n"
198+
"Alternatively, you can try to search for boost python versions explicitly with either:\n"
199+
" 'Boost_PYTHON_VERSION=XY'\n"
200+
" 'Boost_PYTHON_VERSION_MAJOR=X'")
201+
endif()
191202

192-
if(TARGET Boost::numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
193-
message(STATUS "Found boost_numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR}")
194-
list(APPEND OPENVDB_PYTHON_DEPS Boost::numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
195-
elseif(TARGET Boost::numpy${Python_VERSION_MAJOR})
196-
message(STATUS "Found boost_numpy${Python_VERSION_MAJOR}")
197-
list(APPEND OPENVDB_PYTHON_DEPS Boost::numpy${Python_VERSION_MAJOR})
198-
elseif(TARGET Boost::numpy)
203+
# If we didn't create the target but CMake didn't create a broken alias, try another search
204+
if(NOT TARGET Boost::python${Python_VERSION_MAJOR}${Python_VERSION_MINOR} AND NOT TARGET Boost::python)
205+
find_package(Boost ${MINIMUM_BOOST_VERSION} COMPONENTS python REQUIRED)
206+
message(STATUS "Found non-suffixed boost_python, assuming to be python version "
207+
"\"${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}\" compatible")
208+
endif()
209+
if(USE_NUMPY AND
210+
NOT TARGET Boost::numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR} AND NOT TARGET Boost::numpy)
211+
find_package(Boost ${MINIMUM_BOOST_VERSION} COMPONENTS numpy REQUIRED)
199212
message(STATUS "Found non-suffixed boost_numpy, assuming to be python version "
200-
"\"${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}\" compatible"
201-
)
202-
list(APPEND OPENVDB_PYTHON_DEPS Boost::numpy)
203-
else()
204-
message(FATAL_ERROR "Unable to find boost_numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR}, "
205-
"boost_numpy${Python_VERSION_MAJOR} or boost_numpy."
206-
)
213+
"\"${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}\" compatible")
207214
endif()
208215
endif()
209216

217+
if(TARGET Boost::python${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
218+
list(APPEND OPENVDB_PYTHON_DEPS Boost::python${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
219+
elseif(TARGET Boost::python)
220+
list(APPEND OPENVDB_PYTHON_DEPS Boost::python)
221+
message(STATUS "Found non-suffixed boost_python, assuming to be python version "
222+
"\"${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}\" compatible")
223+
endif()
224+
225+
if(TARGET Boost::numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
226+
list(APPEND OPENVDB_PYTHON_DEPS Boost::numpy${Python_VERSION_MAJOR}${Python_VERSION_MINOR})
227+
elseif(TARGET Boost::numpy)
228+
list(APPEND OPENVDB_PYTHON_DEPS Boost::numpy)
229+
message(STATUS "Found non-suffixed boost_numpy, assuming to be python version "
230+
"\"${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}\" compatible")
231+
endif()
232+
210233
##########################################################################
211234

212235
set(OPENVDB_PYTHON_MODULE_SOURCE_FILES

openvdb/openvdb/python/test/TestOpenVDB.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@
1212
import os, os.path
1313
import sys
1414
import unittest
15-
try:
16-
from studio import openvdb
17-
except ImportError:
18-
import pyopenvdb as openvdb
15+
import pyopenvdb as openvdb
1916

2017

2118
def valueFactory(zeroValue, elemValue):
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Build:
2+
- Changed the way boost_python and boost_numpy are located. Both
3+
components must match the major/minor version of python in use. This
4+
can be circumvented by providing Boost_PYTHON_VERSION or Boost_PYTHON_VERSION_MAJOR.

0 commit comments

Comments
 (0)