Compare commits
36 Commits
temp-ui-bu
...
eevee-moti
Author | SHA1 | Date | |
---|---|---|---|
d8f46a4452 | |||
a737ca11e1 | |||
92520f1791 | |||
6a1a894df1 | |||
c98f92f998 | |||
4f9d1a5765 | |||
33359237fe | |||
8ac06377a5 | |||
a0c947ed4c | |||
5fab2ce500 | |||
e7744caf64 | |||
00f8cfd4ac | |||
75008dc4b9 | |||
8ded0dd4d5 | |||
e5062a775e | |||
13aa113d7d | |||
d8876e78a1 | |||
e8592a0412 | |||
693b88f152 | |||
3651ebb1db | |||
7aef17d361 | |||
417f0d720b | |||
ed58e3656a | |||
7b9a6f823b | |||
2f2fb4453f | |||
f9f6042bcf | |||
16fd236e14 | |||
8cd42410c5 | |||
0213d9f865 | |||
bd6abacc04 | |||
c42e68c484 | |||
a83ad13c49 | |||
7ebb1f2ff3 | |||
5de40f4838 | |||
52f8ba66cb | |||
536142e12f |
44
.clang-tidy
44
.clang-tidy
@@ -1,44 +0,0 @@
|
||||
Checks: >
|
||||
-*,
|
||||
readability-*,
|
||||
-readability-uppercase-literal-suffix,
|
||||
-readability-magic-numbers,
|
||||
-readability-isolate-declaration,
|
||||
-readability-convert-member-functions-to-static,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-avoid-const-params-in-decls,
|
||||
-readability-simplify-boolean-expr,
|
||||
-readability-make-member-function-const,
|
||||
|
||||
-readability-misleading-indentation,
|
||||
|
||||
-readability-else-after-return,
|
||||
-readability-inconsistent-declaration-parameter-name,
|
||||
-readability-redundant-preprocessor,
|
||||
-readability-function-size,
|
||||
-readability-function-size,
|
||||
-readability-redundant-member-init,
|
||||
-readability-const-return-type,
|
||||
-readability-static-accessed-through-instance,
|
||||
-readability-redundant-declaration,
|
||||
-readability-qualified-auto,
|
||||
-readability-use-anyofallof,
|
||||
|
||||
bugprone-*,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-unhandled-self-assignment,
|
||||
-bugprone-branch-clone,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-reserved-identifier,
|
||||
|
||||
-bugprone-sizeof-expression,
|
||||
-bugprone-integer-division,
|
||||
-bugprone-incorrect-roundings,
|
||||
-bugprone-suspicious-string-compare,
|
||||
-bugprone-not-null-terminated-result,
|
||||
-bugprone-suspicious-missing-comma,
|
||||
-bugprone-parent-virtual-call,
|
||||
-bugprone-infinite-loop,
|
||||
-bugprone-copy-constructor-init,
|
||||
|
||||
WarningsAsErrors: '*'
|
@@ -41,7 +41,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# Prever LEGACY OpenGL to eb compatible with all the existing releases and
|
||||
# platforms which don't hare GLVND yet. Only do it if preference was not set
|
||||
@@ -214,8 +214,6 @@ if(WITH_GHOST_X11)
|
||||
option(WITH_GHOST_XDND "Enable drag'n'drop support on X11 using XDND protocol" ON)
|
||||
endif()
|
||||
|
||||
option(WITH_GMP "Use the gmp library for more accurate booleans" OFF)
|
||||
|
||||
# Misc...
|
||||
option(WITH_HEADLESS "Build without graphical support (renderfarm, server mode only)" OFF)
|
||||
mark_as_advanced(WITH_HEADLESS)
|
||||
@@ -280,6 +278,7 @@ option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd
|
||||
|
||||
# Alembic support
|
||||
option(WITH_ALEMBIC "Enable Alembic Support" ON)
|
||||
option(WITH_ALEMBIC_HDF5 "Enable Legacy Alembic Support (not officially supported)" OFF)
|
||||
|
||||
# Universal Scene Description support
|
||||
option(WITH_USD "Enable Universal Scene Description (USD) Support" ON)
|
||||
@@ -323,6 +322,14 @@ mark_as_advanced(WITH_SYSTEM_GLOG)
|
||||
# Freestyle
|
||||
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
|
||||
|
||||
# New object types
|
||||
option(WITH_NEW_OBJECT_TYPES "Enable new hair and pointcloud objects (use for development only, don't save in files)" OFF)
|
||||
mark_as_advanced(WITH_NEW_OBJECT_TYPES)
|
||||
|
||||
# New simulation data block
|
||||
option(WITH_NEW_SIMULATION_TYPE "Enable simulation data block (use for development only, don't save in files)" OFF)
|
||||
mark_as_advanced(WITH_NEW_SIMULATION_TYPE)
|
||||
|
||||
# Misc
|
||||
if(WIN32)
|
||||
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
|
||||
@@ -364,12 +371,12 @@ option(WITH_CYCLES "Enable Cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
|
||||
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
|
||||
option(WITH_CYCLES_OSL "Build Cycles with OSL support" ON)
|
||||
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
|
||||
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" OFF)
|
||||
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
|
||||
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
|
||||
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
|
||||
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 compute_75 CACHE STRING "CUDA architectures to build binaries for")
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 CACHE STRING "CUDA architectures to build binaries for")
|
||||
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
|
||||
unset(PLATFORM_DEFAULT)
|
||||
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
|
||||
@@ -417,11 +424,6 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC)
|
||||
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" ON)
|
||||
mark_as_advanced(WITH_ASSERT_ABORT)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(WITH_CLANG_TIDY "Use Clang Tidy to analyze the source code (only enable for development on Linux using Clang)" OFF)
|
||||
mark_as_advanced(WITH_CLANG_TIDY)
|
||||
endif()
|
||||
|
||||
option(WITH_BOOST "Enable features depending on boost" ON)
|
||||
option(WITH_TBB "Enable features depending on TBB (OpenVDB, OpenImageDenoise, sculpt multithreading)" ON)
|
||||
|
||||
@@ -653,7 +655,6 @@ if(WITH_BOOST AND NOT (WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR
|
||||
set(WITH_BOOST OFF)
|
||||
endif()
|
||||
|
||||
set_and_warn_dependency(WITH_TBB WITH_CYCLES OFF)
|
||||
set_and_warn_dependency(WITH_TBB WITH_USD OFF)
|
||||
set_and_warn_dependency(WITH_TBB WITH_OPENIMAGEDENOISE OFF)
|
||||
set_and_warn_dependency(WITH_TBB WITH_OPENVDB OFF)
|
||||
@@ -902,7 +903,7 @@ if(MSVC)
|
||||
# endianess-detection and auto-setting is counterproductive
|
||||
# so we just set endianness according CMAKE_OSX_ARCHITECTURES
|
||||
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64 OR CMAKE_OSX_ARCHITECTURES MATCHES arm64)
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64)
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES ppc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc64)
|
||||
add_definitions(-D__BIG_ENDIAN__)
|
||||
@@ -1245,7 +1246,7 @@ endif()
|
||||
|
||||
if(WITH_LIBMV)
|
||||
# We always have C++11 which includes unordered_map.
|
||||
set(CERES_DEFINES "-DCERES_STD_UNORDERED_MAP;-DCERES_USE_CXX_THREADS")
|
||||
set(CERES_DEFINES -DCERES_STD_UNORDERED_MAP)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@@ -1561,15 +1562,20 @@ if(WITH_PYTHON)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
|
||||
# MSVC needs to be tested first, since clang on windows will
|
||||
# match the compiler test below but clang-cl does not accept -std=c++11
|
||||
# since it is on by default and cannot be turned off.
|
||||
#
|
||||
# Nothing special is needed, C++11 features are available by default.
|
||||
elseif(
|
||||
CMAKE_COMPILER_IS_GNUCC OR
|
||||
CMAKE_C_COMPILER_ID MATCHES "Clang" OR
|
||||
CMAKE_C_COMPILER_ID MATCHES "Intel"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||
# TODO(sergey): Do we want c++11 or gnu-c++11 here?
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown compiler ${CMAKE_C_COMPILER_ID}, can't enable C++17 build")
|
||||
message(FATAL_ERROR "Unknown compiler ${CMAKE_C_COMPILER_ID}, can't enable C++11 build")
|
||||
endif()
|
||||
|
||||
# Visual Studio has all standards it supports available by default
|
||||
@@ -1630,6 +1636,10 @@ endif()
|
||||
#-----------------------------------------------------------------------------
|
||||
# Libraries
|
||||
|
||||
if(WITH_GTESTS)
|
||||
include(GTestTesting)
|
||||
endif()
|
||||
|
||||
if(WITH_BLENDER)
|
||||
add_subdirectory(intern)
|
||||
add_subdirectory(extern)
|
||||
|
@@ -142,10 +142,6 @@ Information
|
||||
endef
|
||||
# HELP_TEXT (end)
|
||||
|
||||
# This makefile is not meant for Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
$(error On Windows, use "cmd //c make.bat" instead of "make")
|
||||
endif
|
||||
|
||||
# System Vars
|
||||
OS:=$(shell uname -s)
|
||||
|
@@ -30,7 +30,7 @@
|
||||
# build_deps 2015 x64 / build_deps 2015 x86
|
||||
#
|
||||
# MAC OS X USAGE:
|
||||
# Install with homebrew: brew install cmake autoconf automake libtool yasm nasm bison
|
||||
# Install with homebrew: brew install cmake autoconf automake libtool yasm nasm
|
||||
# Run "make deps" from main Blender directory
|
||||
#
|
||||
# LINUX USAGE:
|
||||
@@ -48,7 +48,11 @@ include(cmake/options.cmake)
|
||||
include(cmake/versions.cmake)
|
||||
|
||||
if(ENABLE_MINGW64)
|
||||
include(cmake/setup_mingw64.cmake)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
include(cmake/setup_mingw64.cmake)
|
||||
else()
|
||||
include(cmake/setup_mingw32.cmake)
|
||||
endif()
|
||||
else()
|
||||
set(mingw_LIBDIR ${LIBDIR})
|
||||
endif()
|
||||
@@ -76,7 +80,6 @@ include(cmake/llvm.cmake)
|
||||
include(cmake/clang.cmake)
|
||||
if(APPLE)
|
||||
include(cmake/openmp.cmake)
|
||||
include(cmake/nasm.cmake)
|
||||
endif()
|
||||
include(cmake/openimageio.cmake)
|
||||
include(cmake/tiff.cmake)
|
||||
@@ -94,20 +97,17 @@ if(UNIX)
|
||||
else()
|
||||
include(cmake/pugixml.cmake)
|
||||
endif()
|
||||
if((NOT APPLE) OR ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
|
||||
include(cmake/ispc.cmake)
|
||||
include(cmake/openimagedenoise.cmake)
|
||||
include(cmake/embree.cmake)
|
||||
endif()
|
||||
if(NOT APPLE)
|
||||
include(cmake/xr_openxr.cmake)
|
||||
endif()
|
||||
include(cmake/openimagedenoise.cmake)
|
||||
include(cmake/embree.cmake)
|
||||
include(cmake/xr_openxr.cmake)
|
||||
|
||||
if(WITH_WEBP)
|
||||
include(cmake/webp.cmake)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# HMD branch deps
|
||||
include(cmake/hidapi.cmake)
|
||||
# OCIO deps
|
||||
include(cmake/tinyxml.cmake)
|
||||
include(cmake/yamlcpp.cmake)
|
||||
@@ -117,7 +117,6 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 OR ENABLE_MINGW64)
|
||||
include(cmake/gmp.cmake)
|
||||
include(cmake/openjpeg.cmake)
|
||||
if(NOT WIN32 OR BUILD_MODE STREQUAL Release)
|
||||
if(WIN32)
|
||||
|
@@ -16,6 +16,16 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
if(ALEMBIC_HDF5)
|
||||
set(ALEMBIC_HDF5_HL)
|
||||
# in debug mode we do not build HDF5_hdf5_hl_LIBRARY which makes cmake really
|
||||
# unhappy, stub it with the debug mode lib. it's not linking it in at this
|
||||
# point in time anyhow
|
||||
if(BUILD_MODE STREQUAL Debug)
|
||||
set(ALEMBIC_HDF5_HL -DHDF5_hdf5_hl_LIBRARY=${LIBDIR}/hdf5/lib/libhdf5_hl_D.${LIBEXT})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ALEMBIC_EXTRA_ARGS
|
||||
-DBUILDSTATIC=ON
|
||||
-DLINKSTATIC=ON
|
||||
@@ -43,6 +53,7 @@ set(ALEMBIC_EXTRA_ARGS
|
||||
-DUSE_PRMAN=0
|
||||
-DUSE_HDF5=Off
|
||||
-DUSE_STATIC_HDF5=Off
|
||||
-DHDF5_ROOT=${LIBDIR}/hdf5
|
||||
-DUSE_TESTS=Off
|
||||
-DALEMBIC_NO_OPENGL=1
|
||||
-DUSE_BINARIES=ON
|
||||
@@ -51,6 +62,7 @@ set(ALEMBIC_EXTRA_ARGS
|
||||
-DGLUT_INCLUDE_DIR=""
|
||||
-DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
|
||||
-DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
|
||||
${ALEMBIC_HDF5_HL}
|
||||
)
|
||||
|
||||
ExternalProject_Add(external_alembic
|
||||
|
@@ -44,7 +44,7 @@ if(WIN32)
|
||||
elseif(APPLE)
|
||||
set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh)
|
||||
set(BOOST_BUILD_COMMAND ./b2)
|
||||
set(BOOST_BUILD_OPTIONS toolset=clang-darwin cxxflags=${PLATFORM_CXXFLAGS} linkflags=${PLATFORM_LDFLAGS} visibility=global --disable-icu boost.locale.icu=off)
|
||||
set(BOOST_BUILD_OPTIONS toolset=darwin cxxflags=${PLATFORM_CXXFLAGS} linkflags=${PLATFORM_LDFLAGS} visibility=global --disable-icu boost.locale.icu=off)
|
||||
set(BOOST_HARVEST_CMD echo .)
|
||||
set(BOOST_PATCH_COMMAND echo .)
|
||||
else()
|
||||
|
@@ -30,7 +30,6 @@ if(UNIX)
|
||||
nasm
|
||||
yasm
|
||||
tclsh
|
||||
bison
|
||||
)
|
||||
|
||||
foreach(_software ${_required_software})
|
||||
@@ -41,12 +40,6 @@ if(UNIX)
|
||||
unset(_software_find CACHE)
|
||||
endforeach()
|
||||
|
||||
if(APPLE)
|
||||
if(NOT EXISTS "/usr/local/opt/bison/bin/bison")
|
||||
set(_software_missing "${_software_missing} bison")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(_software_missing)
|
||||
message(
|
||||
"\n"
|
||||
@@ -57,7 +50,7 @@ if(UNIX)
|
||||
" apt install autoconf automake libtool yasm nasm tcl\n"
|
||||
"\n"
|
||||
"On macOS (with homebrew):\n"
|
||||
" brew install cmake autoconf automake libtool yasm nasm bison\n"
|
||||
" brew install cmake autoconf automake libtool yasm nasm\n"
|
||||
"\n"
|
||||
"Other platforms:\n"
|
||||
" Install equivalent packages.\n")
|
||||
|
@@ -30,11 +30,6 @@ else()
|
||||
set(CLANG_GENERATOR "Unix Makefiles")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CLANG_EXTRA_ARGS ${CLANG_EXTRA_ARGS}
|
||||
-DLIBXML2_LIBRARY=${LIBDIR}/xml2/lib/libxml2.a
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_clang
|
||||
URL ${CLANG_URI}
|
||||
|
@@ -51,7 +51,6 @@ ExternalProject_Add(external_embree
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH MD5=${EMBREE_HASH}
|
||||
PREFIX ${BUILD_DIR}/embree
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/embree/src/external_embree < ${PATCH_DIR}/embree.diff
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/embree ${DEFAULT_CMAKE_FLAGS} ${EMBREE_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/embree
|
||||
)
|
||||
|
@@ -50,8 +50,7 @@ if(APPLE)
|
||||
set(FFMPEG_EXTRA_FLAGS
|
||||
${FFMPEG_EXTRA_FLAGS}
|
||||
--target-os=darwin
|
||||
--x86asmexe=${LIBDIR}/nasm/bin/nasm
|
||||
)
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_ffmpeg
|
||||
@@ -144,12 +143,6 @@ if(WIN32)
|
||||
external_zlib_mingw
|
||||
)
|
||||
endif()
|
||||
if(APPLE)
|
||||
add_dependencies(
|
||||
external_ffmpeg
|
||||
external_nasm
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||
ExternalProject_Add_Step(external_ffmpeg after_install
|
||||
|
@@ -24,8 +24,7 @@ set(FREETYPE_EXTRA_ARGS
|
||||
-DFT_WITH_HARFBUZZ=OFF
|
||||
-DFT_WITH_BZIP2=OFF
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_BrotliDec=TRUE)
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE)
|
||||
|
||||
ExternalProject_Add(external_freetype
|
||||
URL ${FREETYPE_URI}
|
||||
|
@@ -1,88 +0,0 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(GMP_EXTRA_ARGS -enable-cxx)
|
||||
|
||||
if(WIN32)
|
||||
# Shared for windows because static libs will drag in a libgcc dependency.
|
||||
set(GMP_OPTIONS --disable-static --enable-shared --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32)
|
||||
else()
|
||||
set(GMP_OPTIONS --enable-static --disable-shared )
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_gmp
|
||||
URL ${GMP_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH MD5=${GMP_HASH}
|
||||
PREFIX ${BUILD_DIR}/gmp
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/gmp/src/external_gmp/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/gmp ${GMP_OPTIONS} ${GMP_EXTRA_ARGS}
|
||||
BUILD_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/gmp/src/external_gmp/ && make -j${MAKE_THREADS}
|
||||
INSTALL_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/gmp/src/external_gmp/ && make install
|
||||
INSTALL_DIR ${LIBDIR}/gmp
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
set_target_properties(external_gmp PROPERTIES FOLDER Mingw)
|
||||
endif()
|
||||
|
||||
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||
ExternalProject_Add_Step(external_gmp after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def
|
||||
COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/gmp/bin/libgmp-10.dll ${HARVEST_TARGET}/gmp/lib/libgmp-10.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib ${HARVEST_TARGET}/gmp/lib/libgmp-10.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/gmp/include ${HARVEST_TARGET}/gmp/include
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_MODE STREQUAL Debug AND WIN32)
|
||||
ExternalProject_Add_Step(external_gmp after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def
|
||||
COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# gmpxx is somewhat special, it builds on top of the C style gmp library but exposes C++ bindings
|
||||
# given the C++ ABI between MSVC and mingw is not compatible, we need to build the bindings
|
||||
# with MSVC, while GMP can only be build with mingw.
|
||||
ExternalProject_Add(external_gmpxx
|
||||
URL ${GMP_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH MD5=${GMP_HASH}
|
||||
PREFIX ${BUILD_DIR}/gmpxx
|
||||
PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_gmpxx.txt ${BUILD_DIR}/gmpxx/src/external_gmpxx/CMakeLists.txt &&
|
||||
${CMAKE_COMMAND} -E copy ${PATCH_DIR}/config_gmpxx.h ${BUILD_DIR}/gmpxx/src/external_gmpxx/config.h
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/gmpxx ${DEFAULT_CMAKE_FLAGS} -DGMP_LIBRARY=${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib -DGMP_INCLUDE_DIR=${BUILD_DIR}/gmp/src/external_gmp -DCMAKE_DEBUG_POSTFIX=_d
|
||||
INSTALL_DIR ${LIBDIR}/gmpxx
|
||||
)
|
||||
set_target_properties(external_gmpxx PROPERTIES FOLDER Mingw)
|
||||
|
||||
add_dependencies(
|
||||
external_gmpxx
|
||||
external_gmp
|
||||
)
|
||||
|
||||
ExternalProject_Add_Step(external_gmpxx after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/gmpxx/ ${HARVEST_TARGET}/gmp
|
||||
DEPENDEES install
|
||||
)
|
||||
|
||||
endif()
|
@@ -42,11 +42,22 @@ if(BUILD_MODE STREQUAL Release)
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/glew/include/ ${HARVEST_TARGET}/opengl/include/ &&
|
||||
# tiff
|
||||
${CMAKE_COMMAND} -E copy ${LIBDIR}/tiff/lib/tiff.lib ${HARVEST_TARGET}/tiff/lib/libtiff.lib &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tiff/include/ ${HARVEST_TARGET}/tiff/include/
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tiff/include/ ${HARVEST_TARGET}/tiff/include/ &&
|
||||
# hidapi
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hidapi/ ${HARVEST_TARGET}/hidapi/
|
||||
DEPENDS
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_MODE STREQUAL Debug)
|
||||
add_custom_target(Harvest_Debug_Results
|
||||
COMMAND
|
||||
# hdf5
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hdf5/lib ${HARVEST_TARGET}/hdf5/lib &&
|
||||
DEPENDS Package_Python
|
||||
)
|
||||
endif()
|
||||
|
||||
else(WIN32)
|
||||
|
||||
function(harvest from to)
|
||||
@@ -89,8 +100,6 @@ harvest(freetype/include freetype/include "*.h")
|
||||
harvest(freetype/lib/libfreetype2ST.a freetype/lib/libfreetype.a)
|
||||
harvest(glew/include glew/include "*.h")
|
||||
harvest(glew/lib glew/lib "*.a")
|
||||
harvest(gmp/include gmp/include "*.h")
|
||||
harvest(gmp/lib gmp/lib "*.a")
|
||||
harvest(jemalloc/include jemalloc/include "*.h")
|
||||
harvest(jemalloc/lib jemalloc/lib "*.a")
|
||||
harvest(jpg/include jpeg/include "*.h")
|
||||
@@ -134,12 +143,8 @@ harvest(openimageio/bin openimageio/bin "maketx")
|
||||
harvest(openimageio/bin openimageio/bin "oiiotool")
|
||||
harvest(openimageio/include openimageio/include "*")
|
||||
harvest(openimageio/lib openimageio/lib "*.a")
|
||||
if((NOT APPLE) OR ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
|
||||
harvest(openimagedenoise/include openimagedenoise/include "*")
|
||||
harvest(openimagedenoise/lib openimagedenoise/lib "*.a")
|
||||
harvest(embree/include embree/include "*.h")
|
||||
harvest(embree/lib embree/lib "*.a")
|
||||
endif()
|
||||
harvest(openimagedenoise/include openimagedenoise/include "*")
|
||||
harvest(openimagedenoise/lib openimagedenoise/lib "*.a")
|
||||
harvest(openjpeg/include/openjpeg-2.3 openjpeg/include "*.h")
|
||||
harvest(openjpeg/lib openjpeg/lib "*.a")
|
||||
harvest(opensubdiv/include opensubdiv/include "*.h")
|
||||
@@ -174,6 +179,8 @@ harvest(vpx/lib ffmpeg/lib "*.a")
|
||||
harvest(webp/lib ffmpeg/lib "*.a")
|
||||
harvest(x264/lib ffmpeg/lib "*.a")
|
||||
harvest(xvidcore/lib ffmpeg/lib "*.a")
|
||||
harvest(embree/include embree/include "*.h")
|
||||
harvest(embree/lib embree/lib "*.a")
|
||||
harvest(usd/include usd/include "*.h")
|
||||
harvest(usd/lib/usd usd/lib/usd "*")
|
||||
harvest(usd/plugin usd/plugin "*")
|
||||
|
42
build_files/build_environment/cmake/hdf5.cmake
Normal file
42
build_files/build_environment/cmake/hdf5.cmake
Normal file
@@ -0,0 +1,42 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(HDF5_EXTRA_ARGS
|
||||
-DHDF5_ENABLE_THREADSAFE=Off
|
||||
-DHDF5_BUILD_CPP_LIB=Off
|
||||
-DBUILD_TESTING=Off
|
||||
-DHDF5_BUILD_TOOLS=Off
|
||||
-DHDF5_BUILD_EXAMPLES=Off
|
||||
-DHDF5_BUILD_HL_LIB=On
|
||||
-DBUILD_STATIC_CRT_LIBS=On
|
||||
-DBUILD_SHARED_LIBS=On
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(HDF5_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/hdf5/src/external_hdf5 < ${PATCH_DIR}/hdf5.diff)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_hdf5
|
||||
URL ${HDF5_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH MD5=${HDF5_HASH}
|
||||
PREFIX ${BUILD_DIR}/hdf5
|
||||
PATCH_COMMAND ${HDF5_PATCH}
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/hdf5 ${HDF5_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/hdf5
|
||||
)
|
@@ -16,14 +16,14 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
ExternalProject_Add(external_nasm
|
||||
URL ${NASM_URI}
|
||||
set(HIDAPI_EXTRA_ARGS)
|
||||
|
||||
ExternalProject_Add(external_hidapi
|
||||
URL ${HIDAPI_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH SHA256=${NASM_HASH}
|
||||
PREFIX ${BUILD_DIR}/nasm
|
||||
PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/nasm/src/external_nasm < ${PATCH_DIR}/nasm.diff
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/nasm
|
||||
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make -j${MAKE_THREADS}
|
||||
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make install
|
||||
INSTALL_DIR ${LIBDIR}/nasm
|
||||
URL_HASH MD5=${HIDAPI_HASH}
|
||||
PREFIX ${BUILD_DIR}/hidapi
|
||||
PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_hidapi.txt ${BUILD_DIR}/hidapi/src/external_hidapi/cmakelists.txt && ${PATCH_CMD} -p 0 -d ${BUILD_DIR}/hidapi/src/external_hidapi < ${PATCH_DIR}/hidapi.diff
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/hidapi -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${HIDAPI_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/hidapi
|
||||
)
|
@@ -1,75 +0,0 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
if(WIN32)
|
||||
set(ISPC_EXTRA_ARGS_WIN
|
||||
-DFLEX_EXECUTABLE=${LIBDIR}/flexbison/win_flex.exe
|
||||
-DBISON_EXECUTABLE=${LIBDIR}/flexbison/win_bison.exe
|
||||
-DM4_EXECUTABLE=${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/m4.exe
|
||||
)
|
||||
elseif(APPLE)
|
||||
# Use bison installed via Homebrew.
|
||||
# The one which comes which Xcode toolset is too old.
|
||||
set(ISPC_EXTRA_ARGS_APPLE
|
||||
-DBISON_EXECUTABLE=/usr/local/opt/bison/bin/bison
|
||||
)
|
||||
elseif(UNIX)
|
||||
set(ISPC_EXTRA_ARGS_UNIX
|
||||
-DCMAKE_C_COMPILER=${LIBDIR}/clang/bin/clang
|
||||
-DCMAKE_CXX_COMPILER=${LIBDIR}/clang/bin/clang++
|
||||
)
|
||||
endif()
|
||||
|
||||
set(ISPC_EXTRA_ARGS
|
||||
-DARM_ENABLED=Off
|
||||
-DISPC_NO_DUMPS=On
|
||||
-DISPC_INCLUDE_EXAMPLES=Off
|
||||
-DISPC_INCLUDE_TESTS=Off
|
||||
-DLLVM_ROOT=${LIBDIR}/llvm/lib/cmake/llvm
|
||||
-DLLVM_LIBRARY_DIR=${LIBDIR}/llvm/lib
|
||||
-DCLANG_EXECUTABLE=${LIBDIR}/clang/bin/clang
|
||||
-DISPC_INCLUDE_TESTS=Off
|
||||
-DCLANG_LIBRARY_DIR=${LIBDIR}/clang/lib
|
||||
-DCLANG_INCLUDE_DIRS=${LIBDIR}/clang/include
|
||||
${ISPC_EXTRA_ARGS_WIN}
|
||||
${ISPC_EXTRA_ARGS_APPLE}
|
||||
${ISPC_EXTRA_ARGS_UNIX}
|
||||
)
|
||||
|
||||
ExternalProject_Add(external_ispc
|
||||
URL ${ISPC_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH MD5=${ISPC_HASH}
|
||||
PREFIX ${BUILD_DIR}/ispc
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/ispc/src/external_ispc < ${PATCH_DIR}/ispc.diff
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/ispc -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${ISPC_EXTRA_ARGS} ${BUILD_DIR}/ispc/src/external_ispc
|
||||
INSTALL_DIR ${LIBDIR}/ispc
|
||||
)
|
||||
|
||||
add_dependencies(
|
||||
external_ispc
|
||||
ll
|
||||
external_clang
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
add_dependencies(
|
||||
external_ispc
|
||||
external_flexbison
|
||||
)
|
||||
endif()
|
@@ -16,17 +16,11 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
set(LLVM_TARGETS AArch64)
|
||||
else()
|
||||
set(LLVM_TARGETS X86)
|
||||
endif()
|
||||
|
||||
set(LLVM_EXTRA_ARGS
|
||||
-DLLVM_USE_CRT_RELEASE=MD
|
||||
-DLLVM_USE_CRT_DEBUG=MDd
|
||||
-DLLVM_INCLUDE_TESTS=OFF
|
||||
-DLLVM_TARGETS_TO_BUILD=${LLVM_TARGETS}
|
||||
-DLLVM_TARGETS_TO_BUILD=X86
|
||||
-DLLVM_INCLUDE_EXAMPLES=OFF
|
||||
-DLLVM_ENABLE_TERMINFO=OFF
|
||||
-DLLVM_BUILD_LLVM_C_DYLIB=OFF
|
||||
|
@@ -38,7 +38,6 @@ ExternalProject_Add(external_numpy
|
||||
PREFIX ${BUILD_DIR}/numpy
|
||||
PATCH_COMMAND ${NUMPY_PATCH}
|
||||
CONFIGURE_COMMAND ""
|
||||
PATCH_COMMAND COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff
|
||||
LOG_BUILD 1
|
||||
BUILD_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/numpy/src/external_numpy/setup.py build ${NUMPY_BUILD_OPTION} install --old-and-unmanageable
|
||||
INSTALL_COMMAND ""
|
||||
|
@@ -21,7 +21,6 @@ ExternalProject_Add(external_ogg
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH SHA256=${OGG_HASH}
|
||||
PREFIX ${BUILD_DIR}/ogg
|
||||
PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/ogg/src/external_ogg < ${PATCH_DIR}/ogg.diff
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/ogg/src/external_ogg/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/ogg --disable-shared --enable-static
|
||||
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/ogg/src/external_ogg/ && make -j${MAKE_THREADS}
|
||||
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/ogg/src/external_ogg/ && make install
|
||||
|
@@ -30,13 +30,6 @@ set(OPENCOLORIO_EXTRA_ARGS
|
||||
-DOCIO_STATIC_JNIGLUE=OFF
|
||||
)
|
||||
|
||||
if(APPLE AND NOT("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
|
||||
set(OPENCOLORIO_EXTRA_ARGS
|
||||
${OPENCOLORIO_EXTRA_ARGS}
|
||||
-DOCIO_USE_SSE=OFF
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(OCIO_PATCH opencolorio_win.diff)
|
||||
set(OPENCOLORIO_EXTRA_ARGS
|
||||
|
@@ -18,41 +18,26 @@
|
||||
|
||||
|
||||
set(OIDN_EXTRA_ARGS
|
||||
-DOIDN_APPS=OFF
|
||||
-DWITH_EXAMPLE=OFF
|
||||
-DWITH_TEST=OFF
|
||||
-DTBB_ROOT=${LIBDIR}/tbb
|
||||
-DTBB_STATIC_LIB=${TBB_STATIC_LIBRARY}
|
||||
-DOIDN_STATIC_LIB=ON
|
||||
-DOIDN_STATIC_RUNTIME=OFF
|
||||
-DISPC_EXECUTABLE=${LIBDIR}/ispc/bin/ispc
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(OIDN_EXTRA_ARGS
|
||||
${OIDN_EXTRA_ARGS}
|
||||
-DTBB_DEBUG_LIBRARY=${LIBDIR}/tbb/lib/tbb.lib
|
||||
-DTBB_DEBUG_LIBRARY_MALLOC=${LIBDIR}/tbb/lib/tbbmalloc.lib
|
||||
)
|
||||
else()
|
||||
set(OIDN_EXTRA_ARGS
|
||||
${OIDN_EXTRA_ARGS}
|
||||
-Dtbb_LIBRARY_RELEASE=${LIBDIR}/tbb/lib/tbb_static.a
|
||||
-Dtbbmalloc_LIBRARY_RELEASE=${LIBDIR}/tbb/lib/tbbmalloc_static.a
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_openimagedenoise
|
||||
URL ${OIDN_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH MD5=${OIDN_HASH}
|
||||
PREFIX ${BUILD_DIR}/openimagedenoise
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openimagedenoise ${DEFAULT_CMAKE_FLAGS} ${OIDN_EXTRA_ARGS}
|
||||
PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/openimagedenoise/src/external_openimagedenoise < ${PATCH_DIR}/openimagedenoise.diff
|
||||
INSTALL_DIR ${LIBDIR}/openimagedenoise
|
||||
)
|
||||
|
||||
add_dependencies(
|
||||
external_openimagedenoise
|
||||
external_tbb
|
||||
external_ispc
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
@@ -61,7 +46,7 @@ if(WIN32)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openimagedenoise/include ${HARVEST_TARGET}/openimagedenoise/include
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/dnnl.lib ${HARVEST_TARGET}/openimagedenoise/lib/dnnl.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn.lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
@@ -69,7 +54,7 @@ if(WIN32)
|
||||
ExternalProject_Add_Step(external_openimagedenoise after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise_d.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common_d.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/dnnl.lib ${HARVEST_TARGET}/openimagedenoise/lib/dnnl_d.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn_d.lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
@@ -22,7 +22,6 @@ ExternalProject_Add(external_openmp
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH MD5=${OPENMP_HASH}
|
||||
PREFIX ${BUILD_DIR}/openmp
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openmp/src/external_openmp < ${PATCH_DIR}/openmp.diff
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openmp ${DEFAULT_CMAKE_FLAGS}
|
||||
INSTALL_COMMAND cd ${BUILD_DIR}/openmp/src/external_openmp-build && install_name_tool -id @executable_path/../Resources/lib/libomp.dylib runtime/src/libomp.dylib && make install
|
||||
INSTALL_DIR ${LIBDIR}/openmp
|
||||
|
@@ -17,7 +17,7 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
if(WIN32)
|
||||
option(ENABLE_MINGW64 "Enable building of ffmpeg/iconv/libsndfile/fftw3 by installing mingw64" ON)
|
||||
option(ENABLE_MINGW64 "Enable building of ffmpeg/iconv/libsndfile/lapack/fftw3 by installing mingw64" ON)
|
||||
endif()
|
||||
option(WITH_WEBP "Enable building of oiio with webp support" OFF)
|
||||
set(MAKE_THREADS 1 CACHE STRING "Number of threads to run make with")
|
||||
@@ -45,7 +45,11 @@ message("PATCH_DIR = ${PATCH_DIR}")
|
||||
message("BUILD_DIR = ${BUILD_DIR}")
|
||||
|
||||
if(WIN32)
|
||||
set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/patch.exe)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/patch.exe)
|
||||
else()
|
||||
set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/patch.exe)
|
||||
endif()
|
||||
set(LIBEXT ".lib")
|
||||
set(LIBPREFIX "")
|
||||
|
||||
@@ -78,10 +82,17 @@ if(WIN32)
|
||||
set(PLATFORM_CXX_FLAGS)
|
||||
set(PLATFORM_CMAKE_FLAGS)
|
||||
|
||||
set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw64)
|
||||
set(MINGW_SHELL ming64sh.cmd)
|
||||
set(PERL_SHELL ${DOWNLOAD_DIR}/perl/portableshell.bat)
|
||||
set(MINGW_HOST x86_64-w64-mingw32)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw64)
|
||||
set(MINGW_SHELL ming64sh.cmd)
|
||||
set(PERL_SHELL ${DOWNLOAD_DIR}/perl/portableshell.bat)
|
||||
set(MINGW_HOST x86_64-w64-mingw32)
|
||||
else()
|
||||
set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw32)
|
||||
set(MINGW_SHELL ming32sh.cmd)
|
||||
set(PERL_SHELL ${DOWNLOAD_DIR}/perl32/portableshell.bat)
|
||||
set(MINGW_HOST i686-w64-mingw32)
|
||||
endif()
|
||||
|
||||
set(CONFIGURE_ENV
|
||||
cd ${MINGW_PATH} &&
|
||||
@@ -113,32 +124,16 @@ else()
|
||||
COMMAND xcode-select --print-path
|
||||
OUTPUT_VARIABLE XCODE_DEV_PATH OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
COMMAND xcodebuild -version -sdk macosx SDKVersion
|
||||
OUTPUT_VARIABLE MACOSX_SDK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(NOT CMAKE_OSX_ARCHITECTURES)
|
||||
execute_process(COMMAND uname -m OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "Detected native architecture ${ARCHITECTURE}.")
|
||||
set(CMAKE_OSX_ARCHITECTURES "${ARCHITECTURE}")
|
||||
endif()
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")
|
||||
set(OSX_DEPLOYMENT_TARGET 10.13)
|
||||
else()
|
||||
set(OSX_DEPLOYMENT_TARGET 11.00)
|
||||
endif()
|
||||
set(OSX_ARCHITECTURES x86_64)
|
||||
set(OSX_DEPLOYMENT_TARGET 10.11)
|
||||
set(OSX_SYSROOT ${XCODE_DEV_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk)
|
||||
|
||||
set(PLATFORM_CFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -arch ${CMAKE_OSX_ARCHITECTURES}")
|
||||
set(PLATFORM_CXXFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -std=c++11 -stdlib=libc++ -arch ${CMAKE_OSX_ARCHITECTURES}")
|
||||
set(PLATFORM_LDFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -arch ${CMAKE_OSX_ARCHITECTURES}")
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")
|
||||
set(PLATFORM_BUILD_TARGET --build=x86_64-apple-darwin17.0.0) # OS X 10.13
|
||||
else()
|
||||
set(PLATFORM_BUILD_TARGET --build=aarch64-apple-darwin20.0.0) # macOS 11.00
|
||||
endif()
|
||||
set(PLATFORM_CFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET}")
|
||||
set(PLATFORM_CXXFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -std=c++11 -stdlib=libc++")
|
||||
set(PLATFORM_LDFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET}")
|
||||
set(PLATFORM_BUILD_TARGET --build=x86_64-apple-darwin15.0.0) # OS X 10.11
|
||||
set(PLATFORM_CMAKE_FLAGS
|
||||
-DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DCMAKE_OSX_ARCHITECTURES:STRING=${OSX_ARCHITECTURES}
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${OSX_DEPLOYMENT_TARGET}
|
||||
-DCMAKE_OSX_SYSROOT:PATH=${OSX_SYSROOT}
|
||||
)
|
||||
@@ -171,7 +166,6 @@ else()
|
||||
|
||||
set(CONFIGURE_ENV
|
||||
export MACOSX_DEPLOYMENT_TARGET=${OSX_DEPLOYMENT_TARGET} &&
|
||||
export MACOSX_SDK_VERSION=${OSX_DEPLOYMENT_TARGET} &&
|
||||
export CFLAGS=${PLATFORM_CFLAGS} &&
|
||||
export CXXFLAGS=${PLATFORM_CXXFLAGS} &&
|
||||
export LDFLAGS=${PLATFORM_LDFLAGS}
|
||||
|
@@ -75,7 +75,6 @@ set(OSL_EXTRA_ARGS
|
||||
-DUSE_LLVM_BITCODE=OFF
|
||||
-DUSE_PARTIO=OFF
|
||||
-DUSE_QT=OFF
|
||||
-DINSTALL_DOCS=OFF
|
||||
${OSL_SIMD_FLAGS}
|
||||
-DPARTIO_LIBRARIES=
|
||||
)
|
||||
|
@@ -22,10 +22,6 @@ set(PNG_EXTRA_ARGS
|
||||
-DPNG_STATIC=ON
|
||||
)
|
||||
|
||||
if(APPLE AND ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64"))
|
||||
set(PNG_EXTRA_ARGS ${PNG_EXTRA_ARGS} -DPNG_HARDWARE_OPTIMIZATIONS=ON -DPNG_ARM_NEON=on -DCMAKE_SYSTEM_PROCESSOR="aarch64")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_png
|
||||
URL ${PNG_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
|
@@ -48,12 +48,7 @@ if(WIN32)
|
||||
|
||||
else()
|
||||
if(APPLE)
|
||||
# Disable functions that can be in 10.13 sdk but aren't available on 10.9 target.
|
||||
#
|
||||
# Disable libintl (gettext library) as it might come from Homebrew, which makes
|
||||
# it so test program compiles, but the Python does not. This is because for Python
|
||||
# we use isysroot, which seems to forbid using libintl.h.
|
||||
# The gettext functionality seems to come from CoreFoundation, so should be all fine.
|
||||
# disable functions that can be in 10.13 sdk but aren't available on 10.9 target
|
||||
set(PYTHON_FUNC_CONFIGS
|
||||
export ac_cv_func_futimens=no &&
|
||||
export ac_cv_func_utimensat=no &&
|
||||
@@ -65,21 +60,13 @@ else()
|
||||
export ac_cv_func_getentropy=no &&
|
||||
export ac_cv_func_mkostemp=no &&
|
||||
export ac_cv_func_mkostemps=no &&
|
||||
export ac_cv_func_timingsafe_bcmp=no &&
|
||||
export ac_cv_header_libintl_h=no &&
|
||||
export ac_cv_lib_intl_textdomain=no
|
||||
)
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
set(PYTHON_FUNC_CONFIGS ${PYTHON_FUNC_CONFIGS} && export PYTHON_DECIMAL_WITH_MACHINE=ansi64)
|
||||
endif()
|
||||
export ac_cv_func_timingsafe_bcmp=no)
|
||||
set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV} && ${PYTHON_FUNC_CONFIGS})
|
||||
set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python.exe)
|
||||
set(PYTHON_PATCH ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_macos.diff)
|
||||
else()
|
||||
set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV})
|
||||
set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python)
|
||||
set(PYTHON_PATCH ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_linux.diff)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(PYTHON_CONFIGURE_EXTRA_ARGS "--with-openssl=${LIBDIR}/ssl")
|
||||
set(PYTHON_CFLAGS "-I${LIBDIR}/sqlite/include -I${LIBDIR}/bzip2/include -I${LIBDIR}/lzma/include -I${LIBDIR}/zlib/include")
|
||||
@@ -89,6 +76,7 @@ else()
|
||||
export CPPFLAGS=${PYTHON_CFLAGS} &&
|
||||
export LDFLAGS=${PYTHON_LDFLAGS} &&
|
||||
export PKG_CONFIG_PATH=${LIBDIR}/ffi/lib/pkgconfig)
|
||||
set(PYTHON_PATCH ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_linux.diff)
|
||||
|
||||
ExternalProject_Add(external_python
|
||||
URL ${PYTHON_URI}
|
||||
|
227
build_files/build_environment/cmake/setup_mingw32.cmake
Normal file
227
build_files/build_environment/cmake/setup_mingw32.cmake
Normal file
@@ -0,0 +1,227 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
####################################################################################################################
|
||||
# Mingw32 Builds
|
||||
####################################################################################################################
|
||||
# This installs mingw32+msys to compile ffmpeg/iconv/libsndfile/lapack/fftw3
|
||||
####################################################################################################################
|
||||
|
||||
message("LIBDIR = ${LIBDIR}")
|
||||
macro(cmake_to_msys_path MsysPath ResultingPath)
|
||||
string(REPLACE ":" "" TmpPath "${MsysPath}")
|
||||
string(SUBSTRING ${TmpPath} 0 1 Drive)
|
||||
string(SUBSTRING ${TmpPath} 1 255 PathPart)
|
||||
string(TOLOWER ${Drive} LowerDrive)
|
||||
string(CONCAT ${ResultingPath} "/" ${LowerDrive} ${PathPart})
|
||||
endmacro()
|
||||
cmake_to_msys_path(${LIBDIR} mingw_LIBDIR)
|
||||
message("mingw_LIBDIR = ${mingw_LIBDIR}")
|
||||
|
||||
message("Checking for mingw32")
|
||||
# download mingw32
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z")
|
||||
message("Downloading mingw32")
|
||||
file(DOWNLOAD "https://astuteinternet.dl.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.4/threads-win32/sjlj/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z" "${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z")
|
||||
endif()
|
||||
|
||||
# make mingw root directory
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/mingw
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
# extract mingw32
|
||||
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd") AND (EXISTS "${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z"))
|
||||
message("Extracting mingw32")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/i686-4.9.4-release-win32-sjlj-rt_v5-rev0.7z
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw
|
||||
)
|
||||
endif()
|
||||
|
||||
message("Checking for pkg-config")
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
|
||||
message("Downloading pkg-config")
|
||||
file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/pkgconfiglite/0.28-1/pkg-config-lite-0.28-1_bin-win32.zip" "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
|
||||
endif()
|
||||
|
||||
# extract pkgconfig
|
||||
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/pkg-config.exe") AND (EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"))
|
||||
message("Extracting pkg-config")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1/bin/pkg-config.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/pkg-config.exe"
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
message("Checking for nasm")
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip")
|
||||
message("Downloading nasm")
|
||||
file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.13.02/win32/nasm-2.13.02-win32.zip" "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip")
|
||||
endif()
|
||||
|
||||
# extract nasm
|
||||
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip"))
|
||||
message("Extracting nasm")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip"
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.13.02/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe"
|
||||
)
|
||||
|
||||
endif()
|
||||
SET(NASM_PATH ${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe)
|
||||
message("Checking for mingwGet")
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
|
||||
message("Downloading mingw-get")
|
||||
file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/Installer/mingw-get/mingw-get-0.6.2-beta-20131004-1/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip" "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
|
||||
endif()
|
||||
|
||||
# extract mingw_get
|
||||
if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"))
|
||||
message("Extracting mingw-get")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/
|
||||
)
|
||||
endif()
|
||||
|
||||
if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/make.exe"))
|
||||
message("Installing MSYS")
|
||||
execute_process(
|
||||
COMMAND ${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get install msys msys-patch
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/bin/
|
||||
)
|
||||
endif()
|
||||
|
||||
if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/mktemp.exe"))
|
||||
message("Installing mktemp")
|
||||
execute_process(
|
||||
COMMAND ${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get install msys msys-mktemp
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/bin/
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
message("Checking for CoreUtils")
|
||||
# download old core_utils for pr.exe (ffmpeg needs it to build)
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
|
||||
message("Downloading CoreUtils 5.97")
|
||||
file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/MSYS/Base/msys-core/_obsolete/coreutils-5.97-MSYS-1.0.11-2/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2" "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
|
||||
endif()
|
||||
|
||||
if((EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/pr.exe"))
|
||||
message("Installing pr from CoreUtils 5.97")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/tmp_coreutils
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${DOWNLOAD_DIR}/tmp_coreutils/coreutils-5.97/bin/pr.exe "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/pr.exe"
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd")
|
||||
message("Installing ming32sh.cmd")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/ming32sh.cmd ${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd
|
||||
)
|
||||
endif()
|
||||
|
||||
message("Checking for perl")
|
||||
# download perl for libvpx
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip")
|
||||
message("Downloading perl")
|
||||
file(DOWNLOAD "http://strawberryperl.com/download/5.22.1.3/strawberry-perl-5.22.1.3-32bit-portable.zip" "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip")
|
||||
endif()
|
||||
|
||||
# make perl root directory
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/perl32")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/perl32
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
# extract perl
|
||||
if((NOT EXISTS "${DOWNLOAD_DIR}/perl32/portable.perl") AND (EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip"))
|
||||
message("Extracting perl")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/perl32
|
||||
)
|
||||
endif()
|
||||
|
||||
# get yasm for vpx
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/yasm.exe")
|
||||
message("Downloading yasm")
|
||||
file(DOWNLOAD "http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win32.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/yasm.exe")
|
||||
endif()
|
||||
|
||||
message("checking i686-w64-mingw32-strings")
|
||||
# copy strings.exe to i686-w64-mingw32-strings for x264
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strings.exe")
|
||||
message("fixing i686-w64-mingw32-strings.exe")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/strings.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strings.exe"
|
||||
)
|
||||
endif()
|
||||
|
||||
message("checking i686-w64-mingw32-ar.exe")
|
||||
# copy ar.exe to i686-w64-mingw32-ar.exe for x264
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ar.exe")
|
||||
message("fixing i686-w64-mingw32-ar.exe")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/ar.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ar.exe"
|
||||
)
|
||||
endif()
|
||||
|
||||
message("checking i686-w64-mingw32-strip.exe")
|
||||
# copy strip.exe to i686-w64-mingw32-strip.exe for x264
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strip.exe")
|
||||
message("fixing i686-w64-mingw32-strip.exe")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/strip.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strip.exe"
|
||||
)
|
||||
endif()
|
||||
|
||||
message("checking i686-w64-mingw32-ranlib.exe")
|
||||
# copy ranlib.exe to i686-w64-mingw32-ranlib.exe for x264
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ranlib.exe")
|
||||
message("fixing i686-w64-mingw32-ranlib.exe")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/ranlib.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ranlib.exe"
|
||||
)
|
||||
endif()
|
@@ -19,7 +19,7 @@
|
||||
####################################################################################################################
|
||||
# Mingw64 Builds
|
||||
####################################################################################################################
|
||||
# This installs mingw64+msys to compile ffmpeg/iconv/libsndfile/fftw3
|
||||
# This installs mingw64+msys to compile ffmpeg/iconv/libsndfile/lapack/fftw3
|
||||
####################################################################################################################
|
||||
|
||||
message("LIBDIR = ${LIBDIR}")
|
||||
@@ -128,14 +128,6 @@ if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get.exe") AND (NOT EXISTS "$
|
||||
)
|
||||
endif()
|
||||
|
||||
if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/m4.exe"))
|
||||
message("Installing m4")
|
||||
execute_process(
|
||||
COMMAND ${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get install msys msys-m4
|
||||
WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw64/bin/
|
||||
)
|
||||
endif()
|
||||
|
||||
message("Checking for CoreUtils")
|
||||
# download old core_utils for pr.exe (ffmpeg needs it to build)
|
||||
if(NOT EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
|
||||
|
@@ -51,7 +51,7 @@ ExternalProject_Add(external_sqlite
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH SHA1=${SQLITE_HASH}
|
||||
PREFIX ${BUILD_DIR}/sqlite
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/sqlite/src/external_sqlite < ${PATCH_DIR}/sqlite.diff
|
||||
PATCH_COMMAND ${SQLITE_PATCH_CMD}
|
||||
CONFIGURE_COMMAND ${SQLITE_CONFIGURE_ENV} && cd ${BUILD_DIR}/sqlite/src/external_sqlite/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/sqlite ${SQLITE_CONFIGURATION_ARGS}
|
||||
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sqlite/src/external_sqlite/ && make -j${MAKE_THREADS}
|
||||
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sqlite/src/external_sqlite/ && make install
|
||||
|
@@ -20,7 +20,7 @@ set(SSL_CONFIGURE_COMMAND ./Configure)
|
||||
set(SSL_PATCH_CMD echo .)
|
||||
|
||||
if(APPLE)
|
||||
set(SSL_OS_COMPILER "blender-darwin-${CMAKE_OSX_ARCHITECTURES}")
|
||||
set(SSL_OS_COMPILER "blender-darwin-x86_64")
|
||||
else()
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(SSL_EXTRA_ARGS enable-ec_nistp_64_gcc_128)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
my %targets = (
|
||||
%targets = (
|
||||
|
||||
"blender-linux-x86" => {
|
||||
inherit_from => [ "linux-x86" ],
|
||||
@@ -12,9 +12,4 @@ my %targets = (
|
||||
inherit_from => [ "darwin64-x86_64-cc" ],
|
||||
cflags => add("-fPIC"),
|
||||
},
|
||||
"blender-darwin-arm64" => {
|
||||
inherit_from => [ "darwin-common" ],
|
||||
cxxflags => add("-fPIC -arch arm64"),
|
||||
cflags => add("-fPIC -arch arm64"),
|
||||
},
|
||||
);
|
||||
|
@@ -50,13 +50,6 @@ ExternalProject_Add(external_tbb
|
||||
if(WIN32)
|
||||
if(BUILD_MODE STREQUAL Release)
|
||||
ExternalProject_Add_Step(external_tbb after_install
|
||||
# findtbb.cmake in some deps *NEEDS* to find tbb_debug.lib even if they are not going to use it
|
||||
# to make that test pass, we place a copy with the right name in the lib folder.
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.lib ${HARVEST_TARGET}/tbb/lib/tbb_debug.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc.lib ${HARVEST_TARGET}/tbb/lib/tbbmalloc_debug.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.dll ${HARVEST_TARGET}/tbb/lib/tbb_debug.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc.dll ${HARVEST_TARGET}/tbb/lib/tbbmalloc_debug.dll
|
||||
# Normal collection of build artifacts
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.lib ${HARVEST_TARGET}/tbb/lib/tbb.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb.dll ${HARVEST_TARGET}/tbb/lib/tbb.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc.lib ${HARVEST_TARGET}/tbb/lib/tbbmalloc.lib
|
||||
|
@@ -27,7 +27,6 @@ ExternalProject_Add(external_theora
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH SHA256=${THEORA_HASH}
|
||||
PREFIX ${BUILD_DIR}/theora
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 0 -d ${BUILD_DIR}/theora/src/external_theora < ${PATCH_DIR}/theora.diff
|
||||
CONFIGURE_COMMAND ${THEORA_CONFIGURE_ENV} && cd ${BUILD_DIR}/theora/src/external_theora/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/theora
|
||||
--disable-shared
|
||||
--enable-static
|
||||
|
@@ -16,12 +16,6 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
if(WITH_WEBP)
|
||||
set(WITH_TIFF_WEBP ON)
|
||||
else()
|
||||
set(WITH_TIFF_WEBP OFF)
|
||||
endif()
|
||||
|
||||
set(TIFF_EXTRA_ARGS
|
||||
-DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
|
||||
-DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include
|
||||
@@ -29,8 +23,6 @@ set(TIFF_EXTRA_ARGS
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-Dlzma=OFF
|
||||
-Djbig=OFF
|
||||
-Dzstd=OFF
|
||||
-Dwebp=${WITH_TIFF_WEBP}
|
||||
)
|
||||
|
||||
ExternalProject_Add(external_tiff
|
||||
|
@@ -27,9 +27,6 @@ set(USD_EXTRA_ARGS
|
||||
-DTBB_INCLUDE_DIRS=${LIBDIR}/tbb/include
|
||||
-DTBB_LIBRARIES=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT}
|
||||
-DTbb_TBB_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT}
|
||||
# USD wants the tbb debug lib set even when you are doing a release build
|
||||
# Otherwise it will error out during the cmake configure phase.
|
||||
-DTBB_LIBRARIES_DEBUG=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT}
|
||||
|
||||
# This is a preventative measure that avoids possible conflicts when add-ons
|
||||
# try to load another USD library into the same process space.
|
||||
@@ -81,14 +78,14 @@ if(WIN32)
|
||||
if(BUILD_MODE STREQUAL Release)
|
||||
ExternalProject_Add_Step(external_usd after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/usd/ ${HARVEST_TARGET}/usd
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Release/usd_m.lib ${HARVEST_TARGET}/usd/lib/libusd_m.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Release/libusd_m.lib ${HARVEST_TARGET}/usd/lib/libusd_m.lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
if(BUILD_MODE STREQUAL Debug)
|
||||
ExternalProject_Add_Step(external_usd after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/usd/lib ${HARVEST_TARGET}/usd/lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Debug/usd_m_d.lib ${HARVEST_TARGET}/usd/lib/libusd_m_d.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Debug/libusd_m_d.lib ${HARVEST_TARGET}/usd/lib/libusd_m_d.lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
@@ -78,6 +78,10 @@ set(FREEGLUT_VERSION 3.0.0)
|
||||
set(FREEGLUT_URI http://pilotfiber.dl.sourceforge.net/project/freeglut/freeglut/${FREEGLUT_VERSION}/freeglut-${FREEGLUT_VERSION}.tar.gz)
|
||||
set(FREEGLUT_HASH 90c3ca4dd9d51cf32276bc5344ec9754)
|
||||
|
||||
set(HDF5_VERSION 1.8.17)
|
||||
set(HDF5_URI https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-${HDF5_VERSION}/src/hdf5-${HDF5_VERSION}.tar.gz)
|
||||
set(HDF5_HASH 7d572f8f3b798a628b8245af0391a0ca)
|
||||
|
||||
set(ALEMBIC_VERSION 1.7.12)
|
||||
set(ALEMBIC_URI https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.tar.gz)
|
||||
set(ALEMBIC_MD5 e2b3777f23c5c09481a008cc6f0f8a40)
|
||||
@@ -135,11 +139,11 @@ set(OSL_VERSION 1.10.10)
|
||||
set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.tar.gz)
|
||||
set(OSL_HASH 00dec08a93c8084e53848b9ad047889f)
|
||||
|
||||
set(PYTHON_VERSION 3.7.7)
|
||||
set(PYTHON_VERSION 3.7.4)
|
||||
set(PYTHON_SHORT_VERSION 3.7)
|
||||
set(PYTHON_SHORT_VERSION_NO_DOTS 37)
|
||||
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
|
||||
set(PYTHON_HASH 172c650156f7bea68ce31b2fd01fa766)
|
||||
set(PYTHON_HASH d33e4aae66097051c2eca45ee3604803)
|
||||
|
||||
set(TBB_VERSION 2019_U9)
|
||||
set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz)
|
||||
@@ -149,16 +153,16 @@ set(OPENVDB_VERSION 7.0.0)
|
||||
set(OPENVDB_URI https://github.com/dreamworksanimation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)
|
||||
set(OPENVDB_HASH fd6c4f168282f7e0e494d290cd531fa8)
|
||||
|
||||
set(IDNA_VERSION 2.9)
|
||||
set(IDNA_VERSION 2.8)
|
||||
set(CHARDET_VERSION 3.0.4)
|
||||
set(URLLIB3_VERSION 1.25.9)
|
||||
set(CERTIFI_VERSION 2020.4.5.2)
|
||||
set(REQUESTS_VERSION 2.23.0)
|
||||
set(URLLIB3_VERSION 1.25.3)
|
||||
set(CERTIFI_VERSION 2019.6.16)
|
||||
set(REQUESTS_VERSION 2.22.0)
|
||||
|
||||
set(NUMPY_VERSION 1.17.5)
|
||||
set(NUMPY_VERSION v1.17.0)
|
||||
set(NUMPY_SHORT_VERSION 1.17)
|
||||
set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}/numpy-${NUMPY_VERSION}.zip)
|
||||
set(NUMPY_HASH 763a5646fa6eef7a22f4895bca0524f2)
|
||||
set(NUMPY_URI https://files.pythonhosted.org/packages/da/32/1b8f2bb5fb50e4db68543eb85ce37b9fa6660cd05b58bddfafafa7ed62da/numpy-1.17.0.zip)
|
||||
set(NUMPY_HASH aed49b31bcb44ec73b8155be78566135)
|
||||
|
||||
set(LAME_VERSION 3.100)
|
||||
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
|
||||
@@ -188,8 +192,8 @@ set(OPUS_VERSION 1.3.1)
|
||||
set(OPUS_URI https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz)
|
||||
set(OPUS_HASH 65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d)
|
||||
|
||||
set(X264_URI https://code.videolan.org/videolan/x264/-/archive/33f9e1474613f59392be5ab6a7e7abf60fa63622/x264-33f9e1474613f59392be5ab6a7e7abf60fa63622.tar.gz)
|
||||
set(X264_HASH 5456450ee1ae02cd2328be3157367a232a0ab73315e8c8f80dab80469524f525)
|
||||
set(X264_URI https://code.videolan.org/videolan/x264/-/archive/master/x264-33f9e1474613f59392be5ab6a7e7abf60fa63622.tar.gz)
|
||||
set(X264_HASH 300dfb5b6c35722516f168868ce9419252a9e9eb77a05d82c9cede925b691bd6)
|
||||
|
||||
set(XVIDCORE_VERSION 1.3.7)
|
||||
set(XVIDCORE_URI https://downloads.xvid.com/downloads/xvidcore-${XVIDCORE_VERSION}.tar.gz)
|
||||
@@ -212,6 +216,10 @@ set(ICONV_VERSION 1.16)
|
||||
set(ICONV_URI http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz)
|
||||
set(ICONV_HASH 7d2a800b952942bb2880efb00cfd524c)
|
||||
|
||||
set(LAPACK_VERSION 3.6.0)
|
||||
set(LAPACK_URI http://www.netlib.org/lapack/lapack-${LAPACK_VERSION}.tgz)
|
||||
set(LAPACK_HASH f2f6c67134e851fe189bb3ca1fbb5101)
|
||||
|
||||
set(SNDFILE_VERSION 1.0.28)
|
||||
set(SNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${SNDFILE_VERSION}.tar.gz)
|
||||
set(SNDFILE_HASH 646b5f98ce89ac60cdb060fcd398247c)
|
||||
@@ -232,13 +240,13 @@ set(SPNAV_VERSION 0.2.3)
|
||||
set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
|
||||
set(SPNAV_HASH 44d840540d53326d4a119c0f1aa7bf0a)
|
||||
|
||||
set(JEMALLOC_VERSION 5.2.1)
|
||||
set(JEMALLOC_VERSION 5.0.1)
|
||||
set(JEMALLOC_URI https://github.com/jemalloc/jemalloc/releases/download/${JEMALLOC_VERSION}/jemalloc-${JEMALLOC_VERSION}.tar.bz2)
|
||||
set(JEMALLOC_HASH 3d41fbf006e6ebffd489bdb304d009ae)
|
||||
set(JEMALLOC_HASH 507f7b6b882d868730d644510491d18f)
|
||||
|
||||
set(XML2_VERSION 2.9.10)
|
||||
set(XML2_VERSION 2.9.4)
|
||||
set(XML2_URI http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz)
|
||||
set(XML2_HASH 10942a1dc23137a8aa07f0639cbfece5)
|
||||
set(XML2_HASH ae249165c173b1ff386ee8ad676815f5)
|
||||
|
||||
set(TINYXML_VERSION 2_6_2)
|
||||
set(TINYXML_VERSION_DOTS 2.6.2)
|
||||
@@ -265,23 +273,23 @@ set(FLEXBISON_HASH d87a3938194520d904013abef3df10ce)
|
||||
|
||||
# NOTE: bzip.org domain does no longer belong to BZip 2 project, so we download
|
||||
# sources from Debian packaging.
|
||||
set(BZIP2_VERSION 1.0.8)
|
||||
set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERSION}.orig.tar.gz)
|
||||
set(BZIP2_HASH ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269)
|
||||
set(BZIP2_VERSION 1.0.6)
|
||||
set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERSION}.orig.tar.bz2)
|
||||
set(BZIP2_HASH d70a9ccd8bdf47e302d96c69fecd54925f45d9c7b966bb4ef5f56b770960afa7)
|
||||
|
||||
set(FFI_VERSION 3.3)
|
||||
set(FFI_VERSION 3.2.1)
|
||||
set(FFI_URI https://sourceware.org/pub/libffi/libffi-${FFI_VERSION}.tar.gz)
|
||||
set(FFI_HASH 72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056)
|
||||
set(FFI_HASH d06ebb8e1d9a22d19e38d63fdb83954253f39bedc5d46232a05645685722ca37)
|
||||
|
||||
set(LZMA_VERSION 5.2.5)
|
||||
set(LZMA_VERSION 5.2.4)
|
||||
set(LZMA_URI https://tukaani.org/xz/xz-${LZMA_VERSION}.tar.bz2)
|
||||
set(LZMA_HASH 5117f930900b341493827d63aa910ff5e011e0b994197c3b71c08a20228a42df)
|
||||
set(LZMA_HASH 3313fd2a95f43d88e44264e6b015e7d03053e681860b0d5d3f9baca79c57b7bf)
|
||||
|
||||
set(SSL_VERSION 1.1.1g)
|
||||
set(SSL_VERSION 1.1.0i)
|
||||
set(SSL_URI https://www.openssl.org/source/openssl-${SSL_VERSION}.tar.gz)
|
||||
set(SSL_HASH ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46)
|
||||
set(SSL_HASH ebbfc844a8c8cc0ea5dc10b86c9ce97f401837f3fa08c17b2cdadc118253cf99)
|
||||
|
||||
set(SQLITE_VERSION 3.31.1)
|
||||
set(SQLITE_VERSION 3.24.0)
|
||||
set(SQLITE_URI https://www.sqlite.org/2018/sqlite-src-3240000.zip)
|
||||
set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7)
|
||||
|
||||
@@ -289,13 +297,13 @@ set(EMBREE_VERSION 3.10.0)
|
||||
set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip)
|
||||
set(EMBREE_HASH 4bbe29e7eaa46417efc75fc5f1e8eb87)
|
||||
|
||||
set(USD_VERSION 20.05)
|
||||
set(USD_VERSION 19.11)
|
||||
set(USD_URI https://github.com/PixarAnimationStudios/USD/archive/v${USD_VERSION}.tar.gz)
|
||||
set(USD_HASH 6d679e739e7f65725d9c029e37dda9fc)
|
||||
set(USD_HASH 79ff176167b3fe85f4953abd6cc5e0cc)
|
||||
|
||||
set(OIDN_VERSION 1.2.1)
|
||||
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.tar.gz)
|
||||
set(OIDN_HASH cbebc1a25eb6de62af3a59e943063608)
|
||||
set(OIDN_VERSION 1.0.0)
|
||||
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.zip)
|
||||
set(OIDN_HASH 19fe67b0164e8f020ac8a4f520defe60)
|
||||
|
||||
set(LIBGLU_VERSION 9.0.1)
|
||||
set(LIBGLU_URI ftp://ftp.freedesktop.org/pub/mesa/glu/glu-${LIBGLU_VERSION}.tar.xz)
|
||||
@@ -305,17 +313,6 @@ set(MESA_VERSION 18.3.1)
|
||||
set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa//mesa-${MESA_VERSION}.tar.xz)
|
||||
set(MESA_HASH d60828056d77bfdbae0970f9b15fb1be)
|
||||
|
||||
set(NASM_VERSION 2.15.02)
|
||||
set(NASM_URI https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}/nasm-${NASM_VERSION}.tar.xz)
|
||||
set(NASM_HASH f4fd1329b1713e1ccd34b2fc121c4bcd278c9f91cc4cb205ae8fcd2e4728dd14)
|
||||
|
||||
set(XR_OPENXR_SDK_VERSION 1.0.8)
|
||||
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)
|
||||
set(XR_OPENXR_SDK_HASH c6de63d2e0f9029aa58dfa97cad8ce07)
|
||||
set(ISPC_VERSION v1.13.0)
|
||||
set(ISPC_URI https://github.com/ispc/ispc/archive/${ISPC_VERSION}.tar.gz)
|
||||
set(ISPC_HASH 4bf5e8d0020c4b9980faa702c1a6f25f)
|
||||
|
||||
set(GMP_VERSION 6.2.0)
|
||||
set(GMP_URI https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.xz)
|
||||
set(GMP_HASH a325e3f09e6d91e62101e59f9bda3ec1)
|
||||
|
@@ -24,11 +24,7 @@ if(WIN32)
|
||||
endif()
|
||||
else()
|
||||
if(APPLE)
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
set(VPX_EXTRA_FLAGS --target=generic-gnu)
|
||||
else()
|
||||
set(VPX_EXTRA_FLAGS --target=x86_64-darwin17-gcc)
|
||||
endif()
|
||||
set(VPX_EXTRA_FLAGS --target=x86_64-darwin13-gcc)
|
||||
else()
|
||||
set(VPX_EXTRA_FLAGS --target=generic-gnu)
|
||||
endif()
|
||||
|
@@ -21,26 +21,12 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
|
||||
if(APPLE)
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
set(X264_EXTRA_ARGS ${X264_EXTRA_ARGS} "--disable-asm")
|
||||
set(X264_CONFIGURE_ENV echo .)
|
||||
else()
|
||||
set(X264_CONFIGURE_ENV
|
||||
export AS=${LIBDIR}/nasm/bin/nasm
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
set(X264_CONFIGURE_ENV echo .)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_x264
|
||||
URL ${X264_URI}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH SHA256=${X264_HASH}
|
||||
PREFIX ${BUILD_DIR}/x264
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${X264_CONFIGURE_ENV} && cd ${BUILD_DIR}/x264/src/external_x264/ &&
|
||||
${CONFIGURE_COMMAND} --prefix=${LIBDIR}/x264
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/x264/src/external_x264/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/x264
|
||||
--enable-static
|
||||
--enable-pic
|
||||
--disable-lavf
|
||||
@@ -53,10 +39,3 @@ ExternalProject_Add(external_x264
|
||||
if(MSVC)
|
||||
set_target_properties(external_x264 PROPERTIES FOLDER Mingw)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
add_dependencies(
|
||||
external_x264
|
||||
external_nasm
|
||||
)
|
||||
endif()
|
||||
|
@@ -376,7 +376,7 @@ USE_CXX11=true
|
||||
|
||||
CLANG_FORMAT_VERSION_MIN="6.0"
|
||||
|
||||
PYTHON_VERSION="3.7.7"
|
||||
PYTHON_VERSION="3.7.4"
|
||||
PYTHON_VERSION_MIN="3.7"
|
||||
PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_MIN
|
||||
PYTHON_FORCE_BUILD=false
|
||||
@@ -459,7 +459,7 @@ ALEMBIC_FORCE_BUILD=false
|
||||
ALEMBIC_FORCE_REBUILD=false
|
||||
ALEMBIC_SKIP=false
|
||||
|
||||
USD_VERSION="20.05"
|
||||
USD_VERSION="19.11"
|
||||
USD_FORCE_BUILD=false
|
||||
USD_FORCE_REBUILD=false
|
||||
USD_SKIP=false
|
||||
@@ -1030,7 +1030,7 @@ Those libraries should be available as packages in all recent distributions (opt
|
||||
* libjpeg, libpng, libtiff, [openjpeg2], [libopenal].
|
||||
* libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed).
|
||||
* libsqlite3, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp.
|
||||
* libsdl2, libglew, [libgmp], [libglewmx].\""
|
||||
* libsdl2, libglew, [libglewmx].\""
|
||||
|
||||
DEPS_SPECIFIC_INFO="\"BUILDABLE DEPENDENCIES:
|
||||
|
||||
@@ -1574,7 +1574,7 @@ compile_TBB() {
|
||||
if [ ! -d $_inst ]; then
|
||||
INFO "Building TBB-$TBB_VERSION$TBB_VERSION_UPDATE"
|
||||
_is_building=true
|
||||
|
||||
|
||||
# Rebuild dependencies as well!
|
||||
_update_deps_tbb
|
||||
|
||||
@@ -1691,7 +1691,7 @@ compile_OCIO() {
|
||||
if [ ! -d $_inst ]; then
|
||||
INFO "Building OpenColorIO-$OCIO_VERSION"
|
||||
_is_building=true
|
||||
|
||||
|
||||
# Rebuild dependencies as well!
|
||||
_update_deps_ocio
|
||||
|
||||
@@ -3524,8 +3524,7 @@ install_DEB() {
|
||||
libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \
|
||||
libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev \
|
||||
libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV \
|
||||
libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev \
|
||||
libgmp-dev"
|
||||
libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev"
|
||||
# libglewmx-dev (broken in deb testing currently...)
|
||||
|
||||
VORBIS_USE=true
|
||||
@@ -3679,7 +3678,7 @@ install_DEB() {
|
||||
check_package_version_ge_DEB python3-dev $PYTHON_VERSION_MIN
|
||||
if [ $? -eq 0 ]; then
|
||||
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_DEB python3-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
|
||||
|
||||
install_packages_DEB python3-dev
|
||||
clean_Python
|
||||
PRINT ""
|
||||
@@ -3893,6 +3892,7 @@ install_DEB() {
|
||||
INFO "Forced Alembic building, as requested..."
|
||||
compile_ALEMBIC
|
||||
else
|
||||
# No package currently, only HDF5!
|
||||
compile_ALEMBIC
|
||||
fi
|
||||
|
||||
@@ -4176,7 +4176,7 @@ install_RPM() {
|
||||
libX11-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel \
|
||||
wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \
|
||||
glew-devel yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV patch \
|
||||
libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel gmp-devel"
|
||||
libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel"
|
||||
|
||||
OPENJPEG_USE=true
|
||||
VORBIS_USE=true
|
||||
@@ -4736,7 +4736,7 @@ install_ARCH() {
|
||||
_packages="$BASE_DEVEL git cmake \
|
||||
libxi libxcursor libxrandr libxinerama glew libpng libtiff wget openal \
|
||||
$OPENJPEG_DEV $VORBIS_DEV $OGG_DEV $THEORA_DEV yasm sdl2 fftw \
|
||||
libxml2 yaml-cpp tinyxml python-requests jemalloc gmp"
|
||||
libxml2 yaml-cpp tinyxml python-requests jemalloc"
|
||||
|
||||
OPENJPEG_USE=true
|
||||
VORBIS_USE=true
|
||||
|
@@ -91,41 +91,3 @@ diff -Naur external_blosc.orig/blosc/blosc.c external_blosc/blosc/blosc.c
|
||||
|
||||
|
||||
/* Some useful units */
|
||||
diff --git a/blosc/shuffle.c b/blosc/shuffle.c
|
||||
index 84b5095..23053b4 100644
|
||||
--- a/blosc/shuffle.c
|
||||
+++ b/blosc/shuffle.c
|
||||
@@ -490,12 +490,12 @@ void unshuffle(size_t bytesoftype, size_t blocksize,
|
||||
#else /* no __SSE2__ available */
|
||||
|
||||
void shuffle(size_t bytesoftype, size_t blocksize,
|
||||
- uint8_t* _src, uint8_t* _dest) {
|
||||
+ const uint8_t* _src, uint8_t* _dest) {
|
||||
_shuffle(bytesoftype, blocksize, _src, _dest);
|
||||
}
|
||||
|
||||
void unshuffle(size_t bytesoftype, size_t blocksize,
|
||||
- uint8_t* _src, uint8_t* _dest) {
|
||||
+ const uint8_t* _src, uint8_t* _dest) {
|
||||
_unshuffle(bytesoftype, blocksize, _src, _dest);
|
||||
}
|
||||
--- a/cmake/FindSSE.cmake
|
||||
+++ b/cmake/FindSSE.cmake
|
||||
@@ -49,6 +49,17 @@
|
||||
set(AVX_FOUND false CACHE BOOL "AVX available on host")
|
||||
ENDIF (AVX_TRUE)
|
||||
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
+ execute_process(COMMAND uname -m OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
+ message(STATUS "Detected architecture ${ARCHITECTURE}")
|
||||
+ IF("${ARCHITECTURE}" STREQUAL "arm64")
|
||||
+ set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
|
||||
+ set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
|
||||
+ set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
|
||||
+ set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
|
||||
+ set(AVX_FOUND false CACHE BOOL "AVX available on host")
|
||||
+ return()
|
||||
+ ENDIF()
|
||||
+
|
||||
EXEC_PROGRAM("/usr/sbin/sysctl -n machdep.cpu.features" OUTPUT_VARIABLE
|
||||
CPUINFO)
|
||||
|
@@ -1,22 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(libgmpxx)
|
||||
|
||||
include_directories(. cxx ${GMP_INCLUDE_DIR})
|
||||
add_definitions(-D__GMP_WITHIN_GMPXX)
|
||||
add_library(libgmpxx SHARED
|
||||
cxx/dummy.cc
|
||||
cxx/isfuns.cc
|
||||
cxx/ismpf.cc
|
||||
cxx/ismpq.cc
|
||||
cxx/ismpz.cc
|
||||
cxx/ismpznw.cc
|
||||
cxx/limits.cc
|
||||
cxx/osdoprnti.cc
|
||||
cxx/osfuns.cc
|
||||
cxx/osmpf.cc
|
||||
cxx/osmpq.cc
|
||||
cxx/osmpz.cc
|
||||
)
|
||||
|
||||
target_link_libraries(libgmpxx ${GMP_LIBRARY})
|
||||
install(TARGETS libgmpxx DESTINATION lib)
|
20
build_files/build_environment/patches/cmakelists_hidapi.txt
Normal file
20
build_files/build_environment/patches/cmakelists_hidapi.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(hidapi)
|
||||
|
||||
set(SRC_FILES
|
||||
windows/hid.c
|
||||
)
|
||||
|
||||
set(HEADER_FILES
|
||||
hidapi/hidapi.h
|
||||
)
|
||||
include_directories(hidapi)
|
||||
add_definitions(-DHID_API_STATIC)
|
||||
add_library(hidapi STATIC ${SRC_FILES} ${HEADER_FILES})
|
||||
|
||||
install(TARGETS hidapi DESTINATION lib)
|
||||
|
||||
INSTALL(FILES hidapi/hidapi.h
|
||||
DESTINATION "include"
|
||||
)
|
||||
|
@@ -1,668 +0,0 @@
|
||||
/* config.h. Generated from config.in by configure. */
|
||||
/* config.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1996-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* The gmp-mparam.h file (a string) the tune program should suggest updating.
|
||||
*/
|
||||
#define GMP_MPARAM_H_SUGGEST "./mpn/x86_64/coreisbr/gmp-mparam.h"
|
||||
|
||||
/* Define to 1 if you have the `alarm' function. */
|
||||
#define HAVE_ALARM 1
|
||||
|
||||
/* Define to 1 if alloca() works (via gmp-impl.h). */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
/* #undef HAVE_ALLOCA_H */
|
||||
|
||||
/* Define to 1 if the compiler accepts gcc style __attribute__ ((const)) */
|
||||
//#define HAVE_ATTRIBUTE_CONST 1
|
||||
|
||||
/* Define to 1 if the compiler accepts gcc style __attribute__ ((malloc)) */
|
||||
//#define HAVE_ATTRIBUTE_MALLOC 1
|
||||
|
||||
/* Define to 1 if the compiler accepts gcc style __attribute__ ((mode (XX)))
|
||||
*/
|
||||
//#define HAVE_ATTRIBUTE_MODE 1
|
||||
|
||||
/* Define to 1 if the compiler accepts gcc style __attribute__ ((noreturn)) */
|
||||
//#define HAVE_ATTRIBUTE_NORETURN 1
|
||||
|
||||
/* Define to 1 if you have the `attr_get' function. */
|
||||
/* #undef HAVE_ATTR_GET */
|
||||
|
||||
/* Define to 1 if tests/libtests has calling conventions checking for the CPU
|
||||
*/
|
||||
/* #undef HAVE_CALLING_CONVENTIONS */
|
||||
|
||||
/* Define to 1 if you have the `clock' function. */
|
||||
#define HAVE_CLOCK 1
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function */
|
||||
/* #undef HAVE_CLOCK_GETTIME */
|
||||
|
||||
/* Define to 1 if you have the `cputime' function. */
|
||||
/* #undef HAVE_CPUTIME */
|
||||
|
||||
/* Define to 1 if you have the declaration of `fgetc', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_FGETC 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `fscanf', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_FSCANF 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_OPTARG 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `sys_errlist', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_SYS_ERRLIST 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `sys_nerr', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_SYS_NERR 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `ungetc', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_UNGETC 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `vfprintf', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_VFPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
|
||||
/* Define one of the following to 1 for the format of a `double'.
|
||||
If your format is not among these choices, or you don't know what it is,
|
||||
then leave all undefined.
|
||||
IEEE_LITTLE_SWAPPED means little endian, but with the two 4-byte halves
|
||||
swapped, as used by ARM CPUs in little endian mode. */
|
||||
/* #undef HAVE_DOUBLE_IEEE_BIG_ENDIAN */
|
||||
#define HAVE_DOUBLE_IEEE_LITTLE_ENDIAN 1
|
||||
/* #undef HAVE_DOUBLE_IEEE_LITTLE_SWAPPED */
|
||||
/* #undef HAVE_DOUBLE_VAX_D */
|
||||
/* #undef HAVE_DOUBLE_VAX_G */
|
||||
/* #undef HAVE_DOUBLE_CRAY_CFP */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <float.h> header file. */
|
||||
#define HAVE_FLOAT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
|
||||
/* Define to 1 if you have the `getrusage' function. */
|
||||
/* #undef HAVE_GETRUSAGE */
|
||||
|
||||
/* Define to 1 if you have the `getsysinfo' function. */
|
||||
/* #undef HAVE_GETSYSINFO */
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if the compiler accepts gcc style __attribute__ ((visibility))
|
||||
and __attribute__ ((alias)) */
|
||||
#define HAVE_HIDDEN_ALIAS 1
|
||||
|
||||
/* Define one of these to 1 for the host CPU family.
|
||||
If your CPU is not in any of these families, leave all undefined.
|
||||
For an AMD64 chip, define "x86" in ABI=32, but not in ABI=64. */
|
||||
/* #undef HAVE_HOST_CPU_FAMILY_alpha */
|
||||
/* #undef HAVE_HOST_CPU_FAMILY_m68k */
|
||||
/* #undef HAVE_HOST_CPU_FAMILY_power */
|
||||
/* #undef HAVE_HOST_CPU_FAMILY_powerpc */
|
||||
/* #undef HAVE_HOST_CPU_FAMILY_x86 */
|
||||
#define HAVE_HOST_CPU_FAMILY_x86_64 1
|
||||
|
||||
/* Define one of the following to 1 for the host CPU, as per the output of
|
||||
./config.guess. If your CPU is not listed here, leave all undefined. */
|
||||
/* #undef HAVE_HOST_CPU_alphaev67 */
|
||||
/* #undef HAVE_HOST_CPU_alphaev68 */
|
||||
/* #undef HAVE_HOST_CPU_alphaev7 */
|
||||
/* #undef HAVE_HOST_CPU_m68020 */
|
||||
/* #undef HAVE_HOST_CPU_m68030 */
|
||||
/* #undef HAVE_HOST_CPU_m68040 */
|
||||
/* #undef HAVE_HOST_CPU_m68060 */
|
||||
/* #undef HAVE_HOST_CPU_m68360 */
|
||||
/* #undef HAVE_HOST_CPU_powerpc604 */
|
||||
/* #undef HAVE_HOST_CPU_powerpc604e */
|
||||
/* #undef HAVE_HOST_CPU_powerpc750 */
|
||||
/* #undef HAVE_HOST_CPU_powerpc7400 */
|
||||
/* #undef HAVE_HOST_CPU_supersparc */
|
||||
/* #undef HAVE_HOST_CPU_i386 */
|
||||
/* #undef HAVE_HOST_CPU_i586 */
|
||||
/* #undef HAVE_HOST_CPU_i686 */
|
||||
/* #undef HAVE_HOST_CPU_pentium */
|
||||
/* #undef HAVE_HOST_CPU_pentiummmx */
|
||||
/* #undef HAVE_HOST_CPU_pentiumpro */
|
||||
/* #undef HAVE_HOST_CPU_pentium2 */
|
||||
/* #undef HAVE_HOST_CPU_pentium3 */
|
||||
/* #undef HAVE_HOST_CPU_pentium4 */
|
||||
/* #undef HAVE_HOST_CPU_core2 */
|
||||
/* #undef HAVE_HOST_CPU_nehalem */
|
||||
/* #undef HAVE_HOST_CPU_westmere */
|
||||
/* #undef HAVE_HOST_CPU_sandybridge */
|
||||
#define HAVE_HOST_CPU_ivybridge 1
|
||||
/* #undef HAVE_HOST_CPU_haswell */
|
||||
/* #undef HAVE_HOST_CPU_broadwell */
|
||||
/* #undef HAVE_HOST_CPU_skylake */
|
||||
/* #undef HAVE_HOST_CPU_silvermont */
|
||||
/* #undef HAVE_HOST_CPU_goldmont */
|
||||
/* #undef HAVE_HOST_CPU_k8 */
|
||||
/* #undef HAVE_HOST_CPU_k10 */
|
||||
/* #undef HAVE_HOST_CPU_bulldozer */
|
||||
/* #undef HAVE_HOST_CPU_piledriver */
|
||||
/* #undef HAVE_HOST_CPU_steamroller */
|
||||
/* #undef HAVE_HOST_CPU_excavator */
|
||||
/* #undef HAVE_HOST_CPU_zen */
|
||||
/* #undef HAVE_HOST_CPU_bobcat */
|
||||
/* #undef HAVE_HOST_CPU_jaguar */
|
||||
/* #undef HAVE_HOST_CPU_s390_z900 */
|
||||
/* #undef HAVE_HOST_CPU_s390_z990 */
|
||||
/* #undef HAVE_HOST_CPU_s390_z9 */
|
||||
/* #undef HAVE_HOST_CPU_s390_z10 */
|
||||
/* #undef HAVE_HOST_CPU_s390_z196 */
|
||||
|
||||
/* Define to 1 iff we have a s390 with 64-bit registers. */
|
||||
/* #undef HAVE_HOST_CPU_s390_zarch */
|
||||
|
||||
/* Define to 1 if the system has the type `intmax_t'. */
|
||||
#define HAVE_INTMAX_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `intptr_t'. */
|
||||
#define HAVE_INTPTR_T 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <invent.h> header file. */
|
||||
/* #undef HAVE_INVENT_H */
|
||||
|
||||
/* Define to 1 if you have the <langinfo.h> header file. */
|
||||
/* #undef HAVE_LANGINFO_H */
|
||||
|
||||
/* Define one of these to 1 for the endianness of `mp_limb_t'.
|
||||
If the endianness is not a simple big or little, or you don't know what
|
||||
it is, then leave both undefined. */
|
||||
/* #undef HAVE_LIMB_BIG_ENDIAN */
|
||||
#define HAVE_LIMB_LITTLE_ENDIAN 1
|
||||
|
||||
/* Define to 1 if you have the `localeconv' function. */
|
||||
#define HAVE_LOCALECONV 1
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `long double'. */
|
||||
#define HAVE_LONG_DOUBLE 1
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#define HAVE_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
|
||||
/* #undef HAVE_MACHINE_HAL_SYSINFO_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
/* #undef HAVE_MMAP */
|
||||
|
||||
/* Define to 1 if you have the `mprotect' function. */
|
||||
#define HAVE_MPROTECT 1
|
||||
|
||||
/* Define to 1 each of the following for which a native (ie. CPU specific)
|
||||
implementation of the corresponding routine exists. */
|
||||
#define HAVE_NATIVE_mpn_add_n 1
|
||||
/* #undef HAVE_NATIVE_mpn_add_n_sub_n */
|
||||
#define HAVE_NATIVE_mpn_add_nc 1
|
||||
/* #undef HAVE_NATIVE_mpn_addaddmul_1msb0 */
|
||||
#define HAVE_NATIVE_mpn_addlsh1_n 1
|
||||
#define HAVE_NATIVE_mpn_addlsh2_n 1
|
||||
#define HAVE_NATIVE_mpn_addlsh_n 1
|
||||
#define HAVE_NATIVE_mpn_addlsh1_nc 1
|
||||
#define HAVE_NATIVE_mpn_addlsh2_nc 1
|
||||
#define HAVE_NATIVE_mpn_addlsh_nc 1
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh1_n_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh2_n_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh_n_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh1_nc_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh2_nc_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh_nc_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh1_n_ip2 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh2_n_ip2 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh_n_ip2 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh1_nc_ip2 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh2_nc_ip2 */
|
||||
/* #undef HAVE_NATIVE_mpn_addlsh_nc_ip2 */
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_1c */
|
||||
#define HAVE_NATIVE_mpn_addmul_2 1
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_3 */
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_4 */
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_5 */
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_6 */
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_7 */
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_8 */
|
||||
/* #undef HAVE_NATIVE_mpn_addmul_2s */
|
||||
#define HAVE_NATIVE_mpn_and_n 1
|
||||
#define HAVE_NATIVE_mpn_andn_n 1
|
||||
#define HAVE_NATIVE_mpn_bdiv_dbm1c 1
|
||||
#define HAVE_NATIVE_mpn_bdiv_q_1 1
|
||||
#define HAVE_NATIVE_mpn_pi1_bdiv_q_1 1
|
||||
#define HAVE_NATIVE_mpn_cnd_add_n 1
|
||||
#define HAVE_NATIVE_mpn_cnd_sub_n 1
|
||||
#define HAVE_NATIVE_mpn_com 1
|
||||
#define HAVE_NATIVE_mpn_copyd 1
|
||||
#define HAVE_NATIVE_mpn_copyi 1
|
||||
/* #undef HAVE_NATIVE_mpn_div_qr_1n_pi1 */
|
||||
/* #undef HAVE_NATIVE_mpn_div_qr_2 */
|
||||
#define HAVE_NATIVE_mpn_divexact_1 1
|
||||
/* #undef HAVE_NATIVE_mpn_divexact_by3c */
|
||||
#define HAVE_NATIVE_mpn_divrem_1 1
|
||||
/* #undef HAVE_NATIVE_mpn_divrem_1c */
|
||||
#define HAVE_NATIVE_mpn_divrem_2 1
|
||||
/* #undef HAVE_NATIVE_mpn_gcd_1 */
|
||||
#define HAVE_NATIVE_mpn_gcd_11 1
|
||||
/* #undef HAVE_NATIVE_mpn_gcd_22 */
|
||||
#define HAVE_NATIVE_mpn_hamdist 1
|
||||
#define HAVE_NATIVE_mpn_invert_limb 1
|
||||
#define HAVE_NATIVE_mpn_ior_n 1
|
||||
#define HAVE_NATIVE_mpn_iorn_n 1
|
||||
#define HAVE_NATIVE_mpn_lshift 1
|
||||
#define HAVE_NATIVE_mpn_lshiftc 1
|
||||
/* #undef HAVE_NATIVE_mpn_lshsub_n */
|
||||
/* #undef HAVE_NATIVE_mpn_mod_1 */
|
||||
#define HAVE_NATIVE_mpn_mod_1_1p 1
|
||||
/* #undef HAVE_NATIVE_mpn_mod_1c */
|
||||
#define HAVE_NATIVE_mpn_mod_1s_2p 1
|
||||
#define HAVE_NATIVE_mpn_mod_1s_4p 1
|
||||
#define HAVE_NATIVE_mpn_mod_34lsub1 1
|
||||
#define HAVE_NATIVE_mpn_modexact_1_odd 1
|
||||
#define HAVE_NATIVE_mpn_modexact_1c_odd 1
|
||||
#define HAVE_NATIVE_mpn_mul_1 1
|
||||
#define HAVE_NATIVE_mpn_mul_1c 1
|
||||
#define HAVE_NATIVE_mpn_mul_2 1
|
||||
/* #undef HAVE_NATIVE_mpn_mul_3 */
|
||||
/* #undef HAVE_NATIVE_mpn_mul_4 */
|
||||
/* #undef HAVE_NATIVE_mpn_mul_5 */
|
||||
/* #undef HAVE_NATIVE_mpn_mul_6 */
|
||||
#define HAVE_NATIVE_mpn_mul_basecase 1
|
||||
#define HAVE_NATIVE_mpn_mullo_basecase 1
|
||||
#define HAVE_NATIVE_mpn_nand_n 1
|
||||
#define HAVE_NATIVE_mpn_nior_n 1
|
||||
#define HAVE_NATIVE_mpn_popcount 1
|
||||
#define HAVE_NATIVE_mpn_preinv_divrem_1 1
|
||||
/* #undef HAVE_NATIVE_mpn_preinv_mod_1 */
|
||||
#define HAVE_NATIVE_mpn_redc_1 1
|
||||
/* #undef HAVE_NATIVE_mpn_redc_2 */
|
||||
#define HAVE_NATIVE_mpn_rsblsh1_n 1
|
||||
#define HAVE_NATIVE_mpn_rsblsh2_n 1
|
||||
#define HAVE_NATIVE_mpn_rsblsh_n 1
|
||||
#define HAVE_NATIVE_mpn_rsblsh1_nc 1
|
||||
/* #undef HAVE_NATIVE_mpn_rsblsh2_nc */
|
||||
/* #undef HAVE_NATIVE_mpn_rsblsh_nc */
|
||||
#define HAVE_NATIVE_mpn_rsh1add_n 1
|
||||
#define HAVE_NATIVE_mpn_rsh1add_nc 1
|
||||
#define HAVE_NATIVE_mpn_rsh1sub_n 1
|
||||
#define HAVE_NATIVE_mpn_rsh1sub_nc 1
|
||||
#define HAVE_NATIVE_mpn_rshift 1
|
||||
/* #undef HAVE_NATIVE_mpn_sbpi1_bdiv_r */
|
||||
#define HAVE_NATIVE_mpn_sqr_basecase 1
|
||||
/* #undef HAVE_NATIVE_mpn_sqr_diagonal */
|
||||
#define HAVE_NATIVE_mpn_sqr_diag_addlsh1 1
|
||||
#define HAVE_NATIVE_mpn_sub_n 1
|
||||
#define HAVE_NATIVE_mpn_sub_nc 1
|
||||
#define HAVE_NATIVE_mpn_sublsh1_n 1
|
||||
#define HAVE_NATIVE_mpn_sublsh2_n 1
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh_n */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh1_nc */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh2_nc */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh_nc */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh1_n_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh2_n_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh_n_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh1_nc_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh2_nc_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_sublsh_nc_ip1 */
|
||||
/* #undef HAVE_NATIVE_mpn_submul_1c */
|
||||
/* #undef HAVE_NATIVE_mpn_tabselect */
|
||||
/* #undef HAVE_NATIVE_mpn_udiv_qrnnd */
|
||||
/* #undef HAVE_NATIVE_mpn_udiv_qrnnd_r */
|
||||
/* #undef HAVE_NATIVE_mpn_umul_ppmm */
|
||||
/* #undef HAVE_NATIVE_mpn_umul_ppmm_r */
|
||||
#define HAVE_NATIVE_mpn_xor_n 1
|
||||
#define HAVE_NATIVE_mpn_xnor_n 1
|
||||
|
||||
/* Define to 1 if you have the `nl_langinfo' function. */
|
||||
/* #undef HAVE_NL_LANGINFO */
|
||||
|
||||
/* Define to 1 if you have the <nl_types.h> header file. */
|
||||
/* #undef HAVE_NL_TYPES_H */
|
||||
|
||||
/* Define to 1 if you have the `obstack_vprintf' function. */
|
||||
/* #undef HAVE_OBSTACK_VPRINTF */
|
||||
|
||||
/* Define to 1 if you have the `popen' function. */
|
||||
#define HAVE_POPEN 1
|
||||
|
||||
/* Define to 1 if you have the `processor_info' function. */
|
||||
/* #undef HAVE_PROCESSOR_INFO */
|
||||
|
||||
/* Define to 1 if <sys/pstat.h> `struct pst_processor' exists and contains
|
||||
`psp_iticksperclktick'. */
|
||||
/* #undef HAVE_PSP_ITICKSPERCLKTICK */
|
||||
|
||||
/* Define to 1 if you have the `pstat_getprocessor' function. */
|
||||
/* #undef HAVE_PSTAT_GETPROCESSOR */
|
||||
|
||||
/* Define to 1 if the system has the type `ptrdiff_t'. */
|
||||
#define HAVE_PTRDIFF_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `quad_t'. */
|
||||
/* #undef HAVE_QUAD_T */
|
||||
|
||||
/* Define to 1 if you have the `raise' function. */
|
||||
#define HAVE_RAISE 1
|
||||
|
||||
/* Define to 1 if you have the `read_real_time' function. */
|
||||
/* #undef HAVE_READ_REAL_TIME */
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
/* #undef HAVE_SIGACTION */
|
||||
|
||||
/* Define to 1 if you have the `sigaltstack' function. */
|
||||
/* #undef HAVE_SIGALTSTACK */
|
||||
|
||||
/* Define to 1 if you have the `sigstack' function. */
|
||||
/* #undef HAVE_SIGSTACK */
|
||||
|
||||
/* Tune directory speed_cyclecounter, undef=none, 1=32bits, 2=64bits) */
|
||||
#define HAVE_SPEED_CYCLECOUNTER 2
|
||||
|
||||
/* Define to 1 if you have the <sstream> header file. */
|
||||
#define HAVE_SSTREAM 1
|
||||
|
||||
/* Define to 1 if the system has the type `stack_t'. */
|
||||
/* #undef HAVE_STACK_T */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `std::locale'. */
|
||||
#define HAVE_STD__LOCALE 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strnlen' function. */
|
||||
#define HAVE_STRNLEN 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
/* #undef HAVE_SYSCONF */
|
||||
|
||||
/* Define to 1 if you have the `sysctl' function. */
|
||||
/* #undef HAVE_SYSCTL */
|
||||
|
||||
/* Define to 1 if you have the `sysctlbyname' function. */
|
||||
/* #undef HAVE_SYSCTLBYNAME */
|
||||
|
||||
/* Define to 1 if you have the `syssgi' function. */
|
||||
/* #undef HAVE_SYSSGI */
|
||||
|
||||
/* Define to 1 if you have the <sys/attributes.h> header file. */
|
||||
/* #undef HAVE_SYS_ATTRIBUTES_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/iograph.h> header file. */
|
||||
/* #undef HAVE_SYS_IOGRAPH_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
/* #undef HAVE_SYS_MMAN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/processor.h> header file. */
|
||||
/* #undef HAVE_SYS_PROCESSOR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/pstat.h> header file. */
|
||||
/* #undef HAVE_SYS_PSTAT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
/* #undef HAVE_SYS_RESOURCE_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
/* #undef HAVE_SYS_SYSCTL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/sysinfo.h> header file. */
|
||||
/* #undef HAVE_SYS_SYSINFO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/syssgi.h> header file. */
|
||||
/* #undef HAVE_SYS_SYSSGI_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/systemcfg.h> header file. */
|
||||
/* #undef HAVE_SYS_SYSTEMCFG_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/times.h> header file. */
|
||||
/* #undef HAVE_SYS_TIMES_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `times' function. */
|
||||
/* #undef HAVE_TIMES */
|
||||
|
||||
/* Define to 1 if the system has the type `uint_least32_t'. */
|
||||
#define HAVE_UINT_LEAST32_T 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function and it works properly. */
|
||||
/* #undef HAVE_VSNPRINTF */
|
||||
|
||||
/* Define to 1 for Windos/64 */
|
||||
#define HOST_DOS64 1
|
||||
|
||||
/* Assembler local label prefix */
|
||||
#define LSYM_PREFIX "L"
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 to disable the use of inline assembly */
|
||||
/* #undef NO_ASM */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "gmp"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "gmp-bugs@gmplib.org, see https://gmplib.org/manual/Reporting-Bugs.html"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "GNU MP"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "GNU MP 6.2.0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "gmp"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "http://www.gnu.org/software/gmp/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "6.2.0"
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* The size of `mp_limb_t', as computed by sizeof. */
|
||||
#define SIZEOF_MP_LIMB_T 8
|
||||
|
||||
/* The size of `unsigned', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED 4
|
||||
|
||||
/* The size of `unsigned long', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_LONG 4
|
||||
|
||||
/* The size of `unsigned short', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_SHORT 2
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#define SIZEOF_VOID_P 8
|
||||
|
||||
/* Define to 1 if sscanf requires writable inputs */
|
||||
/* #undef SSCANF_WRITABLE_INPUT */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Maximum size the tune program can test for SQR_TOOM2_THRESHOLD */
|
||||
/* #undef TUNE_SQR_TOOM2_MAX */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "6.2.0"
|
||||
|
||||
/* Define to 1 to enable ASSERT checking, per --enable-assert */
|
||||
/* #undef WANT_ASSERT */
|
||||
|
||||
/* Define to 1 to enable GMP_CPU_TYPE faking cpuid, per --enable-fake-cpuid */
|
||||
/* #undef WANT_FAKE_CPUID */
|
||||
|
||||
/* Define to 1 when building a fat binary. */
|
||||
/* #undef WANT_FAT_BINARY */
|
||||
|
||||
/* Define to 1 to enable FFTs for multiplication, per --enable-fft */
|
||||
#define WANT_FFT 1
|
||||
|
||||
/* Define to 1 to enable old mpn_mul_fft_full for multiplication, per
|
||||
--enable-old-fft-full */
|
||||
/* #undef WANT_OLD_FFT_FULL */
|
||||
|
||||
/* Define to 1 if --enable-profiling=gprof */
|
||||
/* #undef WANT_PROFILING_GPROF */
|
||||
|
||||
/* Define to 1 if --enable-profiling=instrument */
|
||||
/* #undef WANT_PROFILING_INSTRUMENT */
|
||||
|
||||
/* Define to 1 if --enable-profiling=prof */
|
||||
/* #undef WANT_PROFILING_PROF */
|
||||
|
||||
/* Define one of these to 1 for the desired temporary memory allocation
|
||||
method, per --enable-alloca. */
|
||||
#define WANT_TMP_ALLOCA 1
|
||||
/* #undef WANT_TMP_REENTRANT */
|
||||
/* #undef WANT_TMP_NOTREENTRANT */
|
||||
/* #undef WANT_TMP_DEBUG */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
/* # undef WORDS_BIGENDIAN */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to 1 if the assembler understands the mulx instruction */
|
||||
/* #undef X86_ASM_MULX */
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
/* #undef YYTEXT_POINTER */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to the equivalent of the C99 'restrict' keyword, or to
|
||||
nothing if this is not supported. Do not define if restrict is
|
||||
supported directly. */
|
||||
#define restrict __restrict
|
||||
/* Work around a bug in Sun C++: it does not support _Restrict or
|
||||
__restrict__, even though the corresponding Sun C compiler ends up with
|
||||
"#define restrict _Restrict" or "#define restrict __restrict__" in the
|
||||
previous line. Perhaps some future version of Sun C++ will work with
|
||||
restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
|
||||
#if defined __SUNPRO_CC && !defined __RESTRICT
|
||||
# define _Restrict
|
||||
# define __restrict__
|
||||
#endif
|
||||
|
||||
/* Define to empty if the keyword `volatile' does not work. Warning: valid
|
||||
code using `volatile' can become incorrect without. Disable with care. */
|
||||
/* #undef volatile */
|
@@ -1,14 +0,0 @@
|
||||
diff -Naur orig/common/sys/platform.h external_embree/common/sys/platform.h
|
||||
--- orig/common/sys/platform.h 2020-05-13 23:08:53 -0600
|
||||
+++ external_embree/common/sys/platform.h 2020-06-13 17:40:26 -0600
|
||||
@@ -84,8 +84,8 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __WIN32__
|
||||
-#define dll_export __declspec(dllexport)
|
||||
-#define dll_import __declspec(dllimport)
|
||||
+#define dll_export
|
||||
+#define dll_import
|
||||
#else
|
||||
#define dll_export __attribute__ ((visibility ("default")))
|
||||
#define dll_import
|
@@ -9,62 +9,3 @@
|
||||
enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++"
|
||||
enabled libopus && {
|
||||
enabled libopus_decoder && {
|
||||
--- a/libavcodec/cfhddata.c
|
||||
+++ b/libavcodec/cfhddata.c
|
||||
@@ -276,10 +276,10 @@
|
||||
av_cold int ff_cfhd_init_vlcs(CFHDContext *s)
|
||||
{
|
||||
int i, j, ret = 0;
|
||||
- uint32_t new_cfhd_vlc_bits[NB_VLC_TABLE_18 * 2];
|
||||
- uint8_t new_cfhd_vlc_len[NB_VLC_TABLE_18 * 2];
|
||||
- uint16_t new_cfhd_vlc_run[NB_VLC_TABLE_18 * 2];
|
||||
- int16_t new_cfhd_vlc_level[NB_VLC_TABLE_18 * 2];
|
||||
+ uint32_t *new_cfhd_vlc_bits = av_calloc(sizeof(uint32_t), NB_VLC_TABLE_18 * 2);
|
||||
+ uint8_t *new_cfhd_vlc_len = av_calloc(sizeof(uint8_t), NB_VLC_TABLE_18 * 2);
|
||||
+ uint16_t *new_cfhd_vlc_run = av_calloc(sizeof(uint16_t), NB_VLC_TABLE_18 * 2);
|
||||
+ int16_t *new_cfhd_vlc_level = av_calloc(sizeof(int16_t), NB_VLC_TABLE_18 * 2);
|
||||
|
||||
/** Similar to dv.c, generate signed VLC tables **/
|
||||
|
||||
@@ -305,8 +305,13 @@
|
||||
|
||||
ret = init_vlc(&s->vlc_9, VLC_BITS, j, new_cfhd_vlc_len,
|
||||
1, 1, new_cfhd_vlc_bits, 4, 4, 0);
|
||||
- if (ret < 0)
|
||||
+ if (ret < 0) {
|
||||
+ av_free(new_cfhd_vlc_bits);
|
||||
+ av_free(new_cfhd_vlc_len);
|
||||
+ av_free(new_cfhd_vlc_run);
|
||||
+ av_free(new_cfhd_vlc_level);
|
||||
return ret;
|
||||
+ }
|
||||
for (i = 0; i < s->vlc_9.table_size; i++) {
|
||||
int code = s->vlc_9.table[i][0];
|
||||
int len = s->vlc_9.table[i][1];
|
||||
@@ -346,8 +351,14 @@
|
||||
|
||||
ret = init_vlc(&s->vlc_18, VLC_BITS, j, new_cfhd_vlc_len,
|
||||
1, 1, new_cfhd_vlc_bits, 4, 4, 0);
|
||||
- if (ret < 0)
|
||||
+ if (ret < 0) {
|
||||
+ av_free(new_cfhd_vlc_bits);
|
||||
+ av_free(new_cfhd_vlc_len);
|
||||
+ av_free(new_cfhd_vlc_run);
|
||||
+ av_free(new_cfhd_vlc_level);
|
||||
return ret;
|
||||
+ }
|
||||
+
|
||||
av_assert0(s->vlc_18.table_size == 4572);
|
||||
|
||||
for (i = 0; i < s->vlc_18.table_size; i++) {
|
||||
@@ -367,5 +378,10 @@
|
||||
s->table_18_rl_vlc[i].run = run;
|
||||
}
|
||||
|
||||
+ av_free(new_cfhd_vlc_bits);
|
||||
+ av_free(new_cfhd_vlc_len);
|
||||
+ av_free(new_cfhd_vlc_run);
|
||||
+ av_free(new_cfhd_vlc_level);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
15
build_files/build_environment/patches/hidapi.diff
Normal file
15
build_files/build_environment/patches/hidapi.diff
Normal file
@@ -0,0 +1,15 @@
|
||||
--- hidapi/hidapi.h 2011-10-25 20:58:16 -0600
|
||||
+++ hidapi/hidapi.h 2016-11-01 12:05:58 -0600
|
||||
@@ -30,7 +30,11 @@
|
||||
#include <wchar.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
- #define HID_API_EXPORT __declspec(dllexport)
|
||||
+ #ifdef HID_API_STATIC
|
||||
+ #define HID_API_EXPORT
|
||||
+ #else
|
||||
+ #define HID_API_EXPORT __declspec(dllexport)
|
||||
+ #endif
|
||||
#define HID_API_CALL
|
||||
#else
|
||||
#define HID_API_EXPORT /**< API export macro */
|
@@ -1,85 +0,0 @@
|
||||
diff -Naur external_ispc/CMakeLists.txt external_ispc_fixed/CMakeLists.txt
|
||||
--- external_ispc/CMakeLists.txt 2020-04-23 17:29:06 -0600
|
||||
+++ external_ispc_fixed/CMakeLists.txt 2020-05-05 09:01:09 -0600
|
||||
@@ -389,7 +389,7 @@
|
||||
|
||||
# Link against Clang libraries
|
||||
foreach(clangLib ${CLANG_LIBRARY_LIST})
|
||||
- find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS})
|
||||
+ find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS} ${CLANG_LIBRARY_DIR})
|
||||
list(APPEND CLANG_LIBRARY_FULL_PATH_LIST ${${clangLib}Path})
|
||||
endforeach()
|
||||
target_link_libraries(${PROJECT_NAME} ${CLANG_LIBRARY_FULL_PATH_LIST})
|
||||
diff -Naur orig/CMakeLists.txt external_ispc/CMakeLists.txt
|
||||
--- orig/CMakeLists.txt 2020-05-05 09:19:11 -0600
|
||||
+++ external_ispc/CMakeLists.txt 2020-05-05 09:26:44 -0600
|
||||
@@ -333,7 +333,7 @@
|
||||
|
||||
# Include directories
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
- ${LLVM_INCLUDE_DIRS}
|
||||
+ ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
|
||||
# Compile options
|
||||
diff -Naur orig/cmake/GenerateBuiltins.cmake.txt external_ispc/cmake/GenerateBuiltins.cmake.txt
|
||||
+++ orig/cmake/GenerateBuiltins.cmake 2020-05-25 13:32:40.830803821 +0200
|
||||
+++ external_ispc/cmake/GenerateBuiltins.cmake 2020-05-25 13:32:40.830803821 +0200
|
||||
@@ -97,6 +97,8 @@
|
||||
|
||||
if ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "x86")
|
||||
set(target_arch "i386")
|
||||
+ # Blender: disable 32bit due to build issues on Linux and being unnecessary.
|
||||
+ set(SKIP ON)
|
||||
elseif ("${bit}" STREQUAL "64" AND ${arch} STREQUAL "x86")
|
||||
set(target_arch "x86_64")
|
||||
elseif ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "arm")
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 46a8db8..f53beef 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -36,8 +36,12 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
if (UNIX)
|
||||
- set(CMAKE_C_COMPILER "clang")
|
||||
- set(CMAKE_CXX_COMPILER "clang++")
|
||||
+ if (NOT CMAKE_C_COMPILER)
|
||||
+ set(CMAKE_C_COMPILER "clang")
|
||||
+ endif()
|
||||
+ if (NOT CMAKE_CXX_COMPILER)
|
||||
+ set(CMAKE_CXX_COMPILER "clang++")
|
||||
+ endif()
|
||||
endif()
|
||||
|
||||
set(PROJECT_NAME ispc)
|
||||
@@ -412,6 +416,29 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
+# Link against libstdc++.a which must be provided to the linker after
|
||||
+# LLVM and CLang libraries.
|
||||
+# This is needed because some of LLVM/CLang dependencies are using
|
||||
+# std::make_shared, which is defined in one of those:
|
||||
+# - libclang-cpp.so
|
||||
+# - libstdc++.a
|
||||
+# Using the former one is tricky because then generated binary depends
|
||||
+# on a library which is outside of the LD_LIBRARY_PATH.
|
||||
+#
|
||||
+# Hence, using C++ implementation from G++ which seems to work just fine.
|
||||
+# In fact, from investigation seems that libclang-cpp.so itself is pulling
|
||||
+# std::_Sp_make_shared_tag from G++'s libstdc++.a.
|
||||
+if(UNIX AND NOT APPLE)
|
||||
+ execute_process(
|
||||
+ COMMAND g++ --print-file-name libstdc++.a
|
||||
+ OUTPUT_VARIABLE GCC_LIBSTDCXX_A
|
||||
+ OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
+ )
|
||||
+ if(GCC_LIBSTDCXX_A AND EXISTS ${GCC_LIBSTDCXX_A})
|
||||
+ target_link_libraries(${PROJECT_NAME} ${GCC_LIBSTDCXX_A})
|
||||
+ endif()
|
||||
+endif()
|
||||
+
|
||||
# Build target for utility checking host ISA
|
||||
if (ISPC_INCLUDE_UTILS)
|
||||
add_executable(check_isa "")
|
@@ -1,129 +0,0 @@
|
||||
diff --git a/output/macho.h b/output/macho.h
|
||||
index 538c531e..fd5e8849 100644
|
||||
--- a/output/macho.h
|
||||
+++ b/output/macho.h
|
||||
@@ -60,6 +60,8 @@
|
||||
#define LC_SEGMENT 0x1
|
||||
#define LC_SEGMENT_64 0x19
|
||||
#define LC_SYMTAB 0x2
|
||||
+#define LC_VERSION_MIN_MACOSX 0x24
|
||||
+#define LC_BUILD_VERSION 0x32
|
||||
|
||||
/* Symbol type bits */
|
||||
#define N_STAB 0xe0
|
||||
diff --git a/output/outmacho.c b/output/outmacho.c
|
||||
index 08147883..de6ec902 100644
|
||||
--- a/output/outmacho.c
|
||||
+++ b/output/outmacho.c
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
#include "nctype.h"
|
||||
|
||||
#include "nasm.h"
|
||||
@@ -64,6 +66,8 @@
|
||||
#define MACHO_SYMCMD_SIZE 24
|
||||
#define MACHO_NLIST_SIZE 12
|
||||
#define MACHO_RELINFO_SIZE 8
|
||||
+#define MACHO_BUILD_VERSION_SIZE 24
|
||||
+#define MACHO_VERSION_MIN_MACOSX_SIZE 16
|
||||
|
||||
#define MACHO_HEADER64_SIZE 32
|
||||
#define MACHO_SEGCMD64_SIZE 72
|
||||
@@ -1224,6 +1228,46 @@ static void macho_layout_symbols (uint32_t *numsyms,
|
||||
}
|
||||
}
|
||||
|
||||
+static bool get_full_version_from_env (const char *variable_name,
|
||||
+ int *r_major,
|
||||
+ int *r_minor,
|
||||
+ int *r_patch) {
|
||||
+ *r_major = 0;
|
||||
+ *r_minor = 0;
|
||||
+ *r_patch = 0;
|
||||
+
|
||||
+ const char *value = getenv(variable_name);
|
||||
+ if (value == NULL || value[0] == '\0') {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ const char *current_value = value;
|
||||
+ const char *end_value = value + strlen(value);
|
||||
+
|
||||
+ char *endptr;
|
||||
+
|
||||
+ *r_major = strtol(current_value, &endptr, 10);
|
||||
+ if (endptr >= end_value) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ current_value = endptr + 1;
|
||||
+
|
||||
+ *r_minor = strtol(current_value, &endptr, 10);
|
||||
+ if (endptr >= end_value) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ current_value = endptr + 1;
|
||||
+
|
||||
+ *r_patch = strtol(current_value, &endptr, 10);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static bool need_version_min_macosx_command (void) {
|
||||
+ return getenv("MACOSX_DEPLOYMENT_TARGET") &&
|
||||
+ getenv("MACOSX_SDK_VERSION");
|
||||
+}
|
||||
+
|
||||
/* Calculate some values we'll need for writing later. */
|
||||
|
||||
static void macho_calculate_sizes (void)
|
||||
@@ -1270,6 +1314,12 @@ static void macho_calculate_sizes (void)
|
||||
head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
|
||||
}
|
||||
|
||||
+ /* LC_VERSION_MIN_MACOSX */
|
||||
+ if (need_version_min_macosx_command()) {
|
||||
+ ++head_ncmds;
|
||||
+ head_sizeofcmds += MACHO_VERSION_MIN_MACOSX_SIZE;
|
||||
+ }
|
||||
+
|
||||
if (nsyms > 0) {
|
||||
++head_ncmds;
|
||||
head_sizeofcmds += MACHO_SYMCMD_SIZE;
|
||||
@@ -1653,6 +1703,33 @@ static void macho_write (void)
|
||||
else
|
||||
nasm_warn(WARN_OTHER, "no sections?");
|
||||
|
||||
+#define ENCODE_BUILD_VERSION(major, minor, patch) \
|
||||
+ (((major) << 16) | ((minor) << 8) | (patch))
|
||||
+
|
||||
+ if (0) {
|
||||
+ fwriteint32_t(LC_BUILD_VERSION, ofile); /* cmd == LC_BUILD_VERSION */
|
||||
+ fwriteint32_t(MACHO_BUILD_VERSION_SIZE, ofile); /* size of load command */
|
||||
+ fwriteint32_t(1, ofile); /* platform */
|
||||
+ fwriteint32_t(ENCODE_BUILD_VERSION(10, 13, 0), ofile); /* minos, X.Y.Z is encoded in nibbles xxxx.yy.zz */
|
||||
+ fwriteint32_t(ENCODE_BUILD_VERSION(10, 15, 4), ofile); /* sdk, X.Y.Z is encoded in nibbles xxxx.yy.zz */
|
||||
+ fwriteint32_t(0, ofile); /* number of tool entries following this */
|
||||
+ }
|
||||
+
|
||||
+ if (need_version_min_macosx_command()) {
|
||||
+ int sdk_major, sdk_minor, sdk_patch;
|
||||
+ get_full_version_from_env("MACOSX_SDK_VERSION", &sdk_major, &sdk_minor, &sdk_patch);
|
||||
+
|
||||
+ int version_major, version_minor, version_patch;
|
||||
+ get_full_version_from_env("MACOSX_DEPLOYMENT_TARGET", &version_major, &version_minor, &version_patch);
|
||||
+
|
||||
+ fwriteint32_t(LC_VERSION_MIN_MACOSX, ofile); /* cmd == LC_VERSION_MIN_MACOSX */
|
||||
+ fwriteint32_t(MACHO_VERSION_MIN_MACOSX_SIZE, ofile); /* size of load command */
|
||||
+ fwriteint32_t(ENCODE_BUILD_VERSION(version_major, version_minor, version_patch), ofile); /* minos, X.Y.Z is encoded in nibbles xxxx.yy.zz */
|
||||
+ fwriteint32_t(ENCODE_BUILD_VERSION(sdk_major, sdk_minor, sdk_patch), ofile); /* sdk, X.Y.Z is encoded in nibbles xxxx.yy.zz */
|
||||
+ }
|
||||
+
|
||||
+#undef ENCODE_BUILD_VERSION
|
||||
+
|
||||
if (nsyms > 0) {
|
||||
/* write out symbol command */
|
||||
fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
|
@@ -1,27 +0,0 @@
|
||||
diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py
|
||||
index ba2b1f4..b10f7df 100644
|
||||
--- a/numpy/distutils/system_info.py
|
||||
+++ b/numpy/distutils/system_info.py
|
||||
@@ -2164,8 +2164,8 @@ class accelerate_info(system_info):
|
||||
'accelerate' in libraries):
|
||||
if intel:
|
||||
args.extend(['-msse3'])
|
||||
- else:
|
||||
- args.extend(['-faltivec'])
|
||||
+# else:
|
||||
+# args.extend(['-faltivec'])
|
||||
args.extend([
|
||||
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
|
||||
link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
|
||||
@@ -2174,8 +2174,8 @@ class accelerate_info(system_info):
|
||||
'veclib' in libraries):
|
||||
if intel:
|
||||
args.extend(['-msse3'])
|
||||
- else:
|
||||
- args.extend(['-faltivec'])
|
||||
+# else:
|
||||
+# args.extend(['-faltivec'])
|
||||
args.extend([
|
||||
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
|
||||
link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
|
||||
|
@@ -1,12 +0,0 @@
|
||||
diff --git a/include/ogg/os_types.h b/include/ogg/os_types.h
|
||||
index eb8a322..6f73b72 100644
|
||||
--- a/include/ogg/os_types.h
|
||||
+++ b/include/ogg/os_types.h
|
||||
@@ -71,6 +71,7 @@
|
||||
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
|
||||
|
||||
# include <sys/types.h>
|
||||
+# include <stdint.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
@@ -86,47 +86,3 @@ index 1f9a3ee..d151e9a 100644
|
||||
return isnan( value );
|
||||
#else
|
||||
return std::isnan(value);
|
||||
|
||||
|
||||
diff --git a/DAEValidator/library/src/Dae.cpp b/DAEValidator/library/src/Dae.cpp
|
||||
index 9256ee1..241ad67 100644
|
||||
--- a/DAEValidator/library/src/Dae.cpp
|
||||
+++ b/DAEValidator/library/src/Dae.cpp
|
||||
@@ -304,7 +304,7 @@ namespace opencollada
|
||||
if (auto root_node = root())
|
||||
{
|
||||
const auto & nodes = root_node.selectNodes("//*[@id]");
|
||||
- for (const auto & node : nodes)
|
||||
+ for (const auto node : nodes)
|
||||
{
|
||||
string id = node.attribute("id").value();
|
||||
mIdCache.insert(id);
|
||||
@@ -312,4 +312,4 @@ namespace opencollada
|
||||
}
|
||||
}
|
||||
}
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
diff --git a/DAEValidator/library/src/DaeValidator.cpp b/DAEValidator/library/src/DaeValidator.cpp
|
||||
index 715d903..24423ce 100644
|
||||
--- a/DAEValidator/library/src/DaeValidator.cpp
|
||||
+++ b/DAEValidator/library/src/DaeValidator.cpp
|
||||
@@ -162,7 +162,7 @@ namespace opencollada
|
||||
|
||||
// Find xsi:schemaLocation attributes in dae and try to validate against specified xsd documents
|
||||
const auto & elements = dae.root().selectNodes("//*[@xsi:schemaLocation]");
|
||||
- for (const auto & element : elements)
|
||||
+ for (const auto element : elements)
|
||||
{
|
||||
if (auto schemaLocation = element.attribute("schemaLocation"))
|
||||
{
|
||||
@@ -274,7 +274,7 @@ namespace opencollada
|
||||
int result = 0;
|
||||
map<string, size_t> ids;
|
||||
const auto & nodes = dae.root().selectNodes("//*[@id]");
|
||||
- for (const auto & node : nodes)
|
||||
+ for (const auto node : nodes)
|
||||
{
|
||||
string id = node.attribute("id").value();
|
||||
size_t line = node.line();
|
||||
|
120
build_files/build_environment/patches/openimagedenoise.diff
Normal file
120
build_files/build_environment/patches/openimagedenoise.diff
Normal file
@@ -0,0 +1,120 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 70ec895..e616b63 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -178,7 +178,9 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY SOVERSION "0")
|
||||
## Open Image Denoise examples
|
||||
## ----------------------------------------------------------------------------
|
||||
|
||||
-add_subdirectory(examples)
|
||||
+if(WITH_EXAMPLE)
|
||||
+ add_subdirectory(examples)
|
||||
+endif()
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
## Open Image Denoise install and packaging
|
||||
Submodule mkl-dnn contains modified content
|
||||
diff --git a/mkl-dnn/cmake/TBB.cmake b/mkl-dnn/cmake/TBB.cmake
|
||||
index 0711e699..c14210b6 100644
|
||||
--- a/mkl-dnn/cmake/TBB.cmake
|
||||
+++ b/mkl-dnn/cmake/TBB.cmake
|
||||
@@ -138,13 +138,13 @@ else()
|
||||
set(TBB_LIBRARY_MALLOC TBB_LIBRARY_MALLOC-NOTFOUND)
|
||||
if(APPLE)
|
||||
find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH)
|
||||
- find_library(TBB_LIBRARY tbb PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
|
||||
- find_library(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
|
||||
+ find_library(TBB_LIBRARY tbb_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
|
||||
+ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH)
|
||||
set(TBB_HINTS HINTS ${TBB_ROOT}/lib/intel64/gcc4.4 ${TBB_ROOT}/lib ${TBB_ROOT}/lib64 PATHS /usr/libx86_64-linux-gnu/)
|
||||
- find_library(TBB_LIBRARY tbb ${TBB_HINTS})
|
||||
- find_library(TBB_LIBRARY_MALLOC tbbmalloc ${TBB_HINTS})
|
||||
+ find_library(TBB_LIBRARY tbb_static ${TBB_HINTS})
|
||||
+ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static ${TBB_HINTS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r
|
||||
--- a/cmake/install.cmake 2019-08-12 18:02:20.794402575 +0200
|
||||
+++ b/cmake/install.cmake 2019-08-12 18:06:07.470045703 +0200
|
||||
@@ -18,6 +18,13 @@
|
||||
## Install library
|
||||
## ----------------------------------------------------------------------------
|
||||
|
||||
+if(UNIX)
|
||||
+install(FILES
|
||||
+ ${CMAKE_BINARY_DIR}/libOpenImageDenoise.a
|
||||
+ ${CMAKE_BINARY_DIR}/libmkldnn.a
|
||||
+ ${CMAKE_BINARY_DIR}/libcommon.a
|
||||
+ DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
+else()
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
EXPORT
|
||||
${PROJECT_NAME}_Export
|
||||
@@ -38,6 +45,7 @@
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
|
||||
)
|
||||
endif()
|
||||
+endif()
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
## Install headers
|
||||
@@ -78,6 +86,7 @@
|
||||
## Install CMake configuration files
|
||||
## ----------------------------------------------------------------------------
|
||||
|
||||
+if(NOT UNIX)
|
||||
install(EXPORT ${PROJECT_NAME}_Export
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
|
||||
#NAMESPACE ${PROJECT_NAME}::
|
||||
@@ -92,3 +101,4 @@
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
|
||||
COMPONENT devel
|
||||
)
|
||||
+endif()
|
||||
diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r
|
||||
--- a/CMakeLists.txt 2019-08-12 14:22:00.974078598 +0200
|
||||
+++ b/CMakeLists.txt 2019-08-12 18:05:05.949057375 +0200
|
||||
@@ -14,7 +14,11 @@
|
||||
## limitations under the License. ##
|
||||
## ======================================================================== ##
|
||||
|
||||
-cmake_minimum_required(VERSION 3.1)
|
||||
+if(UNIX)
|
||||
+ cmake_minimum_required(VERSION 3.1)
|
||||
+else()
|
||||
+ cmake_minimum_required(VERSION 3.13)
|
||||
+endif()
|
||||
|
||||
set(OIDN_VERSION_MAJOR 1)
|
||||
set(OIDN_VERSION_MINOR 0)
|
||||
@@ -32,13 +36,8 @@
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
|
||||
|
||||
# Build as shared or static library
|
||||
-if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
|
||||
- option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.")
|
||||
- mark_as_advanced(CLEAR OIDN_STATIC_LIB)
|
||||
-else()
|
||||
- set(OIDN_STATIC_LIB OFF CACHE BOOL "Build Open Image Denoise as a static library." FORCE)
|
||||
- mark_as_advanced(OIDN_STATIC_LIB)
|
||||
-endif()
|
||||
+option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.")
|
||||
+mark_as_advanced(CLEAR OIDN_STATIC_LIB)
|
||||
if(OIDN_STATIC_LIB)
|
||||
set(OIDN_LIB_TYPE STATIC)
|
||||
else()
|
||||
diff -Naur orig/core/api.cpp external_openimagedenoise/core/api.cpp
|
||||
--- orig/core/api.cpp 2019-07-19 08:37:04 -0600
|
||||
+++ external_openimagedenoise/core/api.cpp 2020-01-21 15:10:56 -0700
|
||||
@@ -15,7 +15,7 @@
|
||||
// ======================================================================== //
|
||||
|
||||
#ifdef _WIN32
|
||||
-# define OIDN_API extern "C" __declspec(dllexport)
|
||||
+# define OIDN_API extern "C"
|
||||
#else
|
||||
# define OIDN_API extern "C" __attribute__ ((visibility ("default")))
|
||||
#endif
|
@@ -1,23 +0,0 @@
|
||||
diff --git a/runtime/src/z_Linux_asm.S b/runtime/src/z_Linux_asm.S
|
||||
index 0d8885e..42aa5ad 100644
|
||||
--- a/runtime/src/z_Linux_asm.S
|
||||
+++ b/runtime/src/z_Linux_asm.S
|
||||
@@ -1540,10 +1540,12 @@ __kmp_unnamed_critical_addr:
|
||||
.comm .gomp_critical_user_,32,8
|
||||
.data
|
||||
.align 8
|
||||
- .global __kmp_unnamed_critical_addr
|
||||
-__kmp_unnamed_critical_addr:
|
||||
+ .global ___kmp_unnamed_critical_addr
|
||||
+___kmp_unnamed_critical_addr:
|
||||
.8byte .gomp_critical_user_
|
||||
- .size __kmp_unnamed_critical_addr,8
|
||||
+# if !(KMP_OS_DARWIN)
|
||||
+ .size ___kmp_unnamed_critical_addr,8
|
||||
+# endif
|
||||
#endif /* KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 */
|
||||
|
||||
#if KMP_OS_LINUX
|
||||
|
||||
|
||||
|
@@ -1,289 +0,0 @@
|
||||
diff -ru a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
|
||||
--- a/Doc/library/ctypes.rst 2020-03-10 07:11:12.000000000 +0100
|
||||
+++ b/Doc/library/ctypes.rst 2020-07-14 08:10:10.000000000 +0200
|
||||
@@ -1551,6 +1551,13 @@
|
||||
value usable as argument (integer, string, ctypes instance). This allows
|
||||
defining adapters that can adapt custom objects as function parameters.
|
||||
|
||||
+ .. attribute:: variadic
|
||||
+
|
||||
+ Assign a boolean to specify that the function takes a variable number of
|
||||
+ arguments. This does not matter on most platforms, but for Apple arm64
|
||||
+ platforms variadic functions have a different calling convention than
|
||||
+ normal functions.
|
||||
+
|
||||
.. attribute:: errcheck
|
||||
|
||||
Assign a Python function or another callable to this attribute. The
|
||||
diff -ru a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
|
||||
--- a/Modules/_ctypes/_ctypes.c 2020-03-10 07:11:12.000000000 +0100
|
||||
+++ b/Modules/_ctypes/_ctypes.c 2020-07-14 08:14:41.000000000 +0200
|
||||
@@ -3175,6 +3175,35 @@
|
||||
}
|
||||
|
||||
static int
|
||||
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
|
||||
+{
|
||||
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
||||
+ assert(dict);
|
||||
+ int r = PyObject_IsTrue(ob);
|
||||
+ if (r == 1) {
|
||||
+ dict->flags |= FUNCFLAG_VARIADIC;
|
||||
+ return 0;
|
||||
+ } else if (r == 0) {
|
||||
+ dict->flags &= ~FUNCFLAG_VARIADIC;
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ return -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static PyObject *
|
||||
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
|
||||
+{
|
||||
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
||||
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
|
||||
+ if (dict->flags & FUNCFLAG_VARIADIC)
|
||||
+ Py_RETURN_TRUE;
|
||||
+ else
|
||||
+ Py_RETURN_FALSE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *converters;
|
||||
@@ -5632,6 +5661,7 @@
|
||||
PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
|
||||
PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
|
||||
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
|
||||
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
|
||||
PyModule_AddStringConstant(m, "__version__", "1.1.0");
|
||||
|
||||
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
|
||||
diff -ru a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
|
||||
--- a/Modules/_ctypes/callproc.c 2020-03-10 07:11:12.000000000 +0100
|
||||
+++ b/Modules/_ctypes/callproc.c 2020-07-14 08:18:33.000000000 +0200
|
||||
@@ -767,7 +767,8 @@
|
||||
ffi_type **atypes,
|
||||
ffi_type *restype,
|
||||
void *resmem,
|
||||
- int argcount)
|
||||
+ int argcount,
|
||||
+ int argtypecount)
|
||||
{
|
||||
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
|
||||
PyObject *error_object = NULL;
|
||||
@@ -793,15 +794,38 @@
|
||||
if ((flags & FUNCFLAG_CDECL) == 0)
|
||||
cc = FFI_STDCALL;
|
||||
#endif
|
||||
- if (FFI_OK != ffi_prep_cif(&cif,
|
||||
- cc,
|
||||
- argcount,
|
||||
- restype,
|
||||
- atypes)) {
|
||||
- PyErr_SetString(PyExc_RuntimeError,
|
||||
- "ffi_prep_cif failed");
|
||||
- return -1;
|
||||
- }
|
||||
+#if HAVE_FFI_PREP_CIF_VAR
|
||||
+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
|
||||
+ * lots of existing code will not. If there's at least one arg and more
|
||||
+ * args are passed than are defined in the prototype, then it must be a
|
||||
+ * variadic function. */
|
||||
+ if ((flags & FUNCFLAG_VARIADIC) ||
|
||||
+ (argtypecount != 0 && argcount > argtypecount))
|
||||
+ {
|
||||
+ if (FFI_OK != ffi_prep_cif_var(&cif,
|
||||
+ cc,
|
||||
+ argtypecount,
|
||||
+ argcount,
|
||||
+ restype,
|
||||
+ atypes)) {
|
||||
+ PyErr_SetString(PyExc_RuntimeError,
|
||||
+ "ffi_prep_cif_var failed");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+#endif
|
||||
+ if (FFI_OK != ffi_prep_cif(&cif,
|
||||
+ cc,
|
||||
+ argcount,
|
||||
+ restype,
|
||||
+ atypes)) {
|
||||
+ PyErr_SetString(PyExc_RuntimeError,
|
||||
+ "ffi_prep_cif failed");
|
||||
+ return -1;
|
||||
+ }
|
||||
+#if HAVE_FFI_PREP_CIF_VAR
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
|
||||
error_object = _ctypes_get_errobj(&space);
|
||||
@@ -1185,9 +1209,8 @@
|
||||
|
||||
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
|
||||
rtype, resbuf,
|
||||
- Py_SAFE_DOWNCAST(argcount,
|
||||
- Py_ssize_t,
|
||||
- int)))
|
||||
+ Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
|
||||
+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
|
||||
goto cleanup;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
diff -ru a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
|
||||
--- a/Modules/_ctypes/ctypes.h 2020-03-10 07:11:12.000000000 +0100
|
||||
+++ b/Modules/_ctypes/ctypes.h 2020-07-14 08:30:53.000000000 +0200
|
||||
@@ -285,6 +285,7 @@
|
||||
#define FUNCFLAG_PYTHONAPI 0x4
|
||||
#define FUNCFLAG_USE_ERRNO 0x8
|
||||
#define FUNCFLAG_USE_LASTERROR 0x10
|
||||
+#define FUNCFLAG_VARIADIC 0x20
|
||||
|
||||
#define TYPEFLAG_ISPOINTER 0x100
|
||||
#define TYPEFLAG_HASPOINTER 0x200
|
||||
diff -ru a/configure b/configure
|
||||
--- a/configure 2020-03-10 07:11:12.000000000 +0100
|
||||
+++ b/configure 2020-07-14 08:03:27.000000000 +0200
|
||||
@@ -3374,7 +3374,7 @@
|
||||
# has no effect, don't bother defining them
|
||||
Darwin/[6789].*)
|
||||
define_xopen_source=no;;
|
||||
- Darwin/1[0-9].*)
|
||||
+ Darwin/[12][0-9].*)
|
||||
define_xopen_source=no;;
|
||||
# On AIX 4 and 5.1, mbstate_t is defined only when _XOPEN_SOURCE == 500 but
|
||||
# used in wcsnrtombs() and mbsnrtowcs() even if _XOPEN_SOURCE is not defined
|
||||
@@ -9251,6 +9251,9 @@
|
||||
ppc)
|
||||
MACOSX_DEFAULT_ARCH="ppc64"
|
||||
;;
|
||||
+ arm64)
|
||||
+ MACOSX_DEFAULT_ARCH="arm64"
|
||||
+ ;;
|
||||
*)
|
||||
as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
|
||||
;;
|
||||
diff -ru a/configure.ac b/configure.ac
|
||||
--- a/configure.ac 2020-03-10 07:11:12.000000000 +0100
|
||||
+++ b/configure.ac 2020-07-14 08:03:27.000000000 +0200
|
||||
@@ -2456,6 +2456,9 @@
|
||||
ppc)
|
||||
MACOSX_DEFAULT_ARCH="ppc64"
|
||||
;;
|
||||
+ arm64)
|
||||
+ MACOSX_DEFAULT_ARCH="arm64"
|
||||
+ ;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unexpected output of 'arch' on OSX])
|
||||
;;
|
||||
diff -ru a/setup.py b/setup.py
|
||||
--- a/setup.py 2020-03-10 07:11:12.000000000 +0100
|
||||
+++ b/setup.py 2020-07-14 08:28:12.000000000 +0200
|
||||
@@ -141,6 +141,13 @@
|
||||
os.unlink(tmpfile)
|
||||
|
||||
return MACOS_SDK_ROOT
|
||||
+
|
||||
+def is_macosx_at_least(vers):
|
||||
+ if host_platform == 'darwin':
|
||||
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
|
||||
+ if dep_target:
|
||||
+ return tuple(map(int, dep_target.split('.'))) >= vers
|
||||
+ return False
|
||||
|
||||
def is_macosx_sdk_path(path):
|
||||
"""
|
||||
@@ -150,6 +157,13 @@
|
||||
or path.startswith('/System/')
|
||||
or path.startswith('/Library/') )
|
||||
|
||||
+def grep_headers_for(function, headers):
|
||||
+ for header in headers:
|
||||
+ with open(header, 'r') as f:
|
||||
+ if function in f.read():
|
||||
+ return True
|
||||
+ return False
|
||||
+
|
||||
def find_file(filename, std_dirs, paths):
|
||||
"""Searches for the directory where a given file is located,
|
||||
and returns a possibly-empty list of additional directories, or None
|
||||
@@ -1972,7 +1986,11 @@
|
||||
return True
|
||||
|
||||
def detect_ctypes(self, inc_dirs, lib_dirs):
|
||||
- self.use_system_libffi = False
|
||||
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
|
||||
+ self.use_system_libffi = True
|
||||
+ else:
|
||||
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
|
||||
+
|
||||
include_dirs = []
|
||||
extra_compile_args = []
|
||||
extra_link_args = []
|
||||
@@ -2016,32 +2034,48 @@
|
||||
ext_test = Extension('_ctypes_test',
|
||||
sources=['_ctypes/_ctypes_test.c'],
|
||||
libraries=['m'])
|
||||
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
|
||||
+ ffi_lib = None
|
||||
+
|
||||
self.extensions.extend([ext, ext_test])
|
||||
|
||||
if host_platform == 'darwin':
|
||||
- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
|
||||
+ if not self.use_system_libffi:
|
||||
return
|
||||
- # OS X 10.5 comes with libffi.dylib; the include files are
|
||||
- # in /usr/include/ffi
|
||||
- inc_dirs.append('/usr/include/ffi')
|
||||
-
|
||||
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
|
||||
- if not ffi_inc or ffi_inc[0] == '':
|
||||
- ffi_inc = find_file('ffi.h', [], inc_dirs)
|
||||
- if ffi_inc is not None:
|
||||
- ffi_h = ffi_inc[0] + '/ffi.h'
|
||||
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
|
||||
+ if os.path.exists(ffi_in_sdk):
|
||||
+ ffi_inc = ffi_in_sdk
|
||||
+ ffi_lib = 'ffi'
|
||||
+ else:
|
||||
+ # OS X 10.5 comes with libffi.dylib; the include files are
|
||||
+ # in /usr/include/ffi
|
||||
+ ffi_inc_dirs.append('/usr/include/ffi')
|
||||
+
|
||||
+ if not ffi_inc:
|
||||
+ found = find_file('ffi.h', [], ffi_inc_dirs)
|
||||
+ if found:
|
||||
+ ffi_inc = found[0]
|
||||
+ if ffi_inc:
|
||||
+ ffi_h = ffi_inc + '/ffi.h'
|
||||
if not os.path.exists(ffi_h):
|
||||
ffi_inc = None
|
||||
print('Header file {} does not exist'.format(ffi_h))
|
||||
- ffi_lib = None
|
||||
- if ffi_inc is not None:
|
||||
+ if ffi_lib is None and ffi_inc:
|
||||
for lib_name in ('ffi', 'ffi_pic'):
|
||||
if (self.compiler.find_library_file(lib_dirs, lib_name)):
|
||||
ffi_lib = lib_name
|
||||
break
|
||||
|
||||
if ffi_inc and ffi_lib:
|
||||
- ext.include_dirs.extend(ffi_inc)
|
||||
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
|
||||
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
|
||||
+ try:
|
||||
+ sources.remove('_ctypes/malloc_closure.c')
|
||||
+ except ValueError:
|
||||
+ pass
|
||||
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
|
||||
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
|
||||
+ ext.include_dirs.append(ffi_inc)
|
||||
ext.libraries.append(ffi_lib)
|
||||
self.use_system_libffi = True
|
||||
|
@@ -1,14 +0,0 @@
|
||||
Only in external_sqlite_orig: config.log
|
||||
diff -ru external_sqlite_orig/config.sub external_sqlite/config.sub
|
||||
--- external_sqlite_orig/config.sub 2020-07-10 14:06:42.000000000 +0200
|
||||
+++ external_sqlite/config.sub 2020-07-10 14:10:24.000000000 +0200
|
||||
@@ -314,6 +314,7 @@
|
||||
# Recognize the basic CPU types with company name.
|
||||
580-* \
|
||||
| a29k-* \
|
||||
+ | aarch64-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
Only in external_sqlite: mksourceid
|
||||
Only in external_sqlite: sqlite3session.h
|
@@ -1,18 +0,0 @@
|
||||
--- config.sub
|
||||
+++ config.sub
|
||||
@@ -226,6 +226,7 @@
|
||||
# Some are omitted here because they have special meanings below.
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
+ | aarch64 \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
@@ -286,6 +287,7 @@
|
||||
# Recognize the basic CPU types with company name.
|
||||
580-* \
|
||||
| a29k-* \
|
||||
+ | aarch64-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
@@ -1,3 +1,14 @@
|
||||
diff -x .git -ur usd.orig/cmake/defaults/Options.cmake external_usd/cmake/defaults/Options.cmake
|
||||
--- usd.orig/cmake/defaults/Options.cmake 2019-10-24 22:39:53.000000000 +0200
|
||||
+++ external_usd/cmake/defaults/Options.cmake 2019-11-28 13:00:33.197957712 +0100
|
||||
@@ -25,6 +25,7 @@
|
||||
option(PXR_VALIDATE_GENERATED_CODE "Validate script generated code" OFF)
|
||||
option(PXR_HEADLESS_TEST_MODE "Disallow GUI based tests, useful for running under headless CI systems." OFF)
|
||||
option(PXR_BUILD_TESTS "Build tests" ON)
|
||||
+option(PXR_BUILD_USD_TOOLS "Build commandline tools" ON)
|
||||
option(PXR_BUILD_IMAGING "Build imaging components" ON)
|
||||
option(PXR_BUILD_EMBREE_PLUGIN "Build embree imaging plugin" OFF)
|
||||
option(PXR_BUILD_OPENIMAGEIO_PLUGIN "Build OpenImageIO plugin" OFF)
|
||||
diff -x .git -ur usd.orig/cmake/defaults/Packages.cmake external_usd/cmake/defaults/Packages.cmake
|
||||
--- usd.orig/cmake/defaults/Packages.cmake 2019-10-24 22:39:53.000000000 +0200
|
||||
+++ external_usd/cmake/defaults/Packages.cmake 2019-11-28 13:00:33.185957483 +0100
|
||||
@@ -10,11 +21,11 @@ diff -x .git -ur usd.orig/cmake/defaults/Packages.cmake external_usd/cmake/defau
|
||||
add_definitions(${TBB_DEFINITIONS})
|
||||
|
||||
# --math
|
||||
diff -x .git -ur usd.orig/pxr/base/plug/initConfig.cpp external_usd/pxr/base/plug/initConfig.cpp
|
||||
--- usd.orig/pxr/base/plug/initConfig.cpp.orig 2020-06-12 17:20:07.478199779 +0200
|
||||
+++ external_usd/pxr/base/plug/initConfig.cpp 2020-06-12 17:25:28.648588552 +0200
|
||||
@@ -69,10 +69,40 @@
|
||||
|
||||
diff -x .git -ur usd.orig/pxr/base/lib/plug/initConfig.cpp external_usd/pxr/base/lib/plug/initConfig.cpp
|
||||
--- usd.orig/pxr/base/lib/plug/initConfig.cpp 2019-10-24 22:39:53.000000000 +0200
|
||||
+++ external_usd/pxr/base/lib/plug/initConfig.cpp 2019-12-11 11:00:37.643323127 +0100
|
||||
@@ -69,8 +69,38 @@
|
||||
|
||||
ARCH_CONSTRUCTOR(Plug_InitConfig, 2, void)
|
||||
{
|
||||
+ /* The contents of this constructor have been moved to usd_initialise_plugin_path(...) */
|
||||
@@ -39,9 +50,7 @@ diff -x .git -ur usd.orig/pxr/base/plug/initConfig.cpp external_usd/pxr/base/plu
|
||||
+usd_initialise_plugin_path(const char *datafiles_usd_path)
|
||||
+{
|
||||
std::vector<std::string> result;
|
||||
|
||||
std::vector<std::string> debugMessages;
|
||||
|
||||
|
||||
+ // Add Blender-specific paths. They MUST end in a slash, or symlinks will not be treated as directory.
|
||||
+ if (datafiles_usd_path != NULL && datafiles_usd_path[0] != '\0') {
|
||||
+ std::string datafiles_usd_path_str(datafiles_usd_path);
|
||||
@@ -51,14 +60,14 @@ diff -x .git -ur usd.orig/pxr/base/plug/initConfig.cpp external_usd/pxr/base/plu
|
||||
+ result.push_back(datafiles_usd_path_str);
|
||||
+ }
|
||||
+
|
||||
// Determine the absolute path to the Plug shared library. Any relative
|
||||
// paths specified in the plugin search path will be anchored to this
|
||||
// directory, to allow for relocatability. Note that this can fail when pxr
|
||||
@@ -114,9 +144,24 @@
|
||||
_AppendPathList(&result, installLocation, binaryPath);
|
||||
// Determine the absolute path to the Plug shared library.
|
||||
// Any relative paths specified in the plugin search path will be
|
||||
// anchored to this directory, to allow for relocatability.
|
||||
@@ -94,9 +124,24 @@
|
||||
_AppendPathList(&result, installLocation, sharedLibPath);
|
||||
#endif // PXR_INSTALL_LOCATION
|
||||
|
||||
- Plug_SetPaths(result, debugMessages);
|
||||
|
||||
- Plug_SetPaths(result);
|
||||
-}
|
||||
+ if (!TfGetenv("PXR_PATH_DEBUG").empty()) {
|
||||
+ printf("USD Plugin paths: (%zu in total):\n", result.size());
|
||||
@@ -66,10 +75,10 @@ diff -x .git -ur usd.orig/pxr/base/plug/initConfig.cpp external_usd/pxr/base/plu
|
||||
+ printf(" %s\n", path.c_str());
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ Plug_SetPaths(result, debugMessages);
|
||||
|
||||
+ Plug_SetPaths(result);
|
||||
}
|
||||
|
||||
|
||||
PXR_NAMESPACE_CLOSE_SCOPE
|
||||
+
|
||||
+/* Workaround to make it possible to pass a path at runtime to USD. */
|
||||
@@ -81,6 +90,37 @@ diff -x .git -ur usd.orig/pxr/base/plug/initConfig.cpp external_usd/pxr/base/plu
|
||||
+ PXR_NS::usd_initialise_plugin_path(datafiles_usd_path);
|
||||
+}
|
||||
+}
|
||||
diff -x .git -ur usd.orig/pxr/usd/CMakeLists.txt external_usd/pxr/usd/CMakeLists.txt
|
||||
--- usd.orig/pxr/usd/CMakeLists.txt 2019-10-24 22:39:53.000000000 +0200
|
||||
+++ external_usd/pxr/usd/CMakeLists.txt 2019-11-28 13:00:33.197957712 +0100
|
||||
@@ -1,6 +1,5 @@
|
||||
set(DIRS
|
||||
lib
|
||||
- bin
|
||||
plugin
|
||||
)
|
||||
|
||||
@@ -8,3 +7,8 @@
|
||||
add_subdirectory(${d})
|
||||
endforeach()
|
||||
|
||||
+if (PXR_BUILD_USD_TOOLS)
|
||||
+ add_subdirectory(bin)
|
||||
+else()
|
||||
+ message(STATUS "Skipping commandline tools because PXR_BUILD_USD_TOOLS=OFF")
|
||||
+endif()
|
||||
diff -Naur external_usd_orig/pxr/base/lib/tf/preprocessorUtils.h external_usd/pxr/base/lib/tf/preprocessorUtils.h
|
||||
--- external_usd_orig/pxr/base/lib/tf/preprocessorUtils.h 2019-10-24 14:39:53 -0600
|
||||
+++ external_usd/pxr/base/lib/tf/preprocessorUtils.h 2020-01-14 09:30:18 -0700
|
||||
@@ -189,7 +189,7 @@
|
||||
/// Exapnds to 1 if the argument is a tuple, and 0 otherwise.
|
||||
/// \ingroup group_tf_Preprocessor
|
||||
/// \hideinitializer
|
||||
-#if defined(ARCH_OS_WINDOWS)
|
||||
+#if defined(ARCH_COMPILER_MSVC)
|
||||
#define TF_PP_IS_TUPLE(sequence) \
|
||||
BOOST_VMD_IS_TUPLE(sequence)
|
||||
#else
|
||||
diff -Naur external_usd_base/cmake/macros/Public.cmake external_usd/cmake/macros/Public.cmake
|
||||
--- external_usd_base/cmake/macros/Public.cmake 2019-10-24 14:39:53 -0600
|
||||
+++ external_usd/cmake/macros/Public.cmake 2020-01-11 13:33:29 -0700
|
||||
@@ -97,36 +137,3 @@ diff -Naur external_usd_base/cmake/macros/Public.cmake external_usd/cmake/macros
|
||||
endforeach()
|
||||
foreach(lib ${PXR_OBJECT_LIBS})
|
||||
set(objects "${objects};\$<TARGET_OBJECTS:${lib}>")
|
||||
|
||||
diff --git a/pxr/base/arch/align.h b/pxr/base/arch/align.h
|
||||
index f3cabf4..ebc8a69 100644
|
||||
--- a/pxr/base/arch/align.h
|
||||
+++ b/pxr/base/arch/align.h
|
||||
@@ -77,7 +77,11 @@ ArchAlignMemory(void *base)
|
||||
/// The size of a CPU cache line on the current processor architecture in bytes.
|
||||
///
|
||||
/// \hideinitializer
|
||||
+#if defined(ARCH_OS_DARWIN) && defined(ARCH_CPU_ARM)
|
||||
+#define ARCH_CACHE_LINE_SIZE 128
|
||||
+#else
|
||||
#define ARCH_CACHE_LINE_SIZE 64
|
||||
+#endif
|
||||
|
||||
///@}
|
||||
|
||||
diff --git a/pxr/base/arch/math.h b/pxr/base/arch/math.h
|
||||
index 3e66c37..64a052c 100644
|
||||
--- a/pxr/base/arch/math.h
|
||||
+++ b/pxr/base/arch/math.h
|
||||
@@ -42,7 +42,7 @@ PXR_NAMESPACE_OPEN_SCOPE
|
||||
/// \addtogroup group_arch_Math
|
||||
///@{
|
||||
|
||||
-#if defined (ARCH_CPU_INTEL) || defined(doxygen)
|
||||
+#if defined (ARCH_CPU_INTEL) || defined(ARCH_CPU_ARM) || defined(doxygen)
|
||||
|
||||
/// This is the smallest value e such that 1+e^2 == 1, using floats.
|
||||
/// True for all IEEE754 chipsets.
|
||||
|
||||
|
||||
|
||||
|
@@ -8,7 +8,7 @@ Code signing is done as part of INSTALL target, which makes it possible to sign
|
||||
files which are aimed into a bundle and coming from a non-signed source (such as
|
||||
libraries SVN).
|
||||
|
||||
This is achieved by specifying `worker_codesign.cmake` as a post-install script
|
||||
This is achieved by specifying `slave_codesign.cmake` as a post-install script
|
||||
run by CMake. This CMake script simply involves an utility script written in
|
||||
Python which takes care of an actual signing.
|
||||
|
||||
|
@@ -33,16 +33,15 @@ def is_tool(name):
|
||||
return which(name) is not None
|
||||
|
||||
class Builder:
|
||||
def __init__(self, name, branch, codesign):
|
||||
def __init__(self, name, branch):
|
||||
self.name = name
|
||||
self.branch = branch
|
||||
self.is_release_branch = re.match("^blender-v(.*)-release$", branch) is not None
|
||||
self.codesign = codesign
|
||||
|
||||
# Buildbot runs from build/ directory
|
||||
self.blender_dir = os.path.abspath(os.path.join('..', 'blender.git'))
|
||||
self.build_dir = os.path.abspath(os.path.join('..', 'build'))
|
||||
self.install_dir = os.path.abspath(os.path.join('..', 'install'))
|
||||
self.build_dir = os.path.abspath(os.path.join('..', 'build', name))
|
||||
self.install_dir = os.path.abspath(os.path.join('..', 'install', name))
|
||||
self.upload_dir = os.path.abspath(os.path.join('..', 'install'))
|
||||
|
||||
# Detect platform
|
||||
@@ -52,7 +51,7 @@ class Builder:
|
||||
elif name.startswith('linux'):
|
||||
self.platform = 'linux'
|
||||
if is_tool('scl'):
|
||||
self.command_prefix = ['scl', 'enable', 'devtoolset-9', '--']
|
||||
self.command_prefix = ['scl', 'enable', 'devtoolset-6', '--']
|
||||
else:
|
||||
self.command_prefix = []
|
||||
elif name.startswith('win'):
|
||||
@@ -68,9 +67,8 @@ def create_builder_from_arguments():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('builder_name')
|
||||
parser.add_argument('branch', default='master', nargs='?')
|
||||
parser.add_argument("--codesign", action="store_true")
|
||||
args = parser.parse_args()
|
||||
return Builder(args.builder_name, args.branch, args.codesign)
|
||||
return Builder(args.builder_name, args.branch)
|
||||
|
||||
|
||||
class VersionInfo:
|
||||
|
@@ -48,7 +48,6 @@ import shutil
|
||||
import subprocess
|
||||
import time
|
||||
import tarfile
|
||||
import uuid
|
||||
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
@@ -122,10 +121,21 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
# Consider this an input of the code signing server.
|
||||
unsigned_storage_dir: Path
|
||||
|
||||
# Information about archive which contains files which are to be signed.
|
||||
#
|
||||
# This archive is created by the buildbot worked and acts as an input for
|
||||
# the code signing server.
|
||||
unsigned_archive_info: ArchiveWithIndicator
|
||||
|
||||
# Storage where signed files are stored.
|
||||
# Consider this an output of the code signer server.
|
||||
signed_storage_dir: Path
|
||||
|
||||
# Information about archive which contains signed files.
|
||||
#
|
||||
# This archive is created by the code signing server.
|
||||
signed_archive_info: ArchiveWithIndicator
|
||||
|
||||
# Platform the code is currently executing on.
|
||||
platform: util.Platform
|
||||
|
||||
@@ -136,44 +146,50 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
|
||||
# Unsigned (signing server input) configuration.
|
||||
self.unsigned_storage_dir = absolute_shared_storage_dir / 'unsigned'
|
||||
self.unsigned_archive_info = ArchiveWithIndicator(
|
||||
self.unsigned_storage_dir, 'unsigned_files.tar', 'ready.stamp')
|
||||
|
||||
# Signed (signing server output) configuration.
|
||||
self.signed_storage_dir = absolute_shared_storage_dir / 'signed'
|
||||
self.signed_archive_info = ArchiveWithIndicator(
|
||||
self.signed_storage_dir, 'signed_files.tar', 'ready.stamp')
|
||||
|
||||
self.platform = util.get_current_platform()
|
||||
|
||||
"""
|
||||
General note on cleanup environment functions.
|
||||
|
||||
It is expected that there is only one instance of the code signer server
|
||||
running for a given input/output directory, and that it serves a single
|
||||
buildbot worker.
|
||||
By its nature, a buildbot worker only produces one build at a time and
|
||||
never performs concurrent builds.
|
||||
This leads to a conclusion that when starting in a clean environment
|
||||
there shouldn't be any archives remaining from a previous build.
|
||||
|
||||
However, it is possible to have various failure scenarios which might
|
||||
leave the environment in a non-clean state:
|
||||
|
||||
- Network hiccup which makes buildbot worker to stop current build
|
||||
and re-start it after connection to server is re-established.
|
||||
|
||||
Note, this could also happen during buildbot server maintenance.
|
||||
|
||||
- Signing server might get restarted due to updates or other reasons.
|
||||
|
||||
Requiring manual interaction in such cases is not something good to
|
||||
require, so here we simply assume that the system is used the way it is
|
||||
intended to and restore environment to a prestine clean state.
|
||||
"""
|
||||
|
||||
def cleanup_environment_for_builder(self) -> None:
|
||||
# TODO(sergey): Revisit need of cleaning up the existing files.
|
||||
# In practice it wasn't so helpful, and with multiple clients
|
||||
# talking to the same server it becomes even mor etricky.
|
||||
pass
|
||||
self.unsigned_archive_info.clean()
|
||||
self.signed_archive_info.clean()
|
||||
|
||||
def cleanup_environment_for_signing_server(self) -> None:
|
||||
# TODO(sergey): Revisit need of cleaning up the existing files.
|
||||
# In practice it wasn't so helpful, and with multiple clients
|
||||
# talking to the same server it becomes even mor etricky.
|
||||
pass
|
||||
|
||||
def generate_request_id(self) -> str:
|
||||
"""
|
||||
Generate an unique identifier for code signing request.
|
||||
"""
|
||||
return str(uuid.uuid4())
|
||||
|
||||
def archive_info_for_request_id(
|
||||
self, path: Path, request_id: str) -> ArchiveWithIndicator:
|
||||
return ArchiveWithIndicator(
|
||||
path, f'{request_id}.tar', f'{request_id}.ready')
|
||||
|
||||
def signed_archive_info_for_request_id(
|
||||
self, request_id: str) -> ArchiveWithIndicator:
|
||||
return self.archive_info_for_request_id(
|
||||
self.signed_storage_dir, request_id)
|
||||
|
||||
def unsigned_archive_info_for_request_id(
|
||||
self, request_id: str) -> ArchiveWithIndicator:
|
||||
return self.archive_info_for_request_id(
|
||||
self.unsigned_storage_dir, request_id)
|
||||
# Don't clear the requested to-be-signed archive since we might be
|
||||
# restarting signing machine while the buildbot is busy.
|
||||
self.signed_archive_info.clean()
|
||||
|
||||
############################################################################
|
||||
# Buildbot worker side helpers.
|
||||
@@ -216,7 +232,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
if self.check_file_is_to_be_signed(file)]
|
||||
return files_to_be_signed
|
||||
|
||||
def wait_for_signed_archive_or_die(self, request_id) -> None:
|
||||
def wait_for_signed_archive_or_die(self) -> None:
|
||||
"""
|
||||
Wait until archive with signed files is available.
|
||||
|
||||
@@ -224,19 +240,13 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
is still no responce from the signing server the application will exit
|
||||
with a non-zero exit code.
|
||||
"""
|
||||
|
||||
signed_archive_info = self.signed_archive_info_for_request_id(
|
||||
request_id)
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
|
||||
timeout_in_seconds = self.config.TIMEOUT_IN_SECONDS
|
||||
time_start = time.monotonic()
|
||||
while not signed_archive_info.is_ready():
|
||||
while not self.signed_archive_info.is_ready():
|
||||
time.sleep(1)
|
||||
time_slept_in_seconds = time.monotonic() - time_start
|
||||
if time_slept_in_seconds > timeout_in_seconds:
|
||||
unsigned_archive_info.clean()
|
||||
self.unsigned_archive_info.clean()
|
||||
raise SystemExit("Signing server didn't finish signing in "
|
||||
f"{timeout_in_seconds} seconds, dying :(")
|
||||
|
||||
@@ -293,19 +303,13 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
return
|
||||
logger_builder.info('Found %d files to sign.', len(files))
|
||||
|
||||
request_id = self.generate_request_id()
|
||||
signed_archive_info = self.signed_archive_info_for_request_id(
|
||||
request_id)
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
|
||||
pack_files(files=files,
|
||||
archive_filepath=unsigned_archive_info.archive_filepath)
|
||||
unsigned_archive_info.tag_ready()
|
||||
archive_filepath=self.unsigned_archive_info.archive_filepath)
|
||||
self.unsigned_archive_info.tag_ready()
|
||||
|
||||
# Wait for the signing server to finish signing.
|
||||
logger_builder.info('Waiting signing server to sign the files...')
|
||||
self.wait_for_signed_archive_or_die(request_id)
|
||||
self.wait_for_signed_archive_or_die()
|
||||
|
||||
# Extract signed files from archive and move files to final location.
|
||||
with TemporaryDirectory(prefix='blender-buildbot-') as temp_dir_str:
|
||||
@@ -313,7 +317,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
|
||||
logger_builder.info('Extracting signed files from archive...')
|
||||
extract_files(
|
||||
archive_filepath=signed_archive_info.archive_filepath,
|
||||
archive_filepath=self.signed_archive_info.archive_filepath,
|
||||
extraction_dir=unpacked_signed_files_dir)
|
||||
|
||||
destination_dir = path
|
||||
@@ -323,44 +327,19 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
unpacked_signed_files_dir, destination_dir)
|
||||
|
||||
logger_builder.info('Removing archive with signed files...')
|
||||
signed_archive_info.clean()
|
||||
self.signed_archive_info.clean()
|
||||
|
||||
############################################################################
|
||||
# Signing server side helpers.
|
||||
|
||||
def wait_for_sign_request(self) -> str:
|
||||
def wait_for_sign_request(self) -> None:
|
||||
"""
|
||||
Wait for the buildbot to request signing of an archive.
|
||||
|
||||
Returns an identifier of signing request.
|
||||
"""
|
||||
|
||||
# TOOD(sergey): Support graceful shutdown on Ctrl-C.
|
||||
|
||||
logger_server.info(
|
||||
f'Waiting for a request directory {self.unsigned_storage_dir} to appear.')
|
||||
while not self.unsigned_storage_dir.exists():
|
||||
while not self.unsigned_archive_info.is_ready():
|
||||
time.sleep(1)
|
||||
|
||||
logger_server.info(
|
||||
'Waiting for a READY indicator of any signing request.')
|
||||
request_id = None
|
||||
while request_id is None:
|
||||
for file in self.unsigned_storage_dir.iterdir():
|
||||
if file.suffix != '.ready':
|
||||
continue
|
||||
request_id = file.stem
|
||||
logger_server.info(f'Found READY for request ID {request_id}.')
|
||||
if request_id is None:
|
||||
time.sleep(1)
|
||||
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
while not unsigned_archive_info.is_ready():
|
||||
time.sleep(1)
|
||||
|
||||
return request_id
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign_all_files(self, files: List[AbsoluteAndRelativeFileName]) -> None:
|
||||
"""
|
||||
@@ -369,7 +348,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
NOTE: Signing should happen in-place.
|
||||
"""
|
||||
|
||||
def run_signing_pipeline(self, request_id: str):
|
||||
def run_signing_pipeline(self):
|
||||
"""
|
||||
Run the full signing pipeline starting from the point when buildbot
|
||||
worker have requested signing.
|
||||
@@ -381,14 +360,9 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
with TemporaryDirectory(prefix='blender-codesign-') as temp_dir_str:
|
||||
temp_dir = Path(temp_dir_str)
|
||||
|
||||
signed_archive_info = self.signed_archive_info_for_request_id(
|
||||
request_id)
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
|
||||
logger_server.info('Extracting unsigned files from archive...')
|
||||
extract_files(
|
||||
archive_filepath=unsigned_archive_info.archive_filepath,
|
||||
archive_filepath=self.unsigned_archive_info.archive_filepath,
|
||||
extraction_dir=temp_dir)
|
||||
|
||||
logger_server.info('Collecting all files which needs signing...')
|
||||
@@ -400,11 +374,11 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
|
||||
logger_server.info('Packing signed files...')
|
||||
pack_files(files=files,
|
||||
archive_filepath=signed_archive_info.archive_filepath)
|
||||
signed_archive_info.tag_ready()
|
||||
archive_filepath=self.signed_archive_info.archive_filepath)
|
||||
self.signed_archive_info.tag_ready()
|
||||
|
||||
logger_server.info('Removing signing request...')
|
||||
unsigned_archive_info.clean()
|
||||
self.unsigned_archive_info.clean()
|
||||
|
||||
logger_server.info('Signing is complete.')
|
||||
|
||||
@@ -415,11 +389,11 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
while True:
|
||||
logger_server.info('Waiting for the signing request in %s...',
|
||||
self.unsigned_storage_dir)
|
||||
request_id = self.wait_for_sign_request()
|
||||
self.wait_for_sign_request()
|
||||
|
||||
logger_server.info(
|
||||
f'Beging signign procedure for request ID {request_id}.')
|
||||
self.run_signing_pipeline(request_id)
|
||||
'Got signing request, beging signign procedure.')
|
||||
self.run_signing_pipeline()
|
||||
|
||||
############################################################################
|
||||
# Command executing.
|
||||
|
@@ -30,7 +30,7 @@ from tempfile import TemporaryDirectory, NamedTemporaryFile
|
||||
from typing import List
|
||||
|
||||
BUILDBOT_DIRECTORY = Path(__file__).absolute().parent
|
||||
CODESIGN_SCRIPT = BUILDBOT_DIRECTORY / 'worker_codesign.py'
|
||||
CODESIGN_SCRIPT = BUILDBOT_DIRECTORY / 'slave_codesign.py'
|
||||
BLENDER_GIT_ROOT_DIRECTORY = BUILDBOT_DIRECTORY.parent.parent
|
||||
DARWIN_DIRECTORY = BLENDER_GIT_ROOT_DIRECTORY / 'release' / 'darwin'
|
||||
|
||||
@@ -82,10 +82,6 @@ def create_argument_parser():
|
||||
type=Path,
|
||||
help="Optional path to applescript to set up folder looks of DMG."
|
||||
"If not provided default Blender's one is used.")
|
||||
parser.add_argument(
|
||||
'--codesign',
|
||||
action="store_true",
|
||||
help="Code sign and notarize DMG contents.")
|
||||
return parser
|
||||
|
||||
|
||||
@@ -399,8 +395,7 @@ def create_final_dmg(app_bundles: List[Path],
|
||||
dmg_filepath: Path,
|
||||
background_image_filepath: Path,
|
||||
volume_name: str,
|
||||
applescript: Path,
|
||||
codesign: bool) -> None:
|
||||
applescript: Path) -> None:
|
||||
"""
|
||||
Create DMG with all app bundles
|
||||
|
||||
@@ -426,8 +421,7 @@ def create_final_dmg(app_bundles: List[Path],
|
||||
#
|
||||
# This allows to recurs into the content of bundles without worrying about
|
||||
# possible interfereice of Application symlink.
|
||||
if codesign:
|
||||
codesign_app_bundles_in_dmg(mount_directory)
|
||||
codesign_app_bundles_in_dmg(mount_directory)
|
||||
|
||||
copy_background_if_needed(background_image_filepath, mount_directory)
|
||||
create_applications_link(mount_directory)
|
||||
@@ -440,8 +434,7 @@ def create_final_dmg(app_bundles: List[Path],
|
||||
compress_dmg(writable_dmg_filepath, dmg_filepath)
|
||||
writable_dmg_filepath.unlink()
|
||||
|
||||
if codesign:
|
||||
codesign_and_notarize_dmg(dmg_filepath)
|
||||
codesign_and_notarize_dmg(dmg_filepath)
|
||||
|
||||
|
||||
def ensure_dmg_extension(filepath: Path) -> Path:
|
||||
@@ -528,7 +521,6 @@ def main():
|
||||
source_dir = args.source_dir.absolute()
|
||||
background_image_filepath = get_background_image(args.background_image)
|
||||
applescript = get_applescript(args.applescript)
|
||||
codesign = args.codesign
|
||||
|
||||
app_bundles = collect_and_log_app_bundles(source_dir)
|
||||
if not app_bundles:
|
||||
@@ -543,8 +535,7 @@ def main():
|
||||
dmg_filepath,
|
||||
background_image_filepath,
|
||||
volume_name,
|
||||
applescript,
|
||||
codesign)
|
||||
applescript)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
@@ -33,7 +33,7 @@ else()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/worker_codesign.py"
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/slave_codesign.py"
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
RESULT_VARIABLE exit_code
|
@@ -24,8 +24,8 @@ import shutil
|
||||
import buildbot_utils
|
||||
|
||||
def get_cmake_options(builder):
|
||||
codesign_script = os.path.join(
|
||||
builder.blender_dir, 'build_files', 'buildbot', 'worker_codesign.cmake')
|
||||
post_install_script = os.path.join(
|
||||
builder.blender_dir, 'build_files', 'buildbot', 'slave_codesign.cmake')
|
||||
|
||||
config_file = "build_files/cmake/config/blender_release.cmake"
|
||||
options = ['-DCMAKE_BUILD_TYPE:STRING=Release',
|
||||
@@ -35,9 +35,8 @@ def get_cmake_options(builder):
|
||||
options.append('-DCMAKE_OSX_ARCHITECTURES:STRING=x86_64')
|
||||
options.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9')
|
||||
elif builder.platform == 'win':
|
||||
options.extend(['-G', 'Visual Studio 16 2019', '-A', 'x64'])
|
||||
if builder.codesign:
|
||||
options.extend(['-DPOSTINSTALL_SCRIPT:PATH=' + codesign_script])
|
||||
options.extend(['-G', 'Visual Studio 15 2017 Win64'])
|
||||
options.extend(['-DPOSTINSTALL_SCRIPT:PATH=' + post_install_script])
|
||||
elif builder.platform == 'linux':
|
||||
config_file = "build_files/buildbot/config/blender_linux.cmake"
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# Runs on buildbot worker, creating a release package using the build
|
||||
# Runs on buildbot slave, creating a release package using the build
|
||||
# system and zipping it into buildbot_upload.zip. This is then uploaded
|
||||
# to the master in the next buildbot step.
|
||||
|
||||
@@ -110,15 +110,13 @@ def pack_mac(builder):
|
||||
|
||||
release_dir = os.path.join(builder.blender_dir, 'release', 'darwin')
|
||||
buildbot_dir = os.path.join(builder.blender_dir, 'build_files', 'buildbot')
|
||||
bundle_script = os.path.join(buildbot_dir, 'worker_bundle_dmg.py')
|
||||
bundle_script = os.path.join(buildbot_dir, 'slave_bundle_dmg.py')
|
||||
|
||||
command = [bundle_script]
|
||||
command += ['--dmg', package_filepath]
|
||||
if info.is_development_build:
|
||||
background_image = os.path.join(release_dir, 'buildbot', 'background.tif')
|
||||
command += ['--background-image', background_image]
|
||||
if builder.codesign:
|
||||
command += ['--codesign']
|
||||
command += [builder.install_dir]
|
||||
buildbot_utils.call(command)
|
||||
|
||||
@@ -152,8 +150,7 @@ def pack_win(builder):
|
||||
|
||||
package_filename = package_name + '.msi'
|
||||
package_filepath = os.path.join(builder.build_dir, package_filename)
|
||||
if builder.codesign:
|
||||
sign_file_or_directory(package_filepath)
|
||||
sign_file_or_directory(package_filepath)
|
||||
|
||||
package_files += [(package_filepath, package_filename)]
|
||||
|
37
build_files/buildbot/slave_rsync.py
Normal file
37
build_files/buildbot/slave_rsync.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# Runs on buildbot slave, rsync zip directly to buildbot server rather
|
||||
# than using upload which is much slower
|
||||
|
||||
import buildbot_utils
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
builder = buildbot_utils.create_builder_from_arguments()
|
||||
|
||||
# rsync, this assumes ssh keys are setup so no password is needed
|
||||
local_zip = "buildbot_upload.zip"
|
||||
remote_folder = "builder.blender.org:/data/buildbot-master/uploaded/"
|
||||
remote_zip = remote_folder + "buildbot_upload_" + builder.name + ".zip"
|
||||
|
||||
command = ["rsync", "-avz", local_zip, remote_zip]
|
||||
buildbot_utils.call(command)
|
@@ -1,104 +0,0 @@
|
||||
# - Find clang-tidy executable
|
||||
#
|
||||
# Find the native clang-tidy executable
|
||||
#
|
||||
# This module defines
|
||||
# CLANG_TIDY_EXECUTABLE, the ful lpath to clang-tidy executable
|
||||
#
|
||||
# CLANG_TIDY_VERSION, the full version of the clang-tidy in the
|
||||
# major,minor.patch format
|
||||
#
|
||||
# CLANG_TIDY_VERSION_MAJOR,
|
||||
# CLANG_TIDY_VERSION_MINOR,
|
||||
# CLANG_TIDY_VERSION_PATCH, individual components of the clang-tidy version.
|
||||
#
|
||||
# CLANG_TIDY_FOUND, If false, do not try to use Eigen3.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2020 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
|
||||
# If CLANG_TIDY_ROOT_DIR was defined in the environment, use it.
|
||||
if(NOT CLANG_TIDY_ROOT_DIR AND NOT $ENV{CLANG_TIDY_ROOT_DIR} STREQUAL "")
|
||||
set(CLANG_TIDY_ROOT_DIR $ENV{CLANG_TIDY_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
set(_clang_tidy_SEARCH_DIRS
|
||||
${CLANG_TIDY_ROOT_DIR}
|
||||
/usr/local/bin
|
||||
)
|
||||
|
||||
# TODO(sergey): Find more reliable way of finding the latest clang-tidy.
|
||||
find_program(CLANG_TIDY_EXECUTABLE
|
||||
NAMES
|
||||
clang-tidy-10
|
||||
clang-tidy-9
|
||||
clang-tidy-8
|
||||
clang-tidy-7
|
||||
clang-tidy
|
||||
HINTS
|
||||
${_clang_tidy_SEARCH_DIRS}
|
||||
)
|
||||
|
||||
if(CLANG_TIDY_EXECUTABLE)
|
||||
# Mark clang-tidy as found.
|
||||
set(CLANG_TIDY_FOUND TRUE)
|
||||
|
||||
# Setup fallback values.
|
||||
set(CLANG_TIDY_VERSION_MAJOR 0)
|
||||
set(CLANG_TIDY_VERSION_MINOR 0)
|
||||
set(CLANG_TIDY_VERSION_PATCH 0)
|
||||
|
||||
# Get version from the output.
|
||||
#
|
||||
# NOTE: Don't use name of the executable file since that only includes a
|
||||
# major version. Also, even the major version might be missing in the
|
||||
# executable name.
|
||||
execute_process(COMMAND ${CLANG_TIDY_EXECUTABLE} -version
|
||||
OUTPUT_VARIABLE CLANG_TIDY_VERSION_RAW
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Parse parts.
|
||||
if(CLANG_TIDY_VERSION_RAW MATCHES "LLVM version .*")
|
||||
# Strip the LLVM prefix and get list of individual version components.
|
||||
string(REGEX REPLACE
|
||||
".*LLVM version ([.0-9]+).*" "\\1"
|
||||
CLANG_SEMANTIC_VERSION "${CLANG_TIDY_VERSION_RAW}")
|
||||
string(REPLACE "." ";" CLANG_VERSION_PARTS "${CLANG_SEMANTIC_VERSION}")
|
||||
list(LENGTH CLANG_VERSION_PARTS NUM_CLANG_TIDY_VERSION_PARTS)
|
||||
|
||||
# Extract components into corresponding variables.
|
||||
if(NUM_CLANG_TIDY_VERSION_PARTS GREATER 0)
|
||||
list(GET CLANG_VERSION_PARTS 0 CLANG_TIDY_VERSION_MAJOR)
|
||||
endif()
|
||||
if(NUM_CLANG_TIDY_VERSION_PARTS GREATER 1)
|
||||
list(GET CLANG_VERSION_PARTS 1 CLANG_TIDY_VERSION_MINOR)
|
||||
endif()
|
||||
if(NUM_CLANG_TIDY_VERSION_PARTS GREATER 2)
|
||||
list(GET CLANG_VERSION_PARTS 2 CLANG_TIDY_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
# Unset temp variables.
|
||||
unset(NUM_CLANG_TIDY_VERSION_PARTS)
|
||||
unset(CLANG_SEMANTIC_VERSION)
|
||||
unset(CLANG_VERSION_PARTS)
|
||||
endif()
|
||||
|
||||
# Construct full semantic version.
|
||||
set(CLANG_TIDY_VERSION "${CLANG_TIDY_VERSION_MAJOR}.\
|
||||
${CLANG_TIDY_VERSION_MINOR}.\
|
||||
${CLANG_TIDY_VERSION_PATCH}")
|
||||
unset(CLANG_TIDY_VERSION_RAW)
|
||||
|
||||
message(STATUS "Found clang-tidy ${CLANG_TIDY_EXECUTABLE} (${CLANG_TIDY_VERSION})")
|
||||
else()
|
||||
set(CLANG_TIDY_FOUND FALSE)
|
||||
endif()
|
@@ -82,7 +82,7 @@ FIND_LIBRARY(EMBREE_LIBRARY
|
||||
# handle the QUIETLY and REQUIRED arguments and set EMBREE_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Embree DEFAULT_MSG
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(EMBREE DEFAULT_MSG
|
||||
_embree_LIBRARIES EMBREE_INCLUDE_DIR)
|
||||
|
||||
IF(EMBREE_FOUND)
|
||||
|
@@ -1,96 +0,0 @@
|
||||
# - Find GMP library
|
||||
# Find the native GMP includes and library
|
||||
# This module defines
|
||||
# GMP_INCLUDE_DIRS, where to find gmp.h, Set when
|
||||
# GMP_INCLUDE_DIR is found.
|
||||
# GMP_LIBRARIES, libraries to link against to use GMP.
|
||||
# GMP_ROOT_DIR, The base directory to search for GMP.
|
||||
# This can also be an environment variable.
|
||||
# GMP_FOUND, If false, do not try to use GMP.
|
||||
#
|
||||
# also defined, but not for general use are
|
||||
# GMP_LIBRARY, where to find the GMP library.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
|
||||
# If GMP_ROOT_DIR was defined in the environment, use it.
|
||||
IF(NOT GMP_ROOT_DIR AND NOT $ENV{GMP_ROOT_DIR} STREQUAL "")
|
||||
SET(GMP_ROOT_DIR $ENV{GMP_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_gmp_SEARCH_DIRS
|
||||
${GMP_ROOT_DIR}
|
||||
/opt/lib/gmp
|
||||
)
|
||||
|
||||
FIND_PATH(GMP_INCLUDE_DIR
|
||||
NAMES
|
||||
gmp.h
|
||||
HINTS
|
||||
${_gmp_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include/gmp
|
||||
)
|
||||
|
||||
FIND_PATH(GMPXX_INCLUDE_DIR
|
||||
NAMES
|
||||
gmpxx.h
|
||||
HINTS
|
||||
${_gmp_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include/gmp
|
||||
)
|
||||
|
||||
FIND_LIBRARY(GMP_LIBRARY
|
||||
NAMES
|
||||
gmp
|
||||
HINTS
|
||||
${_gmp_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
FIND_LIBRARY(GMPXX_LIBRARY
|
||||
NAMES
|
||||
gmpxx
|
||||
HINTS
|
||||
${_gmp_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
if(GMP_INCLUDE_DIR)
|
||||
SET(_version_regex "^#define[ \t]+__GNU_MP_VERSION[ \t]+\"([^\"]+)\".*")
|
||||
file(STRINGS "${GMP_INCLUDE_DIR}/gmp.h"
|
||||
GMP_VERSION REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||
GMP_VERSION "${GMP_VERSION}")
|
||||
unset(_version_regex)
|
||||
endif()
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP DEFAULT_MSG
|
||||
GMP_LIBRARY GMPXX_LIBRARY GMP_INCLUDE_DIR GMPXX_INCLUDE_DIR)
|
||||
|
||||
IF(GMP_FOUND)
|
||||
SET(GMP_LIBRARIES ${GMP_LIBRARY} ${GMPXX_LIBRARY})
|
||||
SET(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR} ${GMPXX_INCLUDE_DIR})
|
||||
ENDIF(GMP_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
GMP_INCLUDE_DIR
|
||||
GMP_LIBRARY
|
||||
GMPXX_INCLUDE_DIR
|
||||
GMPXX_LIBRARY
|
||||
)
|
65
build_files/cmake/Modules/FindHDF5.cmake
Normal file
65
build_files/cmake/Modules/FindHDF5.cmake
Normal file
@@ -0,0 +1,65 @@
|
||||
# - Find HDF5 library
|
||||
# Find the native HDF5 includes and libraries
|
||||
# This module defines
|
||||
# HDF5_INCLUDE_DIRS, where to find hdf5.h, Set when HDF5_INCLUDE_DIR is found.
|
||||
# HDF5_LIBRARIES, libraries to link against to use HDF5.
|
||||
# HDF5_ROOT_DIR, The base directory to search for HDF5.
|
||||
# This can also be an environment variable.
|
||||
# HDF5_FOUND, If false, do not try to use HDF5.
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2016 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
|
||||
# If HDF5_ROOT_DIR was defined in the environment, use it.
|
||||
IF(NOT HDF5_ROOT_DIR AND NOT $ENV{HDF5_ROOT_DIR} STREQUAL "")
|
||||
SET(HDF5_ROOT_DIR $ENV{HDF5_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_hdf5_SEARCH_DIRS
|
||||
${HDF5_ROOT_DIR}
|
||||
/opt/lib/hdf5
|
||||
)
|
||||
|
||||
FIND_LIBRARY(HDF5_LIBRARY
|
||||
NAMES
|
||||
hdf5
|
||||
HINTS
|
||||
${_hdf5_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
FIND_PATH(HDF5_INCLUDE_DIR
|
||||
NAMES
|
||||
hdf5.h
|
||||
HINTS
|
||||
${_hdf5_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set HDF5_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(HDF5 DEFAULT_MSG HDF5_LIBRARY HDF5_INCLUDE_DIR)
|
||||
|
||||
IF(HDF5_FOUND)
|
||||
SET(HDF5_LIBRARIES ${HDF5_LIBRARY})
|
||||
SET(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR})
|
||||
ENDIF(HDF5_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
HDF5_INCLUDE_DIR
|
||||
HDF5_LIBRARY
|
||||
)
|
||||
|
||||
UNSET(_hdf5_SEARCH_DIRS)
|
@@ -48,14 +48,7 @@ SET(_openimagedenoise_FIND_COMPONENTS
|
||||
# These are needed when building statically
|
||||
SET(_openimagedenoise_FIND_STATIC_COMPONENTS
|
||||
common
|
||||
|
||||
# These additional library names change between versions, we list all of them
|
||||
# so builds work with multiple versions. Missing libraries are skipped.
|
||||
dnnl_cpu
|
||||
dnnl_common
|
||||
dnnl_cpu # Second time because of circular dependency
|
||||
mkldnn
|
||||
dnnl
|
||||
)
|
||||
|
||||
SET(_openimagedenoise_LIBRARIES)
|
||||
|
@@ -1,550 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
GoogleTest
|
||||
----------
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
This module defines functions to help use the Google Test infrastructure. Two
|
||||
mechanisms for adding tests are provided. :command:`gtest_add_tests` has been
|
||||
around for some time, originally via ``find_package(GTest)``.
|
||||
:command:`gtest_discover_tests` was introduced in CMake 3.10.
|
||||
|
||||
The (older) :command:`gtest_add_tests` scans source files to identify tests.
|
||||
This is usually effective, with some caveats, including in cross-compiling
|
||||
environments, and makes setting additional properties on tests more convenient.
|
||||
However, its handling of parameterized tests is less comprehensive, and it
|
||||
requires re-running CMake to detect changes to the list of tests.
|
||||
|
||||
The (newer) :command:`gtest_discover_tests` discovers tests by asking the
|
||||
compiled test executable to enumerate its tests. This is more robust and
|
||||
provides better handling of parameterized tests, and does not require CMake
|
||||
to be re-run when tests change. However, it may not work in a cross-compiling
|
||||
environment, and setting test properties is less convenient.
|
||||
|
||||
More details can be found in the documentation of the respective functions.
|
||||
|
||||
Both commands are intended to replace use of :command:`add_test` to register
|
||||
tests, and will create a separate CTest test for each Google Test test case.
|
||||
Note that this is in some cases less efficient, as common set-up and tear-down
|
||||
logic cannot be shared by multiple test cases executing in the same instance.
|
||||
However, it provides more fine-grained pass/fail information to CTest, which is
|
||||
usually considered as more beneficial. By default, the CTest test name is the
|
||||
same as the Google Test name (i.e. ``suite.testcase``); see also
|
||||
``TEST_PREFIX`` and ``TEST_SUFFIX``.
|
||||
|
||||
.. command:: gtest_add_tests
|
||||
|
||||
Automatically add tests with CTest by scanning source code for Google Test
|
||||
macros::
|
||||
|
||||
gtest_add_tests(TARGET target
|
||||
[SOURCES src1...]
|
||||
[EXTRA_ARGS arg1...]
|
||||
[WORKING_DIRECTORY dir]
|
||||
[TEST_PREFIX prefix]
|
||||
[TEST_SUFFIX suffix]
|
||||
[SKIP_DEPENDENCY]
|
||||
[TEST_LIST outVar]
|
||||
)
|
||||
|
||||
``gtest_add_tests`` attempts to identify tests by scanning source files.
|
||||
Although this is generally effective, it uses only a basic regular expression
|
||||
match, which can be defeated by atypical test declarations, and is unable to
|
||||
fully "split" parameterized tests. Additionally, it requires that CMake be
|
||||
re-run to discover any newly added, removed or renamed tests (by default,
|
||||
this means that CMake is re-run when any test source file is changed, but see
|
||||
``SKIP_DEPENDENCY``). However, it has the advantage of declaring tests at
|
||||
CMake time, which somewhat simplifies setting additional properties on tests,
|
||||
and always works in a cross-compiling environment.
|
||||
|
||||
The options are:
|
||||
|
||||
``TARGET target``
|
||||
Specifies the Google Test executable, which must be a known CMake
|
||||
executable target. CMake will substitute the location of the built
|
||||
executable when running the test.
|
||||
|
||||
``SOURCES src1...``
|
||||
When provided, only the listed files will be scanned for test cases. If
|
||||
this option is not given, the :prop_tgt:`SOURCES` property of the
|
||||
specified ``target`` will be used to obtain the list of sources.
|
||||
|
||||
``EXTRA_ARGS arg1...``
|
||||
Any extra arguments to pass on the command line to each test case.
|
||||
|
||||
``WORKING_DIRECTORY dir``
|
||||
Specifies the directory in which to run the discovered test cases. If this
|
||||
option is not provided, the current binary directory is used.
|
||||
|
||||
``TEST_PREFIX prefix``
|
||||
Specifies a ``prefix`` to be prepended to the name of each discovered test
|
||||
case. This can be useful when the same source files are being used in
|
||||
multiple calls to ``gtest_add_test()`` but with different ``EXTRA_ARGS``.
|
||||
|
||||
``TEST_SUFFIX suffix``
|
||||
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
|
||||
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
|
||||
be specified.
|
||||
|
||||
``SKIP_DEPENDENCY``
|
||||
Normally, the function creates a dependency which will cause CMake to be
|
||||
re-run if any of the sources being scanned are changed. This is to ensure
|
||||
that the list of discovered tests is updated. If this behavior is not
|
||||
desired (as may be the case while actually writing the test cases), this
|
||||
option can be used to prevent the dependency from being added.
|
||||
|
||||
``TEST_LIST outVar``
|
||||
The variable named by ``outVar`` will be populated in the calling scope
|
||||
with the list of discovered test cases. This allows the caller to do
|
||||
things like manipulate test properties of the discovered tests.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
include(GoogleTest)
|
||||
add_executable(FooTest FooUnitTest.cxx)
|
||||
gtest_add_tests(TARGET FooTest
|
||||
TEST_SUFFIX .noArgs
|
||||
TEST_LIST noArgsTests
|
||||
)
|
||||
gtest_add_tests(TARGET FooTest
|
||||
EXTRA_ARGS --someArg someValue
|
||||
TEST_SUFFIX .withArgs
|
||||
TEST_LIST withArgsTests
|
||||
)
|
||||
set_tests_properties(${noArgsTests} PROPERTIES TIMEOUT 10)
|
||||
set_tests_properties(${withArgsTests} PROPERTIES TIMEOUT 20)
|
||||
|
||||
For backward compatibility, the following form is also supported::
|
||||
|
||||
gtest_add_tests(exe args files...)
|
||||
|
||||
``exe``
|
||||
The path to the test executable or the name of a CMake target.
|
||||
``args``
|
||||
A ;-list of extra arguments to be passed to executable. The entire
|
||||
list must be passed as a single argument. Enclose it in quotes,
|
||||
or pass ``""`` for no arguments.
|
||||
``files...``
|
||||
A list of source files to search for tests and test fixtures.
|
||||
Alternatively, use ``AUTO`` to specify that ``exe`` is the name
|
||||
of a CMake executable target whose sources should be scanned.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
include(GoogleTest)
|
||||
set(FooTestArgs --foo 1 --bar 2)
|
||||
add_executable(FooTest FooUnitTest.cxx)
|
||||
gtest_add_tests(FooTest "${FooTestArgs}" AUTO)
|
||||
|
||||
.. command:: gtest_discover_tests
|
||||
|
||||
Automatically add tests with CTest by querying the compiled test executable
|
||||
for available tests::
|
||||
|
||||
gtest_discover_tests(target
|
||||
[EXTRA_ARGS arg1...]
|
||||
[WORKING_DIRECTORY dir]
|
||||
[TEST_PREFIX prefix]
|
||||
[TEST_SUFFIX suffix]
|
||||
[NO_PRETTY_TYPES] [NO_PRETTY_VALUES]
|
||||
[PROPERTIES name1 value1...]
|
||||
[TEST_LIST var]
|
||||
[DISCOVERY_TIMEOUT seconds]
|
||||
[XML_OUTPUT_DIR dir]
|
||||
[DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
|
||||
)
|
||||
|
||||
``gtest_discover_tests()`` sets up a post-build command on the test executable
|
||||
that generates the list of tests by parsing the output from running the test
|
||||
with the ``--gtest_list_tests`` argument. Compared to the source parsing
|
||||
approach of :command:`gtest_add_tests`, this ensures that the full list of
|
||||
tests, including instantiations of parameterized tests, is obtained. Since
|
||||
test discovery occurs at build time, it is not necessary to re-run CMake when
|
||||
the list of tests changes.
|
||||
However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set
|
||||
in order to function in a cross-compiling environment.
|
||||
|
||||
Additionally, setting properties on tests is somewhat less convenient, since
|
||||
the tests are not available at CMake time. Additional test properties may be
|
||||
assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
|
||||
more fine-grained test control is needed, custom content may be provided
|
||||
through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
|
||||
directory property. The set of discovered tests is made accessible to such a
|
||||
script via the ``<target>_TESTS`` variable.
|
||||
|
||||
The options are:
|
||||
|
||||
``target``
|
||||
Specifies the Google Test executable, which must be a known CMake
|
||||
executable target. CMake will substitute the location of the built
|
||||
executable when running the test.
|
||||
|
||||
``EXTRA_ARGS arg1...``
|
||||
Any extra arguments to pass on the command line to each test case.
|
||||
|
||||
``WORKING_DIRECTORY dir``
|
||||
Specifies the directory in which to run the discovered test cases. If this
|
||||
option is not provided, the current binary directory is used.
|
||||
|
||||
``TEST_PREFIX prefix``
|
||||
Specifies a ``prefix`` to be prepended to the name of each discovered test
|
||||
case. This can be useful when the same test executable is being used in
|
||||
multiple calls to ``gtest_discover_tests()`` but with different
|
||||
``EXTRA_ARGS``.
|
||||
|
||||
``TEST_SUFFIX suffix``
|
||||
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
|
||||
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
|
||||
be specified.
|
||||
|
||||
``NO_PRETTY_TYPES``
|
||||
By default, the type index of type-parameterized tests is replaced by the
|
||||
actual type name in the CTest test name. If this behavior is undesirable
|
||||
(e.g. because the type names are unwieldy), this option will suppress this
|
||||
behavior.
|
||||
|
||||
``NO_PRETTY_VALUES``
|
||||
By default, the value index of value-parameterized tests is replaced by the
|
||||
actual value in the CTest test name. If this behavior is undesirable
|
||||
(e.g. because the value strings are unwieldy), this option will suppress
|
||||
this behavior.
|
||||
|
||||
``PROPERTIES name1 value1...``
|
||||
Specifies additional properties to be set on all tests discovered by this
|
||||
invocation of ``gtest_discover_tests()``.
|
||||
|
||||
``TEST_LIST var``
|
||||
Make the list of tests available in the variable ``var``, rather than the
|
||||
default ``<target>_TESTS``. This can be useful when the same test
|
||||
executable is being used in multiple calls to ``gtest_discover_tests()``.
|
||||
Note that this variable is only available in CTest.
|
||||
|
||||
``DISCOVERY_TIMEOUT num``
|
||||
Specifies how long (in seconds) CMake will wait for the test to enumerate
|
||||
available tests. If the test takes longer than this, discovery (and your
|
||||
build) will fail. Most test executables will enumerate their tests very
|
||||
quickly, but under some exceptional circumstances, a test may require a
|
||||
longer timeout. The default is 5. See also the ``TIMEOUT`` option of
|
||||
:command:`execute_process`.
|
||||
|
||||
.. note::
|
||||
|
||||
In CMake versions 3.10.1 and 3.10.2, this option was called ``TIMEOUT``.
|
||||
This clashed with the ``TIMEOUT`` test property, which is one of the
|
||||
common properties that would be set with the ``PROPERTIES`` keyword,
|
||||
usually leading to legal but unintended behavior. The keyword was
|
||||
changed to ``DISCOVERY_TIMEOUT`` in CMake 3.10.3 to address this
|
||||
problem. The ambiguous behavior of the ``TIMEOUT`` keyword in 3.10.1
|
||||
and 3.10.2 has not been preserved.
|
||||
|
||||
``XML_OUTPUT_DIR dir``
|
||||
If specified, the parameter is passed along with ``--gtest_output=xml:``
|
||||
to test executable. The actual file name is the same as the test target,
|
||||
including prefix and suffix. This should be used instead of
|
||||
``EXTRA_ARGS --gtest_output=xml`` to avoid race conditions writing the
|
||||
XML result output when using parallel test execution.
|
||||
|
||||
``DISCOVERY_MODE``
|
||||
Provides greater control over when ``gtest_discover_tests()`` performs test
|
||||
discovery. By default, ``POST_BUILD`` sets up a post-build command
|
||||
to perform test discovery at build time. In certain scenarios, like
|
||||
cross-compiling, this ``POST_BUILD`` behavior is not desirable.
|
||||
By contrast, ``PRE_TEST`` delays test discovery until just prior to test
|
||||
execution. This way test discovery occurs in the target environment
|
||||
where the test has a better chance at finding appropriate runtime
|
||||
dependencies.
|
||||
|
||||
``DISCOVERY_MODE`` defaults to the value of the
|
||||
``CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not
|
||||
passed when calling ``gtest_discover_tests()``. This provides a mechanism
|
||||
for globally selecting a preferred test discovery behavior without having
|
||||
to modify each call site.
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
# Save project's policies
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0057 NEW) # if IN_LIST
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function(gtest_add_tests)
|
||||
|
||||
if (ARGC LESS 1)
|
||||
message(FATAL_ERROR "No arguments supplied to gtest_add_tests()")
|
||||
endif()
|
||||
|
||||
set(options
|
||||
SKIP_DEPENDENCY
|
||||
)
|
||||
set(oneValueArgs
|
||||
TARGET
|
||||
WORKING_DIRECTORY
|
||||
TEST_PREFIX
|
||||
TEST_SUFFIX
|
||||
TEST_LIST
|
||||
)
|
||||
set(multiValueArgs
|
||||
SOURCES
|
||||
EXTRA_ARGS
|
||||
)
|
||||
set(allKeywords ${options} ${oneValueArgs} ${multiValueArgs})
|
||||
|
||||
unset(sources)
|
||||
if("${ARGV0}" IN_LIST allKeywords)
|
||||
cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
set(autoAddSources YES)
|
||||
else()
|
||||
# Non-keyword syntax, convert to keyword form
|
||||
if (ARGC LESS 3)
|
||||
message(FATAL_ERROR "gtest_add_tests() without keyword options requires at least 3 arguments")
|
||||
endif()
|
||||
set(ARGS_TARGET "${ARGV0}")
|
||||
set(ARGS_EXTRA_ARGS "${ARGV1}")
|
||||
if(NOT "${ARGV2}" STREQUAL "AUTO")
|
||||
set(ARGS_SOURCES "${ARGV}")
|
||||
list(REMOVE_AT ARGS_SOURCES 0 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The non-keyword syntax allows the first argument to be an arbitrary
|
||||
# executable rather than a target if source files are also provided. In all
|
||||
# other cases, both forms require a target.
|
||||
if(NOT TARGET "${ARGS_TARGET}" AND NOT ARGS_SOURCES)
|
||||
message(FATAL_ERROR "${ARGS_TARGET} does not define an existing CMake target")
|
||||
endif()
|
||||
if(NOT ARGS_WORKING_DIRECTORY)
|
||||
unset(workDir)
|
||||
else()
|
||||
set(workDir WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
if(NOT ARGS_SOURCES)
|
||||
get_property(ARGS_SOURCES TARGET ${ARGS_TARGET} PROPERTY SOURCES)
|
||||
endif()
|
||||
|
||||
unset(testList)
|
||||
|
||||
set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
|
||||
set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
|
||||
|
||||
foreach(source IN LISTS ARGS_SOURCES)
|
||||
if(NOT ARGS_SKIP_DEPENDENCY)
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source})
|
||||
endif()
|
||||
file(READ "${source}" contents)
|
||||
string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests "${contents}")
|
||||
foreach(hit ${found_tests})
|
||||
string(REGEX MATCH "${gtest_test_type_regex}" test_type ${hit})
|
||||
|
||||
# Parameterized tests have a different signature for the filter
|
||||
if("x${test_type}" STREQUAL "xTEST_P")
|
||||
string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1.\\2/*" gtest_test_name ${hit})
|
||||
elseif("x${test_type}" STREQUAL "xTEST_F" OR "x${test_type}" STREQUAL "xTEST")
|
||||
string(REGEX REPLACE ${gtest_case_name_regex} "\\1.\\2" gtest_test_name ${hit})
|
||||
elseif("x${test_type}" STREQUAL "xTYPED_TEST")
|
||||
string(REGEX REPLACE ${gtest_case_name_regex} "\\1/*.\\2" gtest_test_name ${hit})
|
||||
else()
|
||||
message(WARNING "Could not parse GTest ${hit} for adding to CTest.")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Make sure tests disabled in GTest get disabled in CTest
|
||||
if(gtest_test_name MATCHES "(^|\\.)DISABLED_")
|
||||
# Add the disabled test if CMake is new enough
|
||||
# Note that this check is to allow backwards compatibility so this
|
||||
# module can be copied locally in projects to use with older CMake
|
||||
# versions
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.8.20170401)
|
||||
string(REGEX REPLACE
|
||||
"(^|\\.)DISABLED_" "\\1"
|
||||
orig_test_name "${gtest_test_name}"
|
||||
)
|
||||
set(ctest_test_name
|
||||
${ARGS_TEST_PREFIX}${orig_test_name}${ARGS_TEST_SUFFIX}
|
||||
)
|
||||
add_test(NAME ${ctest_test_name}
|
||||
${workDir}
|
||||
COMMAND ${ARGS_TARGET}
|
||||
--gtest_also_run_disabled_tests
|
||||
--gtest_filter=${gtest_test_name}
|
||||
${ARGS_EXTRA_ARGS}
|
||||
)
|
||||
set_tests_properties(${ctest_test_name} PROPERTIES DISABLED TRUE)
|
||||
list(APPEND testList ${ctest_test_name})
|
||||
endif()
|
||||
else()
|
||||
set(ctest_test_name ${ARGS_TEST_PREFIX}${gtest_test_name}${ARGS_TEST_SUFFIX})
|
||||
add_test(NAME ${ctest_test_name}
|
||||
${workDir}
|
||||
COMMAND ${ARGS_TARGET}
|
||||
--gtest_filter=${gtest_test_name}
|
||||
${ARGS_EXTRA_ARGS}
|
||||
)
|
||||
list(APPEND testList ${ctest_test_name})
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
if(ARGS_TEST_LIST)
|
||||
set(${ARGS_TEST_LIST} ${testList} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
function(gtest_discover_tests TARGET)
|
||||
cmake_parse_arguments(
|
||||
""
|
||||
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
|
||||
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE"
|
||||
"EXTRA_ARGS;PROPERTIES"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
if(NOT _WORKING_DIRECTORY)
|
||||
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
if(NOT _TEST_LIST)
|
||||
set(_TEST_LIST ${TARGET}_TESTS)
|
||||
endif()
|
||||
if(NOT _DISCOVERY_TIMEOUT)
|
||||
set(_DISCOVERY_TIMEOUT 5)
|
||||
endif()
|
||||
if(NOT _DISCOVERY_MODE)
|
||||
if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
|
||||
set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
|
||||
endif()
|
||||
set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE})
|
||||
endif()
|
||||
|
||||
get_property(
|
||||
has_counter
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
|
||||
SET
|
||||
)
|
||||
if(has_counter)
|
||||
get_property(
|
||||
counter
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
|
||||
)
|
||||
math(EXPR counter "${counter} + 1")
|
||||
else()
|
||||
set(counter 1)
|
||||
endif()
|
||||
set_property(
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
|
||||
${counter}
|
||||
)
|
||||
|
||||
# Define rule to generate test list for aforementioned test executable
|
||||
# Blender: use _ instead of [] to avoid problems with zsh regex.
|
||||
set(ctest_file_base "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_${counter}_")
|
||||
set(ctest_include_file "${ctest_file_base}_include.cmake")
|
||||
set(ctest_tests_file "${ctest_file_base}_tests.cmake")
|
||||
get_property(crosscompiling_emulator
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CROSSCOMPILING_EMULATOR
|
||||
)
|
||||
|
||||
if(_DISCOVERY_MODE STREQUAL "POST_BUILD")
|
||||
add_custom_command(
|
||||
TARGET ${TARGET} POST_BUILD
|
||||
BYPRODUCTS "${ctest_tests_file}"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "TEST_TARGET=${TARGET}"
|
||||
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
|
||||
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
|
||||
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
|
||||
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
|
||||
-D "TEST_PROPERTIES=${_PROPERTIES}"
|
||||
-D "TEST_PREFIX=${_TEST_PREFIX}"
|
||||
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
|
||||
-D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
|
||||
-D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
|
||||
-D "TEST_LIST=${_TEST_LIST}"
|
||||
-D "CTEST_FILE=${ctest_tests_file}"
|
||||
-D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
|
||||
-D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}"
|
||||
-P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
file(WRITE "${ctest_include_file}"
|
||||
"if(EXISTS \"${ctest_tests_file}\")\n"
|
||||
" include(\"${ctest_tests_file}\")\n"
|
||||
"else()\n"
|
||||
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
|
||||
"endif()\n"
|
||||
)
|
||||
elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST")
|
||||
|
||||
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL
|
||||
PROPERTY GENERATOR_IS_MULTI_CONFIG
|
||||
)
|
||||
|
||||
if(GENERATOR_IS_MULTI_CONFIG)
|
||||
set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
|
||||
endif()
|
||||
|
||||
string(CONCAT ctest_include_content
|
||||
"if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n"
|
||||
" if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n"
|
||||
" include(\"${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}\")" "\n"
|
||||
" gtest_discover_tests_impl(" "\n"
|
||||
" TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n"
|
||||
" TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n"
|
||||
" TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n"
|
||||
" TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n"
|
||||
" TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n"
|
||||
" TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n"
|
||||
" TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n"
|
||||
" NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n"
|
||||
" NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n"
|
||||
" TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n"
|
||||
" CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n"
|
||||
" TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}" "]==]" "\n"
|
||||
" TEST_XML_OUTPUT_DIR" " [==[" "${_XML_OUTPUT_DIR}" "]==]" "\n"
|
||||
" )" "\n"
|
||||
" endif()" "\n"
|
||||
" include(\"${ctest_tests_file}\")" "\n"
|
||||
"else()" "\n"
|
||||
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n"
|
||||
"endif()" "\n"
|
||||
)
|
||||
|
||||
if(GENERATOR_IS_MULTI_CONFIG)
|
||||
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||
file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>)
|
||||
endforeach()
|
||||
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")")
|
||||
else()
|
||||
file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}")
|
||||
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
|
||||
endif()
|
||||
|
||||
# Add discovered tests to directory TEST_INCLUDE_FILES
|
||||
set_property(DIRECTORY
|
||||
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
|
||||
)
|
||||
|
||||
endfunction()
|
||||
|
||||
###############################################################################
|
||||
|
||||
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
|
||||
${CMAKE_CURRENT_LIST_DIR}/GTestAddTests.cmake
|
||||
)
|
||||
|
||||
# Restore project's policies
|
||||
cmake_policy(POP)
|
@@ -1,191 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
# Blender: disable ASAN leak detection when trying to discover tests.
|
||||
set(ENV{ASAN_OPTIONS} "detect_leaks=0")
|
||||
|
||||
cmake_minimum_required(VERSION ${CMAKE_VERSION})
|
||||
|
||||
# Overwrite possibly existing ${_CTEST_FILE} with empty file
|
||||
set(flush_tests_MODE WRITE)
|
||||
|
||||
# Flushes script to ${_CTEST_FILE}
|
||||
macro(flush_script)
|
||||
file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}")
|
||||
set(flush_tests_MODE APPEND)
|
||||
|
||||
set(script "")
|
||||
endmacro()
|
||||
|
||||
# Flushes tests_buffer to tests
|
||||
macro(flush_tests_buffer)
|
||||
list(APPEND tests "${tests_buffer}")
|
||||
set(tests_buffer "")
|
||||
endmacro()
|
||||
|
||||
macro(add_command NAME)
|
||||
set(_args "")
|
||||
foreach(_arg ${ARGN})
|
||||
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
|
||||
string(APPEND _args " [==[${_arg}]==]")
|
||||
else()
|
||||
string(APPEND _args " ${_arg}")
|
||||
endif()
|
||||
endforeach()
|
||||
string(APPEND script "${NAME}(${_args})\n")
|
||||
string(LENGTH "${script}" _script_len)
|
||||
if(${_script_len} GREATER "50000")
|
||||
flush_script()
|
||||
endif()
|
||||
# Unsets macro local variables to prevent leakage outside of this macro.
|
||||
unset(_args)
|
||||
unset(_script_len)
|
||||
endmacro()
|
||||
|
||||
function(gtest_discover_tests_impl)
|
||||
|
||||
cmake_parse_arguments(
|
||||
""
|
||||
""
|
||||
"NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_EXECUTOR;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR"
|
||||
"TEST_EXTRA_ARGS;TEST_PROPERTIES"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
set(prefix "${_TEST_PREFIX}")
|
||||
set(suffix "${_TEST_SUFFIX}")
|
||||
set(extra_args ${_TEST_EXTRA_ARGS})
|
||||
set(properties ${_TEST_PROPERTIES})
|
||||
set(script)
|
||||
set(suite)
|
||||
set(tests)
|
||||
set(tests_buffer)
|
||||
|
||||
# Run test executable to get list of available tests
|
||||
if(NOT EXISTS "${_TEST_EXECUTABLE}")
|
||||
message(FATAL_ERROR
|
||||
"Specified test executable does not exist.\n"
|
||||
" Path: '${_TEST_EXECUTABLE}'"
|
||||
)
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests
|
||||
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
|
||||
TIMEOUT ${_TEST_DISCOVERY_TIMEOUT}
|
||||
OUTPUT_VARIABLE output
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
if(NOT ${result} EQUAL 0)
|
||||
string(REPLACE "\n" "\n " output "${output}")
|
||||
message(FATAL_ERROR
|
||||
"Error running test executable.\n"
|
||||
" Path: '${_TEST_EXECUTABLE}'\n"
|
||||
" Result: ${result}\n"
|
||||
" Output:\n"
|
||||
" ${output}\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Preserve semicolon in test-parameters
|
||||
string(REPLACE [[;]] [[\;]] output "${output}")
|
||||
string(REPLACE "\n" ";" output "${output}")
|
||||
|
||||
# Parse output
|
||||
foreach(line ${output})
|
||||
# Skip header
|
||||
if(NOT line MATCHES "gtest_main\\.cc")
|
||||
# Do we have a module name or a test name?
|
||||
if(NOT line MATCHES "^ ")
|
||||
# Module; remove trailing '.' to get just the name...
|
||||
string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
|
||||
if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES)
|
||||
string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
|
||||
else()
|
||||
set(pretty_suite "${suite}")
|
||||
endif()
|
||||
string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
|
||||
else()
|
||||
# Test name; strip spaces and comments to get just the name...
|
||||
string(REGEX REPLACE " +" "" test "${line}")
|
||||
if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES)
|
||||
string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
|
||||
else()
|
||||
string(REGEX REPLACE "#.*" "" pretty_test "${test}")
|
||||
endif()
|
||||
string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
|
||||
string(REGEX REPLACE "#.*" "" test "${test}")
|
||||
if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "")
|
||||
set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${suite}.${test}${suffix}.xml")
|
||||
else()
|
||||
unset(TEST_XML_OUTPUT_PARAM)
|
||||
endif()
|
||||
|
||||
# sanitize test name for further processing downstream
|
||||
set(testname "${prefix}${pretty_suite}.${pretty_test}${suffix}")
|
||||
# escape \
|
||||
string(REPLACE [[\]] [[\\]] testname "${testname}")
|
||||
# escape ;
|
||||
string(REPLACE [[;]] [[\;]] testname "${testname}")
|
||||
# escape $
|
||||
string(REPLACE [[$]] [[\$]] testname "${testname}")
|
||||
|
||||
# ...and add to script
|
||||
add_command(add_test
|
||||
"${testname}"
|
||||
${_TEST_EXECUTOR}
|
||||
"${_TEST_EXECUTABLE}"
|
||||
"--gtest_filter=${suite}.${test}"
|
||||
"--gtest_also_run_disabled_tests"
|
||||
${TEST_XML_OUTPUT_PARAM}
|
||||
${extra_args}
|
||||
)
|
||||
if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
|
||||
add_command(set_tests_properties
|
||||
"${testname}"
|
||||
PROPERTIES DISABLED TRUE
|
||||
)
|
||||
endif()
|
||||
add_command(set_tests_properties
|
||||
"${testname}"
|
||||
PROPERTIES
|
||||
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
|
||||
SKIP_REGULAR_EXPRESSION "\\\\[ SKIPPED \\\\]"
|
||||
${properties}
|
||||
)
|
||||
list(APPEND tests_buffer "${testname}")
|
||||
list(LENGTH tests_buffer tests_buffer_length)
|
||||
if(${tests_buffer_length} GREATER "250")
|
||||
flush_tests_buffer()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
# Create a list of all discovered tests, which users may use to e.g. set
|
||||
# properties on the tests
|
||||
flush_tests_buffer()
|
||||
add_command(set ${_TEST_LIST} ${tests})
|
||||
|
||||
# Write CTest script
|
||||
flush_script()
|
||||
|
||||
endfunction()
|
||||
|
||||
if(CMAKE_SCRIPT_MODE_FILE)
|
||||
gtest_discover_tests_impl(
|
||||
NO_PRETTY_TYPES ${NO_PRETTY_TYPES}
|
||||
NO_PRETTY_VALUES ${NO_PRETTY_VALUES}
|
||||
TEST_EXECUTABLE ${TEST_EXECUTABLE}
|
||||
TEST_EXECUTOR ${TEST_EXECUTOR}
|
||||
TEST_WORKING_DIR ${TEST_WORKING_DIR}
|
||||
TEST_PREFIX ${TEST_PREFIX}
|
||||
TEST_SUFFIX ${TEST_SUFFIX}
|
||||
TEST_LIST ${TEST_LIST}
|
||||
CTEST_FILE ${CTEST_FILE}
|
||||
TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
|
||||
TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR}
|
||||
TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
|
||||
TEST_PROPERTIES ${TEST_PROPERTIES}
|
||||
)
|
||||
endif()
|
@@ -37,11 +37,6 @@ macro(BLENDER_SRC_GTEST_EX)
|
||||
if(WIN32)
|
||||
set(MANIFEST "${CMAKE_BINARY_DIR}/tests.exe.manifest")
|
||||
endif()
|
||||
|
||||
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
|
||||
add_definitions(${GFLAGS_DEFINES})
|
||||
add_definitions(${GLOG_DEFINES})
|
||||
|
||||
add_executable(${TARGET_NAME} ${ARG_SRC} ${MANIFEST})
|
||||
target_include_directories(${TARGET_NAME} PUBLIC "${TEST_INC}")
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC "${TEST_INC_SYS}")
|
||||
|
@@ -11,11 +11,9 @@ set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||
set(WITH_GMP OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
|
||||
|
@@ -15,12 +15,10 @@ set(WITH_CODEC_AVI OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_EMBREE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_GMP OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LLVM OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -12,11 +12,9 @@ set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||
set(WITH_GMP OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
|
||||
@@ -54,7 +52,7 @@ set(WITH_USD ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75;compute_75 CACHE STRING "" FORCE)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75 CACHE STRING "" FORCE)
|
||||
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
|
||||
|
||||
# platform dependent options
|
||||
|
@@ -169,26 +169,6 @@ function(blender_include_dirs_sys
|
||||
include_directories(SYSTEM ${_ALL_INCS})
|
||||
endfunction()
|
||||
|
||||
# Set include paths for header files included with "*.h" syntax.
|
||||
# This enables auto-complete suggestions for user header files on Xcode.
|
||||
# Build process is not affected since the include paths are the same
|
||||
# as in HEADER_SEARCH_PATHS.
|
||||
function(blender_user_header_search_paths
|
||||
name
|
||||
includes
|
||||
)
|
||||
|
||||
if(XCODE)
|
||||
set(_ALL_INCS "")
|
||||
foreach(_INC ${includes})
|
||||
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
||||
# _ALL_INCS is a space-separated string of file paths in quotes.
|
||||
set(_ALL_INCS "${_ALL_INCS} \"${_ABS_INC}\"")
|
||||
endforeach()
|
||||
set_target_properties(${name} PROPERTIES XCODE_ATTRIBUTE_USER_HEADER_SEARCH_PATHS "${_ALL_INCS}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(blender_source_group
|
||||
name
|
||||
sources
|
||||
@@ -337,7 +317,6 @@ function(blender_add_lib__impl
|
||||
# works fine without having the includes
|
||||
# listed is helpful for IDE's (QtCreator/MSVC)
|
||||
blender_source_group("${name}" "${sources}")
|
||||
blender_user_header_search_paths("${name}" "${includes}")
|
||||
|
||||
list_assert_duplicates("${sources}")
|
||||
list_assert_duplicates("${includes}")
|
||||
@@ -375,42 +354,6 @@ function(blender_add_lib
|
||||
set_property(GLOBAL APPEND PROPERTY BLENDER_LINK_LIBS ${name})
|
||||
endfunction()
|
||||
|
||||
# blender_add_test_lib() is used to define a test library. It is intended to be
|
||||
# called in tandem with blender_add_lib(). The test library will be linked into
|
||||
# the bf_gtest_runner_test executable (see tests/gtests/CMakeLists.txt).
|
||||
function(blender_add_test_lib
|
||||
name
|
||||
sources
|
||||
includes
|
||||
includes_sys
|
||||
library_deps
|
||||
)
|
||||
|
||||
add_cc_flags_custom_test(${name} PARENT_SCOPE)
|
||||
|
||||
# Otherwise external projects will produce warnings that we cannot fix.
|
||||
remove_strict_flags()
|
||||
|
||||
# This duplicates logic that's also in GTestTesting.cmake, macro BLENDER_SRC_GTEST_EX.
|
||||
# TODO(Sybren): deduplicate after the general approach in D7649 has been approved.
|
||||
LIST(APPEND includes
|
||||
${CMAKE_SOURCE_DIR}/tests/gtests
|
||||
)
|
||||
LIST(APPEND includes_sys
|
||||
${GLOG_INCLUDE_DIRS}
|
||||
${GFLAGS_INCLUDE_DIRS}
|
||||
${CMAKE_SOURCE_DIR}/extern/gtest/include
|
||||
${CMAKE_SOURCE_DIR}/extern/gmock/include
|
||||
)
|
||||
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
|
||||
add_definitions(${GFLAGS_DEFINES})
|
||||
add_definitions(${GLOG_DEFINES})
|
||||
|
||||
blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
|
||||
endfunction()
|
||||
|
||||
# Ninja only: assign 'heavy pool' to some targets that are especially RAM-consuming to build.
|
||||
function(setup_heavy_lib_pool)
|
||||
if(WITH_NINJA_POOL_JOBS AND NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS)
|
||||
@@ -418,7 +361,7 @@ function(setup_heavy_lib_pool)
|
||||
list(APPEND _HEAVY_LIBS "cycles_device" "cycles_kernel")
|
||||
endif()
|
||||
if(WITH_LIBMV)
|
||||
list(APPEND _HEAVY_LIBS "extern_ceres" "bf_intern_libmv")
|
||||
list(APPEND _HEAVY_LIBS "bf_intern_libmv")
|
||||
endif()
|
||||
if(WITH_OPENVDB)
|
||||
list(APPEND _HEAVY_LIBS "bf_intern_openvdb")
|
||||
@@ -494,6 +437,7 @@ function(SETUP_LIBDIRS)
|
||||
|
||||
if(WITH_ALEMBIC)
|
||||
link_directories(${ALEMBIC_LIBPATH})
|
||||
link_directories(${HDF5_LIBPATH})
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
|
@@ -20,11 +20,7 @@
|
||||
|
||||
# Libraries configuration for Apple.
|
||||
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
set(MACOSX_DEPLOYMENT_TARGET 11.00)
|
||||
else()
|
||||
set(MACOSX_DEPLOYMENT_TARGET 10.13)
|
||||
endif()
|
||||
set(MACOSX_DEPLOYMENT_TARGET "10.11")
|
||||
|
||||
macro(find_package_wrapper)
|
||||
# do nothing, just satisfy the macro
|
||||
@@ -382,12 +378,6 @@ if(WITH_CYCLES_OSL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
set(WITH_CYCLES_EMBREE OFF)
|
||||
set(WITH_OPENIMAGEDENOISE OFF)
|
||||
set(WITH_CPU_SSE OFF)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_EMBREE)
|
||||
find_package(Embree 3.8.0 REQUIRED)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Xlinker -stack_size -Xlinker 0x100000")
|
||||
@@ -437,14 +427,6 @@ if(WITH_XR_OPENXR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_GMP)
|
||||
find_package(GMP)
|
||||
if(NOT GMP_FOUND)
|
||||
message(WARNING "GMP not found, disabling WITH_GMP")
|
||||
set(WITH_GMP OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(EXETYPE MACOSX_BUNDLE)
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
|
||||
@@ -457,8 +439,8 @@ if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" OR CMAKE_OSX_ARCHITECTURES MATCHES "
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ftree-vectorize -fvariable-expansion-in-unroller")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -fno-strict-aliasing")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -fno-strict-aliasing")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
|
||||
endif()
|
||||
|
||||
if(${XCODE_VERSION} VERSION_EQUAL 5 OR ${XCODE_VERSION} VERSION_GREATER 5)
|
||||
|
@@ -21,10 +21,8 @@
|
||||
# Xcode and system configuration for Apple.
|
||||
|
||||
if(NOT CMAKE_OSX_ARCHITECTURES)
|
||||
execute_process(COMMAND uname -m OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "Detected native architecture ${ARCHITECTURE}.")
|
||||
set(CMAKE_OSX_ARCHITECTURES ${ARCHITECTURE} CACHE STRING
|
||||
"Choose the architecture you want to build Blender for: arm64 or x86_64"
|
||||
set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING
|
||||
"Choose the architecture you want to build Blender for: i386, x86_64 or ppc"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
@@ -67,9 +65,13 @@ endif()
|
||||
|
||||
message(STATUS "Detected OS X ${OSX_SYSTEM} and Xcode ${XCODE_VERSION} at ${XCODE_BUNDLE}")
|
||||
|
||||
# Require a relatively recent Xcode version.
|
||||
if(${XCODE_VERSION} VERSION_LESS 10.0)
|
||||
message(FATAL_ERROR "Only Xcode version 10.0 and newer is supported")
|
||||
# Older Xcode versions had different approach to the directory hiearchy.
|
||||
# Require newer Xcode which is also have better chances of being able to compile with the
|
||||
# required deployment target.
|
||||
#
|
||||
# NOTE: Xcode version 8.2 is the latest one which runs on macOS 10.11.
|
||||
if(${XCODE_VERSION} VERSION_LESS 8.2)
|
||||
message(FATAL_ERROR "Only Xcode version 8.2 and newer is supported")
|
||||
endif()
|
||||
|
||||
# note: xcode-select path could be ambiguous,
|
||||
@@ -131,21 +133,14 @@ if(${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||
endif()
|
||||
unset(OSX_SDKROOT)
|
||||
|
||||
|
||||
# 10.13 is our min. target, if you use higher sdk, weak linking happens
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
set(OSX_MIN_DEPLOYMENT_TARGET 11.00)
|
||||
else()
|
||||
set(OSX_MIN_DEPLOYMENT_TARGET 10.13)
|
||||
endif()
|
||||
|
||||
# 10.11 is our min. target, if you use higher sdk, weak linking happens
|
||||
if(CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS ${OSX_MIN_DEPLOYMENT_TARGET})
|
||||
message(STATUS "Setting deployment target to ${OSX_MIN_DEPLOYMENT_TARGET}, lower versions are not supported")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
|
||||
if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.11)
|
||||
message(STATUS "Setting deployment target to 10.11, lower versions are not supported")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||
|
@@ -36,11 +36,6 @@ if(NOT DEFINED LIBDIR)
|
||||
elseif(EXISTS ${LIBDIR_CENTOS7_ABI})
|
||||
set(LIBDIR ${LIBDIR_CENTOS7_ABI})
|
||||
set(WITH_CXX11_ABI OFF)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND
|
||||
CMAKE_C_COMPILER_VERSION VERSION_LESS 9.3)
|
||||
message(FATAL_ERROR "GCC version must be at least 9.3 for precompiled libraries, found ${CMAKE_C_COMPILER_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Avoid namespace pollustion.
|
||||
@@ -270,8 +265,14 @@ endif()
|
||||
if(WITH_ALEMBIC)
|
||||
find_package_wrapper(Alembic)
|
||||
|
||||
if(NOT ALEMBIC_FOUND)
|
||||
if(WITH_ALEMBIC_HDF5)
|
||||
set(HDF5_ROOT_DIR ${LIBDIR}/hdf5)
|
||||
find_package_wrapper(HDF5)
|
||||
endif()
|
||||
|
||||
if(NOT ALEMBIC_FOUND OR (WITH_ALEMBIC_HDF5 AND NOT HDF5_FOUND))
|
||||
set(WITH_ALEMBIC OFF)
|
||||
set(WITH_ALEMBIC_HDF5 OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -435,14 +436,6 @@ if(WITH_XR_OPENXR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_GMP)
|
||||
find_package_wrapper(GMP)
|
||||
if(NOT GMP_FOUND)
|
||||
message(WARNING "GMP not found, disabling WITH_GMP")
|
||||
set(WITH_GMP OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(EXISTS ${LIBDIR})
|
||||
without_system_libs_end()
|
||||
endif()
|
||||
|
@@ -539,10 +539,10 @@ if(WITH_OPENIMAGEDENOISE)
|
||||
set(OPENIMAGEDENOISE_LIBRARIES
|
||||
optimized ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise.lib
|
||||
optimized ${OPENIMAGEDENOISE_LIBPATH}/common.lib
|
||||
optimized ${OPENIMAGEDENOISE_LIBPATH}/dnnl.lib
|
||||
optimized ${OPENIMAGEDENOISE_LIBPATH}/mkldnn.lib
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise_d.lib
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/common_d.lib
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/dnnl_d.lib)
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/mkldnn_d.lib)
|
||||
set(OPENIMAGEDENOISE_DEFINITIONS)
|
||||
endif()
|
||||
|
||||
@@ -750,10 +750,3 @@ if(WITH_XR_OPENXR)
|
||||
set(WITH_XR_OPENXR OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_GMP)
|
||||
set(GMP_INCLUDE_DIRS ${LIBDIR}/gmp/include)
|
||||
set(GMP_LIBRARIES ${LIBDIR}/gmp/lib/libgmp-10.lib optimized ${LIBDIR}/gmp/lib/libgmpxx.lib debug ${LIBDIR}/gmp/lib/libgmpxx_d.lib)
|
||||
set(GMP_ROOT_DIR ${LIBDIR}/gmp)
|
||||
set(GMP_FOUND On)
|
||||
endif()
|
||||
|
@@ -40,8 +40,7 @@ if make_utils.command_missing(git_command):
|
||||
|
||||
# Test if we are building a specific release version.
|
||||
branch = make_utils.git_branch(git_command)
|
||||
tag = make_utils.git_tag(git_command)
|
||||
release_version = make_utils.git_branch_release_version(branch, tag)
|
||||
release_version = make_utils.git_branch_release_version(branch)
|
||||
lib_tests_dirpath = os.path.join('..', 'lib', "tests")
|
||||
|
||||
if not os.path.exists(lib_tests_dirpath):
|
||||
|
@@ -197,8 +197,7 @@ if __name__ == "__main__":
|
||||
|
||||
# Test if we are building a specific release version.
|
||||
branch = make_utils.git_branch(args.git_command)
|
||||
tag = make_utils.git_tag(args.git_command)
|
||||
release_version = make_utils.git_branch_release_version(branch, tag)
|
||||
release_version = make_utils.git_branch_release_version(branch)
|
||||
|
||||
if not args.no_libraries:
|
||||
svn_update(args, release_version)
|
||||
|
@@ -36,7 +36,7 @@ def check_output(cmd, exit_on_error=True):
|
||||
return output.strip()
|
||||
|
||||
def git_branch(git_command):
|
||||
# Get current branch name.
|
||||
# Test if we are building a specific release version.
|
||||
try:
|
||||
branch = subprocess.check_output([git_command, "rev-parse", "--abbrev-ref", "HEAD"])
|
||||
except subprocess.CalledProcessError as e:
|
||||
@@ -45,23 +45,10 @@ def git_branch(git_command):
|
||||
|
||||
return branch.strip().decode('utf8')
|
||||
|
||||
def git_tag(git_command):
|
||||
# Get current tag name.
|
||||
try:
|
||||
tag = subprocess.check_output([git_command, "describe", "--exact-match"], stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
return None
|
||||
|
||||
return tag.strip().decode('utf8')
|
||||
|
||||
def git_branch_release_version(branch, tag):
|
||||
def git_branch_release_version(branch):
|
||||
release_version = re.search("^blender-v(.*)-release$", branch)
|
||||
if release_version:
|
||||
release_version = release_version.group(1)
|
||||
elif tag:
|
||||
release_version = re.search("^v([0-9]*\.[0-9]*).*", tag)
|
||||
if release_version:
|
||||
release_version = release_version.group(1)
|
||||
return release_version
|
||||
|
||||
def svn_libraries_base_url(release_version):
|
||||
|
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "V2.91"
|
||||
PROJECT_NUMBER = "V2.90"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
@@ -20,7 +20,6 @@ from gpu_extras.presets import draw_circle_2d
|
||||
offscreen = gpu.types.GPUOffScreen(512, 512)
|
||||
|
||||
with offscreen.bind():
|
||||
bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
|
||||
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
|
||||
with gpu.matrix.push_pop():
|
||||
# reset matrices -> use normalized device coordinates [-1, 1]
|
||||
|
@@ -25,7 +25,6 @@ RING_AMOUNT = 10
|
||||
offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
|
||||
|
||||
with offscreen.bind():
|
||||
bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
|
||||
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
|
||||
with gpu.matrix.push_pop():
|
||||
# reset matrices -> use normalized device coordinates [-1, 1]
|
||||
|
@@ -1,2 +1,2 @@
|
||||
Sphinx==3.1.1
|
||||
sphinx_rtd_theme==0.5.0
|
||||
Sphinx==3.0.3
|
||||
sphinx_rtd_theme==0.5.0rc1
|
||||
|
@@ -427,7 +427,7 @@ offers a set of extensive examples, including advanced features.
|
||||
|
||||
Return evaluator parameters
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glGetMap.xml>`__
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glGetMap.xml>`_
|
||||
|
||||
:type target: Enumerated constant
|
||||
:arg target: Specifies the symbolic name of a map.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
..
|
||||
This document is appended to the auto generated BMesh API doc to avoid clogging up the C files with details.
|
||||
This document is appended to the auto generated bmesh api doc to avoid clogging up the C files with details.
|
||||
to test this run:
|
||||
./blender.bin -b -noaudio -P doc/python_api/sphinx_doc_gen.py -- \
|
||||
--partial bmesh* ; cd doc/python_api ; sphinx-build sphinx-in sphinx-out ; cd ../../
|
||||
@@ -19,24 +19,25 @@ Submodules:
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This API gives access the Blender's internal mesh editing API, featuring geometry connectivity data and
|
||||
This API gives access the blenders internal mesh editing api, featuring geometry connectivity data and
|
||||
access to editing operations such as split, separate, collapse and dissolve.
|
||||
|
||||
The features exposed closely follow the C API,
|
||||
giving Python access to the functions used by Blender's own mesh editing tools.
|
||||
giving python access to the functions used by blenders own mesh editing tools.
|
||||
|
||||
For an overview of BMesh data types and how they reference each other see:
|
||||
`BMesh Design Document <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`__.
|
||||
`BMesh Design Document <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`_ .
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
**Disk** and **Radial** data is not exposed by the Python API since this is for internal use only.
|
||||
**Disk** and **Radial** data is not exposed by the python api since this is for internal use only.
|
||||
|
||||
|
||||
.. warning:: TODO items are...
|
||||
|
||||
- add access to BMesh **walkers**.
|
||||
- add custom-data manipulation functions add, remove or rename.
|
||||
* add access to BMesh **walkers**
|
||||
* add custom-data manipulation functions add/remove/rename.
|
||||
|
||||
|
||||
Example Script
|
||||
@@ -45,52 +46,55 @@ Example Script
|
||||
.. literalinclude:: __/__/__/release/scripts/templates_py/bmesh_simple.py
|
||||
|
||||
|
||||
Standalone Module
|
||||
^^^^^^^^^^^^^^^^^
|
||||
Stand-Alone Module
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The BMesh module is written to be standalone except for :mod:`mathutils`
|
||||
The bmesh module is written to be standalone except for :mod:`mathutils`
|
||||
which is used for vertex locations and normals.
|
||||
|
||||
The only other exception to this are when converting mesh data to and from :class:`bpy.types.Mesh`.
|
||||
|
||||
|
||||
Mesh Access
|
||||
-----------
|
||||
|
||||
There are two ways to access BMesh data, you can create a new BMesh by converting a mesh from
|
||||
:class:`bpy.types.BlendData.meshes` or by accessing the current Edit-Mode mesh.
|
||||
See: :class:`bmesh.types.BMesh.from_mesh` and :mod:`bmesh.from_edit_mesh` respectively.
|
||||
There are 2 ways to access BMesh data, you can create a new BMesh by converting a mesh from
|
||||
:class:`bpy.types.BlendData.meshes` or by accessing the current edit mode mesh.
|
||||
see: :class:`bmesh.types.BMesh.from_mesh` and :mod:`bmesh.from_edit_mesh` respectively.
|
||||
|
||||
When explicitly converting from mesh data Python **owns** the data, that means that
|
||||
the mesh only exists while Python holds a reference to it.
|
||||
The script is responsible for putting it back into a mesh data-block when the edits are done.
|
||||
When explicitly converting from mesh data python **owns** the data, that is to say -
|
||||
that the mesh only exists while python holds a reference to it,
|
||||
and the script is responsible for putting it back into a mesh data-block when the edits are done.
|
||||
|
||||
Note that unlike :mod:`bpy`, a BMesh does not necessarily correspond to data in the currently open blend-file,
|
||||
Note that unlike :mod:`bpy`, a BMesh does not necessarily correspond to data in the currently open blend file,
|
||||
a BMesh can be created, edited and freed without the user ever seeing or having access to it.
|
||||
Unlike Edit-Mode, the BMesh module can use multiple BMesh instances at once.
|
||||
Unlike edit mode, the bmesh module can use multiple BMesh instances at once.
|
||||
|
||||
Take care when dealing with multiple BMesh instances since the mesh data can use a lot of memory.
|
||||
While a mesh that the Python script owns will be freed when the script holds no references to it,
|
||||
it's good practice to call :class:`bmesh.types.BMesh.free` which will remove all the mesh data immediately
|
||||
and disable further access.
|
||||
Take care when dealing with multiple BMesh instances since the mesh data can use a lot of memory, while a mesh that
|
||||
python owns will be freed in when the script holds no references to it,
|
||||
its good practice to call :class:`bmesh.types.BMesh.free` which will remove all the mesh data immediately and disable
|
||||
further access.
|
||||
|
||||
|
||||
Edit-Mode Tessellation
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
EditMode Tessellation
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When writing scripts that operate on Edit-Mode data you will normally want to re-calculate the tessellation after
|
||||
running the script, this needs to be called explicitly.
|
||||
The BMesh itself does not store the triangulated faces, instead they are stored in the :class:`bpy.types.Mesh`,
|
||||
When writing scripts that operate on editmode data you will normally want to re-calculate the tessellation after
|
||||
running the script, this needs to be called explicitly.
|
||||
|
||||
The BMesh its self does not store the triangulated faces, they are stored in the :class:`bpy.types.Mesh`,
|
||||
to refresh tessellation triangles call :class:`bpy.types.Mesh.calc_loop_triangles`.
|
||||
|
||||
|
||||
CustomData Access
|
||||
-----------------
|
||||
|
||||
BMesh has a unified way to access mesh attributes such as UVs, vertex colors, shape keys, edge crease, etc.
|
||||
This works by having a **layers** property on BMesh data sequences to access the custom data layers
|
||||
which can then be used to access the actual data on each vert, edge, face or loop.
|
||||
BMesh has a unified way to access mesh attributes such as UV's vertex colors, shape keys, edge crease etc.
|
||||
|
||||
Here are some examples:
|
||||
This works by having a **layers** property on bmesh data sequences to access the custom data layers which can then be
|
||||
used to access the actual data on each vert/edge/face/loop.
|
||||
|
||||
Here are some examples ...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -135,27 +139,27 @@ Here are some examples:
|
||||
Keeping a Correct State
|
||||
-----------------------
|
||||
|
||||
When modeling in Blender there are certain assumptions made about the state of the mesh:
|
||||
When modeling in blender there are certain assumptions made about the state of the mesh.
|
||||
|
||||
- Hidden geometry isn't selected.
|
||||
- When an edge is selected, its vertices are selected too.
|
||||
- When a face is selected, its edges and vertices are selected.
|
||||
- Duplicate edges / faces don't exist.
|
||||
- Faces have at least three vertices.
|
||||
* hidden geometry isn't selected.
|
||||
* when an edge is selected, its vertices are selected too.
|
||||
* when a face is selected, its edges and vertices are selected.
|
||||
* duplicate edges / faces don't exist.
|
||||
* faces have at least 3 vertices.
|
||||
|
||||
To give developers flexibility these conventions are not enforced,
|
||||
yet tools must leave the mesh in a valid state or else other tools may behave incorrectly.
|
||||
however tools must leave the mesh in a valid state else other tools may behave incorrectly.
|
||||
|
||||
Any errors that arise from not following these conventions is considered a bug in the script,
|
||||
not a bug in Blender.
|
||||
not a bug in blender.
|
||||
|
||||
|
||||
Selection / Flushing
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As mentioned above, it is possible to create an invalid selection state
|
||||
(by selecting a state and then deselecting one of its vertices for example),
|
||||
mostly the best way to solve this is to flush the selection
|
||||
after performing a series of edits. This validates the selection state.
|
||||
(by selecting a state and then de-selecting one of its vertices's for example), mostly the best way to solve this is to
|
||||
flush the selection after performing a series of edits. this validates the selection state.
|
||||
|
||||
|
||||
Module Functions
|
||||
|
@@ -3,84 +3,94 @@
|
||||
Reference API Usage
|
||||
*******************
|
||||
|
||||
Blender has many interlinking data types which have an auto-generated reference API which often has the information
|
||||
Blender has many interlinking data types which have an auto-generated reference api which often has the information
|
||||
you need to write a script, but can be difficult to use.
|
||||
This document is designed to help you understand how to use the reference API.
|
||||
|
||||
This document is designed to help you understand how to use the reference api.
|
||||
|
||||
|
||||
Reference API Scope
|
||||
===================
|
||||
|
||||
The reference API covers :mod:`bpy.types`, which stores types accessed via :mod:`bpy.context` -- *the user context*
|
||||
or :mod:`bpy.data` -- *blend-file data*.
|
||||
The reference API covers :mod:`bpy.types`, which stores types accessed via :mod:`bpy.context` - *The user context*
|
||||
or :mod:`bpy.data` - *Blend file data*.
|
||||
|
||||
Other modules such as :mod:`bmesh` and :mod:`aud` are not using Blender's data API
|
||||
Other modules such as :mod:`bmesh` and :mod:`aud` are not using Blenders data API
|
||||
so this document doesn't apply to those modules.
|
||||
|
||||
|
||||
Data Access
|
||||
===========
|
||||
|
||||
The most common case for using the reference API is to find out how to access data in the blend-file.
|
||||
Before going any further its best to be aware of ID data-blocks in Blender since you will often find properties
|
||||
The most common case for using the reference API is to find out how to access data in the blend file.
|
||||
|
||||
Before going any further its best to be aware of ID Data-Blocks in Blender since you will often find properties
|
||||
relative to them.
|
||||
|
||||
|
||||
ID Data
|
||||
-------
|
||||
|
||||
ID data-blocks are used in Blender as top-level data containers.
|
||||
From the user interface this isn't so obvious, but when developing you need to know about ID data-blocks.
|
||||
ID data types include Scene, Group, Object, Mesh, Workspace, World, Armature, Image and Texture.
|
||||
For a full list see the subclasses of :class:`bpy.types.ID`.
|
||||
ID Data-Blocks are used in Blender as top-level data containers.
|
||||
|
||||
Here are some characteristics ID data-blocks share:
|
||||
From the user interface this isn't so obvious, but when developing you need to know about ID Data-Blocks.
|
||||
|
||||
- IDs are blend-file data, so loading a new blend-file reloads an entire new set of data-blocks.
|
||||
- IDs can be accessed in Python from ``bpy.data.*``.
|
||||
ID data types include Scene, Group, Object, Mesh, Screen, World, Armature, Image and Texture.
|
||||
for a full list see the sub-classes of :class:`bpy.types.ID`
|
||||
|
||||
Here are some characteristics ID Data-Blocks share.
|
||||
|
||||
- ID's are blend file data, so loading a new blend file reloads an entire new set of Data-Blocks.
|
||||
- ID's can be accessed in Python from ``bpy.data.*``
|
||||
- Each data-block has a unique ``.name`` attribute, displayed in the interface.
|
||||
- Animation data is stored in IDs ``.animation_data``.
|
||||
- IDs are the only data types that can be linked between blend-files.
|
||||
- IDs can be added/copied and removed via Python.
|
||||
- IDs have their own garbage-collection system which frees unused IDs when saving.
|
||||
- When a data-block has a reference to some external data, this is typically an ID data-block.
|
||||
- Animation data is stored in ID's ``.animation_data``.
|
||||
- ID's are the only data types that can be linked between blend files.
|
||||
- ID's can be added/copied and removed via Python.
|
||||
- ID's have their own garbage-collection system which frees unused ID's when saving.
|
||||
- When a data-block has a reference to some external data, this is typically an ID Data-Block.
|
||||
|
||||
|
||||
Simple Data Access
|
||||
------------------
|
||||
|
||||
In this simple case a Python script is used to adjust the object's location.
|
||||
Start by collecting the information where the data is located.
|
||||
Lets start with a simple case, say you want a python script to adjust the object's location.
|
||||
|
||||
First find this setting in the interface ``Properties editor -> Object -> Transform -> Location``.
|
||||
From the button context menu select *Online Python Reference*, this will link you to:
|
||||
:class:`bpy.types.Object.location`.
|
||||
Being an API reference, this link often gives little more information then the tooltip, though some of the pages
|
||||
Start by finding this setting in the interface ``Properties Window -> Object -> Transform -> Location``
|
||||
|
||||
From the button you can right click and select **Online Python Reference**, this will link you to:
|
||||
:class:`bpy.types.Object.location`
|
||||
|
||||
Being an API reference, this link often gives little more information then the tool-tip, though some of the pages
|
||||
include examples (normally at the top of the page).
|
||||
But you now know that you have to use ``.location`` and that its an array of three floats.
|
||||
|
||||
So the next step is to find out where to access objects, go down to the bottom of the page to the references section,
|
||||
for objects there are many references, but one of the most common places to access objects is via the context.
|
||||
It's easy to be overwhelmed at this point since there ``Object`` get referenced in so many places:
|
||||
modifiers, functions, textures and constraints.
|
||||
At this point you may say *Now what?* - you know that you have to use ``.location`` and that its an array of 3 floats
|
||||
but you're still left wondering how to access this in a script.
|
||||
|
||||
So the next step is to find out where to access objects, go down to the bottom of the page to the **References**
|
||||
section, for objects there are many references, but one of the most common places to access objects is via the context.
|
||||
|
||||
It's easy to be overwhelmed at this point since there ``Object`` get referenced in so many places - modifiers,
|
||||
functions, textures and constraints.
|
||||
|
||||
But if you want to access any data the user has selected
|
||||
you typically only need to check the :mod:`bpy.context` references.
|
||||
|
||||
Even then, in this case there are quite a few though
|
||||
if you read over these you'll notice that most are mode specific.
|
||||
If you happen to be writing a tool that only runs in Weight Paint Mode,
|
||||
then using ``weight_paint_object`` would be appropriate.
|
||||
However, to access an item the user last selected, look for the ``active`` members,
|
||||
Having access to a single active member the user selects is a convention in Blender:
|
||||
e.g. ``active_bone``, ``active_pose_bone``, ``active_node``, etc. and in this case you can use ``active_object``.
|
||||
Even then, in this case there are quite a few though if you read over these - most are mode specific.
|
||||
If you happen to be writing a tool that only runs in weight paint mode, then using ``weight_paint_object``
|
||||
would be appropriate.
|
||||
However to access an item the user last selected, look for the ``active`` members,
|
||||
Having access to a single active member the user selects is a convention in Blender: eg. ``active_bone``,
|
||||
``active_pose_bone``, ``active_node`` ... and in this case we can use - ``active_object``.
|
||||
|
||||
So now you have enough information to find the location of the active object.
|
||||
|
||||
So now we have enough information to find the location of the active object.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.location
|
||||
|
||||
You can type this into the Python console to see the result.
|
||||
You can type this into the python console to see the result.
|
||||
|
||||
The other common place to access objects in the reference is :class:`bpy.types.BlendData.objects`.
|
||||
|
||||
.. note::
|
||||
@@ -90,7 +100,7 @@ The other common place to access objects in the reference is :class:`bpy.types.B
|
||||
so the documentation points there.
|
||||
|
||||
|
||||
With :mod:`bpy.data.objects`, this is a collection of objects so you need to access one of its members:
|
||||
With :mod:`bpy.data.objects`, this is a collection of objects so you need to access one of its members.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -107,34 +117,37 @@ Here are some more complex examples:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Access the number of samples for the Cycles render engine.
|
||||
bpy.context.scene.cycles.samples
|
||||
# access a render layers samples
|
||||
bpy.context.scene.render.layers["RenderLayer"].samples
|
||||
|
||||
# Access to the current weight paint brush size.
|
||||
# access to the current weight paint brush size
|
||||
bpy.context.tool_settings.weight_paint.brush.size
|
||||
|
||||
# Check if the window is full-screen.
|
||||
# check if the window is fullscreen
|
||||
bpy.context.window.screen.show_fullscreen
|
||||
|
||||
|
||||
As you can see there are times when you want to access data which is nested
|
||||
in a way that causes you to go through a few indirections.
|
||||
The properties are arranged to match how data is stored internally (in Blender's C code) which is often logical
|
||||
but not always quite what you would expect from using Blender.
|
||||
So this takes some time to learn, it helps you understand how data fits together in Blender
|
||||
which is important to know when writing scripts.
|
||||
|
||||
When starting out scripting you will often run into the problem
|
||||
where you're not sure how to access the data you want.
|
||||
There are a few ways to do this:
|
||||
The properties are arranged to match how data is stored internally (in blenders C code) which is often logical but
|
||||
not always quite what you would expect from using Blender.
|
||||
|
||||
So this takes some time to learn, it helps you understand how data fits together in Blender which is important
|
||||
to know when writing scripts.
|
||||
|
||||
|
||||
When starting out scripting you will often run into the problem where you're not sure how to access the data you want.
|
||||
|
||||
There are a few ways to do this.
|
||||
|
||||
- Use the Python console's auto-complete to inspect properties.
|
||||
*This can be hit-and-miss but has the advantage
|
||||
that you can easily see the values of properties and assign them to interactively see the results.*
|
||||
- Copy the data path from the user interface.
|
||||
*Explained further in* :ref:`Copy Data Path <info_data_path_copy>`.
|
||||
- Copy the Data-Path from the user interface.
|
||||
*Explained further in :ref:`Copy Data Path <info_data_path_copy>`*
|
||||
- Using the documentation to follow references.
|
||||
*Explained further in* :ref:`Indirect Data Access <info_data_path_indirect>`.
|
||||
*Explained further in :ref:`Indirect Data Access <info_data_path_indirect>`*
|
||||
|
||||
|
||||
.. _info_data_path_copy:
|
||||
@@ -142,36 +155,42 @@ There are a few ways to do this:
|
||||
Copy Data Path
|
||||
--------------
|
||||
|
||||
Blender can compute the Python string to a property which is shown in the tooltip,
|
||||
on the line below ``Python: ...``. This saves having to open the API references to find where data is accessed from.
|
||||
In the context menu is a copy data-path tool which gives the path from an :class:`bpy.types.ID` data-block,
|
||||
Blender can compute the Python string to a property which is shown in the tool-tip, on the line below ``Python: ...``,
|
||||
This saves having to use the API reference to click back up the references to find where data is accessed from.
|
||||
|
||||
There is a user-interface feature to copy the data-path which gives the path from an :class:`bpy.types.ID` data-block,
|
||||
to its property.
|
||||
|
||||
To see how this works you'll get the path to the Subdivision Surface modifiers *Levels* setting.
|
||||
Start with the default scene and select the Modifiers tab, then add a Subdivision Surface modifier to the cube.
|
||||
Now hover your mouse over the button labeled *Levels Viewport*,
|
||||
The tooltip includes :class:`bpy.types.SubsurfModifier.levels` but you want the path from the object to this property.
|
||||
To see how this works we'll get the path to the Subdivision-Surface modifiers subdivision setting.
|
||||
|
||||
Start with the default scene and select the **Modifiers** tab, then add a **Subdivision-Surface** modifier to the cube.
|
||||
|
||||
Now hover your mouse over the button labeled **View**, The tool-tip includes :class:`bpy.types.SubsurfModifier.levels`
|
||||
but we want the path from the object to this property.
|
||||
|
||||
Note that the text copied won't include the ``bpy.data.collection["name"].`` component since its assumed that
|
||||
you won't be doing collection look-ups on every access and typically you'll want to use the context rather
|
||||
then access each :class:`bpy.types.ID` instance by name.
|
||||
|
||||
Type in the ID path into a Python console :mod:`bpy.context.active_object`.
|
||||
Include the trailing dot and don't execute the code, yet.
|
||||
|
||||
Now in the button's context menu select *Copy Data Path*, then paste the result into the console:
|
||||
Type in the ID path into a Python console :mod:`bpy.context.active_object`.
|
||||
Include the trailing dot and don't hit "enter", yet.
|
||||
|
||||
Now right-click on the button and select **Copy Data Path**, then paste the result into the console.
|
||||
|
||||
So now you should have the answer:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels
|
||||
|
||||
Press :kbd:`Return` and you'll get the current value of 1. Now try changing the value to 2:
|
||||
Hit "enter" and you'll get the current value of 1. Now try changing the value to 2:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels = 2
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels = 2
|
||||
|
||||
You can see the value update in the Subdivision Surface modifier's UI as well as the cube.
|
||||
You can see the value update in the Subdivision-Surface modifier's UI as well as the cube.
|
||||
|
||||
|
||||
.. _info_data_path_indirect:
|
||||
@@ -179,45 +198,51 @@ You can see the value update in the Subdivision Surface modifier's UI as well as
|
||||
Indirect Data Access
|
||||
--------------------
|
||||
|
||||
This more advanced example shows the steps to access the active sculpt brushes texture.
|
||||
For example, if you want to access the texture of a brush via Python to adjust its ``contrast``.
|
||||
For this example we'll go over something more involved, showing the steps to access the active sculpt brushes texture.
|
||||
|
||||
#. Start in the default scene and enable Sculpt Mode from the 3D Viewport header.
|
||||
#. From the Sidebar expand the Brush Settings panel's *Texture* subpanel and add a new texture.
|
||||
*Notice the texture data-block menu itself doesn't have very useful links (you can check the tooltips).*
|
||||
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the properties editor:
|
||||
Lets say we want to access the texture of a brush via Python, to adjust its ``contrast`` for example.
|
||||
|
||||
- In the properties editor select the Texture tab.
|
||||
- Select brush texture.
|
||||
- Expand the *Colors* panel to locate the *Contrast* number field.
|
||||
#. Open the context menu of the contrast field and select *Online Python Reference*.
|
||||
This takes you to ``bpy.types.Texture.contrast``. Now you can see that ``contrast`` is a property of texture.
|
||||
#. To find out how to access the texture from the brush check on the references at the bottom of the page.
|
||||
Sometimes there are many references, and it may take some guesswork to find the right one,
|
||||
but in this case it's ``Brush.texture``.
|
||||
- Start in the default scene and enable 'Sculpt' mode from the 3D-View header.
|
||||
- From the toolbar expand the **Texture** panel and add a new texture.
|
||||
*Notice the texture button its self doesn't have very useful links (you can check the tooltips).*
|
||||
- The contrast setting isn't exposed in the sculpt toolbar, so view the texture in the properties panel...
|
||||
|
||||
#. Now you know that the texture can be accessed from ``bpy.data.brushes["BrushName"].texture``
|
||||
but normally you *won't* want to access the brush by name, instead you want to access the active brush.
|
||||
So the next step is to check on where brushes are accessed from via the references.
|
||||
In this case there it is simply ``bpy.context.brush``.
|
||||
- In the properties button select the Texture context.
|
||||
- Select the Brush icon to show the brush texture.
|
||||
- Expand the *Colors* panel to locate the *Contrast* button.
|
||||
- Right click on the contrast button and select **Online Python Reference**
|
||||
This takes you to ``bpy.types.Texture.contrast``
|
||||
- Now we can see that ``contrast`` is a property of texture,
|
||||
so next we'll check on how to access the texture from the brush.
|
||||
- Check on the **References** at the bottom of the page, sometimes there are many references, and it may take
|
||||
some guess work to find the right one, but in this case its obviously ``Brush.texture``.
|
||||
|
||||
Now you can use the Python console to form the nested properties needed to access brush textures contrast:
|
||||
*Context -> Brush -> Texture -> Contrast*.
|
||||
*Now we know that the texture can be accessed from* ``bpy.data.brushes["BrushName"].texture``
|
||||
*but normally you won't want to access the brush by name, so we'll see now to access the active brush instead.*
|
||||
- So the next step is to check on where brushes are accessed from via the **References**.
|
||||
In this case there is simply ``bpy.context.brush`` which is all we need.
|
||||
|
||||
Since the attribute for each is given along the way you can compose the data path in the Python console:
|
||||
Now you can use the Python console to form the nested properties needed to access brush textures contrast,
|
||||
logically we now know.
|
||||
|
||||
*Context -> Brush -> Texture -> Contrast*
|
||||
|
||||
Since the attribute for each is given along the way we can compose the data path in the python console:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.brush.texture.contrast
|
||||
|
||||
|
||||
There can be multiple ways to access the same data, which you choose often depends on the task.
|
||||
An alternate path to access the same setting is:
|
||||
|
||||
An alternate path to access the same setting is...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.sculpt.brush.texture.contrast
|
||||
|
||||
Or access the brush directly:
|
||||
Or access the brush directly...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -226,24 +251,27 @@ Or access the brush directly:
|
||||
|
||||
If you are writing a user tool normally you want to use the :mod:`bpy.context` since the user normally expects
|
||||
the tool to operate on what they have selected.
|
||||
For automation you are more likely to use :mod:`bpy.data` since you want to be able to access specific data and
|
||||
manipulate it, no matter what the user currently has the view set at.
|
||||
|
||||
For automation you are more likely to use :mod:`bpy.data` since you want to be able to access specific data and manipulate
|
||||
it, no matter what the user currently has the view set at.
|
||||
|
||||
|
||||
Operators
|
||||
=========
|
||||
|
||||
Most hotkeys and buttons in Blender call an operator which is also exposed to Python via :mod:`bpy.ops`.
|
||||
Most key-strokes and buttons in Blender call an operator which is also exposed to python via :mod:`bpy.ops`,
|
||||
|
||||
To see the Python equivalent hover your mouse over the button and see the tooltip,
|
||||
e.g ``Python: bpy.ops.render.render()``,
|
||||
If there is no tooltip or the ``Python:`` line is missing then this button is not using an operator
|
||||
and can't be accessed from Python.
|
||||
To see the Python equivalent hover your mouse over the button and see the tool-tip,
|
||||
eg ``Python: bpy.ops.render.render()``,
|
||||
If there is no tool-tip or the ``Python:`` line is missing then this button is not using an operator and
|
||||
can't be accessed from Python.
|
||||
|
||||
If you want to use this in a script you can press :kbd:`Ctrl-C` while your mouse is over the button
|
||||
to copy it to the clipboard.
|
||||
You can also use button's context menu and view the *Online Python Reference*, this mainly shows arguments and
|
||||
their defaults, however, operators written in Python show their file and line number which may be useful if you
|
||||
|
||||
If you want to use this in a script you can press :kbd:`Control-C` while your mouse is over the button to copy it to the
|
||||
clipboard.
|
||||
|
||||
You can also right click on the button and view the **Online Python Reference**, this mainly shows arguments and
|
||||
their defaults however operators written in Python show their file and line number which may be useful if you
|
||||
are interested to check on the source code.
|
||||
|
||||
.. note::
|
||||
@@ -252,18 +280,21 @@ are interested to check on the source code.
|
||||
for more on this see :ref:`using operators <using_operators>`.
|
||||
|
||||
|
||||
Info Editor
|
||||
-----------
|
||||
Info View
|
||||
---------
|
||||
|
||||
Blender records operators you run and displays them in the Info editor.
|
||||
Select the Scripting workspace that comes default with Blender to see its output.
|
||||
You can perform some actions and see them show up -- delete a vertex for example.
|
||||
Blender records operators you run and displays them in the **Info** space.
|
||||
This is located above the file-menu which can be dragged down to display its contents.
|
||||
|
||||
Each entry can be selected, then copied :kbd:`Ctrl-C`, usually to paste in the text editor or Python console.
|
||||
Select the **Script** screen that comes default with Blender to see its output.
|
||||
You can perform some actions and see them show up - delete a vertex for example.
|
||||
|
||||
Each entry can be selected (Right-Mouse-Button),
|
||||
then copied :kbd:`Control-C`, usually to paste in the text editor or python console.
|
||||
|
||||
.. note::
|
||||
|
||||
Not all operators get registered for display,
|
||||
zooming the view for example isn't so useful to repeat so its excluded from the output.
|
||||
|
||||
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`.
|
||||
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`
|
||||
|
@@ -3,34 +3,38 @@
|
||||
Best Practice
|
||||
*************
|
||||
|
||||
When writing your own scripts Python is great for new developers to pick up and become productive,
|
||||
but you can also pick up bad practices or at least write scripts that are not easy for others to understand.
|
||||
When writing your own scripts python is great for new developers to pick up and become productive,
|
||||
but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
|
||||
|
||||
For your own work this is of course fine,
|
||||
but if you want to collaborate with others or have your work included with Blender there are practices we encourage.
|
||||
but if you want to collaborate with others or have your work included with blender there are practices we encourage.
|
||||
|
||||
|
||||
Style Conventions
|
||||
=================
|
||||
|
||||
For Blender Python development we have chosen to follow Python suggested style guide to avoid mixing styles
|
||||
among our own scripts and make it easier to use Python scripts from other projects.
|
||||
Using our style guide for your own scripts makes it easier if you eventually want to contribute them to Blender.
|
||||
For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles
|
||||
amongst our own scripts and make it easier to use python scripts from other projects.
|
||||
|
||||
This style guide is known as `pep8 <https://www.python.org/dev/peps/pep-0008/>`__
|
||||
and here is a brief listing of pep8 criteria:
|
||||
Using our style guide for your own scripts makes it easier if you eventually want to contribute them to blender.
|
||||
|
||||
- Camel caps for class names: MyClass
|
||||
- All lower case underscore separated module names: my_module
|
||||
- Indentation of 4 spaces (no tabs)
|
||||
- Spaces around operators: ``1 + 1``, not ``1+1``
|
||||
- Only use explicit imports (no wildcard importing ``*``)
|
||||
- Don't use multiple statements on a single line: ``if val: body``, separate onto two lines instead.
|
||||
This style guide is known as pep8 and can be found `here <https://www.python.org/dev/peps/pep-0008/>`_
|
||||
|
||||
As well as pep8 we have additional conventions used for Blender Python scripts:
|
||||
A brief listing of pep8 criteria.
|
||||
|
||||
- camel caps for class names: MyClass
|
||||
- all lower case underscore separated module names: my_module
|
||||
- indentation of 4 spaces (no tabs)
|
||||
- spaces around operators. ``1 + 1``, not ``1+1``
|
||||
- only use explicit imports, (no importing ``*``)
|
||||
- don't use single line: ``if val: body``, separate onto 2 lines instead.
|
||||
|
||||
|
||||
As well as pep8 we have other conventions used for blender python scripts.
|
||||
|
||||
- Use single quotes for enums, and double quotes for strings.
|
||||
|
||||
Both are of course strings, but in our internal API enums are unique items from a limited set, e.g:
|
||||
Both are of course strings, but in our internal API enums are unique items from a limited set. eg.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -38,14 +42,14 @@ As well as pep8 we have additional conventions used for Blender Python scripts:
|
||||
bpy.context.scene.render.filepath = "//render_out"
|
||||
|
||||
- pep8 also defines that lines should not exceed 79 characters,
|
||||
we have decided that this is too restrictive so it is optional per script.
|
||||
we felt this is too restrictive so this is optional per script.
|
||||
|
||||
Periodically we run checks for pep8 compliance on Blender scripts,
|
||||
for scripts to be included in this check add this line as a comment at the top of the script:
|
||||
Periodically we run checks for pep8 compliance on blender scripts,
|
||||
for scripts to be included in this check add this line as a comment at the top of the script.
|
||||
|
||||
``# <pep8 compliant>``
|
||||
|
||||
To enable line length checks use this instead:
|
||||
To enable line length checks use this instead.
|
||||
|
||||
``# <pep8-80 compliant>``
|
||||
|
||||
@@ -55,79 +59,85 @@ User Interface Layout
|
||||
|
||||
Some notes to keep in mind when writing UI layouts:
|
||||
|
||||
UI code is quite simple. Layout declarations are there to easily create a decent layout.
|
||||
The general rule here is: If you need more code for the layout declaration,
|
||||
than for the actual properties, then you are doing it wrong.
|
||||
- UI code is quite simple. Layout declarations are there to easily create a decent layout.
|
||||
|
||||
General rule here: If you need more code for the layout declaration,
|
||||
then for the actual properties, you do it wrong.
|
||||
|
||||
.. rubric:: Example layouts:
|
||||
Example layouts:
|
||||
|
||||
``layout()``
|
||||
The basic layout is a simple top-to-bottom layout.
|
||||
- layout()
|
||||
|
||||
.. code-block:: python
|
||||
The basic layout is a simple Top -> Bottom layout.
|
||||
|
||||
layout.prop()
|
||||
layout.prop()
|
||||
.. code-block:: python
|
||||
|
||||
``layout.row()``
|
||||
Use ``row()``, when you want more than one property in a single line.
|
||||
layout.prop()
|
||||
layout.prop()
|
||||
|
||||
.. code-block:: python
|
||||
- layout.row()
|
||||
|
||||
row = layout.row()
|
||||
row.prop()
|
||||
row.prop()
|
||||
Use row(), when you want more than 1 property in one line.
|
||||
|
||||
``layout.column()``
|
||||
Use ``column()``, when you want your properties in a column.
|
||||
.. code-block:: python
|
||||
|
||||
.. code-block:: python
|
||||
row = layout.row()
|
||||
row.prop()
|
||||
row.prop()
|
||||
|
||||
col = layout.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
- layout.column()
|
||||
|
||||
``layout.split()``
|
||||
This can be used to create more complex layouts.
|
||||
For example, you can split the layout and create two ``column()`` layouts next to each other.
|
||||
Do not use split, when you simply want two properties in a row. Use ``row()`` instead.
|
||||
Use column(), when you want your properties in a column.
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: python
|
||||
|
||||
split = layout.split()
|
||||
col = layout.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
- layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
This can be used to create more complex layouts.
|
||||
For example you can split the layout and create two column() layouts next to each other.
|
||||
Don't use split, when you simply want two properties in a row. Use row() for that.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
.. rubric:: Declaration names:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
Declaration names:
|
||||
|
||||
Try to only use these variable names for layout declarations:
|
||||
|
||||
:row: for a ``row()`` layout
|
||||
:col: for a ``column()`` layout
|
||||
:split: for a ``split()`` layout
|
||||
:flow: for a ``column_flow()`` layout
|
||||
:sub: for a sub layout (a column inside a column for example)
|
||||
- row for a row() layout
|
||||
- col for a column() layout
|
||||
- split for a split() layout
|
||||
- flow for a column_flow() layout
|
||||
- sub for a sub layout (a column inside a column for example)
|
||||
|
||||
|
||||
Script Efficiency
|
||||
=================
|
||||
|
||||
|
||||
List Manipulation (General Python Tips)
|
||||
---------------------------------------
|
||||
|
||||
Searching for List Items
|
||||
|
||||
Searching for list items
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In Python there are some handy list functions that save you having to search through the list.
|
||||
Even though you are not looping on the list data **Python is**,
|
||||
|
||||
Even though you are not looping on the list data **python is**,
|
||||
so you need to be aware of functions that will slow down your script by searching the whole list.
|
||||
|
||||
.. code-block:: python
|
||||
@@ -140,21 +150,23 @@ so you need to be aware of functions that will slow down your script by searchin
|
||||
|
||||
Modifying Lists
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
In Python you can add and remove from a list, this is slower when the list length is modified,
|
||||
In python we can add and remove from a list, this is slower when the list length is modified,
|
||||
especially at the start of the list, since all the data after the index of
|
||||
modification needs to be moved up or down one place.
|
||||
modification needs to be moved up or down 1 place.
|
||||
|
||||
The fastest way to add onto the end of the list is to use
|
||||
``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and
|
||||
to remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
|
||||
The most simple way to add onto the end of the list is to use
|
||||
``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to
|
||||
remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
|
||||
|
||||
To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(index)``
|
||||
for list removal, but these are slower.
|
||||
|
||||
Sometimes it's faster (but less memory efficient) to just rebuild the list.
|
||||
For example if you want to remove all triangular polygons in a list.
|
||||
Rather than:
|
||||
Sometimes its faster (but more memory hungry) to just rebuild the list.
|
||||
|
||||
|
||||
Say you want to remove all triangular polygons in a list.
|
||||
|
||||
Rather than...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -167,7 +179,7 @@ Rather than:
|
||||
polygons.pop(p_idx) # remove the triangle
|
||||
|
||||
|
||||
It's faster to build a new list with list comprehension:
|
||||
It's faster to build a new list with list comprehension.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -177,14 +189,14 @@ It's faster to build a new list with list comprehension:
|
||||
Adding List Items
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you have a list that you want to add onto another list, rather than:
|
||||
If you have a list that you want to add onto another list, rather than...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
for l in some_list:
|
||||
my_list.append(l)
|
||||
|
||||
Use:
|
||||
Use...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -193,7 +205,9 @@ Use:
|
||||
|
||||
Note that insert can be used when needed,
|
||||
but it is slower than append especially when inserting at the start of a long list.
|
||||
This example shows a very suboptimal way of making a reversed list:
|
||||
|
||||
This example shows a very sub-optimal way of making a reversed list.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -205,6 +219,7 @@ This example shows a very suboptimal way of making a reversed list:
|
||||
Python provides more convenient ways to reverse a list using the slice method,
|
||||
but you may want to time this before relying on it too much:
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
some_reversed_list = some_list[::-1]
|
||||
@@ -213,10 +228,12 @@ but you may want to time this before relying on it too much:
|
||||
Removing List Items
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Use ``my_list.pop(index)`` rather than ``my_list.remove(list_item)``.
|
||||
Use ``my_list.pop(index)`` rather than ``my_list.remove(list_item)``
|
||||
|
||||
This requires you to have the index of the list item but is faster since ``remove()`` will search the list.
|
||||
Here is an example of how to remove items in one loop,
|
||||
removing the last items first, which is faster (as explained above):
|
||||
|
||||
Here is an example of how to remove items in 1 loop,
|
||||
removing the last items first, which is faster (as explained above).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -230,7 +247,7 @@ removing the last items first, which is faster (as explained above):
|
||||
|
||||
This example shows a fast way of removing items,
|
||||
for use in cases where you can alter the list order without breaking the scripts functionality.
|
||||
This works by swapping two list items, so the item you remove is always last:
|
||||
This works by swapping 2 list items, so the item you remove is always last.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -243,59 +260,64 @@ This works by swapping two list items, so the item you remove is always last:
|
||||
my_list.pop()
|
||||
|
||||
|
||||
When removing many items in a large list this can provide a good speed-up.
|
||||
When removing many items in a large list this can provide a good speedup.
|
||||
|
||||
|
||||
Avoid Copying Lists
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When passing a list or dictionary to a function,
|
||||
When passing a list/dictionary to a function,
|
||||
it is faster to have the function modify the list rather than returning
|
||||
a new list so Python doesn't have to duplicate the list in memory.
|
||||
a new list so python doesn't have to duplicate the list in memory.
|
||||
|
||||
Functions that modify a list in-place are more efficient than functions that create new lists.
|
||||
This is generally slower so only use for functions when it makes sense not to modify the list in place:
|
||||
|
||||
|
||||
This is generally slower so only use for functions when it makes sense not to modify the list in place.
|
||||
|
||||
>>> my_list = some_list_func(my_list)
|
||||
|
||||
|
||||
This is generally faster since there is no re-assignment and no list duplication:
|
||||
This is generally faster since there is no re-assignment and no list duplication.
|
||||
|
||||
>>> some_list_func(vec)
|
||||
|
||||
|
||||
Also note that, passing a sliced list makes a copy of the list in Python memory:
|
||||
Also note that passing a sliced list makes a copy of the list in python memory.
|
||||
|
||||
>>> foobar(my_list[:])
|
||||
|
||||
If my_list was a large array containing 10,000's of items, a copy could use a lot of extra memory.
|
||||
If my_list was a large array containing 10000's of items, a copy could use a lot of extra memory.
|
||||
|
||||
|
||||
Writing Strings to a File (Python General)
|
||||
------------------------------------------
|
||||
|
||||
Here are three ways of joining multiple strings into one string for writing.
|
||||
This also applies to any area of your code that involves a lot of string joining:
|
||||
|
||||
String concatenation
|
||||
This is the slowest option, do **not** use if you can avoid it, especially when writing data in a loop.
|
||||
|
||||
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
|
||||
|
||||
String formatting
|
||||
Use this when you are writing string data from floats and ints.
|
||||
|
||||
>>> file.write("%s %s %s\n" % (str1, str2, str3))
|
||||
|
||||
String joining
|
||||
Use to join a list of strings (the list may be temporary). In the following example, the strings are joined with
|
||||
a space " " in between, other examples are "" or ", ".
|
||||
|
||||
>>> file.write(" ".join((str1, str2, str3, "\n")))
|
||||
Here are 3 ways of joining multiple strings into one string for writing.
|
||||
This also applies to any area of your code that involves a lot of string joining.
|
||||
|
||||
|
||||
Join is fastest on many strings, string formatting is quite fast too (better for converting data types).
|
||||
String concatenation is the slowest.
|
||||
``String addition`` -
|
||||
this is the slowest option, *don't use if you can help it, especially when writing data in a loop*.
|
||||
|
||||
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
|
||||
|
||||
|
||||
``String formatting`` -
|
||||
use this when you are writing string data from floats and ints.
|
||||
|
||||
>>> file.write("%s %s %s\n" % (str1, str2, str3))
|
||||
|
||||
|
||||
``String join() function``
|
||||
use to join a list of strings (the list may be temporary). In the following example, the strings are joined with a space " " in between, other examples are "" or ", ".
|
||||
|
||||
>>> file.write(" ".join([str1, str2, str3, "\n"]))
|
||||
|
||||
|
||||
Join is fastest on many strings,
|
||||
`string formatting <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`__
|
||||
is quite fast too (better for converting data types). String arithmetic is slowest.
|
||||
|
||||
|
||||
Parsing Strings (Import/Exporting)
|
||||
@@ -311,35 +333,36 @@ Parsing Numbers
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``,
|
||||
``float()`` will work for an int too but it is faster to read ints with ``int()``.
|
||||
float() will work for an int too but it is faster to read ints with int().
|
||||
|
||||
|
||||
Checking String Start/End
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you are checking the start of a string for a keyword, rather than:
|
||||
If you are checking the start of a string for a keyword, rather than...
|
||||
|
||||
>>> if line[0:5] == "vert ": ...
|
||||
|
||||
Use:
|
||||
use...
|
||||
|
||||
>>> if line.startswith("vert "):
|
||||
|
||||
Using ``startswith()`` is slightly faster (around 5%) and also avoids a possible error
|
||||
with the slice length not matching the string length.
|
||||
Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible
|
||||
error with the slice length not matching the string length.
|
||||
|
||||
``my_string.endswith("foo_bar")`` can be used for line endings too.
|
||||
my_string.endswith("foo_bar") can be used for line endings too.
|
||||
|
||||
If you are unsure whether the text is upper or lower case, use the ``lower()`` or ``upper()`` string function:
|
||||
If you are unsure whether the text is upper or lower case, use the ``lower()`` or ``upper()`` string function.
|
||||
|
||||
>>> if line.lower().startswith("vert ")
|
||||
|
||||
|
||||
Error Handling
|
||||
--------------
|
||||
Use try/except Sparingly
|
||||
------------------------
|
||||
|
||||
The **try** statement is useful to save time writing error checking code.
|
||||
However, **try** is significantly slower than an **if** since an exception has to be set each time,
|
||||
|
||||
However **try** is significantly slower than an **if** since an exception has to be set each time,
|
||||
so avoid using **try** in areas of your code that execute in a loop and runs many times.
|
||||
|
||||
There are cases where using **try** is faster than checking whether the condition will raise an error,
|
||||
@@ -359,7 +382,7 @@ In cases where you know you are checking for the same value which is referenced
|
||||
Time Your Code
|
||||
--------------
|
||||
|
||||
While developing a script it is good to time it to be aware of any changes in performance, this can be done simply:
|
||||
While developing a script it is good to time it to be aware of any changes in performance, this can be done simply.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@@ -4,7 +4,7 @@ Gotchas
|
||||
*******
|
||||
|
||||
This document attempts to help you work with the Blender API in areas
|
||||
that can be troublesome and avoid practices that are known to cause instability.
|
||||
that can be troublesome and avoid practices that are known to give instability.
|
||||
|
||||
|
||||
.. _using_operators:
|
||||
@@ -12,13 +12,13 @@ that can be troublesome and avoid practices that are known to cause instability.
|
||||
Using Operators
|
||||
===============
|
||||
|
||||
Blender's operators are tools for users to access, that can access with Python too which is very useful.
|
||||
Still operators have limitations that can make them cumbersome to script.
|
||||
Blender's operators are tools for users to access, that Python can access them too is very useful
|
||||
nevertheless operators have limitations that can make them cumbersome to script.
|
||||
|
||||
The main limits are:
|
||||
Main limits are...
|
||||
|
||||
- Can't pass data such as objects, meshes or materials to operate on (operators use the context instead).
|
||||
- The return value from calling an operator is the success (if it finished or was canceled),
|
||||
- Can't pass data such as objects, meshes or materials to operate on (operators use the context instead)
|
||||
- The return value from calling an operator gives the success (if it finished or was canceled),
|
||||
in some cases it would be more logical from an API perspective to return the result of the operation.
|
||||
- Operators poll function can fail where an API function would raise an exception giving details on exactly why.
|
||||
|
||||
@@ -34,23 +34,26 @@ When calling an operator gives an error like this:
|
||||
Which raises the question as to what the correct context might be?
|
||||
|
||||
Typically operators check for the active area type, a selection or active object they can operate on,
|
||||
but some operators are more strict when they run.
|
||||
In most cases you can figure out what context an operator needs
|
||||
by examining how it's used in Blender and thinking about what it does.
|
||||
but some operators are more picky about when they run.
|
||||
|
||||
In most cases you can figure out what context an operator needs
|
||||
simply be seeing how it's used in Blender and thinking about what it does.
|
||||
|
||||
Unfortunately if you're still stuck - the only way to **really** know
|
||||
what's going on is to read the source code for the poll function and see what its checking.
|
||||
|
||||
If you're still stuck, unfortunately, the only way to eventually know what is causing the error is
|
||||
to read the source code for the poll function and see what it is checking.
|
||||
For Python operators it's not so hard to find the source
|
||||
since it's included with Blender and the source file and line is included in the operator reference docs.
|
||||
since it's included with Blender and the source file/line is included in the operator reference docs.
|
||||
|
||||
Downloading and searching the C code isn't so simple,
|
||||
especially if you're not familiar with the C language but by searching the operator name or description
|
||||
you should be able to find the poll function with no knowledge of C.
|
||||
especially if you're not familiar with the C language but by searching the
|
||||
operator name or description you should be able to find the poll function with no knowledge of C.
|
||||
|
||||
.. note::
|
||||
|
||||
Blender does have the functionality for poll functions to describe why they fail,
|
||||
but its currently not used much, if you're interested to help improve the API
|
||||
feel free to add calls to ``CTX_wm_operator_poll_msg_set`` where its not obvious why poll fails, e.g:
|
||||
but its currently not used much, if you're interested to help improve our API
|
||||
feel free to add calls to ``CTX_wm_operator_poll_msg_set`` where its not obvious why poll fails.
|
||||
|
||||
>>> bpy.ops.gpencil.draw()
|
||||
RuntimeError: Operator bpy.ops.gpencil.draw.poll() Failed to find Grease Pencil data to draw into
|
||||
@@ -60,7 +63,7 @@ The operator still doesn't work!
|
||||
--------------------------------
|
||||
|
||||
Certain operators in Blender are only intended for use in a specific context,
|
||||
some operators for example are only called from the properties editor where they check the current material,
|
||||
some operators for example are only called from the properties window where they check the current material,
|
||||
modifier or constraint.
|
||||
|
||||
Examples of this are:
|
||||
@@ -71,8 +74,8 @@ Examples of this are:
|
||||
- :mod:`bpy.ops.buttons.file_browse`
|
||||
|
||||
Another possibility is that you are the first person to attempt to use this operator
|
||||
in a script and some modifications need to be made to the operator to run in a different context.
|
||||
If the operator should logically be able to run but fails when accessed from a script
|
||||
in a script and some modifications need to be made to the operator to run in a different context,
|
||||
if the operator should logically be able to run but fails when accessed from a script
|
||||
it should be reported to the bug tracker.
|
||||
|
||||
|
||||
@@ -82,20 +85,22 @@ Stale Data
|
||||
No updates after setting values
|
||||
-------------------------------
|
||||
|
||||
Sometimes you want to modify values from Python and immediately access the updated values, e.g:
|
||||
Sometimes you want to modify values from Python and immediately access the updated values, eg:
|
||||
|
||||
Once changing the objects :class:`bpy.types.Object.location`
|
||||
you may want to access its transformation right after from :class:`bpy.types.Object.matrix_world`,
|
||||
but this doesn't work as you might expect.
|
||||
|
||||
Consider the calculations that might contribute to the object's final transformation, this includes:
|
||||
Consider the calculations that might go into working out the object's final transformation, this includes:
|
||||
|
||||
- Animation function curves.
|
||||
- Drivers and their Python expressions.
|
||||
- Constraints
|
||||
- Parent objects and all of their F-curves, constraints, etc.
|
||||
- animation function curves.
|
||||
- drivers and their Python expressions.
|
||||
- constraints
|
||||
- parent objects and all of their f-curves, constraints etc.
|
||||
|
||||
To avoid expensive recalculations every time a property is modified,
|
||||
Blender defers the evaluation until the results are needed.
|
||||
Blender defers making the actual calculations until they are needed.
|
||||
|
||||
However, while the script runs you may want to access the updated values.
|
||||
In this case you need to call :class:`bpy.types.ViewLayer.update` after modifying values, for example:
|
||||
|
||||
@@ -105,41 +110,44 @@ In this case you need to call :class:`bpy.types.ViewLayer.update` after modifyin
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
|
||||
Now all dependent data (child objects, modifiers, drivers, etc.)
|
||||
Now all dependent data (child objects, modifiers, drivers... etc)
|
||||
has been recalculated and is available to the script within active view layer.
|
||||
|
||||
|
||||
Can I redraw during script execution?
|
||||
-------------------------------------
|
||||
Can I redraw during the script?
|
||||
-------------------------------
|
||||
|
||||
The official answer to this is no, or... *"You don't want to do that"*.
|
||||
To give some background on the topic:
|
||||
|
||||
To give some background on the topic...
|
||||
|
||||
While a script executes Blender waits for it to finish and is effectively locked until its done,
|
||||
while in this state Blender won't redraw or respond to user input.
|
||||
Normally this is not such a problem because scripts distributed with Blender
|
||||
tend not to run for an extended period of time,
|
||||
nevertheless scripts *can* take a long time to complete and it would be nice to see progress in the viewport.
|
||||
nevertheless scripts *can* take ages to execute and its nice to see what's going on in the view port.
|
||||
|
||||
When tools lock Blender in a loop redraw are highly discouraged
|
||||
since they conflict with Blender's ability to run multiple operators
|
||||
Tools that lock Blender in a loop and redraw are highly discouraged
|
||||
since they conflict with Blenders ability to run multiple operators
|
||||
at once and update different parts of the interface as the tool runs.
|
||||
|
||||
So the solution here is to write a **modal** operator, which is an operator that defines a ``modal()`` function,
|
||||
See the modal operator template in the text editor.
|
||||
So the solution here is to write a **modal** operator, that is - an operator which defines a modal() function,
|
||||
See the modal operator template in the text editor.
|
||||
|
||||
Modal operators execute on user input or setup their own timers to run frequently,
|
||||
they can handle the events or pass through to be handled by the keymap or other modal operators.
|
||||
Examples of a modal operators are Transform, Painting, Fly Navigation and File Select.
|
||||
|
||||
Transform, Painting, Fly-Mode and File-Select are example of a modal operators.
|
||||
|
||||
Writing modal operators takes more effort than a simple ``for`` loop
|
||||
that contains draw calls but is more flexible and integrates better with Blender's design.
|
||||
that happens to redraw but is more flexible and integrates better with Blenders design.
|
||||
|
||||
|
||||
.. rubric:: Ok, Ok! I still want to draw from Python
|
||||
**Ok, Ok! I still want to draw from Python**
|
||||
|
||||
If you insist -- yes it's possible, but scripts that use this hack will not be considered
|
||||
for inclusion in Blender and any issue with using it will not be considered a bug,
|
||||
there is also no guaranteed compatibility in future releases.
|
||||
If you insist - yes its possible, but scripts that use this hack won't be considered
|
||||
for inclusion in Blender and any issues with using it won't be considered bugs,
|
||||
this is also not guaranteed to work in future releases.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -149,18 +157,18 @@ there is also no guaranteed compatibility in future releases.
|
||||
Modes and Mesh Access
|
||||
=====================
|
||||
|
||||
When working with mesh data you may run into the problem where a script fails to run as expected in Edit-Mode.
|
||||
This is caused by Edit-Mode having its own data which is only written back to the mesh when exiting Edit-Mode.
|
||||
When working with mesh data you may run into the problem where a script fails to run as expected in edit-mode.
|
||||
This is caused by edit-mode having its own data which is only written back to the mesh when exiting edit-mode.
|
||||
|
||||
A common example is that exporters may access a mesh through ``obj.data`` (a :class:`bpy.types.Mesh`)
|
||||
when the user is in Edit-Mode, where the mesh data is available but out of sync with the edit mesh.
|
||||
but the user is in edit-mode, where the mesh data is available but out of sync with the edit mesh.
|
||||
|
||||
In this situation you can...
|
||||
|
||||
- Exit Edit-Mode before running the tool.
|
||||
- Exit edit-mode before running the tool.
|
||||
- Explicitly update the mesh by calling :class:`bmesh.types.BMesh.to_mesh`.
|
||||
- Modify the script to support working on the edit-mode data directly, see: :mod:`bmesh.from_edit_mesh`.
|
||||
- Report the context as incorrect and only allow the script to run outside Edit-Mode.
|
||||
- Report the context as incorrect and only allow the script to run outside edit-mode.
|
||||
|
||||
|
||||
.. _info_gotcha_mesh_faces:
|
||||
@@ -168,24 +176,24 @@ In this situation you can...
|
||||
N-Gons and Tessellation
|
||||
=======================
|
||||
|
||||
Since 2.63 n-gons are supported, this adds some complexity
|
||||
Since 2.63 NGons are supported, this adds some complexity
|
||||
since in some cases you need to access triangles still (some exporters for example).
|
||||
|
||||
There are now three ways to access faces:
|
||||
There are now 3 ways to access faces:
|
||||
|
||||
- :class:`bpy.types.MeshPolygon` --
|
||||
this is the data structure which now stores faces in Object-Mode
|
||||
- :class:`bpy.types.MeshPolygon` -
|
||||
this is the data structure which now stores faces in object mode
|
||||
(access as ``mesh.polygons`` rather than ``mesh.faces``).
|
||||
- :class:`bpy.types.MeshLoopTriangle` --
|
||||
- :class:`bpy.types.MeshLoopTriangle` -
|
||||
the result of tessellating polygons into triangles
|
||||
(access as ``mesh.loop_triangles``).
|
||||
- :class:`bmesh.types.BMFace` --
|
||||
the polygons as used in Edit-Mode.
|
||||
- :class:`bmesh.types.BMFace` -
|
||||
the polygons as used in editmode.
|
||||
|
||||
For the purpose of the following documentation,
|
||||
these will be referred to as polygons, loop triangles and BMesh-faces respectively.
|
||||
these will be referred to as polygons, loop triangles and bmesh-faces respectively.
|
||||
|
||||
Faces with five or more sides will be referred to as ``ngons``.
|
||||
5+ sided faces will be referred to as ``ngons``.
|
||||
|
||||
|
||||
Support Overview
|
||||
@@ -208,58 +216,58 @@ Support Overview
|
||||
- Unusable *(read-only)*.
|
||||
- Best
|
||||
* - Export/Output
|
||||
- Good *(n-gon support)*
|
||||
- Good *(When n-gons cannot be used)*
|
||||
- Good *(n-gons, extra memory overhead)*
|
||||
- Good *(ngon support)*
|
||||
- Good *(When ngons can't be used)*
|
||||
- Good *(ngons, extra memory overhead)*
|
||||
|
||||
.. note::
|
||||
|
||||
Using the :mod:`bmesh` API is completely separate API from :mod:`bpy`,
|
||||
typically you would use one or the other based on the level of editing needed,
|
||||
typically you would would use one or the other based on the level of editing needed,
|
||||
not simply for a different way to access faces.
|
||||
|
||||
|
||||
Creating
|
||||
--------
|
||||
|
||||
All three data types can be used for face creation:
|
||||
All 3 datatypes can be used for face creation.
|
||||
|
||||
- Polygons are the most efficient way to create faces but the data structure is *very* rigid and inflexible,
|
||||
- polygons are the most efficient way to create faces but the data structure is _very_ rigid and inflexible,
|
||||
you must have all your vertices and faces ready and create them all at once.
|
||||
This is further complicated by the fact that each polygon does not store its own vertices,
|
||||
This is further complicated by the fact that each polygon does not store its own verts,
|
||||
rather they reference an index and size in :class:`bpy.types.Mesh.loops` which are a fixed array too.
|
||||
- BMesh-faces are most likely the easiest way to create faces in new scripts,
|
||||
since faces can be added one by one and the API has features intended for mesh manipulation.
|
||||
- bmesh-faces are most likely the easiest way for new scripts to create faces,
|
||||
since faces can be added one by one and the api has features intended for mesh manipulation.
|
||||
While :class:`bmesh.types.BMesh` uses more memory it can be managed by only operating on one mesh at a time.
|
||||
|
||||
|
||||
Editing
|
||||
-------
|
||||
|
||||
Editing is where the three data types vary most.
|
||||
Editing is where the 3 data types vary most.
|
||||
|
||||
- Polygons are very limited for editing,
|
||||
changing materials and options like smooth works but for anything else
|
||||
they are too inflexible and are only intended for storage.
|
||||
- Tessfaces should not be used for editing geometry because doing so will cause existing n-gons to be tessellated.
|
||||
- BMesh-faces are by far the best way to manipulate geometry.
|
||||
- Tessfaces should not be used for editing geometry because doing so will cause existing ngons to be tessellated.
|
||||
- BMesh-Faces are by far the best way to manipulate geometry.
|
||||
|
||||
|
||||
Exporting
|
||||
---------
|
||||
|
||||
All three data types can be used for exporting,
|
||||
the choice mostly depends on whether the target format supports n-gons or not.
|
||||
All 3 data types can be used for exporting,
|
||||
the choice mostly depends on whether the target format supports ngons or not.
|
||||
|
||||
- Polygons are the most direct and efficient way to export providing they convert into the output format easily enough.
|
||||
- Tessfaces work well for exporting to formats which don't support n-gons,
|
||||
- Polygons are the most direct & efficient way to export providing they convert into the output format easily enough.
|
||||
- Tessfaces work well for exporting to formats which don't support ngons,
|
||||
in fact this is the only place where their use is encouraged.
|
||||
- BMesh-Faces can work for exporting too but may not be necessary if polygons can be used
|
||||
since using BMesh gives some overhead because its not the native storage format in Object-Mode.
|
||||
since using bmesh gives some overhead because its not the native storage format in object mode.
|
||||
|
||||
|
||||
Edit Bones, Pose Bones, Bone... Bones
|
||||
=====================================
|
||||
EditBones, PoseBones, Bone... Bones
|
||||
===================================
|
||||
|
||||
Armature Bones in Blender have three distinct data structures that contain them.
|
||||
If you are accessing the bones through one of them, you may not have access to the properties you really need.
|
||||
@@ -272,41 +280,43 @@ If you are accessing the bones through one of them, you may not have access to t
|
||||
Edit Bones
|
||||
----------
|
||||
|
||||
``bpy.context.object.data.edit_bones`` contains an edit bones;
|
||||
to access them you must set the armature mode to Edit-Mode first (edit bones do not exist in Object or Pose-Mode).
|
||||
``bpy.context.object.data.edit_bones`` contains a editbones;
|
||||
to access them you must set the armature mode to edit mode first (editbones do not exist in object or pose mode).
|
||||
Use these to create new bones, set their head/tail or roll, change their parenting relationships to other bones, etc.
|
||||
|
||||
Example using :class:`bpy.types.EditBone` in armature Edit-Mode
|
||||
which is only possible in Edit-Mode:
|
||||
Example using :class:`bpy.types.EditBone` in armature editmode:
|
||||
|
||||
This is only possible in edit mode.
|
||||
|
||||
>>> bpy.context.object.data.edit_bones["Bone"].head = Vector((1.0, 2.0, 3.0))
|
||||
|
||||
This will be empty outside of Edit-Mode:
|
||||
This will be empty outside of editmode.
|
||||
|
||||
>>> mybones = bpy.context.selected_editable_bones
|
||||
|
||||
Returns an edit bone only in Edit-Mode:
|
||||
Returns an editbone only in edit mode.
|
||||
|
||||
>>> bpy.context.active_bone
|
||||
|
||||
|
||||
Bones (Object-Mode)
|
||||
Bones (Object Mode)
|
||||
-------------------
|
||||
|
||||
``bpy.context.object.data.bones`` contains bones.
|
||||
These *live* in Object-Mode, and have various properties you can change,
|
||||
These *live* in object mode, and have various properties you can change,
|
||||
note that the head and tail properties are read-only.
|
||||
|
||||
Example using :class:`bpy.types.Bone` in Object or Pose-Mode
|
||||
returning a bone (not an edit bone) outside of Edit-Mode:
|
||||
Example using :class:`bpy.types.Bone` in object or pose mode:
|
||||
|
||||
Returns a bone (not an editbone) outside of edit mode
|
||||
|
||||
>>> bpy.context.active_bone
|
||||
|
||||
This works, as with Blender the setting can be edited in any mode:
|
||||
This works, as with blender the setting can be edited in any mode
|
||||
|
||||
>>> bpy.context.object.data.bones["Bone"].use_deform = True
|
||||
|
||||
Accessible but read-only:
|
||||
Accessible but read-only
|
||||
|
||||
>>> tail = myobj.data.bones["Bone"].tail
|
||||
|
||||
@@ -316,42 +326,42 @@ Pose Bones
|
||||
|
||||
``bpy.context.object.pose.bones`` contains pose bones.
|
||||
This is where animation data resides, i.e. animatable transformations
|
||||
are applied to pose bones, as are constraints and IK-settings.
|
||||
are applied to pose bones, as are constraints and ik-settings.
|
||||
|
||||
Examples using :class:`bpy.types.PoseBone` in Object or Pose-Mode:
|
||||
Examples using :class:`bpy.types.PoseBone` in object or pose mode:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Gets the name of the first constraint (if it exists)
|
||||
bpy.context.object.pose.bones["Bone"].constraints[0].name
|
||||
|
||||
# Gets the last selected pose bone (Pose-Mode only)
|
||||
# Gets the last selected pose bone (pose mode only)
|
||||
bpy.context.active_pose_bone
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Notice the pose is accessed from the object rather than the object data,
|
||||
this is why Blender can have two or more objects sharing the same armature in different poses.
|
||||
this is why blender can have 2 or more objects sharing the same armature in different poses.
|
||||
|
||||
.. note::
|
||||
|
||||
Strictly speaking pose bones are not bones, they are just the state of the armature,
|
||||
Strictly speaking PoseBone's are not bones, they are just the state of the armature,
|
||||
stored in the :class:`bpy.types.Object` rather than the :class:`bpy.types.Armature`,
|
||||
yet the real bones are accessible from the pose bones via :class:`bpy.types.PoseBone.bone`.
|
||||
the real bones are however accessible from the pose bones - :class:`bpy.types.PoseBone.bone`
|
||||
|
||||
|
||||
Armature Mode Switching
|
||||
-----------------------
|
||||
|
||||
While writing scripts that deal with armatures you may find you have to switch between modes,
|
||||
when doing so take care when switching out of Edit-Mode not to keep references
|
||||
to the edit bones or their head/tail vectors.
|
||||
Further access to these will crash Blender so its important the script
|
||||
when doing so take care when switching out of edit-mode not to keep references
|
||||
to the edit-bones or their head/tail vectors.
|
||||
Further access to these will crash blender so its important the script
|
||||
clearly separates sections of the code which operate in different modes.
|
||||
|
||||
This is mainly an issue with Edit-Mode since pose data can be manipulated without having to be in Pose-Mode,
|
||||
yet for operator access you may still need to enter Pose-Mode.
|
||||
This is mainly an issue with editmode since pose data can be manipulated without having to be in pose mode,
|
||||
however for operator access you may still need to enter pose mode.
|
||||
|
||||
|
||||
Data Names
|
||||
@@ -362,7 +372,8 @@ Naming Limitations
|
||||
------------------
|
||||
|
||||
A common mistake is to assume newly created data is given the requested name.
|
||||
This can cause bugs when you add data (normally imported) then reference it later by name:
|
||||
|
||||
This can cause bugs when you add some data (normally imported) then reference it later by name.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -372,7 +383,7 @@ This can cause bugs when you add data (normally imported) then reference it late
|
||||
bpy.data.meshes[meshid]
|
||||
|
||||
|
||||
Or with name assignment:
|
||||
Or with name assignment...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -386,12 +397,12 @@ Data names may not match the assigned values if they exceed the maximum length,
|
||||
|
||||
|
||||
Its better practice not to reference objects by names at all,
|
||||
once created you can store the data in a list, dictionary, on a class, etc;
|
||||
once created you can store the data in a list, dictionary, on a class etc,
|
||||
there is rarely a reason to have to keep searching for the same data by name.
|
||||
|
||||
If you do need to use name references, its best to use a dictionary to maintain
|
||||
a mapping between the names of the imported assets and the newly created data,
|
||||
this way you don't run this risk of referencing existing data from the blend-file, or worse modifying it.
|
||||
this way you don't run this risk of referencing existing data from the blend file, or worse modifying it.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -410,14 +421,17 @@ this way you don't run this risk of referencing existing data from the blend-fil
|
||||
Library Collisions
|
||||
------------------
|
||||
|
||||
Blender keeps data names unique (:class:`bpy.types.ID.name`) so you can't name two objects,
|
||||
meshes, scenes, etc., the same by accident.
|
||||
However, when linking in library data from another blend-file naming collisions can occur,
|
||||
Blender keeps data names unique - :class:`bpy.types.ID.name` so you can't name two objects,
|
||||
meshes, scenes etc the same thing by accident.
|
||||
|
||||
However when linking in library data from another blend file naming collisions can occur,
|
||||
so its best to avoid referencing data by name at all.
|
||||
|
||||
This can be tricky at times and not even Blender handles this correctly in some case
|
||||
(when selecting the modifier object for e.g. you can't select between multiple objects with the same name),
|
||||
but its still good to try avoiding these problems in this area.
|
||||
This can be tricky at times and not even blender handles this correctly in some case
|
||||
(when selecting the modifier object for eg you can't select between multiple objects with the same name),
|
||||
but its still good to try avoid problems in this area.
|
||||
|
||||
|
||||
If you need to select between local and library data, there is a feature in ``bpy.data`` members to allow for this.
|
||||
|
||||
.. code-block:: python
|
||||
@@ -440,17 +454,18 @@ If you need to select between local and library data, there is a feature in ``bp
|
||||
Relative File Paths
|
||||
===================
|
||||
|
||||
Blender's relative file paths are not compatible with standard Python modules such as ``sys`` and ``os``.
|
||||
Built-in Python functions don't understand Blender's ``//`` prefix which denotes the blend-file path.
|
||||
Blenders relative file paths are not compatible with standard Python modules such as ``sys`` and ``os``.
|
||||
|
||||
A common case where you would run into this problem is when exporting a material with associated image paths:
|
||||
Built in Python functions don't understand blenders ``//`` prefix which denotes the blend file path.
|
||||
|
||||
A common case where you would run into this problem is when exporting a material with associated image paths.
|
||||
|
||||
>>> bpy.path.abspath(image.filepath)
|
||||
|
||||
|
||||
When using Blender data from linked libraries there is an unfortunate complication
|
||||
since the path will be relative to the library rather than the open blend-file.
|
||||
When the data block may be from an external blend-file pass the library argument from the :class:`bpy.types.ID`.
|
||||
When using blender data from linked libraries there is an unfortunate complication
|
||||
since the path will be relative to the library rather than the open blend file.
|
||||
When the data block may be from an external blend file pass the library argument from the :class:`bpy.types.ID`.
|
||||
|
||||
>>> bpy.path.abspath(image.filepath, library=image.library)
|
||||
|
||||
@@ -463,15 +478,19 @@ Unicode Problems
|
||||
|
||||
Python supports many different encodings so there is nothing stopping you from
|
||||
writing a script in ``latin1`` or ``iso-8859-15``.
|
||||
See `PEP 263 <https://www.python.org/dev/peps/pep-0263/>`__.
|
||||
|
||||
However, this complicates matters for Blender's Python API because ``.blend`` files don't have an explicit encoding.
|
||||
To avoid the problem for Python integration and script authors we have decided all strings in blend-files
|
||||
See `pep-0263 <https://www.python.org/dev/peps/pep-0263/>`_
|
||||
|
||||
However this complicates matters for Blender's Python API because ``.blend`` files don't have an explicit encoding.
|
||||
|
||||
To avoid the problem for Python integration and script authors we have decided all strings in blend files
|
||||
**must** be ``UTF-8``, ``ASCII`` compatible.
|
||||
|
||||
This means assigning strings with different encodings to an object names for instance will raise an error.
|
||||
|
||||
Paths are an exception to this rule since the existence of non-UTF-8 paths on user's file system cannot be ignored.
|
||||
This means seemingly harmless expressions can raise errors, e.g:
|
||||
Paths are an exception to this rule since we cannot ignore the existence of non ``UTF-8`` paths on users file-system.
|
||||
|
||||
This means seemingly harmless expressions can raise errors, eg.
|
||||
|
||||
>>> print(bpy.data.filepath)
|
||||
UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-21: ordinal not in range(128)
|
||||
@@ -482,7 +501,7 @@ This means seemingly harmless expressions can raise errors, e.g:
|
||||
TypeError: bpy_struct: item.attr= val: Object.name expected a string type, not str
|
||||
|
||||
|
||||
Here are two ways around file-system encoding issues:
|
||||
Here are 2 ways around filesystem encoding issues:
|
||||
|
||||
>>> print(repr(bpy.data.filepath))
|
||||
|
||||
@@ -493,11 +512,11 @@ Here are two ways around file-system encoding issues:
|
||||
|
||||
|
||||
Unicode encoding/decoding is a big topic with comprehensive Python documentation,
|
||||
to keep it short about encoding problems -- here are some suggestions:
|
||||
to avoid getting stuck too deep in encoding problems - here are some suggestions:
|
||||
|
||||
- Always use UTF-8 encoding or convert to UTF-8 where the input is unknown.
|
||||
- Avoid manipulating file paths as strings directly, use ``os.path`` functions instead.
|
||||
- Use ``os.fsencode()`` or ``os.fsdecode()`` instead of built-in string decoding functions when operating on paths.
|
||||
- Always use utf-8 encoding or convert to utf-8 where the input is unknown.
|
||||
- Avoid manipulating filepaths as strings directly, use ``os.path`` functions instead.
|
||||
- Use ``os.fsencode()`` / ``os.fsdecode()`` instead of built in string decoding functions when operating on paths.
|
||||
- To print paths or to include them in the user interface use ``repr(path)`` first
|
||||
or ``"%r" % path`` with string formatting.
|
||||
|
||||
@@ -509,11 +528,11 @@ to keep it short about encoding problems -- here are some suggestions:
|
||||
some importers do this.
|
||||
|
||||
|
||||
Strange Errors when Using the 'Threading' Module
|
||||
================================================
|
||||
Strange errors using 'threading' module
|
||||
=======================================
|
||||
|
||||
Python threading with Blender only works properly when the threads finish up before the script does,
|
||||
for example by using ``threading.join()``.
|
||||
Python threading with Blender only works properly when the threads finish up before the script does.
|
||||
By using ``threading.join()`` for example.
|
||||
|
||||
Here is an example of threading supported by Blender:
|
||||
|
||||
@@ -552,8 +571,8 @@ Here is an example of threading supported by Blender:
|
||||
t.join()
|
||||
|
||||
|
||||
This an example of a timer which runs many times a second
|
||||
and moves the default cube continuously while Blender runs **(Unsupported)**.
|
||||
This an example of a timer which runs many times a second and moves
|
||||
the default cube continuously while Blender runs **(Unsupported)**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -573,33 +592,33 @@ and moves the default cube continuously while Blender runs **(Unsupported)**.
|
||||
Use cases like the one above which leave the thread running once the script finishes
|
||||
may seem to work for a while but end up causing random crashes or errors in Blender's own drawing code.
|
||||
|
||||
So far, no work has been done to make Blender's Python integration thread safe,
|
||||
so until it's properly supported, it's best not make use of this.
|
||||
So far, no work has gone into making Blender's Python integration thread safe,
|
||||
so until its properly supported, best not make use of this.
|
||||
|
||||
.. note::
|
||||
|
||||
Python threads only allow concurrency and won't speed up your scripts on multiprocessor systems,
|
||||
the ``subprocess`` and ``multiprocess`` modules can be used with Blender to make use of multiple CPUs too.
|
||||
Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems,
|
||||
the ``subprocess`` and ``multiprocess`` modules can be used with Blender and make use of multiple CPU's too.
|
||||
|
||||
|
||||
Help! My script crashes Blender
|
||||
===============================
|
||||
|
||||
:abbr:`TL;DR (Too long; didn't read.)` Do not keep direct references to Blender data (of any kind)
|
||||
when modifying the container of that data, and/or when some undo/redo may happen
|
||||
(e.g. during modal operators execution...).
|
||||
**TL;DR:** Do not keep direct references to Blender data (of any kind) when modifying the container
|
||||
of that data, and/or when some undo/redo may happen (e.g. during modal operators execution...).
|
||||
Instead, use indices (or other data always stored by value in Python, like string keys...),
|
||||
that allow you to get access to the desired data.
|
||||
|
||||
Ideally it would be impossible to crash Blender from Python,
|
||||
however, there are some problems with the API where it can be made to crash.
|
||||
Ideally it would be impossible to crash Blender from Python
|
||||
however there are some problems with the API where it can be made to crash.
|
||||
|
||||
Strictly speaking this is a bug in the API but fixing it would mean adding memory verification
|
||||
on every access since most crashes are caused by the Python objects referencing Blender's memory directly,
|
||||
on every access since most crashes are caused by the Python objects referencing Blenders memory directly,
|
||||
whenever the memory is freed or re-allocated, further Python access to it can crash the script.
|
||||
But fixing this would make the scripts run very slow,
|
||||
or writing a very different kind of API which doesn't reference the memory directly.
|
||||
|
||||
Here are some general hints to avoid running into these problems:
|
||||
Here are some general hints to avoid running into these problems.
|
||||
|
||||
- Be aware of memory limits,
|
||||
especially when working with large lists since Blender can crash simply by running out of memory.
|
||||
@@ -612,16 +631,16 @@ Here are some general hints to avoid running into these problems:
|
||||
- Modules or classes that remain active while Blender is used,
|
||||
should not hold references to data the user may remove, instead,
|
||||
fetch data from the context each time the script is activated.
|
||||
- Crashes may not happen every time, they may happen more on some configurations or operating systems.
|
||||
- Be careful with recursive patterns, those are very efficient at hiding the issues described here.
|
||||
- See last subsection about `Unfortunate Corner Cases`_ for some known breaking exceptions.
|
||||
- Crashes may not happen every time, they may happen more on some configurations/operating-systems.
|
||||
- Be wary of recursive patterns, those are very efficient at hiding the issues described here.
|
||||
- See last sub-section about `Unfortunate Corner Cases`_ for some known breaking exceptions.
|
||||
|
||||
.. note::
|
||||
|
||||
To find the line of your script that crashes you can use the ``faulthandler`` module.
|
||||
See the `Faulthandler docs <https://docs.python.org/dev/library/faulthandler.html>`__.
|
||||
See the `faulthandler docs <https://docs.python.org/dev/library/faulthandler.html>`_.
|
||||
|
||||
While the crash may be in Blender's C/C++ code,
|
||||
While the crash may be in Blenders C/C++ code,
|
||||
this can help a lot to track down the area of the script that causes the crash.
|
||||
|
||||
.. note::
|
||||
@@ -635,7 +654,7 @@ Here are some general hints to avoid running into these problems:
|
||||
in any possible way.
|
||||
|
||||
|
||||
.. rubric:: Do not:
|
||||
**Don’t:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -654,7 +673,7 @@ Here are some general hints to avoid running into these problems:
|
||||
first_item.name = "foobar"
|
||||
|
||||
|
||||
.. rubric:: Do:
|
||||
**Do:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -677,31 +696,33 @@ Here are some general hints to avoid running into these problems:
|
||||
Undo/Redo
|
||||
---------
|
||||
|
||||
Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh, Light, etc.).
|
||||
Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh, Lamp... etc).
|
||||
|
||||
This example shows how you can tell undo changes the memory locations:
|
||||
This example shows how you can tell undo changes the memory locations.
|
||||
|
||||
>>> hash(bpy.context.object)
|
||||
-9223372036849950810
|
||||
>>> hash(bpy.context.object)
|
||||
-9223372036849950810
|
||||
|
||||
Move the active object, then undo:
|
||||
# ... move the active object, then undo
|
||||
|
||||
>>> hash(bpy.context.object)
|
||||
-9223372036849951740
|
||||
|
||||
As suggested above, simply not holding references to data when Blender is used
|
||||
interactively by the user is the only way to make sure that the script doesn't become unstable.
|
||||
interactively by the user is the only way to ensure the script doesn't become unstable.
|
||||
|
||||
|
||||
Undo & Library Data
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
One of the advantages with Blender's library linking system that undo
|
||||
One of the advantages with Blenders library linking system that undo
|
||||
can skip checking changes in library data since it is assumed to be static.
|
||||
|
||||
Tools in Blender are not allowed to modify library data.
|
||||
But Python does not enforce this restriction.
|
||||
|
||||
Python however does not enforce this restriction.
|
||||
|
||||
This can be useful in some cases, using a script to adjust material values for example.
|
||||
But its also possible to use a script to make library data point to newly created local data,
|
||||
@@ -712,13 +733,13 @@ So it's best to consider modifying library data an advanced usage of the API
|
||||
and only to use it when you know what you're doing.
|
||||
|
||||
|
||||
Edit-Mode / Memory Access
|
||||
Edit Mode / Memory Access
|
||||
-------------------------
|
||||
|
||||
Switching mode ``bpy.ops.object.mode_set(mode='EDIT')`` or ``bpy.ops.object.mode_set(mode='OBJECT')``
|
||||
Switching edit-mode ``bpy.ops.object.mode_set(mode='EDIT')`` / ``bpy.ops.object.mode_set(mode='OBJECT')``
|
||||
will re-allocate objects data,
|
||||
any references to a meshes vertices/polygons/UVs, armatures bones,
|
||||
curves points, etc. cannot be accessed after switching mode.
|
||||
any references to a meshes vertices/polygons/uvs, armatures bones,
|
||||
curves points etc cannot be accessed after switching edit-mode.
|
||||
|
||||
Only the reference to the data its self can be re-accessed, the following example will crash.
|
||||
|
||||
@@ -733,7 +754,7 @@ Only the reference to the data its self can be re-accessed, the following exampl
|
||||
print(polygons)
|
||||
|
||||
|
||||
So after switching mode you need to re-access any object data variables,
|
||||
So after switching edit-mode you need to re-access any object data variables,
|
||||
the following example shows how to avoid the crash above.
|
||||
|
||||
.. code-block:: python
|
||||
@@ -749,7 +770,7 @@ the following example shows how to avoid the crash above.
|
||||
|
||||
|
||||
These kinds of problems can happen for any functions which re-allocate
|
||||
the object data but are most common when switching mode.
|
||||
the object data but are most common when switching edit-mode.
|
||||
|
||||
|
||||
Array Re-Allocation
|
||||
@@ -770,20 +791,21 @@ internally the array which stores this data is re-allocated.
|
||||
This can be avoided by re-assigning the point variables after adding the new one or by storing
|
||||
indices to the points rather than the points themselves.
|
||||
|
||||
The best way is to sidestep the problem altogether by adding all the points to the curve at once.
|
||||
This means you don't have to worry about array re-allocation and it's faster too
|
||||
since re-allocating the entire array for every added point is inefficient.
|
||||
The best way is to sidestep the problem altogether add all the points to the curve at once.
|
||||
This means you don't have to worry about array re-allocation and its faster too
|
||||
since reallocating the entire array for every point added is inefficient.
|
||||
|
||||
|
||||
Removing Data
|
||||
-------------
|
||||
|
||||
**Any** data that you remove shouldn't be modified or accessed afterwards,
|
||||
this includes: F-curves, drivers, render layers, timeline markers, modifiers, constraints
|
||||
along with objects, scenes, collections, bones, etc.
|
||||
this includes f-curves, drivers, render layers, timeline markers, modifiers, constraints
|
||||
along with objects, scenes, collections, bones.. etc.
|
||||
|
||||
The ``remove()`` API calls will invalidate the data they free to prevent common mistakes.
|
||||
The following example shows how this precaution works:
|
||||
The ``remove()`` api calls will invalidate the data they free to prevent common mistakes.
|
||||
|
||||
The following example shows how this precaution works.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -796,7 +818,7 @@ The following example shows how this precaution works:
|
||||
|
||||
|
||||
But take care because this is limited to scripts accessing the variable which is removed,
|
||||
the next example will still crash:
|
||||
the next example will still crash.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -813,8 +835,8 @@ Besides all expected cases listed above, there are a few others that should not
|
||||
an issue but, due to internal implementation details, currently are:
|
||||
|
||||
- ``Object.hide_viewport``, ``Object.hide_select`` and ``Object.hide_render``:
|
||||
Setting any of those Booleans will trigger a rebuild of Collection caches,
|
||||
thus breaking any current iteration over ``Collection.all_objects``.
|
||||
Setting any of those booleans will trigger a rebuild of Collection caches, hence breaking
|
||||
any current iteration over ``Collection.all_objects``.
|
||||
|
||||
|
||||
sys.exit
|
||||
@@ -826,5 +848,5 @@ as if Blender is crashing since ``sys.exit()`` will close Blender immediately.
|
||||
|
||||
For example, the ``argparse`` module will print an error and exit if the arguments are invalid.
|
||||
|
||||
An dirty way of troubleshooting this is to set ``sys.exit = None`` and see what line of Python code is quitting,
|
||||
An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of Python code is quitting,
|
||||
you could of course replace ``sys.exit`` with your own function but manipulating Python in this way is bad practice.
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
.. _info_overview:
|
||||
|
||||
*******************
|
||||
@@ -5,24 +6,24 @@ Python API Overview
|
||||
*******************
|
||||
|
||||
The purpose of this document is to explain how Python and Blender fit together,
|
||||
covering some of the functionality that may not be obvious from reading the API references
|
||||
and example scripts.
|
||||
covering some of the functionality that may not be obvious from reading the API
|
||||
references and example scripts.
|
||||
|
||||
|
||||
Python in Blender
|
||||
=================
|
||||
|
||||
Blender has an embedded Python interpreter which is loaded when Blender is started
|
||||
and stays active while Blender is running. This interpreter runs scripts to draw the user interface
|
||||
and is used for some of Blender's internal tools as well.
|
||||
Blender has an embedded Python interpreter which is loaded when Blender is started and stays
|
||||
active while Blender is running. This interpreter runs scripts to draw the user interface
|
||||
and is used for some of Blender’s internal tools as well.
|
||||
|
||||
Blender's embedded interpreter provides a typical Python environment, so code from tutorials
|
||||
on how to write Python scripts can also be run with Blender's interpreter. Blender provides its
|
||||
on how to write Python scripts can also be run with Blender’s interpreter. Blender provides its
|
||||
Python modules, such as :mod:`bpy` and :mod:`mathutils`, to the embedded interpreter so they can
|
||||
be imported into a script and give access to Blender's data, classes, and functions.
|
||||
Scripts that deal with Blender data will need to import the modules to work.
|
||||
be imported into a script and give access to Blender's data, classes, and functions. Scripts that
|
||||
deal with Blender data will need to import the modules to work.
|
||||
|
||||
Here is a simple example which moves a vertex attached to an object named "Cube":
|
||||
Here is a simple example which moves a vertex attached to an object named **Cube**:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -30,7 +31,7 @@ Here is a simple example which moves a vertex attached to an object named "Cube"
|
||||
bpy.data.objects["Cube"].data.vertices[0].co.x += 1.0
|
||||
|
||||
This modifies Blender's internal data directly.
|
||||
When you run this in the interactive console you will see the 3D Viewport update.
|
||||
When you run this in the interactive console you will see the 3D viewport update.
|
||||
|
||||
|
||||
The Default Environment
|
||||
@@ -40,7 +41,7 @@ When developing your own scripts it may help to understand how Blender sets up i
|
||||
Many Python scripts come bundled with Blender and can be used as a reference
|
||||
because they use the same API that script authors write tools in.
|
||||
Typical usage for scripts include: user interface, import/export,
|
||||
scene manipulation, automation, defining your own tool set and customization.
|
||||
scene manipulation, automation, defining your own toolset and customization.
|
||||
|
||||
On startup Blender scans the ``scripts/startup/`` directory for Python modules and imports them.
|
||||
The exact location of this directory depends on your installation.
|
||||
@@ -53,8 +54,8 @@ Script Loading
|
||||
This may seem obvious, but it is important to note the difference between
|
||||
executing a script directly and importing a script as a module.
|
||||
|
||||
Extending Blender by executing a script directly means the classes that the script defines
|
||||
remain available inside Blender after the script finishes execution.
|
||||
Extending Blender by executing a script directly means the classes that the script
|
||||
defines remain available inside Blender after the script finishes execution.
|
||||
Using scripts this way makes future access to their classes
|
||||
(to unregister them for example) more difficult compared to importing the scripts as modules.
|
||||
When a script is imported as a module, its class instances will remain
|
||||
@@ -62,11 +63,12 @@ inside the module and can be accessed later on by importing that module again.
|
||||
|
||||
For this reason it is preferable to avoid directly executing scripts that extend Blender by registering classes.
|
||||
|
||||
Here are some ways to run scripts directly in Blender:
|
||||
|
||||
- Loaded in the text editor and press *Run Script*.
|
||||
Here are some ways to run scripts directly in Blender.
|
||||
|
||||
- Loaded in the text editor and press **Run Script**.
|
||||
- Typed or pasted into the interactive console.
|
||||
- Execute a Python file from the command line with Blender, e.g:
|
||||
- Execute a Python file from the command line with Blender, eg:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
@@ -75,22 +77,24 @@ Here are some ways to run scripts directly in Blender:
|
||||
|
||||
To run as modules:
|
||||
|
||||
- The obvious way, ``import some_module`` command from the text editor or interactive console.
|
||||
- Open as a text data-block and check the *Register* option, this will load with the blend-file.
|
||||
- Copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
|
||||
- Define as an add-on, enabling the add-on will load it as a Python module.
|
||||
- The obvious way, ``import some_module`` command from the text window or interactive console.
|
||||
- Open as a text block and tick "Register" option, this will load with the blend file.
|
||||
- copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
|
||||
- define as an add-on, enabling the add-on will load it as a Python module.
|
||||
|
||||
|
||||
Add-ons
|
||||
-------
|
||||
|
||||
Some of Blender's functionality is best kept optional,
|
||||
alongside scripts loaded at startup there are add-ons which are kept in their own directory ``scripts/addons``,
|
||||
They are only loaded on startup if selected from the user preferences.
|
||||
Some of Blenders functionality is best kept optional,
|
||||
alongside scripts loaded at startup we have add-ons which are kept in their own directory ``scripts/addons``,
|
||||
and only load on startup if selected from the user preferences.
|
||||
|
||||
The only difference between add-ons and built-in Python modules is that add-ons must contain a ``bl_info``
|
||||
variable which Blender uses to read metadata such as name, author, category and URL.
|
||||
|
||||
The User Preferences add-on listing uses **bl_info** to display information about each add-on.
|
||||
|
||||
The only difference between add-ons and built-in Python modules is that add-ons must contain a ``bl_info`` variable
|
||||
which Blender uses to read metadata such as name, author, category and project link.
|
||||
The User Preferences add-on listing uses ``bl_info`` to display information about each add-on.
|
||||
`See Add-ons <https://wiki.blender.org/index.php/Dev:Py/Scripts/Guidelines/Addons>`__
|
||||
for details on the ``bl_info`` dictionary.
|
||||
|
||||
@@ -101,7 +105,7 @@ Integration through Classes
|
||||
Running Python scripts in the text editor is useful for testing but you'll
|
||||
want to extend Blender to make tools accessible like other built-in functionality.
|
||||
|
||||
The Blender Python API allows integration for:
|
||||
The Blender Python api allows integration for:
|
||||
|
||||
- :class:`bpy.types.Panel`
|
||||
- :class:`bpy.types.Menu`
|
||||
@@ -110,12 +114,13 @@ The Blender Python API allows integration for:
|
||||
- :class:`bpy.types.KeyingSet`
|
||||
- :class:`bpy.types.RenderEngine`
|
||||
|
||||
|
||||
This is intentionally limited. Currently, for more advanced features such as mesh modifiers,
|
||||
object types, or shader nodes, C/C++ must be used.
|
||||
|
||||
For Python integration Blender defines methods which are common to all types.
|
||||
This works by creating a Python subclass of a Blender class which contains variables and functions
|
||||
specified by the parent class which are predefined to interface with Blender.
|
||||
specified by the parent class which are pre-defined to interface with Blender.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -132,20 +137,22 @@ For example:
|
||||
|
||||
bpy.utils.register_class(SimpleOperator)
|
||||
|
||||
First note that it defines a subclass as a member of :mod:`bpy.types`,
|
||||
First note that we subclass a member of :mod:`bpy.types`,
|
||||
this is common for all classes which can be integrated with Blender and
|
||||
is used to distinguish an Operator from a Panel when registering.
|
||||
used so we know if this is an Operator and not a Panel when registering.
|
||||
|
||||
Both class properties start with a ``bl_`` prefix.
|
||||
This is a convention used to distinguish Blender properties from those you add yourself.
|
||||
|
||||
Next see the execute function, which takes an instance of the operator and the current context.
|
||||
A common prefix is not used for functions.
|
||||
|
||||
Lastly the register function is called, this takes the class and loads it into Blender. See `Class Registration`_.
|
||||
|
||||
Regarding inheritance, Blender doesn't impose restrictions on the kinds of class inheritance used,
|
||||
the registration checks will use attributes and functions defined in parent classes.
|
||||
|
||||
Class mix-in example:
|
||||
class mix-in example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -166,8 +173,8 @@ While ``__init__()`` and ``__del__()`` will be called if defined,
|
||||
the class instances lifetime only spans the execution.
|
||||
So a panel for example will have a new instance for every redraw,
|
||||
for this reason there is rarely a cause to store variables in the panel instance.
|
||||
Instead, persistent variables should be stored in Blender's data
|
||||
so that the state can be restored when Blender is restarted.
|
||||
Instead, persistent variables should be stored in Blenders
|
||||
ata so that the state can be restored when Blender is restarted.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -175,14 +182,15 @@ so that the state can be restored when Blender is restarted.
|
||||
|
||||
So once the class is registered with Blender, instancing the class and calling the functions is left up to Blender.
|
||||
In fact you cannot instance these classes from the script as you would expect with most Python API's.
|
||||
To run operators you can call them through the operator API, e.g:
|
||||
|
||||
To run operators you can call them through the operator api, eg:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import bpy
|
||||
bpy.ops.object.simple_operator()
|
||||
|
||||
User interface classes are given a context in which to draw, buttons, window, file header, toolbar, etc.,
|
||||
User interface classes are given a context in which to draw, buttons window, file header, toolbar etc,
|
||||
then they are drawn when that area is displayed so they are never called by Python scripts directly.
|
||||
|
||||
|
||||
@@ -197,7 +205,7 @@ Module Registration
|
||||
Blender modules loaded at startup require ``register()`` and ``unregister()`` functions.
|
||||
These are the *only* functions that Blender calls from your code, which is otherwise a regular Python module.
|
||||
|
||||
A simple Blender Python module can look like this:
|
||||
A simple Blender/Python module can look like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -217,15 +225,16 @@ A simple Blender Python module can look like this:
|
||||
|
||||
These functions usually appear at the bottom of the script containing class registration sometimes adding menu items.
|
||||
You can also use them for internal purposes setting up data for your own tools but take care
|
||||
since register won't re-run when a new blend-file is loaded.
|
||||
since register won't re-run when a new blend file is loaded.
|
||||
|
||||
The register/unregister calls are used so it's possible to toggle add-ons and reload scripts while Blender runs.
|
||||
If the register calls were placed in the body of the script, registration would be called on import,
|
||||
meaning there would be no distinction between importing a module or loading its classes into Blender.
|
||||
|
||||
This becomes problematic when a script imports classes from another module
|
||||
making it difficult to manage which classes are being loaded and when.
|
||||
|
||||
The last two lines are only for testing:
|
||||
The last 2 lines are only for testing:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -242,13 +251,14 @@ Class Registration
|
||||
|
||||
Registering a class with Blender results in the class definition being loaded into Blender,
|
||||
where it becomes available alongside existing functionality.
|
||||
|
||||
Once this class is loaded you can access it from :mod:`bpy.types`,
|
||||
using the ``bl_idname`` rather than the classes original name.
|
||||
|
||||
.. note::
|
||||
|
||||
There are some exceptions to this for class names which aren't guarantee to be unique.
|
||||
In this case use: :func:`bpy.types.Struct.bl_rna_get_subclass_py`.
|
||||
In this case use: :func:`bpy.types.Struct.bl_rna_get_subclass`.
|
||||
|
||||
|
||||
When loading a class, Blender performs sanity checks making sure all required properties and functions are found,
|
||||
@@ -261,23 +271,23 @@ Using the function arguments ``def execute(self, context, spam)``, will raise an
|
||||
|
||||
``ValueError: expected Operator, SimpleOperator class "execute" function to have 2 args, found 3``
|
||||
|
||||
Using ``bl_idname = 1`` will raise:
|
||||
Using ``bl_idname = 1`` will raise.
|
||||
|
||||
``TypeError: validating class error: Operator.bl_idname expected a string type, not int``
|
||||
|
||||
|
||||
Inter-Class Dependencies
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Inter Classes Dependencies
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When customizing Blender you may want to group your own settings together,
|
||||
after all, they will likely have to co-exist with other scripts.
|
||||
To group these properties classes need to be defined,
|
||||
for groups within groups or collections within groups
|
||||
you can't avoid having to deal with the order of registration/unregistration.
|
||||
you can find yourself having to deal with order of registration/unregistration.
|
||||
|
||||
Custom properties groups are themselves classes which need to be registered.
|
||||
|
||||
For example, if you want to store material settings for a custom engine:
|
||||
Say you want to store material settings for a custom engine.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -301,7 +311,7 @@ For example, if you want to store material settings for a custom engine:
|
||||
|
||||
.. note::
|
||||
|
||||
The class **must be** registered before being used in a property, failing to do so will raise an error:
|
||||
*The class must be registered before being used in a property, failing to do so will raise an error:*
|
||||
|
||||
``ValueError: bpy_struct "Material" registration error: my_custom_props could not register``
|
||||
|
||||
@@ -331,17 +341,17 @@ For example, if you want to store material settings for a custom engine:
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
.. important::
|
||||
.. note::
|
||||
|
||||
The lower most class needs to be registered first and that ``unregister()`` is a mirror of ``register()``.
|
||||
*The lower most class needs to be registered first and that unregister() is a mirror of register()*
|
||||
|
||||
|
||||
Manipulating Classes
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Properties can be added and removed as Blender runs,
|
||||
normally done on register or unregister but for some special cases
|
||||
it may be useful to modify types as the script runs.
|
||||
normally happens on register or unregister but for some
|
||||
special cases it may be useful to modify types as the script runs.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -352,7 +362,7 @@ For example:
|
||||
# remove
|
||||
del bpy.types.Object.my_float
|
||||
|
||||
This works just as well for ``PropertyGroup`` subclasses you define yourself.
|
||||
This works just as well for PropertyGroup subclasses you define yourself.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -360,7 +370,7 @@ This works just as well for ``PropertyGroup`` subclasses you define yourself.
|
||||
pass
|
||||
MyPropGroup.my_float: bpy.props.FloatProperty()
|
||||
|
||||
This is equivalent to:
|
||||
...this is equivalent to:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -368,11 +378,11 @@ This is equivalent to:
|
||||
my_float: bpy.props.FloatProperty()
|
||||
|
||||
|
||||
Dynamic Class Definition (Advanced)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Dynamic Defined-Classes (Advanced)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In some cases the specifier for data may not be in Blender, for example a external render engines shader definitions,
|
||||
and it may be useful to define them as types and remove them on the fly.
|
||||
In some cases the specifier for data may not be in Blender, renderman shader definitions
|
||||
for example, and it may be useful to define them as types and remove them on the fly.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@@ -1,16 +1,19 @@
|
||||
|
||||
.. _info_quickstart:
|
||||
|
||||
**********
|
||||
Quickstart
|
||||
**********
|
||||
***********************
|
||||
Quickstart Introduction
|
||||
***********************
|
||||
|
||||
This :abbr:`API (Application Programming Interface)` is generally stable
|
||||
but some areas are still being extended and improved.
|
||||
Preface
|
||||
=======
|
||||
|
||||
.. rubric:: Blender Python API features:
|
||||
This API is generally stable but some areas are still being added and improved.
|
||||
|
||||
The Blender/Python API can do the following:
|
||||
|
||||
- Edit any data the user interface can (Scenes, Meshes, Particles etc.).
|
||||
- Modify user preferences, keymaps and themes.
|
||||
- Modify user preferences, key-maps and themes.
|
||||
- Run tools with own settings.
|
||||
- Create user interface elements such as menus, headers and panels.
|
||||
- Create new tools.
|
||||
@@ -18,10 +21,10 @@ but some areas are still being extended and improved.
|
||||
- Create new rendering engines that integrate with Blender.
|
||||
- Subscribe to changes to data and it's properties.
|
||||
- Define new settings in existing Blender data.
|
||||
- Draw in the 3D Viewport using Python.
|
||||
- Draw in the 3D view using Python.
|
||||
|
||||
|
||||
.. rubric:: (Still) missing features:
|
||||
The Blender/Python API **can't** (yet)...
|
||||
|
||||
- Create new space types.
|
||||
- Assign custom properties to every type.
|
||||
@@ -30,21 +33,22 @@ but some areas are still being extended and improved.
|
||||
Before Starting
|
||||
===============
|
||||
|
||||
This document its intended to familiarize you with Blender Python API
|
||||
but not to fully cover each topic.
|
||||
This document isn't intended to fully cover each topic.
|
||||
Rather, its purpose is to familiarize you with Blender Python API.
|
||||
|
||||
|
||||
A quick list of helpful things to know before starting:
|
||||
|
||||
- Blender uses Python 3.x; some online documentation still assumes version 2.x.
|
||||
- Blender uses Python 3.x; some online documentation still assumes 2.x.
|
||||
- The interactive console is great for testing one-liners.
|
||||
It also has autocompletion so you can inspect the API quickly.
|
||||
- Button tooltips show Python attributes and operator names.
|
||||
- The context menu of buttons directly links to this API documentation.
|
||||
- More operator examples can be found in the text editor's template menu.
|
||||
- Button tool tips show Python attributes and operator names.
|
||||
- Right clicking on buttons and menu items directly links to API documentation.
|
||||
- For more examples, the text menu has a templates section where some example operators can be found.
|
||||
- To examine further scripts distributed with Blender, see:
|
||||
|
||||
- ``scripts/startup/bl_ui`` for the user interface.
|
||||
- ``scripts/startup/bl_operators`` for operators.
|
||||
| ``scripts/startup/bl_ui`` for the user interface,
|
||||
| ``scripts/startup/bl_operators`` for operators.
|
||||
|
||||
Exact location depends on platform, see:
|
||||
:ref:`directory layout docs <blender_manual:blender-directory-layout>`.
|
||||
@@ -55,14 +59,19 @@ Running Scripts
|
||||
|
||||
The two most common ways to execute Python scripts are using the built-in
|
||||
text editor or entering commands in the Python console.
|
||||
Both the *Text Editor* and *Python Console* are space types you can select from the header.
|
||||
|
||||
Both the *Text Editor* and *Python Console* are space types you can select from the view header.
|
||||
|
||||
Rather than manually configuring your spaces for Python development,
|
||||
you can use the *Scripting* workspace accessible from the Topbar tabs.
|
||||
you may prefer to use the *Scripting* screen, included default with Blender,
|
||||
accessible from the top headers screen selector.
|
||||
|
||||
From the text editor you can open ``.py`` files or paste then from the clipboard, then test using *Run Script*.
|
||||
|
||||
The Python Console is typically used for typing in snippets and for testing to get immediate feedback,
|
||||
but can also have entire scripts pasted into it.
|
||||
Scripts can also run from the command line with Blender but to learn scripting in Blender this isn't essential.
|
||||
|
||||
Scripts can also run from the command line with Blender but to learn Blender/Python this isn't essential.
|
||||
|
||||
|
||||
Key Concepts
|
||||
@@ -71,13 +80,14 @@ Key Concepts
|
||||
Data Access
|
||||
-----------
|
||||
|
||||
Accessing Data-Blocks
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
Accessing DataBlocks
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can access Blender's data with the Python API in the same way as the animation system or user interface;
|
||||
this implies that any setting that can be changed via a button can also be changed with Python.
|
||||
Accessing data from the currently loaded blend-file is done with the module :mod:`bpy.data`.
|
||||
It gives access to library data, for example:
|
||||
Python accesses Blender's data in the same way as the animation system and user interface;
|
||||
this implies that any setting that can be changed via a button can also be changed from Python.
|
||||
|
||||
Accessing data from the currently loaded blend file is done with the module :mod:`bpy.data`.
|
||||
This gives access to library data. For example:
|
||||
|
||||
>>> bpy.data.objects
|
||||
<bpy_collection[3], BlendDataObjects>
|
||||
@@ -89,11 +99,12 @@ It gives access to library data, for example:
|
||||
<bpy_collection[1], BlendDataMaterials>
|
||||
|
||||
|
||||
Accessing Collections
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
About Collections
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
You will notice that an index as well as a string can be used to access members of the collection.
|
||||
Unlike Python dictionaries, both methods are available;
|
||||
You'll notice that an index as well as a string can be used to access members of the collection.
|
||||
|
||||
Unlike Python's dictionaries, both methods are acceptable;
|
||||
however, the index of a member may change while running Blender.
|
||||
|
||||
>>> list(bpy.data.objects)
|
||||
@@ -109,7 +120,7 @@ however, the index of a member may change while running Blender.
|
||||
Accessing Attributes
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Once you have a data-block, such as a material, object, collection, etc.,
|
||||
Once you have a data block, such as a material, object, collections etc.,
|
||||
its attributes can be accessed much like you would change a setting using the graphical interface.
|
||||
In fact, the tooltip for each button also displays the Python attribute
|
||||
which can help in finding what settings to change in a script.
|
||||
@@ -124,8 +135,8 @@ which can help in finding what settings to change in a script.
|
||||
bpy.data.materials['MyMaterial']
|
||||
|
||||
|
||||
For testing what data to access it's useful to use the Python Console, which is its own space type.
|
||||
This supports auto-complete, giving you a fast way to explore the data in your file.
|
||||
For testing what data to access it's useful to use the "Console", which is its own space type.
|
||||
This supports auto-complete, giving you a fast way to dig into different data in your file.
|
||||
|
||||
Example of a data path that can be quickly found via the console:
|
||||
|
||||
@@ -138,8 +149,8 @@ Example of a data path that can be quickly found via the console:
|
||||
Data Creation/Removal
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When you are familiar with other Python APIs you may be surprised that
|
||||
new data-blocks in the bpy API cannot be created by calling the class:
|
||||
Those of you familiar with other Python API's may be surprised that
|
||||
new data-blocks in the bpy API can't be created by calling the class:
|
||||
|
||||
>>> bpy.types.Mesh()
|
||||
Traceback (most recent call last):
|
||||
@@ -148,10 +159,10 @@ new data-blocks in the bpy API cannot be created by calling the class:
|
||||
|
||||
|
||||
This is an intentional part of the API design.
|
||||
The Blender Python API can't create Blender data that exists outside the main Blender database
|
||||
(accessed through :mod:`bpy.data`), because this data is managed by Blender (save, load, undo, append, etc).
|
||||
The Blender/Python API can't create Blender data that exists outside the main Blender database
|
||||
(accessed through :mod:`bpy.data`), because this data is managed by Blender (save/load/undo/append... etc).
|
||||
|
||||
Data is added and removed via methods on the collections in :mod:`bpy.data`, e.g:
|
||||
Data is added and removed via methods on the collections in :mod:`bpy.data`, eg:
|
||||
|
||||
>>> mesh = bpy.data.meshes.new(name="MyMesh")
|
||||
>>> print(mesh)
|
||||
@@ -163,12 +174,14 @@ Data is added and removed via methods on the collections in :mod:`bpy.data`, e.g
|
||||
Custom Properties
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Python can access properties on any data-block that has an ID
|
||||
(data that can be linked in and accessed from :mod:`bpy.data`).
|
||||
When assigning a property, you can pick your own names,
|
||||
these will be created when needed or overwritten if they already exist.
|
||||
Python can access properties on any datablock that has an ID
|
||||
(data that can be linked in and accessed from :mod:`bpy.data`.
|
||||
When assigning a property, you can make up your own names,
|
||||
these will be created when needed or overwritten if they exist.
|
||||
|
||||
This data is saved with the blend-file and copied with objects, for example:
|
||||
This data is saved with the blend file and copied with objects.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -188,10 +201,10 @@ This data is saved with the blend-file and copied with objects, for example:
|
||||
del collection["MySettings"]
|
||||
|
||||
|
||||
Note that these properties can only be assigned basic Python types:
|
||||
Note that these properties can only be assigned basic Python types.
|
||||
|
||||
- int, float, string
|
||||
- array of ints or floats
|
||||
- array of ints/floats
|
||||
- dictionary (only string keys are supported, values must be basic types too)
|
||||
|
||||
These properties are valid outside of Python. They can be animated by curves or used in driver paths.
|
||||
@@ -205,16 +218,18 @@ it's more common to operate on the user's selection.
|
||||
The context is always available from ``bpy.context`` and can be used to get the active object, scene,
|
||||
tool settings along with many other attributes.
|
||||
|
||||
Some common use cases are:
|
||||
Common-use cases:
|
||||
|
||||
>>> bpy.context.object
|
||||
>>> bpy.context.selected_objects
|
||||
>>> bpy.context.visible_bones
|
||||
|
||||
Note that the context is read-only, which means that these values cannot be modified directly.
|
||||
But they can be changed by running API functions or by using the data API.
|
||||
Note that the context is read-only.
|
||||
These values cannot be modified directly,
|
||||
though they may be changed by running API functions or by using the data API.
|
||||
|
||||
So ``bpy.context.active_object = obj`` will raise an error.
|
||||
|
||||
But ``bpy.context.view_layer.objects.active = obj`` works as expected.
|
||||
|
||||
The context attributes change depending on where they are accessed.
|
||||
@@ -242,7 +257,7 @@ Examples:
|
||||
|
||||
.. tip::
|
||||
|
||||
The :ref:`Operator Cheat Sheet <blender_manual:bpy.ops.wm.operator_cheat_sheet>`
|
||||
The :ref:`Operator Cheat Sheet <blender_manual:bpy.ops.wm.operator_cheat_sheet>`.
|
||||
gives a list of all operators and their default values in Python syntax, along with the generated docs.
|
||||
This is a good way to get an overview of all Blender's operators.
|
||||
|
||||
@@ -250,8 +265,8 @@ Examples:
|
||||
Operator Poll()
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Many operators have a "poll" function which checks if the cursor
|
||||
is in a valid area or if the object is in the correct mode (Edit Mode, Weight Paint Mode, etc).
|
||||
Many operators have a "poll" function which may check that the cursor
|
||||
is in a valid area or that the object is in the correct mode (Edit Mode, Weight Paint etc).
|
||||
When an operator's poll function fails within Python, an exception is raised.
|
||||
|
||||
For example, calling ``bpy.ops.view3d.render_border()`` from the console raises the following error:
|
||||
@@ -260,10 +275,10 @@ For example, calling ``bpy.ops.view3d.render_border()`` from the console raises
|
||||
|
||||
RuntimeError: Operator bpy.ops.view3d.render_border.poll() failed, context is incorrect
|
||||
|
||||
In this case the context must be the 3D Viewport with an active camera.
|
||||
In this case the context must be the 3d view with an active camera.
|
||||
|
||||
To avoid using try-except clauses wherever operators are called, you can call the operators
|
||||
own ``poll()`` function to check if it can run the operator in the current context.
|
||||
To avoid using try/except clauses wherever operators are called you can call the operators
|
||||
own ``poll()`` function to check if it can run in the current context.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -276,10 +291,11 @@ Integration
|
||||
|
||||
Python scripts can integrate with Blender in the following ways:
|
||||
|
||||
- By defining a render engine.
|
||||
- By defining a rendering engine.
|
||||
- By defining operators.
|
||||
- By defining menus, headers and panels.
|
||||
- By inserting new buttons into existing menus, headers and panels.
|
||||
- By inserting new buttons into existing menus, headers and panels
|
||||
|
||||
|
||||
In Python, this is done by defining a class, which is a subclass of an existing type.
|
||||
|
||||
@@ -290,52 +306,56 @@ Example Operator
|
||||
.. literalinclude:: __/__/__/release/scripts/templates_py/operator_simple.py
|
||||
|
||||
Once this script runs, ``SimpleOperator`` is registered with Blender
|
||||
and can be called from Operator Search or added to the toolbar.
|
||||
and can be called from the operator search popup or added to the toolbar.
|
||||
|
||||
To run the script:
|
||||
|
||||
#. Start Blender and switch to the Scripting workspace.
|
||||
#. Click the *New* button in the text editor to create a new text data-block.
|
||||
#. Copy the code from above and paste it into the text editor.
|
||||
#. Click on the *Run Script* button.
|
||||
#. Highlight the above code then press :kbd:`Ctrl-C` to copy it.
|
||||
#. Start Blender
|
||||
#. Press :kbd:`Ctrl-Right` twice to change to the Scripting layout.
|
||||
#. Click the button labeled ``New`` and the confirmation pop up in order to create a new text block.
|
||||
#. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame).
|
||||
#. Click on the button **Run Script**.
|
||||
#. Move your cursor into the 3D Viewport,
|
||||
open the :ref:`Operator Search menu <blender_manual:bpy.ops.wm.search_menu>`,
|
||||
open the :ref:`operator search menu <blender_manual:bpy.ops.wm.search_menu>`,
|
||||
and type "Simple".
|
||||
#. Click on the "Simple Operator" item found in search.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The class members with the ``bl_`` prefix are documented in the API reference :class:`bpy.types.Operator`.
|
||||
.. seealso:: The class members with the ``bl_`` prefix are documented in the API
|
||||
reference :class:`bpy.types.Operator`
|
||||
|
||||
.. note::
|
||||
|
||||
The output from the ``main`` function is sent to the terminal;
|
||||
in order to see this, be sure to :ref:`use the terminal <use_the_terminal>`.
|
||||
|
||||
|
||||
Example Panel
|
||||
-------------
|
||||
|
||||
Panels are registered as a class, like an operator.
|
||||
Panels register themselves as a class, like an operator.
|
||||
Notice the extra ``bl_`` variables used to set the context they display in.
|
||||
|
||||
.. literalinclude:: __/__/__/release/scripts/templates_py/ui_panel_simple.py
|
||||
|
||||
To run the script:
|
||||
|
||||
#. Start Blender and switch to the Scripting workspace.
|
||||
#. Click the *New* button in the text editor to create a new text data-block.
|
||||
#. Copy the code from above and paste it into the text editor.
|
||||
#. Click on the *Run Script* button.
|
||||
#. Highlight the above code then press :kbd:`Ctrl-C` to copy it.
|
||||
#. Start Blender.
|
||||
#. Click on the tab for the *Scripting* workspace.
|
||||
#. Click the button labeled ``New`` to create a new text block.
|
||||
#. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame).
|
||||
#. Click on the button **Run Script**.
|
||||
|
||||
|
||||
To view the results:
|
||||
|
||||
#. Select the default cube.
|
||||
#. Select the the default cube.
|
||||
#. Click on the Object properties icon in the buttons panel (far right; appears as a tiny cube).
|
||||
#. Scroll down to see a panel named "Hello World Panel".
|
||||
#. Changing the object name also updates *Hello World Panel's* name: field.
|
||||
#. Scroll down to see a panel named **Hello World Panel**.
|
||||
#. Changing the object name also updates **Hello World Panel's** Name: field.
|
||||
|
||||
Note the row distribution and the label and properties that are defined through the code.
|
||||
Note the row distribution and the label and properties that are available through the code.
|
||||
|
||||
.. seealso:: :class:`bpy.types.Panel`
|
||||
|
||||
@@ -344,7 +364,8 @@ Types
|
||||
=====
|
||||
|
||||
Blender defines a number of Python types but also uses Python native types.
|
||||
Blender's Python API can be split up into three categories.
|
||||
|
||||
Blender's Python API can be split up into 3 categories.
|
||||
|
||||
|
||||
Native Types
|
||||
@@ -353,7 +374,7 @@ Native Types
|
||||
In simple cases returning a number or a string as a custom type would be cumbersome,
|
||||
so these are accessed as normal Python types.
|
||||
|
||||
- Blender float, int, boolean -> float, int, boolean
|
||||
- Blender float/int/boolean -> float/int/boolean
|
||||
- Blender enumerator -> string
|
||||
|
||||
>>> C.object.rotation_mode = 'AXIS_ANGLE'
|
||||
@@ -372,10 +393,11 @@ so these are accessed as normal Python types.
|
||||
Internal Types
|
||||
--------------
|
||||
|
||||
:class:`bpy.types.bpy_struct` is used for Blender data-blocks and collections.
|
||||
Also for data that contains its own attributes: collections, meshes, bones, scenes, etc.
|
||||
Used for Blender data-blocks and collections: :class:`bpy.types.bpy_struct`
|
||||
|
||||
There are two main types that wrap Blender's data, one for data-blocks
|
||||
For data that contains its own attributes collections/meshes/bones/scenes... etc.
|
||||
|
||||
There are 2 main types that wrap Blenders data, one for data-blocks
|
||||
(known internally as ``bpy_struct``), another for properties.
|
||||
|
||||
>>> bpy.context.object
|
||||
@@ -384,13 +406,14 @@ There are two main types that wrap Blender's data, one for data-blocks
|
||||
>>> C.scene.objects
|
||||
bpy.data.scenes['Scene'].objects
|
||||
|
||||
Note that these types reference Blender's data so modifying them is visible immediately.
|
||||
Note that these types reference Blender's data so modifying them is immediately visible.
|
||||
|
||||
|
||||
Mathutils Types
|
||||
---------------
|
||||
|
||||
Accessible from :mod:`mathutils` are vectors, quaternions, Euler angles, matrix and color types.
|
||||
Used for vectors, quaternion, eulers, matrix and color types, accessible from :mod:`mathutils`
|
||||
|
||||
Some attributes such as :class:`bpy.types.Object.location`,
|
||||
:class:`bpy.types.PoseBone.rotation_euler` and :class:`bpy.types.Scene.cursor_location`
|
||||
can be accessed as special math types which can be used together and manipulated in various useful ways.
|
||||
@@ -399,13 +422,14 @@ Example of a matrix, vector multiplication:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.object.matrix_world @ bpy.context.object.data.verts[0].co
|
||||
bpy.context.object.matrix_world * bpy.context.object.data.verts[0].co
|
||||
|
||||
.. note::
|
||||
|
||||
mathutils types keep a reference to Blender's internal data so changes can
|
||||
be applied back.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
@@ -425,11 +449,13 @@ Example of a matrix, vector multiplication:
|
||||
Animation
|
||||
=========
|
||||
|
||||
There are two ways to add keyframes through Python.
|
||||
There are 2 ways to add keyframes through Python.
|
||||
|
||||
The first is through key properties directly, which is like inserting a keyframe from the button as a user.
|
||||
The first is through key properties directly, which is similar to inserting a keyframe from the button as a user.
|
||||
You can also manually create the curves and keyframe data, then set the path to the property.
|
||||
Here are examples of both methods. Both insert a keyframe on the active object's Z axis.
|
||||
Here are examples of both methods.
|
||||
|
||||
Both examples insert a keyframe on the active object's Z axis.
|
||||
|
||||
Simple example:
|
||||
|
||||
@@ -441,7 +467,7 @@ Simple example:
|
||||
obj.location[2] = 1.0
|
||||
obj.keyframe_insert(data_path="location", frame=20.0, index=2)
|
||||
|
||||
Using low-level functions:
|
||||
Using Low-Level Functions:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@@ -4,22 +4,23 @@ Tips and Tricks
|
||||
***************
|
||||
|
||||
Here are various suggestions that you might find useful when writing scripts.
|
||||
Some of these are just Python features that you may not have thought to use with Blender,
|
||||
others are Blender-specific.
|
||||
|
||||
Some of these are just Python features that scripters may not have thought to use with Blender,
|
||||
others are Blender specific.
|
||||
|
||||
|
||||
.. _use_the_terminal:
|
||||
|
||||
Use the Terminal
|
||||
Use The Terminal
|
||||
================
|
||||
|
||||
When writing Python scripts, it's useful to have a terminal open,
|
||||
this is not the built-in Python console but a terminal application which is used to start Blender.
|
||||
|
||||
The three main use cases for the terminal are:
|
||||
There are 3 main uses for the terminal, these are:
|
||||
|
||||
- You can see the output of ``print()`` as your script runs, which is useful to view debug info.
|
||||
- The error traceback is printed in full to the terminal which won't always generate an report message in
|
||||
- The error trace-back is printed in full to the terminal which won't always generate an error popup in
|
||||
Blender's user interface (depending on how the script is executed).
|
||||
- If the script runs for too long or you accidentally enter an infinite loop,
|
||||
:kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early.
|
||||
@@ -27,25 +28,26 @@ The three main use cases for the terminal are:
|
||||
.. note::
|
||||
|
||||
For Linux and macOS users this means starting the terminal first, then running Blender from within it.
|
||||
On Windows the terminal can be enabled from the Help menu.
|
||||
On Windows the terminal can be enabled from the help menu.
|
||||
|
||||
|
||||
Interface Tricks
|
||||
================
|
||||
|
||||
|
||||
Access Operator Commands
|
||||
------------------------
|
||||
|
||||
You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops.[...]`` command
|
||||
You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops.[...])`` command
|
||||
to run that button, a handy (hidden) feature is that you can press :kbd:`Ctrl-C` over
|
||||
any menu item or button to copy this command into the clipboard.
|
||||
any menu item/button to copy this command into the clipboard.
|
||||
|
||||
|
||||
Access Data Path
|
||||
----------------
|
||||
|
||||
To find the path from an :class:`ID` data-block to its setting isn't always so simple since it may be nested away.
|
||||
To get this quickly open the context menu of the setting and select *Copy Data Path*,
|
||||
To find the path from an :class:`ID` datablock to its setting isn't always so simple since it may be nested away.
|
||||
To get this quickly you can right click on the setting and select select **Copy Data Path**,
|
||||
if this can't be generated, only the property name is copied.
|
||||
|
||||
.. note::
|
||||
@@ -60,10 +62,11 @@ if this can't be generated, only the property name is copied.
|
||||
Show All Operators
|
||||
==================
|
||||
|
||||
While Blender logs operators in the Info editor,
|
||||
this only reports operators with the ``REGISTER`` option enabled so as not to flood the *Info* view
|
||||
While Blender logs operators in the Info space,
|
||||
this only reports operators with the ``REGISTER`` option enabeld so as not to flood the *Info* view
|
||||
with calls to ``bpy.ops.view3d.smoothview`` and ``bpy.ops.view3d.zoom``.
|
||||
Yet for testing it can be useful to see **every** operator called in a terminal,
|
||||
|
||||
However, for testing it can be useful to see **every** operator called in a terminal,
|
||||
do this by enabling the debug option either by passing the ``--debug-wm`` argument when starting Blender
|
||||
or by setting :mod:`bpy.app.debug_wm` to ``True`` while Blender is running.
|
||||
|
||||
@@ -71,18 +74,20 @@ or by setting :mod:`bpy.app.debug_wm` to ``True`` while Blender is running.
|
||||
Use an External Editor
|
||||
======================
|
||||
|
||||
Blender's text editor is fine for small changes and writing tests but its not full featured,
|
||||
Blenders text editor is fine for small changes and writing tests but its not full featured,
|
||||
for larger projects you'll probably want to use a standalone editor or Python IDE.
|
||||
Editing a text file externally and having the same text open in Blender does work
|
||||
but isn't that optimal so here are two ways you can use an external file from Blender.
|
||||
Using the following examples you'll still need text data-block in Blender to execute,
|
||||
|
||||
Editing a text file externally and having the same text open in Blender does work but isn't that optimal
|
||||
so here are 2 ways you can easily use an external file from Blender.
|
||||
|
||||
Using the following examples you'll still need textblock in Blender to execute,
|
||||
but reference an external file rather than including it directly.
|
||||
|
||||
|
||||
Executing External Scripts
|
||||
--------------------------
|
||||
|
||||
This is the equivalent to running the script directly, referencing a scripts path from a two line code block.
|
||||
This is the equivalent to running the script directly, referencing a scripts path from a 2 line text-block.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -90,7 +95,7 @@ This is the equivalent to running the script directly, referencing a scripts pat
|
||||
exec(compile(open(filename).read(), filename, 'exec'))
|
||||
|
||||
|
||||
You might want to reference a script relative to the blend-file.
|
||||
You might want to reference a script relative to the blend file.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -123,10 +128,9 @@ has to call a function in the module, in this case ``main()`` but it can be any
|
||||
an advantage with this is you can pass arguments to the function from this
|
||||
small script which is often useful for testing different settings quickly.
|
||||
|
||||
The other issue with this is the script has to be in Python's module search path.
|
||||
While this is not best practice -- for testing purposes you can extend the search path,
|
||||
this following example adds the current blend-files directory to the search path
|
||||
and then loads the script as a module.
|
||||
The other issue with this is the script has to be in Pythons module search path.
|
||||
While this is not best practice - for testing you can extend the search path,
|
||||
this example adds the current blend files directory to the search path, then loads the script as a module.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -144,40 +148,42 @@ and then loads the script as a module.
|
||||
myscript.main()
|
||||
|
||||
|
||||
Use Blender without it's User Interface
|
||||
=======================================
|
||||
Don't Use Blender!
|
||||
==================
|
||||
|
||||
While developing your own scripts Blenders interface can get in the way,
|
||||
manually reloading, running the scripts, opening file import etc. adds overhead.
|
||||
|
||||
While developing your own scripts Blender's interface can get in the way,
|
||||
manually reloading, running the scripts, opening file import, etc. adds overhead.
|
||||
For scripts that are not interactive it can end up being more efficient not to use
|
||||
Blender's interface at all and instead execute the script on the command line.
|
||||
Blenders interface at all and instead execute the script on the command line.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
blender --background --python myscript.py
|
||||
|
||||
|
||||
You might want to run this with a blend-file so the script has some data to operate on.
|
||||
You might want to run this with a blend file so the script has some data to operate on.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
blender myscene.blend --background --python myscript.py
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Depending on your setup you might have to enter the full path to the Blender executable.
|
||||
|
||||
|
||||
Once the script is running properly in background mode, you'll want to check the output of the script,
|
||||
this depends completely on the task at hand, however, here are some suggestions:
|
||||
this depends completely on the task at hand however here are some suggestions.
|
||||
|
||||
- Render the output to an image, use an image viewer and keep writing over the same image each time.
|
||||
- Save a new blend-file, or export the file using one of Blender's exporters.
|
||||
- If the results can be displayed as text then print them or write them to a file.
|
||||
- render the output to an image, use an image viewer and keep writing over the same image each time.
|
||||
- save a new blend file, or export the file using one of Blenders exporters.
|
||||
- if the results can be displayed as text - print them or write them to a file.
|
||||
|
||||
|
||||
While this can take a little time to setup, it can be well worth the effort
|
||||
to reduce the time it takes to test changes. You can even have
|
||||
to reduce the time it takes to test changes - you can even have
|
||||
Blender running the script every few seconds with a viewer updating the results,
|
||||
so no need to leave your text editor to see changes.
|
||||
|
||||
@@ -194,7 +200,7 @@ but to quickly setup your own custom pipeline or writing one-off scripts this ca
|
||||
|
||||
Examples include:
|
||||
|
||||
- Run Gimp in batch mode to execute custom scripts for advanced image processing.
|
||||
- Run The Gimp in batch mode to execute custom scripts for advanced image processing.
|
||||
- Write out 3D models to use external mesh manipulation tools and read back in the results.
|
||||
- Convert files into recognizable formats before reading.
|
||||
|
||||
@@ -203,16 +209,15 @@ Bundled Python & Extensions
|
||||
===========================
|
||||
|
||||
The Blender releases distributed from blender.org include a complete Python installation on all platforms,
|
||||
this has the disadvantage that any extensions you have installed on your system's Python environment
|
||||
will not be found by Blender.
|
||||
this has the disadvantage that any extensions you have installed in your systems Python won't be found by Blender.
|
||||
|
||||
There are two ways to work around this:
|
||||
There are 2 ways around this:
|
||||
|
||||
- Remove Blender Python subdirectory, Blender will then fallback on the system's Python and use that instead.
|
||||
- Remove Blender Python sub-directory, Blender will then fallback on the systems Python and use that instead.
|
||||
|
||||
Depending on your platform,
|
||||
you may need to explicitly reference the location of your Python installation using
|
||||
the ``PYTHONPATH`` environment variable, e.g:
|
||||
you may need to explicitly reference the location of your Python installation using the
|
||||
``PYTHONPATH`` environment variable, eg:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
@@ -221,21 +226,21 @@ There are two ways to work around this:
|
||||
.. warning::
|
||||
|
||||
The Python (major, minor) version must match the one that Blender comes with.
|
||||
Therefor you can't use Python 3.6 with Blender built to use Python 3.7.
|
||||
Therefor can't use Python 3.6 with Blender built to use Python 3.7.
|
||||
|
||||
- Copy or link the extensions into Blender's Python subdirectory so Blender can access them,
|
||||
you can also copy the entire Python installation into Blender's subdirectory,
|
||||
- Copy or link the extensions into Blender's Python sub-directory so Blender can access them,
|
||||
you could also copy the entire Python installation into Blenders sub-directory,
|
||||
replacing the one Blender comes with.
|
||||
This works as long as the Python versions match and the paths are created in the same relative locations.
|
||||
Doing this has the advantage that you can redistribute this bundle to others with Blender
|
||||
including any extensions you rely on.
|
||||
|
||||
|
||||
Insert a Python Interpreter into your Script
|
||||
============================================
|
||||
Drop Into a Python Interpreter in Your Script
|
||||
=============================================
|
||||
|
||||
In the middle of a script you may want to inspect variables,
|
||||
run functions and inspect the flow.
|
||||
In the middle of a script you may want to inspect some variables,
|
||||
run some function and generally dig about to see what's going on.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -243,7 +248,7 @@ run functions and inspect the flow.
|
||||
code.interact(local=locals())
|
||||
|
||||
|
||||
If you want to access both global and local variables run this:
|
||||
If you want to access both global and local variables do this...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -261,7 +266,7 @@ The next example is an equivalent single line version of the script above which
|
||||
|
||||
|
||||
``code.interact`` can be added at any line in the script
|
||||
and will pause the script to launch an interactive interpreter in the terminal,
|
||||
and will pause the script an launch an interactive interpreter in the terminal,
|
||||
when you're done you can quit the interpreter and the script will continue execution.
|
||||
|
||||
|
||||
@@ -274,14 +279,13 @@ The IPython prompt has auto-complete and some useful features that the standard
|
||||
IPython.embed()
|
||||
|
||||
|
||||
Admittedly this highlights the lack of any Python debugging support built into Blender,
|
||||
but its still a handy thing to know.
|
||||
|
||||
Admittedly this highlights the lack of any Python debugging support built into Blender, but its still handy to know.
|
||||
|
||||
Advanced
|
||||
========
|
||||
|
||||
Blender as a Module
|
||||
|
||||
Blender as a module
|
||||
-------------------
|
||||
|
||||
From a Python perspective it's nicer to have everything as an extension
|
||||
@@ -289,22 +293,26 @@ which lets the Python script combine many components.
|
||||
|
||||
Advantages include:
|
||||
|
||||
- You can use external editors or IDEs with Blender's Python API and execute scripts within the IDE
|
||||
- you can use external editors/IDE's with Blenders Python API and execute scripts within the IDE
|
||||
(step over code, inspect variables as the script runs).
|
||||
- Editors or IDEs can auto-complete Blender modules and variables.
|
||||
- Existing scripts can import Blender APIs without having to be run inside of Blender.
|
||||
- editors/IDE's can auto complete Blender modules & variables.
|
||||
- existing scripts can import Blender API's without having to run inside Blender.
|
||||
|
||||
|
||||
This is marked advanced because to run Blender as a Python module requires a special build option.
|
||||
|
||||
For instructions on building see
|
||||
`Building Blender as a Python module <https://wiki.blender.org/wiki/Building_Blender/Other/BlenderAsPyModule>`__.
|
||||
`Building Blender as a Python module <https://wiki.blender.org/wiki/Building_Blender/Other/BlenderAsPyModule>`_
|
||||
|
||||
|
||||
Python Safety (Build Option)
|
||||
----------------------------
|
||||
|
||||
Since it's possible to access data which has been removed (see :doc:`Gotchas <info_gotcha>`),
|
||||
can make it hard to track down the cause of crashes.
|
||||
Since it's possible to access data which has been removed (see Gotcha's),
|
||||
this can be hard to track down the cause of crashes.
|
||||
|
||||
To raise Python exceptions on accessing freed data (rather than crashing),
|
||||
enable the CMake build option ``WITH_PYTHON_SAFETY``.
|
||||
This enables data tracking which makes data access about two times slower
|
||||
|
||||
This enables data tracking which makes data access about 2x slower
|
||||
which is why the option isn't enabled in release builds.
|
||||
|
@@ -83,8 +83,6 @@ import inspect
|
||||
import shutil
|
||||
import logging
|
||||
|
||||
from textwrap import indent
|
||||
|
||||
from platform import platform
|
||||
PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows'
|
||||
|
||||
@@ -225,7 +223,6 @@ else:
|
||||
"aud",
|
||||
"bgl",
|
||||
"blf",
|
||||
"bl_math",
|
||||
"imbuf",
|
||||
"bmesh",
|
||||
"bmesh.ops",
|
||||
@@ -360,7 +357,7 @@ INFO_DOCS = (
|
||||
("info_tips_and_tricks.rst",
|
||||
"Tips and Tricks: Hints to help you while writing scripts for Blender"),
|
||||
("info_gotcha.rst",
|
||||
"Gotcha's: some of the problems you may encounter when writing scripts"),
|
||||
"Gotcha's: some of the problems you may come up against when writing scripts"),
|
||||
("change_log.rst", "List of changes since last Blender release"),
|
||||
)
|
||||
|
||||
@@ -441,30 +438,25 @@ if ARGS.sphinx_build:
|
||||
|
||||
if ARGS.log:
|
||||
SPHINX_BUILD_LOG = os.path.join(ARGS.output_dir, ".sphinx-build.log")
|
||||
SPHINX_BUILD = [
|
||||
"sphinx-build",
|
||||
"-w", SPHINX_BUILD_LOG,
|
||||
SPHINX_IN, SPHINX_OUT,
|
||||
]
|
||||
SPHINX_BUILD = ["sphinx-build",
|
||||
"-w", SPHINX_BUILD_LOG,
|
||||
SPHINX_IN, SPHINX_OUT]
|
||||
|
||||
# pdf build
|
||||
if ARGS.sphinx_build_pdf:
|
||||
SPHINX_OUT_PDF = os.path.join(ARGS.output_dir, "sphinx-out_pdf")
|
||||
SPHINX_BUILD_PDF = [
|
||||
"sphinx-build",
|
||||
"-b", "latex",
|
||||
SPHINX_IN, SPHINX_OUT_PDF,
|
||||
]
|
||||
SPHINX_BUILD_PDF = ["sphinx-build",
|
||||
"-b", "latex",
|
||||
SPHINX_IN, SPHINX_OUT_PDF]
|
||||
SPHINX_MAKE_PDF = ["make", "-C", SPHINX_OUT_PDF]
|
||||
SPHINX_MAKE_PDF_STDOUT = None
|
||||
|
||||
if ARGS.log:
|
||||
SPHINX_BUILD_PDF_LOG = os.path.join(ARGS.output_dir, ".sphinx-build_pdf.log")
|
||||
SPHINX_BUILD_PDF = [
|
||||
"sphinx-build", "-b", "latex",
|
||||
"-w", SPHINX_BUILD_PDF_LOG,
|
||||
SPHINX_IN, SPHINX_OUT_PDF,
|
||||
]
|
||||
SPHINX_BUILD_PDF = ["sphinx-build", "-b", "latex",
|
||||
"-w", SPHINX_BUILD_PDF_LOG,
|
||||
SPHINX_IN, SPHINX_OUT_PDF]
|
||||
|
||||
sphinx_make_pdf_log = os.path.join(ARGS.output_dir, ".latex_make.log")
|
||||
SPHINX_MAKE_PDF_STDOUT = open(sphinx_make_pdf_log, "w", encoding="utf-8")
|
||||
|
||||
@@ -696,11 +688,13 @@ def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
|
||||
doc = undocumented_message(module_name, type_name, identifier)
|
||||
|
||||
if type(descr) == GetSetDescriptorType:
|
||||
fw(ident + ".. attribute:: %s\n\n" % identifier)
|
||||
fw(ident + ".. attribute:: %s\n" % identifier)
|
||||
fw(ident + " :noindex:\n\n")
|
||||
write_indented_lines(ident + " ", fw, doc, False)
|
||||
fw("\n")
|
||||
elif type(descr) == MemberDescriptorType: # same as above but use 'data'
|
||||
fw(ident + ".. data:: %s\n\n" % identifier)
|
||||
fw(ident + ".. data:: %s\n" % identifier)
|
||||
fw(ident + " :noindex:\n\n")
|
||||
write_indented_lines(ident + " ", fw, doc, False)
|
||||
fw("\n")
|
||||
elif type(descr) in {MethodDescriptorType, ClassMethodDescriptorType}:
|
||||
@@ -740,11 +734,14 @@ def pyprop2sphinx(ident, fw, identifier, py_prop):
|
||||
'''
|
||||
# readonly properties use "data" directive, variables use "attribute" directive
|
||||
if py_prop.fset is None:
|
||||
fw(ident + ".. data:: %s\n\n" % identifier)
|
||||
fw(ident + ".. data:: %s\n" % identifier)
|
||||
fw(ident + " :noindex:\n\n")
|
||||
else:
|
||||
fw(ident + ".. attribute:: %s\n\n" % identifier)
|
||||
fw(ident + ".. attribute:: %s\n" % identifier)
|
||||
fw(ident + " :noindex:\n\n")
|
||||
write_indented_lines(ident + " ", fw, py_prop.__doc__)
|
||||
if py_prop.fset is None:
|
||||
fw("\n")
|
||||
fw(ident + " (readonly)\n\n")
|
||||
else:
|
||||
fw("\n")
|
||||
@@ -910,7 +907,8 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
elif issubclass(value_type, (bool, int, float, str, tuple)):
|
||||
# constant, not much fun we can do here except to list it.
|
||||
# TODO, figure out some way to document these!
|
||||
fw(".. data:: %s\n\n" % attribute)
|
||||
fw(".. data:: %s\n" % attribute)
|
||||
fw(" :noindex:\n\n")
|
||||
write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
|
||||
fw("\n")
|
||||
else:
|
||||
@@ -1028,7 +1026,6 @@ context_type_map = {
|
||||
"gpencil": ("GreasePencil", False),
|
||||
"gpencil_data": ("GreasePencil", False),
|
||||
"gpencil_data_owner": ("ID", False),
|
||||
"hair": ("Hair", False),
|
||||
"image_paint_object": ("Object", False),
|
||||
"lattice": ("Lattice", False),
|
||||
"light": ("Light", False),
|
||||
@@ -1045,7 +1042,6 @@ context_type_map = {
|
||||
"particle_settings": ("ParticleSettings", False),
|
||||
"particle_system": ("ParticleSystem", False),
|
||||
"particle_system_editable": ("ParticleSystem", False),
|
||||
"pointcloud": ("PointCloud", False),
|
||||
"pose_bone": ("PoseBone", False),
|
||||
"pose_object": ("Object", False),
|
||||
"scene": ("Scene", False),
|
||||
@@ -1120,7 +1116,8 @@ def pycontext2sphinx(basepath):
|
||||
|
||||
type_descr = prop.get_type_description(
|
||||
class_fmt=":class:`bpy.types.%s`", collection_id=_BPY_PROP_COLLECTION_ID)
|
||||
fw(".. data:: %s\n\n" % prop.identifier)
|
||||
fw(".. data:: %s\n" % prop.identifier)
|
||||
fw(" :noindex:\n\n")
|
||||
if prop.description:
|
||||
fw(" %s\n\n" % prop.description)
|
||||
|
||||
@@ -1165,7 +1162,8 @@ def pycontext2sphinx(basepath):
|
||||
i = 0
|
||||
while char_array[i] is not None:
|
||||
member = ctypes.string_at(char_array[i]).decode(encoding="ascii")
|
||||
fw(".. data:: %s\n\n" % member)
|
||||
fw(".. data:: %s\n" % member)
|
||||
fw(" :noindex:\n\n")
|
||||
member_type, is_seq = context_type_map[member]
|
||||
fw(" :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type))
|
||||
unique.add(member)
|
||||
@@ -1198,15 +1196,12 @@ def pyrna_enum2sphinx(prop, use_empty_descriptions=False):
|
||||
break
|
||||
|
||||
if ok:
|
||||
return "".join([
|
||||
"* ``%s``\n"
|
||||
"%s.\n" % (
|
||||
identifier,
|
||||
# Account for multi-line enum descriptions, allowing this to be a block of text.
|
||||
indent(", ".join(escape_rst(val) for val in (name, description) if val) or "Undocumented", " "),
|
||||
)
|
||||
for identifier, name, description in prop.enum_items
|
||||
])
|
||||
return "".join(["* ``%s`` %s.\n" %
|
||||
(identifier,
|
||||
", ".join(escape_rst(val) for val in (name, description) if val),
|
||||
)
|
||||
for identifier, name, description in prop.enum_items
|
||||
])
|
||||
else:
|
||||
return ""
|
||||
|
||||
@@ -1273,7 +1268,7 @@ def pyrna2sphinx(basepath):
|
||||
fw(ident + ":%s%s:\n\n" % (id_name, identifier))
|
||||
|
||||
if prop.name or prop.description:
|
||||
fw(indent(", ".join(val for val in (prop.name, prop.description) if val), ident + " ") + "\n\n")
|
||||
fw(ident + " " + ", ".join(val for val in (prop.name, prop.description) if val) + "\n\n")
|
||||
|
||||
# special exception, can't use generic code here for enums
|
||||
if enum_text:
|
||||
@@ -1371,9 +1366,11 @@ def pyrna2sphinx(basepath):
|
||||
type_descr = prop.get_type_description(class_fmt=":class:`%s`", collection_id=_BPY_PROP_COLLECTION_ID)
|
||||
# readonly properties use "data" directive, variables properties use "attribute" directive
|
||||
if 'readonly' in type_descr:
|
||||
fw(" .. data:: %s\n\n" % prop.identifier)
|
||||
fw(" .. data:: %s\n" % prop.identifier)
|
||||
fw(" :noindex:\n\n")
|
||||
else:
|
||||
fw(" .. attribute:: %s\n\n" % prop.identifier)
|
||||
fw(" .. attribute:: %s\n" % prop.identifier)
|
||||
fw(" :noindex:\n\n")
|
||||
if prop.description:
|
||||
fw(" %s\n\n" % prop.description)
|
||||
|
||||
@@ -1717,7 +1714,7 @@ class PatchedPythonDomain(PythonDomain):
|
||||
# end workaround
|
||||
|
||||
fw("def setup(app):\n")
|
||||
fw(" app.add_css_file('css/theme_overrides.css')\n")
|
||||
fw(" app.add_stylesheet('css/theme_overrides.css')\n")
|
||||
fw(" app.add_domain(PatchedPythonDomain, override=True)\n\n")
|
||||
|
||||
file.close()
|
||||
@@ -1789,18 +1786,8 @@ def write_rst_contents(basepath):
|
||||
|
||||
standalone_modules = (
|
||||
# submodules are added in parent page
|
||||
"aud",
|
||||
"bgl",
|
||||
"bl_math",
|
||||
"blf",
|
||||
"bmesh",
|
||||
"bpy_extras",
|
||||
"freestyle",
|
||||
"gpu",
|
||||
"gpu_extras",
|
||||
"idprop.types",
|
||||
"imbuf",
|
||||
"mathutils",
|
||||
"mathutils", "freestyle", "bgl", "blf", "imbuf", "gpu", "gpu_extras",
|
||||
"aud", "bpy_extras", "idprop.types", "bmesh",
|
||||
)
|
||||
|
||||
for mod in standalone_modules:
|
||||
@@ -1952,7 +1939,6 @@ def write_rst_importable_modules(basepath):
|
||||
"mathutils.kdtree": "KDTree Utilities",
|
||||
"mathutils.interpolate": "Interpolation Utilities",
|
||||
"mathutils.noise": "Noise Utilities",
|
||||
"bl_math": "Additional Math Functions",
|
||||
"freestyle": "Freestyle Module",
|
||||
"freestyle.types": "Freestyle Types",
|
||||
"freestyle.predicates": "Freestyle Predicates",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user