Build against Python from precompiled libraries by default, instead of requiring framework from python.org package install. The resulting bpy module can still be used with any Python install of the same version. Use the same CMake find module as Linux. This simplifies code, and makes it possible to manually set PYTHON_* variables in CMake configuration. Remove WITH_PYTHON_FRAMEWORK option for regular Blender build, as this doesn't work well due to missing required Python packages. Advanced users can still set PYTHON_ROOT_DIR=/Library/Frameworks/Python.framework/Versions/3.10 for the same result.
226 lines
6.2 KiB
CMake
226 lines
6.2 KiB
CMake
# SPDX-License-Identifier: BSD-3-Clause
|
|
# Copyright 2011 Blender Foundation.
|
|
|
|
# - Find Python libraries
|
|
# Find the native Python includes and library
|
|
#
|
|
# Note:, This is not _yet_ intended to be a general python module for other
|
|
# projects to use since its hard coded to fixed Python version
|
|
# as Blender only supports a single Python version at the moment.
|
|
#
|
|
# Note:
|
|
# this is for Blender/Unix Python only.
|
|
#
|
|
# This module defines
|
|
# PYTHON_VERSION
|
|
# PYTHON_INCLUDE_DIRS
|
|
# PYTHON_INCLUDE_CONFIG_DIRS
|
|
# PYTHON_LIBRARIES
|
|
# PYTHON_LIBPATH, Used for installation
|
|
# PYTHON_SITE_PACKAGES, Used for installation (as a Python module)
|
|
# PYTHON_LINKFLAGS
|
|
# PYTHON_ROOT_DIR, The base directory to search for Python.
|
|
# This can also be an environment variable.
|
|
#
|
|
# also defined, but not for general use are
|
|
# PYTHON_LIBRARY, where to find the python library.
|
|
|
|
# If PYTHON_ROOT_DIR was defined in the environment, use it.
|
|
IF(NOT PYTHON_ROOT_DIR AND NOT $ENV{PYTHON_ROOT_DIR} STREQUAL "")
|
|
SET(PYTHON_ROOT_DIR $ENV{PYTHON_ROOT_DIR})
|
|
ENDIF()
|
|
|
|
SET(PYTHON_VERSION 3.10 CACHE STRING "Python Version (major and minor only)")
|
|
MARK_AS_ADVANCED(PYTHON_VERSION)
|
|
|
|
|
|
if(APPLE)
|
|
if(WITH_PYTHON_MODULE)
|
|
set(PYTHON_LINKFLAGS "-undefined dynamic_lookup")
|
|
else()
|
|
set(PYTHON_LINKFLAGS)
|
|
endif()
|
|
else()
|
|
# See: http://docs.python.org/extending/embedding.html#linking-requirements
|
|
SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic" CACHE STRING "Linker flags for python")
|
|
MARK_AS_ADVANCED(PYTHON_LINKFLAGS)
|
|
endif()
|
|
|
|
# if the user passes these defines as args, we don't want to overwrite
|
|
SET(_IS_INC_DEF OFF)
|
|
SET(_IS_INC_CONF_DEF OFF)
|
|
SET(_IS_LIB_DEF OFF)
|
|
SET(_IS_LIB_PATH_DEF OFF)
|
|
IF(DEFINED PYTHON_INCLUDE_DIR)
|
|
SET(_IS_INC_DEF ON)
|
|
ENDIF()
|
|
IF(DEFINED PYTHON_INCLUDE_CONFIG_DIR)
|
|
SET(_IS_INC_CONF_DEF ON)
|
|
ENDIF()
|
|
IF(DEFINED PYTHON_LIBRARY)
|
|
SET(_IS_LIB_DEF ON)
|
|
ENDIF()
|
|
IF(DEFINED PYTHON_LIBPATH)
|
|
SET(_IS_LIB_PATH_DEF ON)
|
|
ENDIF()
|
|
|
|
STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
|
|
|
|
SET(_python_SEARCH_DIRS
|
|
${PYTHON_ROOT_DIR}
|
|
"$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}"
|
|
"/opt/lib/python-${PYTHON_VERSION}"
|
|
)
|
|
|
|
# only search for the dirs if we haven't already
|
|
IF((NOT _IS_INC_DEF) OR (NOT _IS_INC_CONF_DEF) OR (NOT _IS_LIB_DEF) OR (NOT _IS_LIB_PATH_DEF))
|
|
SET(_PYTHON_ABI_FLAGS_TEST
|
|
"u; " # release
|
|
"du;d" # debug
|
|
)
|
|
|
|
FOREACH(_CURRENT_ABI_FLAGS ${_PYTHON_ABI_FLAGS_TEST})
|
|
# IF(CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
# SET(_CURRENT_ABI_FLAGS "d${_CURRENT_ABI_FLAGS}")
|
|
# ENDIF()
|
|
STRING(REPLACE " " "" _CURRENT_ABI_FLAGS ${_CURRENT_ABI_FLAGS})
|
|
|
|
IF(NOT DEFINED PYTHON_INCLUDE_DIR)
|
|
FIND_PATH(PYTHON_INCLUDE_DIR
|
|
NAMES
|
|
Python.h
|
|
HINTS
|
|
${_python_SEARCH_DIRS}
|
|
PATH_SUFFIXES
|
|
include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
|
|
include/${CMAKE_LIBRARY_ARCHITECTURE}/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
|
|
)
|
|
ENDIF()
|
|
|
|
IF(NOT DEFINED PYTHON_INCLUDE_CONFIG_DIR)
|
|
FIND_PATH(PYTHON_INCLUDE_CONFIG_DIR
|
|
NAMES
|
|
pyconfig.h
|
|
HINTS
|
|
${_python_SEARCH_DIRS}
|
|
PATH_SUFFIXES
|
|
include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
|
|
include/${CMAKE_LIBRARY_ARCHITECTURE}/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
|
|
)
|
|
IF((NOT PYTHON_INCLUDE_CONFIG_DIR) AND PYTHON_INCLUDE_DIR)
|
|
# Fallback...
|
|
UNSET(PYTHON_INCLUDE_CONFIG_DIR CACHE)
|
|
SET(PYTHON_INCLUDE_CONFIG_DIR ${PYTHON_INCLUDE_DIR} CACHE PATH "")
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
IF(NOT DEFINED PYTHON_LIBRARY)
|
|
FIND_LIBRARY(PYTHON_LIBRARY
|
|
NAMES
|
|
"python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}"
|
|
HINTS
|
|
${_python_SEARCH_DIRS}
|
|
PATH_SUFFIXES
|
|
lib64 lib
|
|
)
|
|
ENDIF()
|
|
|
|
IF(NOT DEFINED PYTHON_LIBPATH)
|
|
FIND_PATH(PYTHON_LIBPATH
|
|
NAMES
|
|
"python${PYTHON_VERSION}/abc.py" # This is a bit hackish! :/
|
|
HINTS
|
|
${_python_SEARCH_DIRS}
|
|
PATH_SUFFIXES
|
|
lib64 lib
|
|
)
|
|
IF((NOT PYTHON_LIBPATH) AND PYTHON_LIBRARY)
|
|
# Fallback...
|
|
UNSET(PYTHON_LIBPATH CACHE)
|
|
GET_FILENAME_COMPONENT(PYTHON_LIBPATH ${PYTHON_LIBRARY} PATH)
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
IF(PYTHON_LIBRARY AND PYTHON_LIBPATH AND PYTHON_INCLUDE_DIR AND PYTHON_INCLUDE_CONFIG_DIR)
|
|
SET(_PYTHON_ABI_FLAGS "${_CURRENT_ABI_FLAGS}")
|
|
break()
|
|
ELSE()
|
|
# ensure we don't find values from 2 different ABI versions
|
|
IF(NOT _IS_INC_DEF)
|
|
UNSET(PYTHON_INCLUDE_DIR CACHE)
|
|
ENDIF()
|
|
IF(NOT _IS_INC_CONF_DEF)
|
|
UNSET(PYTHON_INCLUDE_CONFIG_DIR CACHE)
|
|
ENDIF()
|
|
IF(NOT _IS_LIB_DEF)
|
|
UNSET(PYTHON_LIBRARY CACHE)
|
|
ENDIF()
|
|
IF(NOT _IS_LIB_PATH_DEF)
|
|
UNSET(PYTHON_LIBPATH CACHE)
|
|
ENDIF()
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
|
|
UNSET(_CURRENT_ABI_FLAGS)
|
|
UNSET(_CURRENT_PATH)
|
|
|
|
UNSET(_PYTHON_ABI_FLAGS_TEST)
|
|
ENDIF()
|
|
|
|
UNSET(_IS_INC_DEF)
|
|
UNSET(_IS_INC_CONF_DEF)
|
|
UNSET(_IS_LIB_DEF)
|
|
UNSET(_IS_LIB_PATH_DEF)
|
|
|
|
# handle the QUIETLY and REQUIRED arguments and SET PYTHONLIBSUNIX_FOUND to TRUE IF
|
|
# all listed variables are TRUE
|
|
INCLUDE(FindPackageHandleStandardArgs)
|
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibsUnix DEFAULT_MSG
|
|
PYTHON_LIBRARY PYTHON_LIBPATH PYTHON_INCLUDE_DIR PYTHON_INCLUDE_CONFIG_DIR)
|
|
|
|
IF(PYTHONLIBSUNIX_FOUND)
|
|
# Assign cache items
|
|
SET(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIR} ${PYTHON_INCLUDE_CONFIG_DIR})
|
|
IF(NOT WITH_PYTHON_MODULE)
|
|
SET(PYTHON_LIBRARIES ${PYTHON_LIBRARY})
|
|
ENDIF()
|
|
|
|
FIND_FILE(PYTHON_SITE_PACKAGES
|
|
NAMES
|
|
# debian specific
|
|
dist-packages
|
|
site-packages
|
|
HINTS
|
|
${PYTHON_LIBPATH}/python${PYTHON_VERSION}
|
|
)
|
|
|
|
# we need this for installation
|
|
# XXX No more valid with debian-like py3.5 packages...
|
|
# GET_FILENAME_COMPONENT(PYTHON_LIBPATH ${PYTHON_LIBRARY} PATH)
|
|
|
|
# not required for build, just used when bundling Python.
|
|
FIND_PROGRAM(
|
|
PYTHON_EXECUTABLE
|
|
NAMES
|
|
"python${PYTHON_VERSION}${_PYTHON_ABI_FLAGS}"
|
|
"python${PYTHON_VERSION}"
|
|
"python"
|
|
HINTS
|
|
${_python_SEARCH_DIRS}
|
|
PATH_SUFFIXES bin
|
|
)
|
|
ENDIF()
|
|
|
|
UNSET(_PYTHON_VERSION_NO_DOTS)
|
|
UNSET(_PYTHON_ABI_FLAGS)
|
|
UNSET(_python_SEARCH_DIRS)
|
|
|
|
MARK_AS_ADVANCED(
|
|
PYTHON_INCLUDE_DIR
|
|
PYTHON_INCLUDE_CONFIG_DIR
|
|
PYTHON_LIBRARY
|
|
PYTHON_LIBPATH
|
|
PYTHON_SITE_PACKAGES
|
|
PYTHON_EXECUTABLE
|
|
)
|