Python: install "bpy" as a package WITH_PYTHON_MODULE

Building WITH_PYTHON_MODULE was creating a "bpy" module that required
Blenders data-files to be located in the module search path too.

This mean that a typical installation on Linux would create:

- `/usr/lib/python3.10/site-packages/bpy.so`
- `/usr/lib/python3.10/site-packages/3.4`
  (containing `scripts` & `datafiles`).

The new behavior creates:

- `/usr/lib/python3.10/site-packages/bpy/__init__.so`
- `/usr/lib/python3.10/site-packages/bpy/3.4`

With the advantage that the "bpy" directory is the self contained Python
module.

No changes are needed for the module loading logic as the mechanism to
swap in blend internal Python "bpy" module
(defined in `release/scripts/modules/bpy/__init__.py`)
works the same in both instances.

Thanks to Brecht for macOS support.

Reviewed by brecht

Ref D15911
This commit is contained in:
Campbell Barton 2022-09-09 10:25:35 +10:00
parent 4a71765f9a
commit 81558783e4
Notes: blender-bot 2023-02-14 06:54:28 +01:00
Referenced by issue #100913, Improve support for building Blender as a Python Module (WITH_PYTHON_MODULE)
3 changed files with 41 additions and 20 deletions

View File

@ -659,6 +659,10 @@ if(WITH_PYTHON)
)
add_definitions(-DWITH_PYTHON)
if(WITH_PYTHON_MODULE)
add_definitions(-DWITH_PYTHON_MODULE)
endif()
if(WITH_PYTHON_SAFETY)
add_definitions(-DWITH_PYTHON_SAFETY)
endif()

View File

@ -374,7 +374,7 @@ static bool get_path_local_ex(char *targetpath,
/* Try `{g_app.program_dirname}/2.xx/{folder_name}` the default directory
* for a portable distribution. See `WITH_INSTALL_PORTABLE` build-option. */
const char *path_base = g_app.program_dirname;
#ifdef __APPLE__
#if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
/* Due new code-sign situation in OSX > 10.9.5
* we must move the blender_version dir with contents to Resources. */
char osx_resourses[FILE_MAX];

View File

@ -247,19 +247,29 @@ add_cc_flags_custom_test(blender)
if(WITH_PYTHON_MODULE)
add_definitions(-DWITH_PYTHON_MODULE)
# creates ./bin/bpy.so which can be imported as a python module.
# Creates `./bpy/__init__.so` which can be imported as a python module.
#
# note that 'SHARED' works on Linux and Windows,
# but not OSX which _must_ be 'MODULE'
add_library(blender MODULE ${SRC})
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(GENERATOR_IS_MULTI_CONFIG)
set(BPY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/$<CONFIG>/bpy)
else()
set(BPY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/bpy)
endif()
set_target_properties(
blender
PROPERTIES
PREFIX ""
OUTPUT_NAME bpy
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin # only needed on windows
OUTPUT_NAME __init__
LIBRARY_OUTPUT_DIRECTORY ${BPY_OUTPUT_DIRECTORY}
RUNTIME_OUTPUT_DIRECTORY ${BPY_OUTPUT_DIRECTORY}
)
unset(BPY_OUTPUT_DIRECTORY)
if(APPLE)
set_target_properties(blender PROPERTIES MACOSX_BUNDLE TRUE)
@ -306,13 +316,13 @@ set(BLENDER_TEXT_FILES
if(UNIX AND NOT APPLE)
if(WITH_PYTHON_MODULE)
if(WITH_INSTALL_PORTABLE)
set(TARGETDIR_BPY .)
set(TARGETDIR_VER ${BLENDER_VERSION})
set(TARGETDIR_LIB lib)
set(TARGETDIR_BPY bpy)
set(TARGETDIR_VER bpy/${BLENDER_VERSION})
set(TARGETDIR_LIB bpy/lib)
else()
set(TARGETDIR_BPY ${PYTHON_SITE_PACKAGES})
set(TARGETDIR_VER ${PYTHON_SITE_PACKAGES}/${BLENDER_VERSION})
set(TARGETDIR_LIB ${PYTHON_SITE_PACKAGES}/lib)
set(TARGETDIR_BPY ${PYTHON_SITE_PACKAGES}/bpy)
set(TARGETDIR_VER ${PYTHON_SITE_PACKAGES}/bpy/${BLENDER_VERSION})
set(TARGETDIR_LIB ${PYTHON_SITE_PACKAGES}/bpy/lib)
endif()
else()
if(WITH_INSTALL_PORTABLE)
@ -326,21 +336,28 @@ if(UNIX AND NOT APPLE)
endif()
elseif(WIN32)
set(TARGETDIR_VER ${BLENDER_VERSION})
set(TARGETDIR_TEXT .)
set(TARGETDIR_LIB .)
if(WITH_PYTHON_MODULE)
set(TARGETDIR_BPY $<TARGET_FILE_DIR:blender>)
set(TARGETDIR_VER $<TARGET_FILE_DIR:blender>/${BLENDER_VERSION})
# Important the DLL's are next to `__init__.pyd` otherwise it won't load.
set(TARGETDIR_LIB $<TARGET_FILE_DIR:blender>)
else()
set(TARGETDIR_VER ${BLENDER_VERSION})
set(TARGETDIR_TEXT .)
set(TARGETDIR_LIB .)
endif()
elseif(APPLE)
if(WITH_PYTHON_MODULE)
if(WITH_INSTALL_PORTABLE)
set(TARGETDIR_VER $<TARGET_FILE_DIR:blender>/../Resources/${BLENDER_VERSION})
set(TARGETDIR_LIB lib)
set(TARGETDIR_BPY bpy)
set(TARGETDIR_VER bpy/${BLENDER_VERSION})
set(TARGETDIR_LIB bpy/lib)
else()
# Paths defined in terms of site-packages since the site-packages
# directory can be a symlink (brew for example).
set(TARGETDIR_BPY ${PYTHON_LIBPATH}/site-packages)
set(TARGETDIR_VER ${TARGETDIR_BPY}/../Resources/${BLENDER_VERSION})
set(TARGETDIR_LIB ${TARGETDIR_BPY}/lib)
set(TARGETDIR_BPY ${PYTHON_LIBPATH}/site-packages/bpy)
set(TARGETDIR_VER ${PYTHON_LIBPATH}/site-packages/bpy/${BLENDER_VERSION})
set(TARGETDIR_LIB ${PYTHON_LIBPATH}/site-packages/bpy/lib)
endif()
else()
set(TARGETDIR_VER Blender.app/Contents/Resources/${BLENDER_VERSION})