diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ce8872d036c5..f794b27d63854 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -178,6 +178,8 @@ core_optional_dep(${optional_deps})
core_optional_dyload_dep(${dyload_optional})
core_require_dep(${required_deps})
+SET(PYTHON_VERSION 3.7)
+
if(ENABLE_MARIADBCLIENT AND NOT ENABLE_MARIADBCLIENT STREQUAL AUTO AND ENABLE_MYSQLCLIENT AND NOT ENABLE_MYSQLCLIENT STREQUAL AUTO)
MESSAGE(FATAL_ERROR "You can not use MySql and MariaDB at the same time. Disable one by adding -DENABLE_MYSQLCLIENT=OFF or -DENABLE_MARIADBCLIENT=OFF.")
elseif(ENABLE_MYSQLCLIENT AND NOT ENABLE_MYSQLCLIENT STREQUAL AUTO)
diff --git a/addons/repository.xbmc.org/addon.xml b/addons/repository.xbmc.org/addon.xml
index c431c0fbca9ed..c6128a4ba5402 100644
--- a/addons/repository.xbmc.org/addon.xml
+++ b/addons/repository.xbmc.org/addon.xml
@@ -8,10 +8,10 @@
- http://mirrors.kodi.tv/addons/leia/addons.xml.gz
- http://mirrors.kodi.tv/addons/leia/addons.xml.gz?sha256
- https://mirrors.kodi.tv/addons/leia
- http://mirrors.kodi.tv/addons/leia
+ http://mirrors.kodi.tv/addons/migration/addons.xml.gz
+ http://mirrors.kodi.tv/addons/migration/addons.xml.gz?sha256
+ https://mirrors.kodi.tv/addons/migration
+ http://mirrors.kodi.tv/addons/migration
sha256
diff --git a/cmake/cpack/deb/packages/kodi.txt.in b/cmake/cpack/deb/packages/kodi.txt.in
index 4776622206ac3..78df46ae47d05 100644
--- a/cmake/cpack/deb/packages/kodi.txt.in
+++ b/cmake/cpack/deb/packages/kodi.txt.in
@@ -15,7 +15,7 @@ PACKAGE_ARCHITECTURE all
PACKAGE_SECTION video
PACKAGE_PRIORITY optional
PACKAGE_SHLIBDEPS
-PACKAGE_DEPENDS @APP_NAME_LC@-bin (>= @CPACK_DEBIAN_PACKAGE_VERSION@), @APP_NAME_LC@-bin (<< @CPACK_DEBIAN_PACKAGE_VERSION@.1~), curl, libcurl4 | libcurl3, mesa-utils, x11-utils, fonts-liberation | ttf-liberation, fonts-dejavu-core | ttf-dejavu-core, python-bluez | python-lightblue, python-imaging | python-pil, python-simplejson, libass9 | libass5 | libass4, libgif5 | libgif7, libnfs8 | libnfs4 | libnfs1, libbluray1 | libbluray2, libshairplay0, libvorbisfile3, libaacs0, libcec4, libgnutls30 | libgnutls-deb0-28 | libgnutls28 | libgnutls26, libxslt1.1
+PACKAGE_DEPENDS @APP_NAME_LC@-bin (>= @CPACK_DEBIAN_PACKAGE_VERSION@), @APP_NAME_LC@-bin (<< @CPACK_DEBIAN_PACKAGE_VERSION@.1~), curl, libcurl4 | libcurl3, mesa-utils, x11-utils, fonts-liberation | ttf-liberation, fonts-dejavu-core | ttf-dejavu-core, python3-pil, python3-simplejson, libass9 | libass5 | libass4, libgif5 | libgif7, libnfs8 | libnfs4 | libnfs1, libbluray1 | libbluray2, libshairplay0, libvorbisfile3, libaacs0, libcec4, libgnutls30 | libgnutls-deb0-28 | libgnutls28 | libgnutls26, libxslt1.1
PACKAGE_RECOMMENDS libvdpau1, libva-intel-vaapi-driver, libva1
PACKAGE_SUGGESTS @APP_NAME_LC@-pvr-mythtv, @APP_NAME_LC@-pvr-vuplus, @APP_NAME_LC@-pvr-vdr-vnsi, @APP_NAME_LC@-pvr-njoy, @APP_NAME_LC@-pvr-nextpvr, @APP_NAME_LC@-pvr-mediaportal-tvserver, @APP_NAME_LC@-pvr-tvheadend-hts, @APP_NAME_LC@-pvr-dvbviewer, @APP_NAME_LC@-pvr-argustv, @APP_NAME_LC@-pvr-iptvsimple, @APP_NAME_LC@-audioencoder-vorbis, @APP_NAME_LC@-audioencoder-flac, @APP_NAME_LC@-audioencoder-lame
PACKAGE_BREAKS xbmc (<< 2:14.0~git20141019), xbmc-data, xbmc-standalone
diff --git a/cmake/modules/FindPython.cmake b/cmake/modules/FindPython.cmake
index 213b17c629378..6c78a77cbc6d3 100644
--- a/cmake/modules/FindPython.cmake
+++ b/cmake/modules/FindPython.cmake
@@ -6,12 +6,12 @@
# PYTHON_LIBRARIES - The python libraries
if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_PYTHON python>=2.7 QUIET)
+ pkg_check_modules(PC_PYTHON python3>=3.5 QUIET)
endif()
-find_program(PYTHON_EXECUTABLE python ONLY_CMAKE_FIND_ROOT_PATH)
-find_library(PYTHON_LIBRARY NAMES python2.7 PATHS ${PC_PYTHON_LIBDIR})
-find_path(PYTHON_INCLUDE_DIR NAMES Python.h PATHS ${PC_PYTHON_INCLUDE_DIRS} ${DEPENDS_PATH}/include/python2.7)
+find_program(PYTHON_EXECUTABLE python3 ONLY_CMAKE_FIND_ROOT_PATH)
+find_library(PYTHON_LIBRARY NAMES python3.7 python3.6 python3.5 PATHS ${PC_PYTHON_LIBDIR})
+find_path(PYTHON_INCLUDE_DIR NAMES Python.h PATHS ${PC_PYTHON_INCLUDE_DIRS})
if(KODI_DEPENDSBUILD)
find_library(FFI_LIBRARY ffi REQUIRED)
@@ -25,7 +25,7 @@ if(KODI_DEPENDSBUILD)
set(PYTHON_LIBRARIES ${PYTHON_LIBRARY} ${FFI_LIBRARY} ${EXPAT_LIBRARY} ${INTL_LIBRARY} ${GMP_LIBRARY} ${PYTHON_DEP_LIBRARIES})
else()
- find_package(PythonLibs 2.7 REQUIRED)
+ find_package(PythonLibs 3.5 REQUIRED)
list(APPEND PYTHON_LIBRARIES ${PC_PYTHON_STATIC_LIBRARIES})
endif()
diff --git a/cmake/scripts/android/Install.cmake b/cmake/scripts/android/Install.cmake
index a121295f31055..a17f73bfa74c9 100644
--- a/cmake/scripts/android/Install.cmake
+++ b/cmake/scripts/android/Install.cmake
@@ -107,7 +107,7 @@ add_custom_target(bundle
${CMAKE_BINARY_DIR}/tools/android/packaging/media
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/tools/android/packaging/xbmc/res
${CMAKE_BINARY_DIR}/tools/android/packaging/xbmc/res
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPENDS_PATH}/lib/python2.7 ${libdir}/python2.7
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPENDS_PATH}/lib/python${PYTHON_VERSION} ${libdir}/python${PYTHON_VERSION}
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPENDS_PATH}/share/${APP_NAME_LC} ${datadir}/${APP_NAME_LC}
COMMAND ${CMAKE_COMMAND} -E copy $
${libdir}/${APP_NAME_LC}/$)
diff --git a/cmake/scripts/ios/Install.cmake b/cmake/scripts/ios/Install.cmake
index 7d8de72b9c922..f7ffd6712a297 100644
--- a/cmake/scripts/ios/Install.cmake
+++ b/cmake/scripts/ios/Install.cmake
@@ -74,6 +74,7 @@ add_custom_command(TARGET ${APP_NAME_LC} POST_BUILD
"FULL_PRODUCT_NAME=${APP_NAME}.app"
"WRAPPER_EXTENSION=app"
"SRCROOT=${CMAKE_BINARY_DIR}"
+ "PYTHON_VERSION=${PYTHON_VERSION}"
${CMAKE_SOURCE_DIR}/tools/darwin/Support/copyframeworks-ios.command
COMMAND "XBMC_DEPENDS=${DEPENDS_PATH}"
"NATIVEPREFIX=${NATIVEPREFIX}"
diff --git a/cmake/scripts/osx/Install.cmake b/cmake/scripts/osx/Install.cmake
index 77c771c9e1485..aca31b47c9b85 100644
--- a/cmake/scripts/osx/Install.cmake
+++ b/cmake/scripts/osx/Install.cmake
@@ -22,6 +22,7 @@ add_custom_target(bundle
"APP_NAME=${APP_NAME}"
"FULL_PRODUCT_NAME=${APP_NAME}.app"
"SRCROOT=${CMAKE_BINARY_DIR}"
+ "PYTHON_VERSION=${PYTHON_VERSION}"
${CMAKE_SOURCE_DIR}/tools/darwin/Support/copyframeworks-osx.command)
set_target_properties(bundle PROPERTIES FOLDER "Build Utilities")
add_dependencies(bundle ${APP_NAME_LC})
diff --git a/cmake/scripts/windows/ArchSetup.cmake b/cmake/scripts/windows/ArchSetup.cmake
index 032632c6a943c..3572371949a4e 100644
--- a/cmake/scripts/windows/ArchSetup.cmake
+++ b/cmake/scripts/windows/ArchSetup.cmake
@@ -35,7 +35,6 @@ set(MINGW_LIBS_DIR ${CMAKE_SOURCE_DIR}/${DEPS_FOLDER_RELATIVE}/mingwlibs/${ARCH}
list(APPEND CMAKE_PREFIX_PATH ${MINGW_LIBS_DIR})
list(APPEND CMAKE_LIBRARY_PATH ${MINGW_LIBS_DIR}/bin)
list(APPEND CMAKE_PREFIX_PATH ${DEPENDENCIES_DIR})
-set(PYTHON_INCLUDE_DIR ${DEPENDENCIES_DIR}/include/python)
# -------- Compiler options ---------
@@ -74,7 +73,7 @@ link_directories(${DEPENDENCIES_DIR}/lib)
# Additional libraries
list(APPEND DEPLIBS bcrypt.lib d3d11.lib DInput8.lib DSound.lib winmm.lib Mpr.lib Iphlpapi.lib WS2_32.lib
- PowrProf.lib setupapi.lib Shlwapi.lib dwmapi.lib dxguid.lib DelayImp.lib)
+ PowrProf.lib setupapi.lib Shlwapi.lib dwmapi.lib dxguid.lib DelayImp.lib Mincore.lib)
# NODEFAULTLIB option
set(_nodefaultlibs_RELEASE libcmt)
diff --git a/project/BuildDependencies/downloads/python3-3.7.1-Win32-v141.7z b/project/BuildDependencies/downloads/python3-3.7.1-Win32-v141.7z
new file mode 100644
index 0000000000000..ab614cb7d23c7
Binary files /dev/null and b/project/BuildDependencies/downloads/python3-3.7.1-Win32-v141.7z differ
diff --git a/project/BuildDependencies/downloads/python3-3.7.1-x64-v141.7z b/project/BuildDependencies/downloads/python3-3.7.1-x64-v141.7z
new file mode 100644
index 0000000000000..2b49ee4dddfc6
Binary files /dev/null and b/project/BuildDependencies/downloads/python3-3.7.1-x64-v141.7z differ
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-arm.list b/project/BuildDependencies/scripts/0_package.target-win10-arm.list
index 3b3ebc4bee9b5..952c2c0ab6de9 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-arm.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-arm.list
@@ -31,9 +31,6 @@ mini_wdk-10.0.14393.0-win32.7z
mysql-connector-c-6.1.9-win10-ARM-v141.7z
openssl-1.0.2o-win10-ARM-v141.7z
pcre-8.40-win10-ARM-v141.7z
-pillow-4.2.1-v1-win10-ARM-v141.7z
-pycryptodome-3.4.7-v1-win10-ARM-v140.7z
-python-2.7.14-v2-win10-ARM-v141.7z
rapidjson-1.1.0-win32.7z
shairplay-ce80e00-win10-ARM-v140.7z
sqlite-3170000-win10-ARM-v140.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-win32.list b/project/BuildDependencies/scripts/0_package.target-win10-win32.list
index d4a5115d08156..80f6a9e9ab872 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-win32.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-win32.list
@@ -31,9 +31,6 @@ mini_wdk-10.0.14393.0-win32.7z
mysql-connector-c-6.1.9-win10-Win32-v141.7z
openssl-1.0.2o-win10-Win32-v141.7z
pcre-8.40-win10-Win32-v141.7z
-pillow-4.2.1-v1-win10-Win32-v141.7z
-pycryptodome-3.4.7-v1-win10-Win32-v140.7z
-python-2.7.14-v2-win10-Win32-v141.7z
rapidjson-1.1.0-win32.7z
shairplay-ce80e00-win10-Win32-v140.7z
sqlite-3170000-win10-Win32-v140.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-x64.list b/project/BuildDependencies/scripts/0_package.target-win10-x64.list
index 9642427c14a4e..f6363617c0b88 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-x64.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-x64.list
@@ -31,9 +31,6 @@ mini_wdk-10.0.14393.0-win32.7z
mysql-connector-c-6.1.9-win10-x64-v141.7z
openssl-1.0.2o-win10-x64-v141.7z
pcre-8.40-win10-x64-v141.7z
-pillow-4.2.1-v1-win10-x64-v141.7z
-pycryptodome-3.4.7-v1-win10-x64-v140.7z
-python-2.7.14-v2-win10-x64-v141.7z
rapidjson-1.1.0-win32.7z
shairplay-ce80e00-win10-x64-v140.7z
sqlite-3170000-win10-x64-v140.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win32.list b/project/BuildDependencies/scripts/0_package.target-win32.list
index 1abe21cd5b794..b9306e07f2e8f 100644
--- a/project/BuildDependencies/scripts/0_package.target-win32.list
+++ b/project/BuildDependencies/scripts/0_package.target-win32.list
@@ -36,9 +36,7 @@ mini_wdk-10.0.14393.0-win32.7z
mysql-connector-c-6.1.6-win32-vc140-v2.7z
openssl-1.0.2g-win32-vc140-v2.7z
pcre-8.37-win32-vc140-v3.7z
-pillow-3.1.0-win32-vc140.7z
-pycryptodome-3.4.3-win32.7z
-python-2.7.13-win32-vc140-v3.7z
+python3-3.7.1-Win32-v141.7z
rapidjson-1.1.0-win32.7z
shairplay-0.9.0-win32-vc140-v2.7z
sqlite-3.10.2-win32-vc140.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-x64.list b/project/BuildDependencies/scripts/0_package.target-x64.list
index 0811a07218f8d..2805de38f79eb 100644
--- a/project/BuildDependencies/scripts/0_package.target-x64.list
+++ b/project/BuildDependencies/scripts/0_package.target-x64.list
@@ -33,9 +33,7 @@ mini_wdk-10.0.14393.0-x64.7z
mariadb-connector-c-3.0.6-x64-v141.7z
openssl-1.1.1-x64-v141.7z
pcre-8.40-x64-vc140.7z
-pillow-4.2.1-x64-vc140.zip
-pycryptodome-3.4.7-x64-vc140.zip
-python-2.7.13-x64-vc140-v3.7z
+python3-3.7.1-x64-v141.7z
rapidjson-1.1.0-win32.7z
shairplay-ce80e00-x64-vc140.7z
sqlite-3.17.0-x64-vc140.7z
diff --git a/tools/android/packaging/Makefile.in b/tools/android/packaging/Makefile.in
index 07776ce320a83..046cad3d8c50b 100644
--- a/tools/android/packaging/Makefile.in
+++ b/tools/android/packaging/Makefile.in
@@ -115,9 +115,9 @@ sharedobb: shared
@echo "$(CMAKE_SOURCE_DIR)/main.@APP_NAME_LC@.obb created"
python: | xbmc/assets
- mkdir -p xbmc/assets/python2.7/lib/
- cp -rfp $(PREFIX)/lib/python2.7 xbmc/assets/python2.7/lib/
- cd xbmc/assets/python2.7/lib/python2.7/; rm -rf test config lib-dynload
+ mkdir -p xbmc/assets/python@PYTHON_VERSION@/lib/
+ cp -rfp $(PREFIX)/lib/python@PYTHON_VERSION@ xbmc/assets/python@PYTHON_VERSION@/lib/
+ cd xbmc/assets/python@PYTHON_VERSION@/lib/python@PYTHON_VERSION@/; rm -rf test config lib-dynload
res:
mkdir -p xbmc/res xbmc/res/raw xbmc/res/values images
@@ -138,7 +138,7 @@ res:
libs: $(PREFIX)/lib/@APP_NAME_LC@/lib@APP_NAME_LC@.so
rm -rf xbmc/lib/$(CPU) xbmc/obj/local/$(CPU)
- mkdir -p xbmc/lib/$(CPU) xbmc/assets/python2.7/lib/ xbmc/obj/local/$(CPU)
+ mkdir -p xbmc/lib/$(CPU) xbmc/assets/python@PYTHON_VERSION@/lib/ xbmc/obj/local/$(CPU)
cp -fpL $(SRCLIBS) xbmc/obj/local/$(CPU)/
cp -fp $(PREFIX)/lib/@APP_NAME_LC@/lib@APP_NAME_LC@.so xbmc/obj/local/$(CPU)/
find $(PREFIX)/lib/@APP_NAME_LC@/addons -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \; || true
@@ -146,7 +146,7 @@ libs: $(PREFIX)/lib/@APP_NAME_LC@/lib@APP_NAME_LC@.so
find $(DEPENDS_PATH)/share/kodi/addons -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \; || true
find $(DEPENDS_PATH)/lib/kodi/addons -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \; || true
find $(PREFIX)/lib/@APP_NAME_LC@/system -name "*.so" -exec cp -fp {} xbmc/obj/local/$(CPU)/ \;
- DIR=${CURDIR}; cd $(PREFIX)/lib/python2.7/site-packages; for i in `find Cryptodome -name \*.so` ; do FN=`echo $$i | cut -c1- | tr "/" "_"` ; mv $$i $$DIR/xbmc/obj/local/$(CPU)/$$FN ; done
+ DIR=${CURDIR}; cd $(PREFIX)/lib/python@PYTHON_VERSION@/site-packages; for i in `find Cryptodome -name \*.so` ; do FN=`echo $$i | cut -c1- | tr "/" "_"` ; mv $$i $$DIR/xbmc/obj/local/$(CPU)/$$FN ; done
cd xbmc/obj/local/$(CPU)/; find . -name "*.so" -not -name "lib*.so" | sed "s/\.\///" | xargs -I@ mv @ lib@
cp -fp xbmc/obj/local/$(CPU)/*.so xbmc/lib/$(CPU)/
$(STRIP) --strip-unneeded xbmc/lib/$(CPU)/*.so
diff --git a/tools/android/packaging/xbmc/src/Splash.java.in b/tools/android/packaging/xbmc/src/Splash.java.in
index 4cf3345b711f8..6b0ec1a4967f3 100644
--- a/tools/android/packaging/xbmc/src/Splash.java.in
+++ b/tools/android/packaging/xbmc/src/Splash.java.in
@@ -416,7 +416,7 @@ public class Splash extends Activity
if (!(sName.startsWith("assets/") || (mInstallLibs && sName.startsWith("lib/"))))
continue;
- if (sName.startsWith("assets/python2.7"))
+ if (sName.startsWith("assets/python"))
continue;
String sFullPath = null;
diff --git a/tools/darwin/Support/copyframeworks-ios.command b/tools/darwin/Support/copyframeworks-ios.command
index d52033ebf931a..6fe7245eac307 100755
--- a/tools/darwin/Support/copyframeworks-ios.command
+++ b/tools/darwin/Support/copyframeworks-ios.command
@@ -74,14 +74,14 @@ for a in $(otool -L "$TARGET_BINARY" | grep "$EXTERNAL_LIBS\|$DYLIB_NAMEPATH" |
install_name_tool -change "$a" "$DYLIB_NAMEPATH/$(basename $a)" "$TARGET_BINARY"
done
-echo "Package $EXTERNAL_LIBS/lib/python2.7"
+echo "Package $EXTERNAL_LIBS/lib/python$PYTHON_VERSION"
mkdir -p "$TARGET_CONTENTS/Frameworks/lib"
PYTHONSYNC="rsync -aq --exclude .DS_Store --exclude *.a --exclude *.exe --exclude test --exclude tests"
-${PYTHONSYNC} "$EXTERNAL_LIBS/lib/python2.7" "$TARGET_FRAMEWORKS/lib/"
-rm -rf "$TARGET_FRAMEWORKS/lib/python2.7/config"
+${PYTHONSYNC} "$EXTERNAL_LIBS/lib/python$PYTHON_VERSION" "$TARGET_FRAMEWORKS/lib/"
+rm -rf "$TARGET_FRAMEWORKS/lib/python$PYTHON_VERSION/config"
echo "Checking python *.so for dylib dependencies"
-check_xbmc_dylib_depends "$TARGET_FRAMEWORKS"/lib/python2.7 "*.so"
+check_xbmc_dylib_depends "$TARGET_FRAMEWORKS"/lib/python$PYTHON_VERSION "*.so"
echo "Checking system *.so for dylib dependencies"
check_xbmc_dylib_depends "$XBMC_HOME"/system "*.so"
diff --git a/tools/darwin/Support/copyframeworks-osx.command b/tools/darwin/Support/copyframeworks-osx.command
index 7f1e6a510cc87..9ef7d28fc8abf 100755
--- a/tools/darwin/Support/copyframeworks-osx.command
+++ b/tools/darwin/Support/copyframeworks-osx.command
@@ -81,14 +81,14 @@ for a in $(otool -LX "$TARGET_BINARY" | grep "$EXTERNAL_LIBS" | awk ' { print $
install_name_tool -change "$a" "$DYLIB_NAMEPATH/$(basename $a)" "$TARGET_BINARY"
done
-echo "Package $EXTERNAL_LIBS/lib/python2.7"
+echo "Package $EXTERNAL_LIBS/lib/python$PYTHON_VERSION"
mkdir -p "$TARGET_CONTENTS/Libraries/lib"
PYTHONSYNC="rsync -aq --exclude .DS_Store --exclude *.a --exclude *.exe --exclude test --exclude tests"
-${PYTHONSYNC} "$EXTERNAL_LIBS/lib/python2.7" "$TARGET_FRAMEWORKS/lib/"
-rm -rf "$TARGET_FRAMEWORKS/lib/python2.7/config"
+${PYTHONSYNC} "$EXTERNAL_LIBS/lib/python$PYTHON_VERSION" "$TARGET_FRAMEWORKS/lib/"
+rm -rf "$TARGET_FRAMEWORKS/lib/python$PYTHON_VERSION/config"
-echo "Checking $TARGET_FRAMEWORKS/lib/python2.7 *.so for dylib dependencies"
-check_xbmc_dylib_depends "$TARGET_FRAMEWORKS"/lib/python2.7 "*.so"
+echo "Checking $TARGET_FRAMEWORKS/lib/python$PYTHON_VERSION *.so for dylib dependencies"
+check_xbmc_dylib_depends "$TARGET_FRAMEWORKS"/lib/python$PYTHON_VERSION "*.so"
echo "Checking $XBMC_HOME/system *.so for dylib dependencies"
check_xbmc_dylib_depends "$XBMC_HOME"/system "*.so"
diff --git a/tools/depends/native/Makefile b/tools/depends/native/Makefile
index ba5b8eba8d4d7..42131704dbd55 100644
--- a/tools/depends/native/Makefile
+++ b/tools/depends/native/Makefile
@@ -6,7 +6,7 @@ endif
NATIVE= m4-native gettext-native autoconf-native automake-native \
libtool-native pkg-config-native yasm-native cmake-native \
- gas-preprocessor-native python27-native zlib-native \
+ gas-preprocessor-native libffi-native python3-native zlib-native \
pcre-native swig-native \
libpng-native libjpeg-turbo-native liblzo2-native giflib-native \
distribute-native distutilscross-native JsonSchemaBuilder TexturePacker \
@@ -23,7 +23,7 @@ endif
ifeq ($(OS),linux)
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),raspberry-pi aml gbm))
- NATIVE += meson-native ninja-native python3-native
+ NATIVE += meson-native ninja-native
endif
endif
@@ -46,11 +46,10 @@ libpng-native: zlib-native
meson-native: python3-native
ninja-native: python3-native
swig-native: pcre-native
-distribute-native: python27-native
-distutilscross-native: python27-native distribute-native
+distribute-native: python3-native
+distutilscross-native: python3-native distribute-native
tar-native: xz-native automake-native
-python27-native: zlib-native
-python3-native: $(EXPAT) zlib-native
+python3-native: $(EXPAT) libffi-native zlib-native
wayland-scanner-native: expat-native
waylandpp-scanner-native: cmake-native
diff --git a/tools/depends/native/distribute-native/Makefile b/tools/depends/native/distribute-native/Makefile
index e9aced11d21f7..ee7ea71a59d07 100644
--- a/tools/depends/native/distribute-native/Makefile
+++ b/tools/depends/native/distribute-native/Makefile
@@ -19,7 +19,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
.installed-$(PLATFORM): $(PLATFORM)
- cd $(PLATFORM); $(PREFIX)/bin/python setup.py install --prefix=$(PREFIX)
+ cd $(PLATFORM); $(PREFIX)/bin/python3 setup.py install --prefix=$(PREFIX)
touch $@
clean:
diff --git a/tools/depends/native/distutilscross-native/Makefile b/tools/depends/native/distutilscross-native/Makefile
index 987b43b37c565..9ed0478d93756 100644
--- a/tools/depends/native/distutilscross-native/Makefile
+++ b/tools/depends/native/distutilscross-native/Makefile
@@ -1,7 +1,7 @@
include ../../Makefile.include
PREFIX=$(NATIVEPREFIX)
PLATFORM=$(NATIVEPLATFORM)
-DEPS= ../../Makefile.include Makefile
+DEPS= ../../Makefile.include Makefile python3.patch
# lib name, version
LIBNAME=distutilscross
@@ -17,9 +17,10 @@ $(TARBALLS_LOCATION)/$(ARCHIVE):
$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
-rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ cd $(PLATFORM); patch -p1 -i ../python3.patch
.installed-$(PLATFORM): $(PLATFORM)
- cd $(PLATFORM); $(PREFIX)/bin/python setup.py install --prefix=$(PREFIX)
+ cd $(PLATFORM); $(PREFIX)/bin/python3 setup.py install --prefix=$(PREFIX)
touch $@
clean:
diff --git a/tools/depends/native/distutilscross-native/python3.patch b/tools/depends/native/distutilscross-native/python3.patch
new file mode 100644
index 0000000000000..6e1059d223e2f
--- /dev/null
+++ b/tools/depends/native/distutilscross-native/python3.patch
@@ -0,0 +1,11 @@
+--- a/distutilscross/crosscompile.py
++++ b/distutilscross/crosscompile.py
+@@ -32,7 +32,7 @@
+ _get_python_lib = sysconfig.get_python_lib
+ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
+ if os.environ.has_key('PYTHONXCPREFIX'):
+- print "Setting prefix"
++ print("Setting prefix")
+ prefix = os.environ['PYTHONXCPREFIX']
+
+ return _get_python_lib(plat_specific, standard_lib, prefix)
diff --git a/tools/depends/native/expat-native/Makefile b/tools/depends/native/expat-native/Makefile
index c6574b606631a..8a0ad30070855 100644
--- a/tools/depends/native/expat-native/Makefile
+++ b/tools/depends/native/expat-native/Makefile
@@ -10,7 +10,7 @@ SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.bz2
# configuration settings
-CONFIGURE=cp -f $(CONFIG_SUB) $(CONFIG_GUESS) ./conftools; ./configure --prefix=$(PREFIX) --disable-shared
+CONFIGURE=cp -f $(CONFIG_SUB) $(CONFIG_GUESS) ./conftools; CFLAGS="-fPIC" ./configure --prefix=$(PREFIX) --disable-shared
LIBDYLIB=$(PLATFORM)/.libs/lib$(LIBNAME).a
diff --git a/tools/depends/native/python27-native/Makefile b/tools/depends/native/libffi-native/Makefile
similarity index 51%
rename from tools/depends/native/python27-native/Makefile
rename to tools/depends/native/libffi-native/Makefile
index 1854dac7307a8..462bc6e4c7923 100644
--- a/tools/depends/native/python27-native/Makefile
+++ b/tools/depends/native/libffi-native/Makefile
@@ -1,21 +1,19 @@
include ../../Makefile.include
+PREFIX=$(NATIVEPREFIX)
PLATFORM=$(NATIVEPLATFORM)
DEPS= ../../Makefile.include Makefile
# lib name, version
-LIBNAME=Python
-VERSION=2.7.15
+LIBNAME=libffi
+VERSION=3.2.1
SOURCE=$(LIBNAME)-$(VERSION)
-ARCHIVE=$(SOURCE).tar.xz
-CWD=$(shell pwd)
-HOSTPYTHONDIR=$(CWD)/$(PLATFORM)/hostpython
+ARCHIVE=$(SOURCE).tar.gz
-CONFIGURE=./configure --prefix=$(NATIVEPREFIX) --disable-shared --disable-toolbox-glue --disable-framework
+# configuration settings
+CONFIGURE= CFLAGS="-fPIC" ./configure --prefix=$(NATIVEPREFIX) --disable-shared --disable-builddir
-LIBDYLIB=$(PLATFORM)/python
-ifeq ($(NATIVE_OS), osx)
- LIBDYLIB=$(PLATFORM)/python.exe
-endif
+
+LIBDYLIB=$(PLATFORM)/.libs/$(LIBNAME).a
all: .installed-$(PLATFORM)
@@ -23,22 +21,23 @@ $(TARBALLS_LOCATION)/$(ARCHIVE):
cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
- rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ rm -rf $(PLATFORM); mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); $(CONFIGURE)
$(LIBDYLIB): $(PLATFORM)
- cd $(PLATFORM); $(MAKE) regen-grammar
- cd $(PLATFORM); $(MAKE)
+ $(MAKE) -j 1 -C $(PLATFORM)
+ touch $@
.installed-$(PLATFORM): $(LIBDYLIB)
- cd $(PLATFORM); $(MAKE) install
- install $(PLATFORM)/Parser/pgen $(NATIVEPREFIX)/bin
- touch $(LIBDYLIB)
+ $(MAKE) -C $(PLATFORM) install
+ mkdir -p $(NATIVEPREFIX)/include/ffi
+ cp $(NATIVEPREFIX)/lib/$(SOURCE)/include/* $(NATIVEPREFIX)/include/ffi/
touch $@
clean:
- rm -rf $(PLATFORM) .installed-$(PLATFORM)
+ $(MAKE) -C $(PLATFORM) clean
+ rm -f .installed-$(PLATFORM)
distclean::
rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/tools/depends/native/python3-native/Makefile b/tools/depends/native/python3-native/Makefile
index 5902fb8692d4f..50570ca8bb260 100644
--- a/tools/depends/native/python3-native/Makefile
+++ b/tools/depends/native/python3-native/Makefile
@@ -4,15 +4,19 @@ DEPS= ../../Makefile.include Makefile
# lib name, version
LIBNAME=Python
-VERSION=3.6.4
+VERSION=3.7.2
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.xz
+CWD=$(shell pwd)
+HOSTPYTHONDIR=$(CWD)/$(PLATFORM)/hostpython
+BASE_URL=https://www.python.org/ftp/python/$(VERSION)
-CONFIGURE=./configure --prefix=$(NATIVEPREFIX) --disable-shared --disable-framework --without-ensurepip --without-pymalloc
+CONFIGURE=./configure --prefix=$(NATIVEPREFIX) --disable-shared --disable-framework --without-pymalloc
ifeq ($(TARGET_PLATFORM),wayland)
CONFIGURE += --with-system-expat
endif
+
LIBDYLIB=$(PLATFORM)/python
ifeq ($(NATIVE_OS), osx)
LIBDYLIB=$(PLATFORM)/python.exe
@@ -29,10 +33,12 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
cd $(PLATFORM); $(CONFIGURE)
$(LIBDYLIB): $(PLATFORM)
+ cd $(PLATFORM); $(MAKE) regen-grammar
cd $(PLATFORM); $(MAKE)
.installed-$(PLATFORM): $(LIBDYLIB)
cd $(PLATFORM); $(MAKE) install
+ install $(PLATFORM)/Parser/pgen $(NATIVEPREFIX)/bin
touch $(LIBDYLIB)
touch $@
diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile
index 9c8d7dd361ae0..3cd7d94665e91 100644
--- a/tools/depends/target/Makefile
+++ b/tools/depends/target/Makefile
@@ -10,7 +10,7 @@ DEPENDS = \
openssl gmp nettle gnutls curl nghttp2 \
libjpeg-turbo libpng fribidi libass \
libxml2 rapidjson libmicrohttpd mariadb libffi \
- python27 libshairplay libfmt \
+ python3 libshairplay libfmt \
libplist libcec libbluray tinyxml \
taglib libusb libnfs \
pythonmodule-pil pythonmodule-pycryptodome pythonmodule-setuptools \
@@ -93,7 +93,7 @@ fontconfig: freetype2 expat $(ICONV)
curl: openssl nghttp2
libass: fontconfig fribidi libpng freetype2 expat $(ICONV)
libmicrohttpd: gnutls libgcrypt libgpg-error
-python27: expat gettext libxml2 sqlite3 openssl libffi
+python3: expat gettext libxml2 sqlite3 openssl libffi
libcdio: $(ICONV)
libcdio-gplv3: $(ICONV)
libplist: $(ZLIB)
@@ -104,9 +104,9 @@ libpng: $(ZLIB)
openssl: $(ZLIB)
gnutls: nettle $(ZLIB)
nettle: gmp
-pythonmodule-pycryptodome: $(PYMODULE_DEPS) python27 pythonmodule-setuptools
-pythonmodule-pil: bzip2 $(PYMODULE_DEPS) $(ZLIB) libjpeg-turbo libpng freetype2 python27 pythonmodule-setuptools
-pythonmodule-setuptools: $(PYMODULE_DEPS) python27
+pythonmodule-pycryptodome: $(PYMODULE_DEPS) python3 pythonmodule-setuptools
+pythonmodule-pil: bzip2 $(PYMODULE_DEPS) $(ZLIB) libjpeg-turbo libpng freetype2 python3 pythonmodule-setuptools
+pythonmodule-setuptools: $(PYMODULE_DEPS) python3
libxslt: libgcrypt libxml2
ffmpeg: $(ICONV) $(ZLIB) bzip2 $(FFMPEG_DEPENDS)
libcec: p8-platform
diff --git a/tools/depends/target/config.site.in b/tools/depends/target/config.site.in
index 36bf2fced25c2..2842797425bc3 100644
--- a/tools/depends/target/config.site.in
+++ b/tools/depends/target/config.site.in
@@ -34,7 +34,7 @@ LIBGCRYPT_CONFIG=@prefix@/@deps_dir@/bin/libgcrypt-config
PATH=@prefix@/@tool_dir@/bin:@use_toolchain@/usr/bin:@use_toolchain@/bin:$PATH
LD_LIBRARY_PATH=@prefix@/@tool_dir@/lib:$LD_LIBRARY_PATH
-PYTHON_VERSION=2.7
+PYTHON_VERSION=3.7
PYTHON_LDFLAGS="-L@prefix@/@deps_dir@/lib -L@prefix@/@deps_dir@/lib64 -lpython${PYTHON_VERSION} -lc -ldl -lm -lexpat -lffi -lintl -lutil -lssl -lcrypto"
PYTHON_CPPFLAGS=-I@prefix@/@deps_dir@/include/python${PYTHON_VERSION}
PYTHON_SITE_PKG=@prefix@/@deps_dir@/lib/python${PYTHON_VERSION}/site-packages
@@ -151,7 +151,10 @@ if test "@platform_os@" = "ios"; then
# in 10.12 but will get wrongly detected if building on 10.11
ac_cv_search_clock_gettime=no
ac_cv_func_clock_gettime=no
+ ac_cv_func_clock_settime=no
+ ac_cv_func_futimens=no
ac_cv_func_getentropy=no
+ ac_cv_func_utimensat=no
# tweaks for libffi
if test "${PACKAGE_NAME}" = "libffi" ; then
diff --git a/tools/depends/target/python27/android-binmodule.patch b/tools/depends/target/python27/android-binmodule.patch
deleted file mode 100644
index ec767a2ac1bb2..0000000000000
--- a/tools/depends/target/python27/android-binmodule.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/Python/dynload_shlib.c
-+++ b/Python/dynload_shlib.c
-@@ -112,10 +112,6 @@
- dlopenflags = PyThreadState_GET()->interp->dlopenflags;
- #endif
-
-- if (Py_VerboseFlag)
-- PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,
-- dlopenflags);
--
- #ifdef __VMS
- /* VMS currently don't allow a pathname, use a logical name instead */
- /* Concatenate 'python_module_' and shortname */
-@@ -125,8 +121,17 @@
- PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",
- shortname);
- pathname = pathbuf;
-+#elif defined(ANDROID)
-+ /* Android does not allow a pathname and wants lib*.so */
-+ PyOS_snprintf(pathbuf, sizeof(pathbuf), "lib%-.200s.so",
-+ shortname);
-+ pathname = pathbuf;
- #endif
-
-+ if (Py_VerboseFlag)
-+ PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,
-+ dlopenflags);
-+
- handle = dlopen(pathname, dlopenflags);
-
- if (handle == NULL) {
diff --git a/tools/depends/target/python27/android-nl_langinfo.patch b/tools/depends/target/python27/android-nl_langinfo.patch
deleted file mode 100644
index e3fec4a8d7ea1..0000000000000
--- a/tools/depends/target/python27/android-nl_langinfo.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/Python/pythonrun.c
-+++ b/Python/pythonrun.c
-@@ -301,7 +301,7 @@
- overridden = 1;
- }
-
--#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
-+#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(HAVE_NL_LANGINFO) && defined(CODESET)
- /* On Unix, set the file system encoding according to the
- user's preference, if the CODESET names a well-known
- Python codec, and Py_FileSystemDefaultEncoding isn't
---- a/configure.ac
-+++ b/configure.ac
-@@ -3114,7 +3114,7 @@
- getentropy \
- getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
- initgroups kill killpg lchmod lchown lstat mkfifo mknod mktime mmap \
-- mremap nice pathconf pause plock poll pthread_init \
-+ mremap nice nl_langinfo pathconf pause plock poll pthread_init \
- putenv readlink realpath \
- select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
- setgid \
diff --git a/tools/depends/target/python27/android.patch b/tools/depends/target/python27/android.patch
deleted file mode 100644
index 6c0386f5e4e97..0000000000000
--- a/tools/depends/target/python27/android.patch
+++ /dev/null
@@ -1,59 +0,0 @@
---- a/Modules/posixmodule.c
-+++ b/Modules/posixmodule.c
-@@ -3991,7 +3991,7 @@
- slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
- if (slave_fd < 0)
- return posix_error();
--#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
-+#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) && !defined(ANDROID)
- ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
- ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
- #ifndef __hpux
---- a/Modules/pwdmodule.c
-+++ b/Modules/pwdmodule.c
-@@ -68,14 +68,14 @@
- #define SETS(i,val) sets(v, i, val)
-
- SETS(setIndex++, p->pw_name);
--#ifdef __VMS
-+#if defined __VMS || defined(ANDROID)
- SETS(setIndex++, "");
- #else
- SETS(setIndex++, p->pw_passwd);
- #endif
- PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromUid(p->pw_uid));
- PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromGid(p->pw_gid));
--#ifdef __VMS
-+#if defined __VMS || defined(ANDROID)
- SETS(setIndex++, "");
- #else
- SETS(setIndex++, p->pw_gecos);
---- a/Modules/termios.c
-+++ b/Modules/termios.c
-@@ -230,6 +230,7 @@
- return Py_None;
- }
-
-+#if !defined(ANDROID)
- PyDoc_STRVAR(termios_tcdrain__doc__,
- "tcdrain(fd) -> None\n\
- \n\
-@@ -249,6 +250,7 @@
- Py_INCREF(Py_None);
- return Py_None;
- }
-+#endif
-
- PyDoc_STRVAR(termios_tcflush__doc__,
- "tcflush(fd, queue) -> None\n\
-@@ -304,8 +306,10 @@
- METH_VARARGS, termios_tcsetattr__doc__},
- {"tcsendbreak", termios_tcsendbreak,
- METH_VARARGS, termios_tcsendbreak__doc__},
-+#if !defined(ANDROID)
- {"tcdrain", termios_tcdrain,
- METH_VARARGS, termios_tcdrain__doc__},
-+#endif
- {"tcflush", termios_tcflush,
- METH_VARARGS, termios_tcflush__doc__},
- {"tcflow", termios_tcflow,
diff --git a/tools/depends/target/python27/crosscompile.patch b/tools/depends/target/python27/crosscompile.patch
deleted file mode 100644
index 5e33c1e8290b1..0000000000000
--- a/tools/depends/target/python27/crosscompile.patch
+++ /dev/null
@@ -1,138 +0,0 @@
---- a/Makefile.pre.in
-+++ b/Makefile.pre.in
-@@ -240,6 +240,7 @@
- ##########################################################################
- # Parser
- PGEN= Parser/pgen$(EXE)
-+PGEN_FOR_BUILD=$(NATIVE_PGEN)
-
- PSRCS= \
- Parser/acceler.c \
-@@ -523,9 +524,9 @@
- *\ -s*|s*) quiet="-q";; \
- *) quiet="";; \
- esac; \
-- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
-+ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
- _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \
-- $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build
-+ PYTHONXCPREFIX='$(DESTDIR)$(prefix)' $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build
-
- # Build static library
- # avoid long command lines, same as LIBRARY_OBJS
-@@ -1131,12 +1132,12 @@
- $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \
- $(DESTDIR)$(LIBDEST)/distutils/tests ; \
- fi
-- PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-+ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- $(PYTHON_FOR_BUILD) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
- -d $(LIBDEST) -f \
- -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
- $(DESTDIR)$(LIBDEST)
-- PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-+ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- $(PYTHON_FOR_BUILD) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
- -d $(LIBDEST) -f \
- -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
-@@ -1264,11 +1265,13 @@
- # Install the dynamically loadable modules
- # This goes into $(exec_prefix)
- sharedinstall: sharedmods
-+ CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
- $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \
-+ --skip-build \
- --prefix=$(prefix) \
-- --install-scripts=$(BINDIR) \
-- --install-platlib=$(DESTSHARED) \
-- --root=$(DESTDIR)/
-+ --install-scripts=$(DESTDIR)$(BINDIR) \
-+ --install-platlib=$(DESTDIR)$(DESTSHARED) \
-+ --root=/
- -rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata.py*
-
- # Here are a couple of targets for MacOSX again, to install a full
---- a/configure.ac
-+++ b/configure.ac
-@@ -343,7 +343,6 @@
- *)
- # for now, limit cross builds to known configurations
- MACHDEP="unknown"
-- AC_MSG_ERROR([cross build not supported for $host])
- esac
- ac_sys_release=
- else
-@@ -389,7 +388,6 @@
- *)
- # for now, limit cross builds to known configurations
- MACHDEP="unknown"
-- AC_MSG_ERROR([cross build not supported for $host])
- esac
- _PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}"
- fi
---- a/setup.py
-+++ b/setup.py
-@@ -17,7 +17,7 @@
- from distutils.command.install_lib import install_lib
- from distutils.spawn import find_executable
-
--cross_compiling = "_PYTHON_HOST_PLATFORM" in os.environ
-+cross_compiling = ("_PYTHON_HOST_PLATFORM" in os.environ) or ('CROSS_COMPILE_TARGET' in os.environ)
-
- def get_platform():
- # cross build
-@@ -178,6 +178,7 @@
-
- def build_extensions(self):
-
-+ return
- # Detect which modules should be compiled
- missing = self.detect_modules()
-
-@@ -342,6 +343,9 @@
-
- # Don't try to load extensions for cross builds
- if cross_compiling:
-+ self.announce(
-+ 'WARNING: skipping import check for cross-compiled: "%s"' %
-+ ext.name)
- return
-
- try:
-@@ -496,7 +500,7 @@
- for directory in reversed(options.dirs):
- add_dir_to_list(dir_list, directory)
-
-- if os.path.normpath(sys.prefix) != '/usr' \
-+ if os.path.normpath(sys.prefix) != '/usr' and not cross_compiling \
- and not sysconfig.get_config_var('PYTHONFRAMEWORK'):
- # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework
- # (PYTHONFRAMEWORK is set) to avoid # linking problems when
-@@ -572,6 +576,11 @@
- if host_platform in ['darwin', 'beos']:
- math_libs = []
-
-+ # Insert libraries and headers from embedded root file system (RFS)
-+ #if 'CROSS_COMPILE_TARGET' in os.environ:
-+ # lib_dirs += [os.environ['RFS'] + '/usr/lib']
-+ # inc_dirs += [os.environ['RFS'] + '/usr/include']
-+
- # XXX Omitted modules: gl, pure, dl, SGI-specific modules
-
- #
-@@ -2043,8 +2052,13 @@
-
- # Pass empty CFLAGS because we'll just append the resulting
- # CFLAGS to Python's; -g or -O2 is to be avoided.
-- cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
-- % (ffi_builddir, ffi_srcdir, " ".join(config_args))
-+ if cross_compiling:
-+ cmd = "cd %s && env CFLAGS='' '%s/configure' --host=%s --build=%s %s" \
-+ % (ffi_builddir, ffi_srcdir, os.environ.get('HOSTARCH'),
-+ os.environ.get('BUILDARCH'), " ".join(config_args))
-+ else:
-+ cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
-+ % (ffi_builddir, ffi_srcdir, " ".join(config_args))
-
- res = os.system(cmd)
- if res or not os.path.exists(ffi_configfile):
diff --git a/tools/depends/target/python27/no-export-path.patch b/tools/depends/target/python27/no-export-path.patch
deleted file mode 100644
index 95e295240aece..0000000000000
--- a/tools/depends/target/python27/no-export-path.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/Makefile.pre.in
-+++ b/Makefile.pre.in
-@@ -1159,8 +1159,6 @@
- $(srcdir)/Lib/$(PLATDIR):
- mkdir $(srcdir)/Lib/$(PLATDIR)
- cp $(srcdir)/Lib/plat-generic/regen $(srcdir)/Lib/$(PLATDIR)/regen
-- export PATH; PATH="`pwd`:$$PATH"; \
-- export PYTHONPATH; PYTHONPATH="$(srcdir)/Lib:$(abs_builddir)/`cat pybuilddir.txt`"; \
- export DYLD_FRAMEWORK_PATH; DYLD_FRAMEWORK_PATH="`pwd`"; \
- export EXE; EXE="$(BUILDEXE)"; \
- if [ -n "$(MULTIARCH)" ]; then export MULTIARCH; MULTIARCH=$(MULTIARCH); fi; \
diff --git a/tools/depends/target/python27/Makefile b/tools/depends/target/python3/Makefile
similarity index 61%
rename from tools/depends/target/python27/Makefile
rename to tools/depends/target/python3/Makefile
index 5016342cc7686..56ac9175b713b 100644
--- a/tools/depends/target/python27/Makefile
+++ b/tools/depends/target/python3/Makefile
@@ -1,12 +1,13 @@
include ../../Makefile.include
-DEPS= ../../Makefile.include Makefile crosscompile.patch android.patch no-export-path.patch android-nl_langinfo.patch \
- setup.patch fix-datetime.patch fix-ffi.patch android-binmodule.patch no-abort.patch urllib.patch modules.setup make-fork-optional.patch
+DEPS= ../../Makefile.include Makefile apple.patch crosscompile.patch android.patch \
+ fix-datetime.patch modules.setup make-fork-optional.patch android-nl_langinfo.patch
# lib name, version
LIBNAME=Python
-VERSION=2.7.15
+VERSION=3.7.2
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.xz
+BASE_URL=https://www.python.org/ftp/python/$(VERSION)
ifeq ($(OS),osx)
HOSTPLATFORM=_PYTHON_HOST_PLATFORM="darwin"
@@ -20,9 +21,9 @@ endif
CONFIGURE=OPT="$(CFLAGS)" \
LIBS=-lm \
./configure --prefix=$(PREFIX) --host=$(HOST) \
- --disable-toolbox-glue --disable-framework --with-system-expat --with-system-ffi --without-pymalloc --enable-ipv6
+ --disable-framework --with-system-expat --with-system-ffi --without-pymalloc --enable-ipv6
-LIBDYLIB=$(PLATFORM)/libpython2.7.a
+LIBDYLIB=$(PLATFORM)/libpython3.7.a
all: .installed-$(PLATFORM)
@@ -34,17 +35,13 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); patch -p1 < ../crosscompile.patch
- cd $(PLATFORM); patch -p1 < ../setup.patch
cd $(PLATFORM); patch -p1 < ../fix-datetime.patch
cd $(PLATFORM); patch -p1 < ../android.patch
- cd $(PLATFORM); patch -p1 < ../no-export-path.patch
cd $(PLATFORM); patch -p1 < ../fix-ffi.patch
- cd $(PLATFORM); patch -p1 < ../android-binmodule.patch
- cd $(PLATFORM); patch -p1 < ../no-abort.patch
- cd $(PLATFORM); patch -p1 < ../android-nl_langinfo.patch
+ cd $(PLATFORM); patch -p1 -i ../android-nl_langinfo.patch
+ cd $(PLATFORM); patch -p1 -i ../apple.patch
ifeq ($(OS),ios)
cd $(PLATFORM); patch -p1 < ../make-fork-optional.patch
- cd $(PLATFORM); patch -p1 < ../urllib.patch
cd $(PLATFORM); sed -ie 's|MACHDEP="unknown"|MACHDEP="darwin"|' configure.ac
endif
cp modules.setup $(PLATFORM)/Modules/Setup.dist
@@ -52,13 +49,13 @@ endif
#Add -liconv as needed, and add the _scproxy module for darwin
# disable locale altogether for Android
ifeq ($(OS),android)
- cd $(PLATFORM); sed -ie 's|_locale _localemodule.c -lintl|#_locale _localemodule.c -lintl|' Modules/Setup.dist
+ cd $(PLATFORM); sed -ie 's|_locale _localemodule.c -lintl|#_locale _localemodule.c -lintl $(LINK_ICONV)|' Modules/Setup.dist
else
- cd $(PLATFORM); sed -ie 's|_locale _localemodule.c -lintl|_locale _localemodule.c -lintl $(LINK_ICONV) |' Modules/Setup.dist
+ cd $(PLATFORM); sed -ie 's|_locale _localemodule.c -lintl|_locale _localemodule.c -lintl $(LINK_ICONV)|' Modules/Setup.dist
endif
ifeq ($(OS),osx)
cd $(PLATFORM); sed -ie 's|MACHDEP="unknown"|MACHDEP="darwin"|' configure.ac
- echo "_scproxy \$$(srcdir)/Mac/Modules/_scproxy.c -framework SystemConfiguration -framework CoreFoundation" >> $(PLATFORM)/Modules/Setup.dist
+ echo "_scproxy \$$(srcdir)/Modules/_scproxy.c -framework SystemConfiguration -framework CoreFoundation" >> $(PLATFORM)/Modules/Setup.dist
endif
ifeq ($(OS),android)
@@ -69,13 +66,13 @@ endif
cd $(PLATFORM); $(CONFIGURE)
$(LIBDYLIB): $(PLATFORM)
- $(MAKE) -C $(PLATFORM) $(HOSTPLATFORM) PYTHON_FOR_BUILD=$(NATIVEPREFIX)/bin/python NATIVE_PGEN=$(NATIVEPREFIX)/bin/pgen CROSS_COMPILE_TARGET=yes libpython2.7.a
+ $(MAKE) -C $(PLATFORM) $(HOSTPLATFORM) PYTHON_FOR_BUILD=$(NATIVEPREFIX)/bin/python3 NATIVE_PGEN=$(NATIVEPREFIX)/bin/pgen CROSS_COMPILE_TARGET=yes libpython3.7.a
touch $@
.installed-$(PLATFORM): $(LIBDYLIB)
- $(MAKE) -C $(PLATFORM) $(HOSTPLATFORM) PYTHON_FOR_BUILD=$(NATIVEPREFIX)/bin/python NATIVE_PGEN=$(NATIVEPREFIX)/bin/pgen CROSS_COMPILE_TARGET=yes install
- find $(PREFIX)/lib/python2.7 -type f -name "*.py" -delete
- find $(PREFIX)/lib/python2.7 -type f -name "*.pyc" -delete
+ $(MAKE) -C $(PLATFORM) $(HOSTPLATFORM) PYTHON_FOR_BUILD=$(NATIVEPREFIX)/bin/python3 NATIVE_PGEN=$(NATIVEPREFIX)/bin/pgen CROSS_COMPILE_TARGET=yes install
+ # find $(PREFIX)/lib/python3.7 -type f -name "*.py" -delete
+ find $(PREFIX)/lib/python3.7 -type f -name "*.pyc" -delete
touch $(LIBDYLIB)
touch $@
diff --git a/tools/depends/target/python3/android-nl_langinfo.patch b/tools/depends/target/python3/android-nl_langinfo.patch
new file mode 100644
index 0000000000000..0f25f219dd719
--- /dev/null
+++ b/tools/depends/target/python3/android-nl_langinfo.patch
@@ -0,0 +1,60 @@
+--- a/Modules/_localemodule.c
++++ b/Modules/_localemodule.c
+@@ -424,7 +424,7 @@
+ }
+ #endif
+
+-#ifdef HAVE_LANGINFO_H
++#if defined(HAVE_LANGINFO_H) && defined(HAVE_NL_LANGINFO)
+ #define LANGINFO(X) {#X, X}
+ static struct langinfo_constant{
+ char* name;
+@@ -690,7 +690,7 @@
+ #if defined(MS_WINDOWS)
+ {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
+ #endif
+-#ifdef HAVE_LANGINFO_H
++#if defined(HAVE_LANGINFO_H) && defined(HAVE_NL_LANGINFO)
+ {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
+ METH_VARARGS, nl_langinfo__doc__},
+ #endif
+@@ -730,7 +730,7 @@
+ PyInit__locale(void)
+ {
+ PyObject *m;
+-#ifdef HAVE_LANGINFO_H
++#if defined(HAVE_LANGINFO_H) && defined(HAVE_NL_LANGINFO)
+ int i;
+ #endif
+
+@@ -758,7 +758,7 @@
+ }
+ PyModule_AddObject(m, "Error", Error);
+
+-#ifdef HAVE_LANGINFO_H
++#if defined(HAVE_LANGINFO_H) && defined(HAVE_NL_LANGINFO)
+ for (i = 0; langinfo_constants[i].name; i++) {
+ PyModule_AddIntConstant(m, langinfo_constants[i].name,
+ langinfo_constants[i].value);
+--- a/Python/fileutils.c
++++ b/Python/fileutils.c
+@@ -56,7 +56,7 @@
+ has no console */
+ if (cp != 0)
+ return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
+-#elif defined(CODESET)
++#elif defined(HAVE_NL_LANGINFO) && defined(CODESET)
+ {
+ char *codeset = nl_langinfo(CODESET);
+ if (codeset != NULL && codeset[0] != 0)
+--- a/configure.ac
++++ b/configure.ac
+@@ -3549,7 +3549,7 @@
+ if_nameindex \
+ initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
+ memrchr mbrtowc mkdirat mkfifo \
+- mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
++ mkfifoat mknod mknodat mktime mremap nice nl_langinfo openat pathconf pause pipe2 plock poll \
+ posix_fallocate posix_fadvise posix_spawn pread preadv preadv2 \
+ pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
+ sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
diff --git a/tools/depends/target/python3/android.patch b/tools/depends/target/python3/android.patch
new file mode 100644
index 0000000000000..3b9504256520e
--- /dev/null
+++ b/tools/depends/target/python3/android.patch
@@ -0,0 +1,40 @@
+--- a/Modules/pwdmodule.c
++++ b/Modules/pwdmodule.c
+@@ -82,7 +82,7 @@
+ #endif
+ PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid));
+ PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid));
+-#if defined(HAVE_STRUCT_PASSWD_PW_GECOS)
++#if defined(HAVE_STRUCT_PASSWD_PW_GECOS) && !defined(__ANDROID__)
+ SETS(setIndex++, p->pw_gecos);
+ #else
+ SETS(setIndex++, "");
+--- a/Modules/termios.c
++++ b/Modules/termios.c
+@@ -224,6 +224,7 @@
+ Py_RETURN_NONE;
+ }
+
++#if !defined(__ANDROID__)
+ PyDoc_STRVAR(termios_tcdrain__doc__,
+ "tcdrain(fd) -> None\n\
+ \n\
+@@ -242,6 +243,7 @@
+
+ Py_RETURN_NONE;
+ }
++#endif
+
+ PyDoc_STRVAR(termios_tcflush__doc__,
+ "tcflush(fd, queue) -> None\n\
+@@ -295,8 +297,10 @@
+ METH_VARARGS, termios_tcsetattr__doc__},
+ {"tcsendbreak", termios_tcsendbreak,
+ METH_VARARGS, termios_tcsendbreak__doc__},
++ #if !defined(__ANDROID__)
+ {"tcdrain", termios_tcdrain,
+ METH_VARARGS, termios_tcdrain__doc__},
++ #endif
+ {"tcflush", termios_tcflush,
+ METH_VARARGS, termios_tcflush__doc__},
+ {"tcflow", termios_tcflow,
diff --git a/tools/depends/target/python3/apple.patch b/tools/depends/target/python3/apple.patch
new file mode 100644
index 0000000000000..bf1fd24c2c426
--- /dev/null
+++ b/tools/depends/target/python3/apple.patch
@@ -0,0 +1,12 @@
+--- a/Modules/posixmodule.c
++++ b/Modules/posixmodule.c
+@@ -113,6 +113,9 @@
+ #include
+ #endif
+
++#if defined(__APPLE__) && defined(_POSIX_C_SOURCE)
++#undef _POSIX_C_SOURCE
++#endif
+ #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+ #ifdef HAVE_SYS_SOCKET_H
+ #include
diff --git a/tools/depends/target/python3/crosscompile.patch b/tools/depends/target/python3/crosscompile.patch
new file mode 100644
index 0000000000000..d92177485e028
--- /dev/null
+++ b/tools/depends/target/python3/crosscompile.patch
@@ -0,0 +1,109 @@
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -38,7 +38,6 @@
+ MAINCC= @MAINCC@
+ LINKCC= @LINKCC@
+ AR= @AR@
+-READELF= @READELF@
+ SOABI= @SOABI@
+ LDVERSION= @LDVERSION@
+ GITVERSION= @GITVERSION@
+@@ -293,7 +292,7 @@
+ ##########################################################################
+ # Parser
+ PGEN= Parser/pgen$(EXE)
+-
++PGEN_FOR_BUILD=$(NATIVE_PGEN)
+ POBJS= \
+ Parser/acceler.o \
+ Parser/grammar1.o \
+@@ -620,7 +619,7 @@
+ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \
+ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
+ _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \
+- $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build
++ PYTHONXCPREFIX='$(DESTDIR)$(prefix)' $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build
+
+
+ # Build static library
+@@ -1524,11 +1523,13 @@
+ # Install the dynamically loadable modules
+ # This goes into $(exec_prefix)
+ sharedinstall: sharedmods
++ CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
+ $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \
++ --skip-build \
+ --prefix=$(prefix) \
+- --install-scripts=$(BINDIR) \
+- --install-platlib=$(DESTSHARED) \
+- --root=$(DESTDIR)/
++ --install-scripts=$(DESTDIR)$(BINDIR) \
++ --install-platlib=$(DESTDIR)$(DESTSHARED) \
++ --root=/
+ -rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py
+ -rm -r $(DESTDIR)$(DESTSHARED)/__pycache__
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -382,7 +382,6 @@
+ *)
+ # for now, limit cross builds to known configurations
+ MACHDEP="unknown"
+- AC_MSG_ERROR([cross build not supported for $host])
+ esac
+ ac_sys_release=
+ else
+@@ -426,7 +425,6 @@
+ *)
+ # for now, limit cross builds to known configurations
+ MACHDEP="unknown"
+- AC_MSG_ERROR([cross build not supported for $host])
+ esac
+ _PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}"
+ fi
+@@ -1200,16 +1198,6 @@
+ ARFLAGS="rcs"
+ fi
+
+-AC_CHECK_TOOLS([READELF], [readelf], [:])
+-if test "$cross_compiling" = yes; then
+- case "$READELF" in
+- readelf|:)
+- AC_MSG_ERROR([readelf for the host is required for cross builds])
+- ;;
+- esac
+-fi
+-AC_SUBST(READELF)
+-
+
+ case $MACHDEP in
+ hp*|HP*)
+--- a/setup.py
++++ b/setup.py
+@@ -16,7 +16,7 @@
+ from distutils.command.build_scripts import build_scripts
+ from distutils.spawn import find_executable
+
+-cross_compiling = "_PYTHON_HOST_PLATFORM" in os.environ
++cross_compiling = ("_PYTHON_HOST_PLATFORM" in os.environ) or ('CROSS_COMPILE_TARGET' in os.environ)
+
+ # Set common compiler and linker flags derived from the Makefile,
+ # reserved for building the interpreter and the stdlib modules.
+@@ -229,6 +229,7 @@
+
+ def build_extensions(self):
+
++ return
+ # Detect which modules should be compiled
+ missing = self.detect_modules()
+
+@@ -438,6 +439,9 @@
+
+ # Don't try to load extensions for cross builds
+ if cross_compiling:
++ self.announce(
++ 'WARNING: skipping import check for cross-compiled: "%s"' %
++ ext.name)
+ return
+
+ loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename)
diff --git a/tools/depends/target/python27/fix-datetime.patch b/tools/depends/target/python3/fix-datetime.patch
similarity index 72%
rename from tools/depends/target/python27/fix-datetime.patch
rename to tools/depends/target/python3/fix-datetime.patch
index dafe720f0e62e..3dce1814d8d73 100644
--- a/tools/depends/target/python27/fix-datetime.patch
+++ b/tools/depends/target/python3/fix-datetime.patch
@@ -1,18 +1,16 @@
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
-@@ -8,8 +8,14 @@
+@@ -10,7 +10,13 @@
#include "Python.h"
#include
#include "structmember.h"
--#include "datetime.h"
- #include "marshal.h"
+#ifdef Py_BUILD_CORE
+#undef Py_BUILD_CORE
-+#include "datetime.h"
+ #include "datetime.h"
+#define Py_BUILD_CORE
+#else
+#include "datetime.h"
+#endif
+ #include "marshal.h"
#include
- #ifdef MS_WINDOWS
- # include
+
diff --git a/tools/depends/target/python27/fix-ffi.patch b/tools/depends/target/python3/fix-ffi.patch
similarity index 96%
rename from tools/depends/target/python27/fix-ffi.patch
rename to tools/depends/target/python3/fix-ffi.patch
index 8fe55100e2b64..17c43ec40df75 100644
--- a/tools/depends/target/python27/fix-ffi.patch
+++ b/tools/depends/target/python3/fix-ffi.patch
@@ -1,6 +1,6 @@
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
-@@ -1735,6 +1735,7 @@
+@@ -1634,6 +1634,7 @@
*/
/* align and size are bogus for void, but they must not be zero */
@@ -8,12 +8,12 @@
ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
-@@ -1751,14 +1752,14 @@
+@@ -1650,14 +1651,15 @@
ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
--
+*/
+
#ifdef ffi_type_longdouble
#undef ffi_type_longdouble
#endif
@@ -24,7 +24,7 @@
ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
-
-+*/
++ */
/*---------------- EOF ----------------*/
--- a/Modules/_ctypes/malloc_closure.c
+++ b/Modules/_ctypes/malloc_closure.c
diff --git a/tools/depends/target/python27/make-fork-optional.patch b/tools/depends/target/python3/make-fork-optional.patch
similarity index 54%
rename from tools/depends/target/python27/make-fork-optional.patch
rename to tools/depends/target/python3/make-fork-optional.patch
index 42b3bc9359c9c..fc103bb610cd6 100644
--- a/tools/depends/target/python27/make-fork-optional.patch
+++ b/tools/depends/target/python3/make-fork-optional.patch
@@ -1,15 +1,13 @@
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
-@@ -167,6 +167,12 @@
+@@ -197,6 +197,10 @@
+ #endif /* _MSC_VER */
#endif /* ! __WATCOMC__ || __QNX__ */
- #endif /* ! __IBMC__ */
-+
+#undef HAVE_FORK
++#undef HAVE_FORKPTY
+#undef HAVE_EXECV
+#undef HAVE_SYSTEM
-+
-+
- #ifndef _MSC_VER
- #if defined(__sgi)&&_COMPILER_VERSION>=700
+ /*[clinic input]
+ # one of the few times we lie about this name!
diff --git a/tools/depends/target/python27/modules.setup b/tools/depends/target/python3/modules.setup
similarity index 61%
rename from tools/depends/target/python27/modules.setup
rename to tools/depends/target/python3/modules.setup
index fbe47b2513f30..b46576479aed3 100644
--- a/tools/depends/target/python27/modules.setup
+++ b/tools/depends/target/python3/modules.setup
@@ -11,8 +11,17 @@
# directory.)
# Each line in this file describes one or more optional modules.
-# Modules enabled here will not be compiled by the setup.py script,
+# Modules configured here will not be compiled by the setup.py script,
# so the file can be used to override setup.py's behavior.
+# Tag lines containing just the word "*static*", "*shared*" or "*disabled*"
+# (without the quotes but with the stars) are used to tag the following module
+# descriptions. Tag lines may alternate throughout this file. Modules are
+# built statically when they are preceded by a "*static*" tag line or when
+# there is no tag line between the start of the file and the module
+# description. Modules are built as a shared library when they are preceded by
+# a "*shared*" tag line. Modules are not built at all, not by the Makefile,
+# nor by the setup.py script, when they are preceded by a "*disabled*" tag
+# line.
# Lines have the following structure:
#
@@ -34,9 +43,7 @@
#
# which defines a Make variable definition inserted into Makefile.in
#
-# Finally, if a line contains just the word "*shared*" (without the
-# quotes but with the stars), then the following modules will not be
-# built statically. The build process works like this:
+# The build process works like this:
#
# 1. Build all modules that are declared as static in Modules/Setup,
# combine them into libpythonxy.a, combine that into python.
@@ -90,18 +97,7 @@ SITEPATH=:site-packages
# Standard path components for test modules
TESTPATH=
-# Path components for machine- or system-dependent modules and shared libraries
-MACHDEPPATH=:plat-$(MACHDEP)
-EXTRAMACHDEPPATH=
-
-# Path component for the Tkinter-related modules
-# The TKPATH variable is always enabled, to save you the effort.
-TKPATH=:lib-tk
-
-# Path component for old modules.
-OLDPATH=:lib-old
-
-COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)$(OLDPATH)
+COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)
PYTHONPATH=$(COREPYTHONPATH)
@@ -112,16 +108,39 @@ PYTHONPATH=$(COREPYTHONPATH)
# This only contains the minimal set of modules required to run the
# setup.py script in the root of the Python source tree.
-posix posixmodule.c # posix (UNIX) system calls
-errno errnomodule.c # posix (UNIX) errno values
-pwd pwdmodule.c # this is needed to find out the user's home dir
- # if $HOME is not set
-_sre _sre.c # Fredrik Lundh's new regular expressions
-_codecs _codecsmodule.c # access to the builtin codecs and codec registry
+posix -DPy_BUILD_CORE posixmodule.c # posix (UNIX) system calls
+errno errnomodule.c # posix (UNIX) errno values
+pwd pwdmodule.c # this is needed to find out the user's home dir
+ # if $HOME is not set
+_sre _sre.c # Fredrik Lundh's new regular expressions
+_codecs _codecsmodule.c # access to the builtin codecs and codec registry
+_weakref _weakref.c # weak references
+_functools -DPy_BUILD_CORE _functoolsmodule.c # Tools for working with functions and callable objects
+_operator _operator.c # operator.add() and similar goodies
+_collections _collectionsmodule.c # Container types
+_abc _abc.c # Abstract base classes
+itertools itertoolsmodule.c # Functions creating iterators for efficient looping
+atexit atexitmodule.c # Register functions to be run at interpreter-shutdown
+_signal -DPy_BUILD_CORE signalmodule.c
+_stat _stat.c # stat.h interface
+time -DPy_BUILD_CORE timemodule.c # -lm # time operations and variables
+_thread -DPy_BUILD_CORE _threadmodule.c # low-level threading interface
+
+# access to ISO C locale support
+_locale _localemodule.c -lintl
+
+# Standard I/O baseline
+_io -DPy_BUILD_CORE -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c
# The zipimport module is always imported at startup. Having it as a
# builtin module avoids some bootstrapping problems and reduces overhead.
-zipimport zipimport.c
+zipimport -DPy_BUILD_CORE zipimport.c
+
+# faulthandler module
+faulthandler faulthandler.c
+
+# debug tool to trace memory blocks allocated by Python
+_tracemalloc _tracemalloc.c hashtable.c
# The rest of the modules listed in this file are all commented out by
# default. Usually they can be detected and built as dynamically
@@ -136,21 +155,9 @@ zipimport zipimport.c
# The Python symtable module depends on .h files that setup.py doesn't track
_symtable symtablemodule.c
-# The SGI specific GL module:
-
-GLHACK=-Dclear=__GLclear
-#gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11
-
-# Pure module. Cannot be linked dynamically.
-# -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE
-#WHICH_PURE_PRODUCTS=-DWITH_ALL_PURE
-#PURE_INCLS=-I/usr/local/include
-#PURE_STUBLIBS=-L/usr/local/lib -lpurify_stubs -lquantify_stubs
-#pure puremodule.c $(WHICH_PURE_PRODUCTS) $(PURE_INCLS) $(PURE_STUBLIBS)
-
# Uncommenting the following line tells makesetup that all following
# modules are to be built as shared libraries (see above for more
-# detail; also note that *static* reverses this effect):
+# detail; also note that *static* or *disabled* cancels this effect):
#*shared*
@@ -162,41 +169,33 @@ GLHACK=-Dclear=__GLclear
# it, depending on your system -- see the GNU readline instructions.
# It's okay for this to be a shared library, too.
-#readline readline.c -lreadline -lncurses
+#readline readline.c -lreadline -ltermcap
# Modules that should always be present (non UNIX dependent):
array arraymodule.c # array objects
-cmath cmathmodule.c # -lm # complex math library functions
+cmath cmathmodule.c _math.c # -lm # complex math library functions
math mathmodule.c _math.c # -lm # math library functions, e.g. sin()
+#_contextvars _contextvarsmodule.c # Context Variables
_struct _struct.c # binary structure packing/unpacking
-time timemodule.c # -lm # time operations and variables
-operator operator.c # operator.add() and similar goodies
_weakref _weakref.c # basic weak reference support
_testcapi _testcapimodule.c # Python C API test module
_random _randommodule.c # Random number generator
-_collections _collectionsmodule.c # Container types
-itertools itertoolsmodule.c # Functions creating iterators for efficient looping
-strop stropmodule.c # String manipulations
-_functools _functoolsmodule.c # Tools for working with functions and callable objects
-
-EXPATDEFINES='-DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI'
-_elementtree $(EXPATDEFINES) _elementtree.c # elementtree accelerator
-#_pickle _pickle.c # pickle accelerator
-datetime datetimemodule.c # date/time type
+_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator
+_pickle _pickle.c # pickle accelerator
+_datetime _datetimemodule.c # datetime accelerator
_bisect _bisectmodule.c # Bisection algorithms
+_heapq _heapqmodule.c # Heap queue algorithm
+_asyncio _asynciomodule.c # Fast asyncio Future
unicodedata unicodedata.c # static Unicode character database
-# access to ISO C locale support
-_locale _localemodule.c -lintl
-
# Modules with some UNIX dependencies -- on by default:
# (If you have a really backward UNIX, select and socket may not be
# supported...)
-#
+
fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
#spwd spwdmodule.c # spwd(3)
#grp grpmodule.c # grp(3)
@@ -224,10 +223,9 @@ _hashlib _hashopenssl.c \
# The crypt module is now disabled by default because it breaks builds
# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
-#
-# First, look at Setup.config; configure may have set this for you.
-#crypt cryptmodule.c -lcrypt # crypt(3); needs -lcrypt on some systems
+#_crypt _cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
+
# Some more UNIX dependent modules -- off by default, since these
# are not supported by all UNIX systems:
@@ -236,6 +234,7 @@ _hashlib _hashopenssl.c \
termios termios.c # Steen Lumholt's termios module
resource resource.c # Jeremy Hylton's rlimit interface
+_posixsubprocess _posixsubprocess.c # POSIX subprocess module helper
# Multimedia modules -- off by default.
# These don't work for 64-bit platforms!!!
@@ -243,77 +242,26 @@ resource resource.c # Jeremy Hylton's rlimit interface
# These represent audio samples or images as strings:
#audioop audioop.c # Operations on audio samples
-#imageop imageop.c # Operations on images
# Note that the _md5 and _sha modules are normally only built if the
# system does not have the OpenSSL libs containing an optimized version.
# The _md5 module implements the RSA Data Security, Inc. MD5
-# Message-Digest Algorithm, described in RFC 1321. The necessary files
-# md5.c and md5.h are included here.
+# Message-Digest Algorithm, described in RFC 1321.
-_md5 md5module.c md5.c
+_md5 md5module.c
# The _sha module implements the SHA checksum algorithms.
# (NIST's Secure Hash Algorithms.)
-_sha shamodule.c
+_sha1 sha1module.c
_sha256 sha256module.c
_sha512 sha512module.c
+_sha3 _sha3/sha3module.c
-
-# SGI IRIX specific modules -- off by default.
-
-# These module work on any SGI machine:
-
-# *** gl must be enabled higher up in this file ***
-#fm fmmodule.c $(GLHACK) -lfm -lgl # Font Manager
-#sgi sgimodule.c # sgi.nap() and a few more
-
-# This module requires the header file
-# /usr/people/4Dgifts/iristools/include/izoom.h:
-#imgfile imgfile.c -limage -lgutil -lgl -lm # Image Processing Utilities
-
-
-# These modules require the Multimedia Development Option (I think):
-
-#al almodule.c -laudio # Audio Library
-#cd cdmodule.c -lcdaudio -lds -lmediad # CD Audio Library
-#cl clmodule.c -lcl -lawareaudio # Compression Library
-#sv svmodule.c yuvconvert.c -lsvideo -lXext -lX11 # Starter Video
-
-
-# The FORMS library, by Mark Overmars, implements user interface
-# components such as dialogs and buttons using SGI's GL and FM
-# libraries. You must ftp the FORMS library separately from
-# ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a.
-# NOTE: if you want to be able to use FORMS and curses simultaneously
-# (or both link them statically into the same binary), you must
-# compile all of FORMS with the cc option "-Dclear=__GLclear".
-
-# The FORMS variable must point to the FORMS subdirectory of the forms
-# toplevel directory:
-
-#FORMS=/ufs/guido/src/forms/FORMS
-#fl flmodule.c -I$(FORMS) $(GLHACK) $(FORMS)/libforms.a -lfm -lgl
-
-
-# SunOS specific modules -- off by default:
-
-#sunaudiodev sunaudiodev.c
-
-
-# A Linux specific module -- off by default; this may also work on
-# some *BSDs.
-
-#linuxaudiodev linuxaudiodev.c
-
-
-# George Neville-Neil's timing module:
-
-timing timingmodule.c
-
+# _blake module
+_blake2 _blake2/blake2module.c _blake2/blake2b_impl.c _blake2/blake2s_impl.c
# The _tkinter module.
#
@@ -359,79 +307,30 @@ timing timingmodule.c
# -lX11
# Lance Ellinghaus's syslog module
-syslog syslogmodule.c # syslog daemon interface
+#syslog syslogmodule.c # syslog daemon interface
-# Curses support, requring the System V version of curses, often
+# Curses support, requiring the System V version of curses, often
# provided by the ncurses library. e.g. on Linux, link with -lncurses
# instead of -lcurses).
-#
-# First, look at Setup.config; configure may have set this for you.
#_curses _cursesmodule.c -lcurses -ltermcap
# Wrapper for the panel library that's part of ncurses and SYSV curses.
#_curses_panel _curses_panel.c -lpanel -lncurses
-# Generic (SunOS / SVR4) dynamic loading module.
-# This is not needed for dynamic loading of Python modules --
-# it is a highly experimental and dangerous device for calling
-# *arbitrary* C functions in *arbitrary* shared libraries:
-
-#dl dlmodule.c
-
-
# Modules that provide persistent dictionary-like semantics. You will
# probably want to arrange for at least one of them to be available on
# your machine, though none are defined by default because of library
-# dependencies. The Python module anydbm.py provides an
-# implementation independent wrapper for these; dumbdbm.py provides
+# dependencies. The Python module dbm/__init__.py provides an
+# implementation independent wrapper for these; dbm/dumb.py provides
# similar functionality (but slower of course) implemented in Python.
-# The standard Unix dbm module has been moved to Setup.config so that
-# it will be compiled as a shared library by default. Compiling it as
-# a built-in module causes conflicts with the pybsddb3 module since it
-# creates a static dependency on an out-of-date version of db.so.
-#
-# First, look at Setup.config; configure may have set this for you.
-
-#dbm -I$(prefix)/include -L$(prefix)/lib dbmmodule.c # dbm(3) may require -lndbm or similar
+#_dbm _dbmmodule.c # dbm(3) may require -lndbm or similar
# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
-#
-# First, look at Setup.config; configure may have set this for you.
-
-#gdbm gdbmmodule.c -I$(prefix)/include -L$(prefix)/lib -lgdbm
-
-
-# Sleepycat Berkeley DB interface.
-#
-# This requires the Sleepycat DB code, see http://www.sleepycat.com/
-# The earliest supported version of that library is 3.0, the latest
-# supported version is 4.0 (4.1 is specifically not supported, as that
-# changes the semantics of transactional databases). A list of available
-# releases can be found at
-#
-# http://www.sleepycat.com/update/index.html
-#
-# Edit the variables DB and DBLIBVERto point to the db top directory
-# and the subdirectory of PORT where you built it.
-#DB=/usr/local/BerkeleyDB.4.0
-#DBLIBVER=4.0
-#DBINC=$(DB)/include
-#DBLIB=$(DB)/lib
-#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
-
-# Historical Berkeley DB 1.85
-#
-# This module is deprecated; the 1.85 version of the Berkeley DB library has
-# bugs that can cause data corruption. If you can, use later versions of the
-# library instead, available from .
-
-#DB=/depot/sundry/src/berkeley-db/db.1.85
-#DBPORT=$(DB)/PORT/irix.5.3
-#bsddb185 bsddbmodule.c -I$(DBPORT)/include -I$(DBPORT) $(DBPORT)/libdb.a
+#_gdbm _gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
# Helper module for various ascii-encoders
@@ -440,32 +339,11 @@ binascii binascii.c
# Fred Drake's interface to the Python parser
parser parsermodule.c
-# cStringIO and cPickle
-cStringIO cStringIO.c
-cPickle cPickle.c
-
-
-# Lee Busby's SIGFPE modules.
-# The library to link fpectl with is platform specific.
-# Choose *one* of the options below for fpectl:
-
-# For SGI IRIX (tested on 5.3):
-#fpectl fpectlmodule.c -lfpe
-
-# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
-# (Without the compiler you don't have -lsunmath.)
-#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
-
-# For other systems: see instructions in fpectlmodule.c.
-#fpectl fpectlmodule.c ...
-
-# Test module for fpectl. No extra libraries needed.
-#fpetest fpetestmodule.c
# Andrew Kuchling's zlib module.
# This require zlib 1.1.3 (or later).
# See http://www.gzip.org/zlib/
-zlib zlibmodule.c -I$(prefix)/include -L$(prefix)/lib -lz
+zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
# Interface to the Expat XML parser
#
@@ -478,13 +356,12 @@ zlib zlibmodule.c -I$(prefix)/include -L$(prefix)/lib -lz
#
# More information on Expat can be found at www.libexpat.org.
#
-pyexpat pyexpat.c $(EXPATDEFINES) -I$(prefix)/include -L$(prefix)/lib -lexpat
-
+#pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI
# Hye-Shik Chang's CJKCodecs
# multibytecodec is required for all the other CJK codec modules
-_multibytecodec cjkcodecs/multibytecodec.c
+#_multibytecodec cjkcodecs/multibytecodec.c
_codecs_cn cjkcodecs/_codecs_cn.c
_codecs_hk cjkcodecs/_codecs_hk.c
@@ -499,14 +376,6 @@ _codecs_tw cjkcodecs/_codecs_tw.c
# Another example -- the 'xxsubtype' module shows C-level subtyping in action
xxsubtype xxsubtype.c
-_lsprof _lsprof.c rotatingtree.c
-_json _json.c
-#_io/fileio _io/fileio.c
-_io _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c
-_heapq _heapqmodule.c
-_hotshot _hotshot.c
-future_builtins future_builtins.c
-
SQLITEDEFINES='-DMODULE_NAME="sqlite3"'
_sqlite3 _sqlite/connection.c \
_sqlite/cursor.c _sqlite/microprotocols.c _sqlite/prepare_protocol.c \
@@ -517,4 +386,12 @@ _ctypes _ctypes/callbacks.c _ctypes/callproc.c _ctypes/cfield.c _ctypes/_ctyp
_ctypes/malloc_closure.c _ctypes/stgdict.c \
-I$(prefix)/include/ffi -L$(prefix)/lib -lffi
-#bz2 bz2module.c -I$(prefix)/include -L$(prefix)/lib -lbz2
+_queue _queuemodule.c
+
+# Uncommenting the following line tells makesetup that all following modules
+# are not built (see above for more detail).
+#
+#*disabled*
+#
+#_sqlite3 _tkinter _curses pyexpat
+#_codecs_jp _codecs_kr _codecs_tw unicodedata
diff --git a/tools/depends/target/python27/no-abort.patch b/tools/depends/target/python3/no-abort.patch
similarity index 68%
rename from tools/depends/target/python27/no-abort.patch
rename to tools/depends/target/python3/no-abort.patch
index 72f82b8332f27..e509c2d1e7bd9 100644
--- a/tools/depends/target/python27/no-abort.patch
+++ b/tools/depends/target/python3/no-abort.patch
@@ -1,8 +1,8 @@
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
-@@ -8649,7 +8649,7 @@
- static PyObject *
- posix_abort(PyObject *self, PyObject *noargs)
+@@ -10365,7 +10365,7 @@
+ os_abort_impl(PyObject *module)
+ /*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
{
- abort();
+ // abort();
@@ -11,12 +11,12 @@
return NULL;
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
-@@ -1706,7 +1706,7 @@
+@@ -1697,7 +1697,7 @@
DebugBreak();
#endif
#endif /* MS_WINDOWS */
- abort();
+ // abort();
}
-
+
/* Clean up and exit */
diff --git a/tools/depends/target/python27/setup.patch b/tools/depends/target/python3/setup.patch
similarity index 94%
rename from tools/depends/target/python27/setup.patch
rename to tools/depends/target/python3/setup.patch
index 565f63e3151a1..64968d413eac3 100644
--- a/tools/depends/target/python27/setup.patch
+++ b/tools/depends/target/python3/setup.patch
@@ -1,13 +1,13 @@
--- a/Modules/makesetup
+++ b/Modules/makesetup
@@ -212,6 +212,7 @@
- objs="$objs $obj"
- case $src in
- glmodule.c) ;;
+ objs="$objs $obj"
+ case $src in
+ glmodule.c) ;;
+ # _*io.c) src='$(srcdir)/'"$srcdir/_io/$(echo $src| tr -d "_")";;
- /*) ;;
- \$*) ;;
- *) src='$(srcdir)/'"$srcdir/$src";;
+ /*) ;;
+ \$*) ;;
+ *) src='$(srcdir)/'"$srcdir/$src";;
--- a/setup.py
+++ b/setup.py
@@ -337,6 +337,9 @@
@@ -16,7 +16,7 @@
return
+ #if os.environ.get('CROSS_COMPILE_TARGET') == 'yes':
+ # return
-+
++
ext_filename = os.path.join(
self.build_lib,
self.get_ext_filename(self.get_ext_fullname(ext.name)))
diff --git a/tools/depends/target/python27/urllib.patch b/tools/depends/target/python3/urllib.patch
similarity index 100%
rename from tools/depends/target/python27/urllib.patch
rename to tools/depends/target/python3/urllib.patch
diff --git a/tools/depends/target/pythonmodule-pil/Makefile b/tools/depends/target/pythonmodule-pil/Makefile
index addd67498c750..d9f2660180cf2 100644
--- a/tools/depends/target/pythonmodule-pil/Makefile
+++ b/tools/depends/target/pythonmodule-pil/Makefile
@@ -10,26 +10,26 @@ VERSION=3.0.0
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.gz
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/"
ifeq ($(OS),android)
PILPATH=$(PREFIX)/share/$(APP_NAME)/addons/script.module.pil
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -L$(PREFIX)/lib/dummy-lib$(APP_NAME)/ -l$(APP_NAME) -lm" PYTHONPATH="$(PILPATH):$(PREFIX)/lib/python2.7/site-packages/"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -L$(PREFIX)/lib/dummy-lib$(APP_NAME)/ -l$(APP_NAME) -lm" PYTHONPATH="$(PILPATH):$(PREFIX)/lib/python3.7/site-packages/"
endif
ifeq (darwin, $(findstring darwin, $(HOST)))
ifeq ($(OS),ios)
-PYTHON_O=$(abs_top_srcdir)/target/python27/$(PLATFORM)/Modules/python.o
+PYTHON_O=$(abs_top_srcdir)/target/python3/$(PLATFORM)/Programs/python.o
endif
#ensure that only our target ldflags are passed to the python build
LDSHARED:=$(CC) -bundle -undefined dynamic_lookup $(LDFLAGS)
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" CCSHARED="$(CC) $(CFLAGS) $(PYTHON_O)" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/" LDSHARED="$(LDSHARED)"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" CCSHARED="$(CC) $(CFLAGS) $(PYTHON_O)" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/" LDSHARED="$(LDSHARED)"
endif
-LIBDYLIB=$(PLATFORM)/dist/Pillow-$(VERSION)-py2.7-$(OS)-$(CPU).egg
+LIBDYLIB=$(PLATFORM)/dist/Pillow-$(VERSION)-py3.7-$(OS)-$(CPU).egg
ifeq ($(OS),android)
LIBDYLIB=$(PREFIX)/share/$(APP_NAME)/addons/script.module.pil/lib/PIL/_imaging.so
else ifeq (darwin, $(findstring darwin, $(HOST)))
-LIBDYLIB=$(PLATFORM)/dist/Pillow-$(VERSION)-py2.7-macosx-10.4-x86_64.egg
+LIBDYLIB=$(PLATFORM)/dist/Pillow-$(VERSION)-py3.7-macosx-10.4-x86_64.egg
endif
all: .installed-$(PLATFORM)
@@ -44,16 +44,16 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
$(LIBDYLIB): $(PLATFORM)
mkdir -p $(PLATFORM)/output
- cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python setup.py build_ext --plat-name $(OS)-$(CPU)
+ cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python3 setup.py build_ext --plat-name $(OS)-$(CPU)
.installed-$(PLATFORM): $(LIBDYLIB)
ifeq ($(OS),android)
mkdir -p $(PREFIX)/share/$(APP_NAME)/addons/script.module.pil/lib
- cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python setup.py install --install-lib $(PREFIX)/share/$(APP_NAME)/addons/script.module.pil
+ cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python3 setup.py install --install-lib $(PREFIX)/share/$(APP_NAME)/addons/script.module.pil
cd $(PREFIX)/share/$(APP_NAME)/addons/script.module.pil/lib && unzip -o ../Pillow-*.egg
cd $(PREFIX)/share/$(APP_NAME)/addons/script.module.pil && rm -rf Pillow-*.egg
else
- cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python setup.py install --prefix=$(PREFIX)
+ cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python3 setup.py install --prefix=$(PREFIX)
endif
touch $@
diff --git a/tools/depends/target/pythonmodule-pil/pillow-crosscompile.patch b/tools/depends/target/pythonmodule-pil/pillow-crosscompile.patch
index 86e1a914f7000..97c61a54c208d 100644
--- a/tools/depends/target/pythonmodule-pil/pillow-crosscompile.patch
+++ b/tools/depends/target/pythonmodule-pil/pillow-crosscompile.patch
@@ -26,7 +26,7 @@
if prefix:
_add_directory(library_dirs, os.path.join(prefix, "lib"))
_add_directory(include_dirs, os.path.join(prefix, "include"))
-+ _add_directory(include_dirs, os.path.join(prefix, "include/python2.7"))
++ _add_directory(include_dirs, os.path.join(prefix, "include/python3.7"))
#
# add platform directories
diff --git a/tools/depends/target/pythonmodule-pycryptodome/Makefile b/tools/depends/target/pythonmodule-pycryptodome/Makefile
index 2c53295eb42b3..d6a48a8f5a955 100644
--- a/tools/depends/target/pythonmodule-pycryptodome/Makefile
+++ b/tools/depends/target/pythonmodule-pycryptodome/Makefile
@@ -10,23 +10,23 @@ VERSION=3.4.3
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.gz
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/"
ifeq ($(OS),android)
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -L$(PREFIX)/lib/dummy-lib$(APP_NAME)/ -l$(APP_NAME) -lm" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -L$(PREFIX)/lib/dummy-lib$(APP_NAME)/ -l$(APP_NAME) -lm" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/"
endif
ifeq (darwin, $(findstring darwin, $(HOST)))
ifeq ($(OS),ios)
-PYTHON_O=$(abs_top_srcdir)/target/python27/$(PLATFORM)/Modules/python.o
+PYTHON_O=$(abs_top_srcdir)/target/python3/$(PLATFORM)/Programs/python.o
endif
#ensure that only our target ldflags are passed to the python build
LDSHARED:=$(CC) -bundle -undefined dynamic_lookup $(LDFLAGS)
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" CCSHARED="$(CC) $(CFLAGS) $(PYTHON_O)" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/" LDSHARED="$(LDSHARED)"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" CCSHARED="$(CC) $(CFLAGS) $(PYTHON_O)" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/" LDSHARED="$(LDSHARED)"
endif
-LIBDYLIB=$(PLATFORM)/build/lib.$(OS)-$(CPU)-2.7/Cryptodome
+LIBDYLIB=$(PLATFORM)/build/lib.$(OS)-$(CPU)-3.7/Cryptodome
ifeq ($(NATIVE_OS), osx)
- LIBDYLIB=$(PLATFORM)/build/lib.macosx-10.4-x86_64-2.7/Cryptodome
+ LIBDYLIB=$(PLATFORM)/build/lib.macosx-10.4-x86_64-3.7/Cryptodome
endif
all: .installed-$(PLATFORM)
@@ -45,10 +45,10 @@ endif
$(LIBDYLIB): $(PLATFORM)
mkdir -p $(PLATFORM)/output
- cd $(PLATFORM); touch .separate_namespace && $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python setup.py build_ext --plat-name $(OS)-$(TARGET_ARCH)
+ cd $(PLATFORM); touch .separate_namespace && $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python3 setup.py build_ext --plat-name $(OS)-$(TARGET_ARCH)
.installed-$(PLATFORM): $(LIBDYLIB)
- cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python setup.py install --prefix=$(PREFIX)
+ cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python3 setup.py install --prefix=$(PREFIX)
touch $@
clean:
diff --git a/tools/depends/target/pythonmodule-setuptools/Makefile b/tools/depends/target/pythonmodule-setuptools/Makefile
index 69dba4c7b9386..b65be1d5713d8 100644
--- a/tools/depends/target/pythonmodule-setuptools/Makefile
+++ b/tools/depends/target/pythonmodule-setuptools/Makefile
@@ -10,20 +10,20 @@ VERSION=18.4
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.gz
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/"
ifeq ($(OS),android)
#PYTHONPATH=$(PREFIX)/share/$(APP_NAME)/addons/script.module.pil
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -L$(PREFIX)/lib/dummy-lib$(APP_NAME)/ -l$(APP_NAME) -lm" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -L$(PREFIX)/lib/dummy-lib$(APP_NAME)/ -l$(APP_NAME) -lm" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/"
endif
ifeq ($(OS),osx)
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -lpython" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/"
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC)" LDSHARED="$(CC) -shared" LDFLAGS="$(LDFLAGS) -lpython" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/"
endif
ifeq ($(OS),ios)
-PYTHON_O=$(abs_top_srcdir)/target/python27/$(PLATFORM)/Modules/python.o
-CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" CCSHARED="$(CC) $(CFLAGS) $(PYTHON_O)" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python2.7/site-packages/"
+PYTHON_O=$(abs_top_srcdir)/target/python3/$(PLATFORM)/Programs/python.o
+CROSSFLAGS=PYTHONXCPREFIX="$(PREFIX)" CC="$(CC) $(CFLAGS)" CCSHARED="$(CC) $(CFLAGS) $(PYTHON_O)" LDFLAGS="$(LDFLAGS)" PYTHONPATH="$(PREFIX)/lib/python3.7/site-packages/"
endif
-LIBDYLIB=$(PLATFORM)/dist/$(LIBNAME)-$(VERSION)-py2.7.egg
+LIBDYLIB=$(PLATFORM)/dist/$(LIBNAME)-$(VERSION)-py3.7.egg
all: .installed-$(PLATFORM)
@@ -36,10 +36,10 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
$(LIBDYLIB): $(PLATFORM)
mkdir -p $(PLATFORM)/output
- cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python setup.py build_ext --plat-name $(OS)-$(CPU)
+ cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python3 setup.py build_ext --plat-name $(OS)-$(CPU)
.installed-$(PLATFORM): $(LIBDYLIB)
- cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python setup.py install --prefix=$(PREFIX)
+ cd $(PLATFORM); $(CROSSFLAGS) $(NATIVEPREFIX)/bin/python3 setup.py install --prefix=$(PREFIX)
touch $@
clean:
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp
index 4d6e27e3d914a..4deb0a565a6bd 100644
--- a/xbmc/addons/AddonManager.cpp
+++ b/xbmc/addons/AddonManager.cpp
@@ -193,19 +193,12 @@ void CAddonMgr::FillCpluffMetadata(const cp_plugin_info_t* plugin, CAddonBuilder
builder.SetLicense(CServiceBroker::GetAddonMgr().GetExtValue(metadata->configuration, "license"));
builder.SetPackageSize(StringUtils::ToUint64(CServiceBroker::GetAddonMgr().GetExtValue(metadata->configuration, "size"), 0));
+ std::string language = CServiceBroker::GetAddonMgr().GetExtValue(metadata->configuration, "language");
+ if (!language.empty())
{
InfoMap extrainfo;
-
- std::string metaString = CServiceBroker::GetAddonMgr().GetExtValue(metadata->configuration, "language");
- if (!metaString.empty())
- extrainfo.insert(std::make_pair("language", metaString));
-
- metaString = CServiceBroker::GetAddonMgr().GetExtValue(metadata->configuration, "reuselanguageinvoker");
- if (!metaString.empty())
- extrainfo.insert(std::make_pair("reuselanguageinvoker", metaString));
-
- if (!extrainfo.empty())
- builder.SetExtrainfo(std::move(extrainfo));
+ extrainfo.insert(std::make_pair("language",language));
+ builder.SetExtrainfo(std::move(extrainfo));
}
builder.SetBroken(CServiceBroker::GetAddonMgr().GetExtValue(metadata->configuration, "broken"));
diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
index 5546f6ecdca35..51cb6e5faee57 100644
--- a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
+++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
@@ -133,8 +133,8 @@ extern "C" void __stdcall init_emu_environ()
// check if we are running as real xbmc.app or just binary
if (!CUtil::GetFrameworksPath(true).empty())
{
- // using external python, it's build looking for xxx/lib/python2.7
- // so point it to frameworks which is where python2.7 is located
+ // using external python, it's build looking for xxx/lib/python3.7
+ // so point it to frameworks which is where python3.7 is located
dll_putenv(("PYTHONPATH=" +
CSpecialProtocol::TranslatePath("special://frameworks")).c_str());
dll_putenv(("PYTHONHOME=" +
@@ -156,7 +156,7 @@ extern "C" void __stdcall init_emu_environ()
#if defined(TARGET_ANDROID)
std::string apkPath = getenv("KODI_ANDROID_APK");
- apkPath += "/assets/python2.7";
+ apkPath += "/assets/python3.7";
dll_putenv(("PYTHONHOME=" + apkPath).c_str());
dll_putenv("PYTHONOPTIMIZE=");
dll_putenv("PYTHONNOUSERSITE=1");
diff --git a/xbmc/filesystem/PluginDirectory.cpp b/xbmc/filesystem/PluginDirectory.cpp
index fcc3a15e1fef9..06de4cde1ab13 100644
--- a/xbmc/filesystem/PluginDirectory.cpp
+++ b/xbmc/filesystem/PluginDirectory.cpp
@@ -85,12 +85,6 @@ int CPluginDirectory::getNewHandle(CPluginDirectory *cp)
return handle;
}
-void CPluginDirectory::reuseHandle(int handle, CPluginDirectory *cp)
-{
- CSingleLock lock(m_handleLock);
- globalHandles[handle] = cp;
-}
-
void CPluginDirectory::removeHandle(int handle)
{
CSingleLock lock(m_handleLock);
@@ -129,12 +123,7 @@ bool CPluginDirectory::StartScript(const std::string& strPath, bool retrievingDi
std::string basePath(url.Get());
// reset our wait event, and grab a new handle
m_fetchComplete.Reset();
- int handle = CScriptInvocationManager::GetInstance().GetReusablePluginHandle(m_addon->LibPath());
-
- if (handle < 0)
- handle = getNewHandle(this);
- else
- reuseHandle(handle, this);
+ int handle = getNewHandle(this);
// clear out our status variables
m_fileResult->Reset();
@@ -161,11 +150,7 @@ bool CPluginDirectory::StartScript(const std::string& strPath, bool retrievingDi
CLog::Log(LOGDEBUG, "%s - calling plugin %s('%s','%s','%s','%s')", __FUNCTION__, m_addon->Name().c_str(), argv[0].c_str(), argv[1].c_str(), argv[2].c_str(), argv[3].c_str());
bool success = false;
std::string file = m_addon->LibPath();
- bool reuseLanguageInvoker = false;
- if (m_addon->ExtraInfo().find("reuselanguageinvoker") != m_addon->ExtraInfo().end())
- reuseLanguageInvoker = m_addon->ExtraInfo().at("reuselanguageinvoker") == "true";
-
- int id = CScriptInvocationManager::GetInstance().ExecuteAsync(file, m_addon, argv, reuseLanguageInvoker, handle);
+ int id = CScriptInvocationManager::GetInstance().ExecuteAsync(file, m_addon, argv);
if (id >= 0)
{ // wait for our script to finish
std::string scriptName = m_addon->Name();
diff --git a/xbmc/filesystem/PluginDirectory.h b/xbmc/filesystem/PluginDirectory.h
index d480b2a5206e5..767414f5bb31b 100644
--- a/xbmc/filesystem/PluginDirectory.h
+++ b/xbmc/filesystem/PluginDirectory.h
@@ -75,8 +75,6 @@ class CPluginDirectory : public IDirectory
static std::map globalHandles;
static int getNewHandle(CPluginDirectory *cp);
- static void reuseHandle(int handle, CPluginDirectory *cp);
-
static void removeHandle(int handle);
static CPluginDirectory *dirFromHandle(int handle);
static CCriticalSection m_handleLock;
diff --git a/xbmc/interfaces/generic/ILanguageInvocationHandler.h b/xbmc/interfaces/generic/ILanguageInvocationHandler.h
index e3912355caef7..3057132cfbdcc 100644
--- a/xbmc/interfaces/generic/ILanguageInvocationHandler.h
+++ b/xbmc/interfaces/generic/ILanguageInvocationHandler.h
@@ -24,7 +24,7 @@ class ILanguageInvocationHandler
virtual bool OnScriptInitialized(ILanguageInvoker *invoker) { return true; }
virtual void OnScriptStarted(ILanguageInvoker *invoker) { }
virtual void OnScriptAbortRequested(ILanguageInvoker *invoker) { }
- virtual void OnExecutionEnded(ILanguageInvoker *invoker) { }
+ virtual void OnScriptEnded(ILanguageInvoker *invoker) { }
virtual void OnScriptFinalized(ILanguageInvoker *invoker) { }
virtual ILanguageInvoker* CreateInvoker() = 0;
diff --git a/xbmc/interfaces/generic/ILanguageInvoker.cpp b/xbmc/interfaces/generic/ILanguageInvoker.cpp
index 4e11cb21a134a..d2a62bf3510c4 100644
--- a/xbmc/interfaces/generic/ILanguageInvoker.cpp
+++ b/xbmc/interfaces/generic/ILanguageInvoker.cpp
@@ -35,7 +35,7 @@ bool ILanguageInvoker::Stop(bool abort /* = false */)
bool ILanguageInvoker::IsActive() const
{
- return GetState() > InvokerStateUninitialized && GetState() < InvokerStateScriptDone;
+ return GetState() > InvokerStateUninitialized && GetState() < InvokerStateDone;
}
bool ILanguageInvoker::IsRunning() const
@@ -71,13 +71,13 @@ void ILanguageInvoker::onAbortRequested()
void ILanguageInvoker::onExecutionFailed()
{
if (m_invocationHandler)
- m_invocationHandler->OnExecutionEnded(this);
+ m_invocationHandler->OnScriptEnded(this);
}
void ILanguageInvoker::onExecutionDone()
{
if (m_invocationHandler)
- m_invocationHandler->OnExecutionEnded(this);
+ m_invocationHandler->OnScriptEnded(this);
}
void ILanguageInvoker::onExecutionFinalized()
diff --git a/xbmc/interfaces/generic/ILanguageInvoker.h b/xbmc/interfaces/generic/ILanguageInvoker.h
index df84b1b9083f0..eeb53280dae31 100644
--- a/xbmc/interfaces/generic/ILanguageInvoker.h
+++ b/xbmc/interfaces/generic/ILanguageInvoker.h
@@ -22,8 +22,7 @@ typedef enum {
InvokerStateInitialized,
InvokerStateRunning,
InvokerStateStopping,
- InvokerStateScriptDone,
- InvokerStateExecutionDone,
+ InvokerStateDone,
InvokerStateFailed
} InvokerState;
@@ -44,7 +43,6 @@ class ILanguageInvoker
InvokerState GetState() const { return m_state; }
bool IsActive() const;
bool IsRunning() const;
- void Reset() { m_state = InvokerStateUninitialized; };
protected:
friend class CLanguageInvokerThread;
diff --git a/xbmc/interfaces/generic/LanguageInvokerThread.cpp b/xbmc/interfaces/generic/LanguageInvokerThread.cpp
index c1000e28c65d1..dc9893dfe2bad 100644
--- a/xbmc/interfaces/generic/LanguageInvokerThread.cpp
+++ b/xbmc/interfaces/generic/LanguageInvokerThread.cpp
@@ -9,12 +9,11 @@
#include "LanguageInvokerThread.h"
#include "ScriptInvocationManager.h"
-CLanguageInvokerThread::CLanguageInvokerThread(LanguageInvokerPtr invoker, CScriptInvocationManager *invocationManager, bool reuseable)
+CLanguageInvokerThread::CLanguageInvokerThread(LanguageInvokerPtr invoker, CScriptInvocationManager *invocationManager)
: ILanguageInvoker(NULL),
CThread("LanguageInvoker"),
m_invoker(invoker),
- m_invocationManager(invocationManager),
- m_reusable(reuseable)
+ m_invocationManager(invocationManager)
{ }
CLanguageInvokerThread::~CLanguageInvokerThread()
@@ -22,7 +21,7 @@ CLanguageInvokerThread::~CLanguageInvokerThread()
Stop(true);
}
-InvokerState CLanguageInvokerThread::GetState() const
+InvokerState CLanguageInvokerThread::GetState()
{
if (m_invoker == NULL)
return InvokerStateFailed;
@@ -30,12 +29,6 @@ InvokerState CLanguageInvokerThread::GetState() const
return m_invoker->GetState();
}
-void CLanguageInvokerThread::Release()
-{
- m_bStop = true;
- m_condition.notify_one();
-}
-
bool CLanguageInvokerThread::execute(const std::string &script, const std::vector &arguments)
{
if (m_invoker == NULL || script.empty())
@@ -44,17 +37,7 @@ bool CLanguageInvokerThread::execute(const std::string &script, const std::vecto
m_script = script;
m_args = arguments;
- if (CThread::IsRunning())
- {
- std::unique_lock lck(m_mutex);
- m_restart = true;
- m_condition.notify_one();
- }
- else
- Create();
-
- //Todo wait until running
-
+ Create();
return true;
}
@@ -66,16 +49,14 @@ bool CLanguageInvokerThread::stop(bool wait)
if (!CThread::IsRunning())
return false;
- Release();
-
bool result = true;
- if (m_invoker->GetState() < InvokerStateExecutionDone)
+ if (m_invoker->GetState() < InvokerStateDone)
{
// stop the language-specific invoker
result = m_invoker->Stop(wait);
+ // stop the thread
+ CThread::StopThread(wait);
}
- // stop the thread
- CThread::StopThread(wait);
return result;
}
@@ -95,17 +76,7 @@ void CLanguageInvokerThread::Process()
if (m_invoker == NULL)
return;
- std::unique_lock lckdl(m_mutex);
- do {
- m_restart = false;
- m_invoker->Execute(m_script, m_args);
-
- if (m_invoker->GetState() != InvokerStateScriptDone)
- m_reusable = false;
-
- m_condition.wait(lckdl, [this] {return m_bStop || m_restart || !m_reusable; });
-
- } while (m_reusable && !m_bStop);
+ m_invoker->Execute(m_script, m_args);
}
void CLanguageInvokerThread::OnExit()
@@ -114,7 +85,7 @@ void CLanguageInvokerThread::OnExit()
return;
m_invoker->onExecutionDone();
- m_invocationManager->OnExecutionDone(GetId());
+ m_invocationManager->OnScriptEnded(GetId());
}
void CLanguageInvokerThread::OnException()
@@ -123,5 +94,5 @@ void CLanguageInvokerThread::OnException()
return;
m_invoker->onExecutionFailed();
- m_invocationManager->OnExecutionDone(GetId());
+ m_invocationManager->OnScriptEnded(GetId());
}
\ No newline at end of file
diff --git a/xbmc/interfaces/generic/LanguageInvokerThread.h b/xbmc/interfaces/generic/LanguageInvokerThread.h
index 72ef1a8cdf88a..e7f0d9eb48225 100644
--- a/xbmc/interfaces/generic/LanguageInvokerThread.h
+++ b/xbmc/interfaces/generic/LanguageInvokerThread.h
@@ -19,15 +19,10 @@ class CScriptInvocationManager;
class CLanguageInvokerThread : public ILanguageInvoker, protected CThread
{
public:
- CLanguageInvokerThread(LanguageInvokerPtr invoker, CScriptInvocationManager *invocationManager, bool reuseable);
+ CLanguageInvokerThread(LanguageInvokerPtr invoker, CScriptInvocationManager *invocationManager);
~CLanguageInvokerThread() override;
- virtual InvokerState GetState() const;
-
- const std::string &GetScript() const { return m_script; };
- LanguageInvokerPtr GetInvoker() const { return m_invoker; };
- bool Reuseable(const std::string &script) const { return !m_bStop && m_reusable && GetState() == InvokerStateScriptDone && m_script == script; };
- virtual void Release();
+ virtual InvokerState GetState();
protected:
bool execute(const std::string &script, const std::vector &arguments) override;
@@ -43,10 +38,4 @@ class CLanguageInvokerThread : public ILanguageInvoker, protected CThread
CScriptInvocationManager *m_invocationManager;
std::string m_script;
std::vector m_args;
-
- std::mutex m_mutex;
- std::condition_variable m_condition;
- bool m_restart = false;
- bool m_reusable = false;
};
-
diff --git a/xbmc/interfaces/generic/ScriptInvocationManager.cpp b/xbmc/interfaces/generic/ScriptInvocationManager.cpp
index c30add2b25817..391a746cc1d7d 100644
--- a/xbmc/interfaces/generic/ScriptInvocationManager.cpp
+++ b/xbmc/interfaces/generic/ScriptInvocationManager.cpp
@@ -77,9 +77,6 @@ void CScriptInvocationManager::Uninitialize()
// execute Process() once more to handle the remaining scripts
Process();
- // it is safe to relese early, thread must be in m_scripts too
- m_lastInvokerThread = nullptr;
-
// make sure all scripts are done
std::vector tempList;
for (LanguageInvokerThreadMap::iterator script = m_scripts.begin(); script != m_scripts.end(); ++script)
@@ -99,11 +96,9 @@ void CScriptInvocationManager::Uninitialize()
if (!it->done)
it->thread->Stop(true);
}
-
- lock.Enter();
-
tempList.clear();
+ lock.Enter();
// uninitialize all invocation handlers and then remove them
for (LanguageInvocationHandlerMap::iterator it = m_invocationHandlers.begin(); it != m_invocationHandlers.end(); ++it)
it->second->Uninitialize();
@@ -180,39 +175,12 @@ bool CScriptInvocationManager::HasLanguageInvoker(const std::string &script) con
return it != m_invocationHandlers.end() && it->second != NULL;
}
-int CScriptInvocationManager::GetReusablePluginHandle(const std::string &script)
+LanguageInvokerPtr CScriptInvocationManager::GetLanguageInvoker(const std::string &script) const
{
- CSingleLock lock(m_critSection);
-
- if (m_lastInvokerThread)
- {
- if (m_lastInvokerThread->Reuseable(script))
- return m_lastPluginHandle;
- m_lastInvokerThread->Release();
- m_lastInvokerThread = nullptr;
- }
- return -1;
-}
-
-LanguageInvokerPtr CScriptInvocationManager::GetLanguageInvoker(const std::string &script)
-{
- CSingleLock lock(m_critSection);
-
- if (m_lastInvokerThread)
- {
- if (m_lastInvokerThread->Reuseable(script))
- {
- CLog::Log(LOGDEBUG, "%s - Reusing LanguageInvokerThread %d for script %s", __FUNCTION__, m_lastInvokerThread->GetId(), script.c_str());
- m_lastInvokerThread->GetInvoker()->Reset();
- return m_lastInvokerThread->GetInvoker();
- }
- m_lastInvokerThread->Release();
- m_lastInvokerThread = nullptr;
- }
-
std::string extension = URIUtils::GetExtension(script);
StringUtils::ToLower(extension);
+ CSingleLock lock(m_critSection);
std::map::const_iterator it = m_invocationHandlers.find(extension);
if (it != m_invocationHandlers.end() && it->second != NULL)
return LanguageInvokerPtr(it->second->CreateInvoker());
@@ -220,11 +188,7 @@ LanguageInvokerPtr CScriptInvocationManager::GetLanguageInvoker(const std::strin
return LanguageInvokerPtr();
}
-int CScriptInvocationManager::ExecuteAsync(const std::string &script,
- const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */,
- const std::vector &arguments /* = std::vector() */,
- bool reuseable /* = false */,
- int pluginHandle /* = -1 */)
+int CScriptInvocationManager::ExecuteAsync(const std::string &script, const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */, const std::vector &arguments /* = std::vector() */)
{
if (script.empty())
return -1;
@@ -236,15 +200,10 @@ int CScriptInvocationManager::ExecuteAsync(const std::string &script,
}
LanguageInvokerPtr invoker = GetLanguageInvoker(script);
- return ExecuteAsync(script, invoker, addon, arguments, reuseable, pluginHandle);
+ return ExecuteAsync(script, invoker, addon, arguments);
}
-int CScriptInvocationManager::ExecuteAsync(const std::string &script,
- LanguageInvokerPtr languageInvoker,
- const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */,
- const std::vector &arguments /* = std::vector() */,
- bool reuseable /* = false */,
- int pluginHandle /* = -1 */)
+int CScriptInvocationManager::ExecuteAsync(const std::string &script, LanguageInvokerPtr languageInvoker, const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */, const std::vector &arguments /* = std::vector() */)
{
if (script.empty() || languageInvoker == NULL)
return -1;
@@ -255,47 +214,26 @@ int CScriptInvocationManager::ExecuteAsync(const std::string &script,
return -1;
}
- CSingleLock lock(m_critSection);
-
- if (m_lastInvokerThread && m_lastInvokerThread->GetInvoker() == languageInvoker)
- {
- if (addon != NULL)
- m_lastInvokerThread->SetAddon(addon);
-
- // After we leave the lock, m_lastInvokerThread can be released -> copy!
- CLanguageInvokerThreadPtr invokerThread = m_lastInvokerThread;
- lock.Leave();
- invokerThread->Execute(script, arguments);
-
- return invokerThread->GetId();
- }
-
- m_lastInvokerThread = CLanguageInvokerThreadPtr(new CLanguageInvokerThread(languageInvoker, this, reuseable));
- if (m_lastInvokerThread == NULL)
+ CLanguageInvokerThreadPtr invokerThread = CLanguageInvokerThreadPtr(new CLanguageInvokerThread(languageInvoker, this));
+ if (invokerThread == NULL)
return -1;
if (addon != NULL)
- m_lastInvokerThread->SetAddon(addon);
+ invokerThread->SetAddon(addon);
- m_lastInvokerThread->SetId(m_nextId++);
- m_lastPluginHandle = pluginHandle;
+ CSingleLock lock(m_critSection);
+ invokerThread->SetId(m_nextId++);
- LanguageInvokerThread thread = { m_lastInvokerThread, script, false };
- m_scripts.insert(std::make_pair(m_lastInvokerThread->GetId(), thread));
- m_scriptPaths.insert(std::make_pair(script, m_lastInvokerThread->GetId()));
- // After we leave the lock, m_lastInvokerThread can be released -> copy!
- CLanguageInvokerThreadPtr invokerThread = m_lastInvokerThread;
+ LanguageInvokerThread thread = { invokerThread, script, false };
+ m_scripts.insert(std::make_pair(invokerThread->GetId(), thread));
+ m_scriptPaths.insert(std::make_pair(script, invokerThread->GetId()));
lock.Leave();
invokerThread->Execute(script, arguments);
return invokerThread->GetId();
}
-int CScriptInvocationManager::ExecuteSync(const std::string &script,
- const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */,
- const std::vector &arguments /* = std::vector() */,
- uint32_t timeoutMs /* = 0 */,
- bool waitShutdown /* = false */)
+int CScriptInvocationManager::ExecuteSync(const std::string &script, const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */, const std::vector &arguments /* = std::vector() */, uint32_t timeoutMs /* = 0 */, bool waitShutdown /* = false */)
{
if (script.empty())
return -1;
@@ -310,12 +248,7 @@ int CScriptInvocationManager::ExecuteSync(const std::string &script,
return ExecuteSync(script, invoker, addon, arguments, timeoutMs, waitShutdown);
}
-int CScriptInvocationManager::ExecuteSync(const std::string &script,
- LanguageInvokerPtr languageInvoker,
- const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */,
- const std::vector &arguments /* = std::vector() */,
- uint32_t timeoutMs /* = 0 */,
- bool waitShutdown /* = false */)
+int CScriptInvocationManager::ExecuteSync(const std::string &script, LanguageInvokerPtr languageInvoker, const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */, const std::vector &arguments /* = std::vector() */, uint32_t timeoutMs /* = 0 */, bool waitShutdown /* = false */)
{
int scriptId = ExecuteAsync(script, languageInvoker, addon, arguments);
if (scriptId < 0)
@@ -389,7 +322,7 @@ bool CScriptInvocationManager::IsRunning(const std::string& scriptPath) const
return IsRunning(it->second);
}
-void CScriptInvocationManager::OnExecutionDone(int scriptId)
+void CScriptInvocationManager::OnScriptEnded(int scriptId)
{
if (scriptId < 0)
return;
diff --git a/xbmc/interfaces/generic/ScriptInvocationManager.h b/xbmc/interfaces/generic/ScriptInvocationManager.h
index 63205d5f12cb7..cecb26061df06 100644
--- a/xbmc/interfaces/generic/ScriptInvocationManager.h
+++ b/xbmc/interfaces/generic/ScriptInvocationManager.h
@@ -32,12 +32,7 @@ class CScriptInvocationManager
void RegisterLanguageInvocationHandler(ILanguageInvocationHandler *invocationHandler, const std::set &extensions);
void UnregisterLanguageInvocationHandler(ILanguageInvocationHandler *invocationHandler);
bool HasLanguageInvoker(const std::string &script) const;
- LanguageInvokerPtr GetLanguageInvoker(const std::string &script);
-
- /*!
- * \brief Returns addon_handle if last reusable invoker is ready to use.
- */
- int GetReusablePluginHandle(const std::string &script);
+ LanguageInvokerPtr GetLanguageInvoker(const std::string &script) const;
/*!
* \brief Executes the given script asynchronously in a separate thread.
@@ -47,11 +42,7 @@ class CScriptInvocationManager
* \param arguments (Optional) List of arguments passed to the script
* \return -1 if an error occurred, otherwise the ID of the script
*/
- int ExecuteAsync(const std::string &script,
- const ADDON::AddonPtr &addon = ADDON::AddonPtr(),
- const std::vector &arguments = std::vector(),
- bool reuseable = false,
- int pluginHandle = -1);
+ int ExecuteAsync(const std::string &script, const ADDON::AddonPtr &addon = ADDON::AddonPtr(), const std::vector &arguments = std::vector());
/*!
* \brief Executes the given script asynchronously in a separate thread.
*
@@ -61,12 +52,7 @@ class CScriptInvocationManager
* \param arguments (Optional) List of arguments passed to the script
* \return -1 if an error occurred, otherwise the ID of the script
*/
- int ExecuteAsync(const std::string &script,
- LanguageInvokerPtr languageInvoker,
- const ADDON::AddonPtr &addon = ADDON::AddonPtr(),
- const std::vector &arguments = std::vector(),
- bool reuseable = false,
- int pluginHandle = -1);
+ int ExecuteAsync(const std::string &script, LanguageInvokerPtr languageInvoker, const ADDON::AddonPtr &addon = ADDON::AddonPtr(), const std::vector &arguments = std::vector());
/*!
* \brief Executes the given script synchronously.
@@ -84,11 +70,7 @@ class CScriptInvocationManager
* \param waitShutdown (Optional) Whether to wait when having to forcefully stop the script's execution or not.
* \return -1 if an error occurred, 0 if the script terminated or ETIMEDOUT if the given timeout expired
*/
- int ExecuteSync(const std::string &script,
- const ADDON::AddonPtr &addon = ADDON::AddonPtr(),
- const std::vector &arguments = std::vector(),
- uint32_t timeoutMs = 0,
- bool waitShutdown = false);
+ int ExecuteSync(const std::string &script, const ADDON::AddonPtr &addon = ADDON::AddonPtr(), const std::vector &arguments = std::vector(), uint32_t timeoutMs = 0, bool waitShutdown = false);
/*!
* \brief Executes the given script synchronously.
*
@@ -106,12 +88,7 @@ class CScriptInvocationManager
* \param waitShutdown (Optional) Whether to wait when having to forcefully stop the script's execution or not.
* \return -1 if an error occurred, 0 if the script terminated or ETIMEDOUT if the given timeout expired
*/
- int ExecuteSync(const std::string &script,
- LanguageInvokerPtr languageInvoker,
- const ADDON::AddonPtr &addon = ADDON::AddonPtr(),
- const std::vector &arguments = std::vector(),
- uint32_t timeoutMs = 0,
- bool waitShutdown = false);
+ int ExecuteSync(const std::string &script, LanguageInvokerPtr languageInvoker, const ADDON::AddonPtr &addon = ADDON::AddonPtr(), const std::vector &arguments = std::vector(), uint32_t timeoutMs = 0, bool waitShutdown = false);
bool Stop(int scriptId, bool wait = false);
bool Stop(const std::string &scriptPath, bool wait = false);
@@ -121,7 +98,7 @@ class CScriptInvocationManager
protected:
friend class CLanguageInvokerThread;
- void OnExecutionDone(int scriptId);
+ void OnScriptEnded(int scriptId);
private:
CScriptInvocationManager() = default;
@@ -141,9 +118,6 @@ class CScriptInvocationManager
LanguageInvocationHandlerMap m_invocationHandlers;
LanguageInvokerThreadMap m_scripts;
- CLanguageInvokerThreadPtr m_lastInvokerThread;
- int m_lastPluginHandle;
-
std::map m_scriptPaths;
int m_nextId = 0;
mutable CCriticalSection m_critSection;
diff --git a/xbmc/interfaces/python/AddonPythonInvoker.cpp b/xbmc/interfaces/python/AddonPythonInvoker.cpp
index dbc5918a18dc6..b906f8438ca51 100644
--- a/xbmc/interfaces/python/AddonPythonInvoker.cpp
+++ b/xbmc/interfaces/python/AddonPythonInvoker.cpp
@@ -36,14 +36,14 @@
#define RUNSCRIPT_SETUPTOOLS_HACK \
"" \
- "import imp,sys\n" \
+ "import types,sys\n" \
"pkg_resources_code = \\\n" \
"\"\"\"\n" \
"def resource_filename(__name__,__path__):\n" \
" return __path__\n" \
"\"\"\"\n" \
- "pkg_resources = imp.new_module('pkg_resources')\n" \
- "exec pkg_resources_code in pkg_resources.__dict__\n" \
+ "pkg_resources = types.ModuleType('pkg_resources')\n" \
+ "exec(pkg_resources_code, pkg_resources.__dict__)\n" \
"sys.modules['pkg_resources'] = pkg_resources\n" \
""
@@ -64,12 +64,12 @@
#endif
namespace PythonBindings {
- void initModule_xbmcdrm(void);
- void initModule_xbmcgui(void);
- void initModule_xbmc(void);
- void initModule_xbmcplugin(void);
- void initModule_xbmcaddon(void);
- void initModule_xbmcvfs(void);
+ PyObject *PyInit_Module_xbmcdrm(void);
+ PyObject *PyInit_Module_xbmcgui(void);
+ PyObject *PyInit_Module_xbmc(void);
+ PyObject *PyInit_Module_xbmcplugin(void);
+ PyObject *PyInit_Module_xbmcaddon(void);
+ PyObject *PyInit_Module_xbmcvfs(void);
}
using namespace PythonBindings;
@@ -82,17 +82,24 @@ typedef struct
static PythonModule PythonModules[] =
{
- { "xbmcdrm", initModule_xbmcdrm },
- { "xbmcgui", initModule_xbmcgui },
- { "xbmc", initModule_xbmc },
- { "xbmcplugin", initModule_xbmcplugin },
- { "xbmcaddon", initModule_xbmcaddon },
- { "xbmcvfs", initModule_xbmcvfs }
+ { "xbmcdrm", PyInit_Module_xbmcdrm },
+ { "xbmcgui", PyInit_Module_xbmcgui },
+ { "xbmc", PyInit_Module_xbmc },
+ { "xbmcplugin", PyInit_Module_xbmcplugin },
+ { "xbmcaddon", PyInit_Module_xbmcaddon },
+ { "xbmcvfs", PyInit_Module_xbmcvfs }
};
CAddonPythonInvoker::CAddonPythonInvoker(ILanguageInvocationHandler *invocationHandler)
: CPythonInvoker(invocationHandler)
-{ }
+{
+ PyImport_AppendInittab("xbmcdrm", PyInit_Module_xbmcdrm);
+ PyImport_AppendInittab("xbmcgui", PyInit_Module_xbmcgui);
+ PyImport_AppendInittab("xbmc", PyInit_Module_xbmc);
+ PyImport_AppendInittab("xbmcplugin", PyInit_Module_xbmcplugin);
+ PyImport_AppendInittab("xbmcaddon", PyInit_Module_xbmcaddon);
+ PyImport_AppendInittab("xbmcvfs", PyInit_Module_xbmcvfs);
+}
CAddonPythonInvoker::~CAddonPythonInvoker() = default;
diff --git a/xbmc/interfaces/python/ContextItemAddonInvoker.cpp b/xbmc/interfaces/python/ContextItemAddonInvoker.cpp
index b40ddd0cdaf04..6165ec710ef1c 100644
--- a/xbmc/interfaces/python/ContextItemAddonInvoker.cpp
+++ b/xbmc/interfaces/python/ContextItemAddonInvoker.cpp
@@ -31,8 +31,7 @@ void CContextItemAddonInvoker::onPythonModuleInitialization(void* moduleDict)
{
XBMCAddon::xbmcgui::ListItem* arg = new XBMCAddon::xbmcgui::ListItem(m_item);
PyObject* pyItem = PythonBindings::makePythonInstance(arg, true);
- //! @bug libpython < 3.0 isn't const correct
- if (pyItem == Py_None || PySys_SetObject(const_cast("listitem"), pyItem) == -1)
+ if (pyItem == Py_None || PySys_SetObject("listitem", pyItem) == -1)
{
CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): Failed to set sys parameter", GetId(), m_sourceFile.c_str());
//FIXME: we should really abort execution
diff --git a/xbmc/interfaces/python/LanguageHook.cpp b/xbmc/interfaces/python/LanguageHook.cpp
index 9d2fea240d08b..c54d60ab097be 100644
--- a/xbmc/interfaces/python/LanguageHook.cpp
+++ b/xbmc/interfaces/python/LanguageHook.cpp
@@ -125,7 +125,7 @@ namespace XBMCAddon
// from the global dictionary
PyObject* pyid = PyDict_GetItemString(global_dict, "__xbmcaddonid__");
if (pyid)
- return PyString_AsString(pyid);
+ return PyUnicode_AsUTF8(pyid);
return "";
}
@@ -140,7 +140,7 @@ namespace XBMCAddon
// from the global dictionary
PyObject* pyversion = PyDict_GetItemString(global_dict, "__xbmcapiversion__");
if (pyversion)
- return PyString_AsString(pyversion);
+ return PyUnicode_AsUTF8(pyversion);
return "";
}
diff --git a/xbmc/interfaces/python/PythonInvoker.cpp b/xbmc/interfaces/python/PythonInvoker.cpp
index f4ec1e3270d99..4f14bd4d8d4b1 100644
--- a/xbmc/interfaces/python/PythonInvoker.cpp
+++ b/xbmc/interfaces/python/PythonInvoker.cpp
@@ -23,14 +23,14 @@
#include "windowing/GraphicContext.h"
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
+#include "interfaces/legacy/Addon.h"
+#include "interfaces/python/LanguageHook.h"
#include "interfaces/python/PyContext.h"
#include "interfaces/python/pythreadstate.h"
#include "interfaces/python/swig.h"
#include "interfaces/python/XBPython.h"
#include "threads/SingleLock.h"
-#if defined(TARGET_WINDOWS)
#include "utils/CharsetConverter.h"
-#endif // defined(TARGET_WINDOWS)
#include "utils/log.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
@@ -56,12 +56,6 @@ extern "C" FILE *fopen_utf8(const char *_Filename, const char *_Mode);
using namespace XFILE;
using namespace KODI::MESSAGING;
-extern "C"
-{
- int xbp_chdir(const char *dirname);
- char* dll_getenv(const char* szKey);
-}
-
#define PythonModulesSize sizeof(PythonModules) / sizeof(PythonModule)
CCriticalSection CPythonInvoker::s_critical;
@@ -84,23 +78,23 @@ static const std::string getListOfAddonClassesAsString(XBMCAddon::AddonClass::Re
return message;
}
-static std::vector> storeArgumentsCCompatible(std::vector const & input)
+static std::vector> storeArgumentsCCompatible(std::vector const & input)
{
- std::vector> output;
+ std::vector> output;
std::transform(input.begin(), input.end(), std::back_inserter(output),
- [](std::string const & i) { return std::vector(i.c_str(), i.c_str() + i.length() + 1); });
+ [](std::wstring const & i) { return std::vector(i.c_str(), i.c_str() + i.length() + 1); });
if (output.empty())
- output.push_back(std::vector(1u, '\0'));
+ output.push_back(std::vector(1u, '\0'));
return output;
}
-static std::vector getCPointersToArguments(std::vector> & input)
+static std::vector getCPointersToArguments(std::vector> & input)
{
- std::vector output;
+ std::vector output;
std::transform(input.begin(), input.end(), std::back_inserter(output),
- [](std::vector & i) { return &i[0]; });
+ [](std::vector & i) { return &i[0]; });
return output;
}
@@ -116,7 +110,7 @@ CPythonInvoker::~CPythonInvoker()
if (GetId() < 0)
return;
- if (GetState() < InvokerStateExecutionDone)
+ if (GetState() < InvokerStateDone)
CLog::Log(LOGDEBUG, "CPythonInvoker(%d): waiting for python thread \"%s\" to stop",
GetId(), (!m_sourceFile.empty() ? m_sourceFile.c_str() : "unknown script"));
Stop(true);
@@ -143,133 +137,135 @@ bool CPythonInvoker::Execute(const std::string &script, const std::vector &arguments)
+{
+ std::vector w_arguments;
+ for (auto argument : arguments)
+ {
+ std::wstring w_argument;
+ g_charsetConverter.utf8ToW(argument, w_argument);
+ w_arguments.push_back(w_argument);
+ }
+ return execute(script, w_arguments);
+}
+
+bool CPythonInvoker::execute(const std::string &script, const std::vector &arguments)
{
// copy the code/script into a local string buffer
m_sourceFile = script;
- m_pythonPath.clear();
// copy the arguments into a local buffer
unsigned int argc = arguments.size();
- std::vector> argvStorage = storeArgumentsCCompatible(arguments);
- std::vector argv = getCPointersToArguments(argvStorage);
+ std::vector> argvStorage = storeArgumentsCCompatible(arguments);
+ std::vector argv = getCPointersToArguments(argvStorage);
CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): start processing", GetId(), m_sourceFile.c_str());
- std::string realFilename(CSpecialProtocol::TranslatePath(m_sourceFile));
- std::string scriptDir = URIUtils::GetDirectory(realFilename);
- URIUtils::RemoveSlashAtEnd(scriptDir);
-
// get the global lock
- PyEval_AcquireLock();
- if (!m_threadState)
+ extern PyThreadState* savestate;
+ PyEval_RestoreThread(savestate);
+ PyThreadState* state = Py_NewInterpreter();
+ if (state == NULL)
{
- m_threadState = Py_NewInterpreter();
- if (m_threadState == NULL)
- {
- PyEval_ReleaseLock();
- CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): FAILED to get thread m_threadState!", GetId(), m_sourceFile.c_str());
- return false;
- }
- // swap in my thread m_threadState
- PyThreadState_Swap(m_threadState);
+ PyEval_ReleaseLock();
+ CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): FAILED to get thread state!", GetId(), m_sourceFile.c_str());
+ return false;
+ }
+ // swap in my thread state
+ PyThreadState_Swap(state);
- m_languageHook = new XBMCAddon::Python::PythonLanguageHook(m_threadState->interp);
- m_languageHook->RegisterMe();
+ XBMCAddon::AddonClass::Ref languageHook(new XBMCAddon::Python::PythonLanguageHook(state->interp));
+ languageHook->RegisterMe();
- onInitialization();
- setState(InvokerStateInitialized);
+ onInitialization();
+ setState(InvokerStateInitialized);
- if (realFilename == m_sourceFile)
- CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): the source file to load is \"%s\"", GetId(), m_sourceFile.c_str(), m_sourceFile.c_str());
- else
- CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): the source file to load is \"%s\" (\"%s\")", GetId(), m_sourceFile.c_str(), m_sourceFile.c_str(), realFilename.c_str());
+ std::string realFilename(CSpecialProtocol::TranslatePath(m_sourceFile));
+ if (realFilename == m_sourceFile)
+ CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): the source file to load is \"%s\"", GetId(), m_sourceFile.c_str(), m_sourceFile.c_str());
+ else
+ CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): the source file to load is \"%s\" (\"%s\")", GetId(), m_sourceFile.c_str(), m_sourceFile.c_str(), realFilename.c_str());
- // get path from script file name and add python path's
- // this is used for python so it will search modules from script path first
- addPath(scriptDir);
+ // get path from script file name and add python path's
+ // this is used for python so it will search modules from script path first
+ std::string scriptDir = URIUtils::GetDirectory(realFilename);
+ URIUtils::RemoveSlashAtEnd(scriptDir);
+ addPath(scriptDir);
- // add all addon module dependencies to path
- if (m_addon)
- {
- std::set paths;
- getAddonModuleDeps(m_addon, paths);
- for (std::set::const_iterator it = paths.begin(); it != paths.end(); ++it)
- addPath(*it);
- }
- else
- { // for backwards compatibility.
- // we don't have any addon so just add all addon modules installed
- CLog::Log(LOGWARNING, "CPythonInvoker(%d): Script invoked without an addon. Adding all addon "
+ // add all addon module dependencies to path
+ if (m_addon)
+ {
+ std::set paths;
+ getAddonModuleDeps(m_addon, paths);
+ for (std::set::const_iterator it = paths.begin(); it != paths.end(); ++it)
+ addPath(*it);
+ }
+ else
+ { // for backwards compatibility.
+ // we don't have any addon so just add all addon modules installed
+ CLog::Log(LOGWARNING, "CPythonInvoker(%d): Script invoked without an addon. Adding all addon "
"modules installed to python path as fallback. This behaviour will be removed in future "
"version.", GetId());
- ADDON::VECADDONS addons;
- CServiceBroker::GetAddonMgr().GetAddons(addons, ADDON::ADDON_SCRIPT_MODULE);
- for (unsigned int i = 0; i < addons.size(); ++i)
- addPath(CSpecialProtocol::TranslatePath(addons[i]->LibPath()));
- }
+ ADDON::VECADDONS addons;
+ CServiceBroker::GetAddonMgr().GetAddons(addons, ADDON::ADDON_SCRIPT_MODULE);
+ for (unsigned int i = 0; i < addons.size(); ++i)
+ addPath(CSpecialProtocol::TranslatePath(addons[i]->LibPath()));
+ }
- // we want to use sys.path so it includes site-packages
- // if this fails, default to using Py_GetPath
- PyObject *sysMod(PyImport_ImportModule("sys")); // must call Py_DECREF when finished
- PyObject *sysModDict(PyModule_GetDict(sysMod)); // borrowed ref, no need to delete
- PyObject *pathObj(PyDict_GetItemString(sysModDict, "path")); // borrowed ref, no need to delete
+ // we want to use sys.path so it includes site-packages
+ // if this fails, default to using Py_GetPath
+ PyObject *sysMod(PyImport_ImportModule("sys")); // must call Py_DECREF when finished
+ PyObject *sysModDict(PyModule_GetDict(sysMod)); // borrowed ref, no need to delete
+ PyObject *pathObj(PyDict_GetItemString(sysModDict, "path")); // borrowed ref, no need to delete
- if (pathObj != NULL && PyList_Check(pathObj))
+ if (pathObj != NULL && PyList_Check(pathObj))
+ {
+ for (int i = 0; i < PyList_Size(pathObj); i++)
{
- for (int i = 0; i < PyList_Size(pathObj); i++)
- {
- PyObject *e = PyList_GetItem(pathObj, i); // borrowed ref, no need to delete
- if (e != NULL && PyString_Check(e))
- addNativePath(PyString_AsString(e)); // returns internal data, don't delete or modify
-#ifdef TARGET_WINDOWS_STORE
- // uwp python operates unicodes
- else if (e != NULL && PyUnicode_Check(e))
- {
- PyObject *utf8 = PyUnicode_AsUTF8String(e);
- addNativePath(PyString_AsString(utf8));
- Py_DECREF(utf8);
- }
-#endif
- }
+ PyObject *e = PyList_GetItem(pathObj, i); // borrowed ref, no need to delete
+ if (e != NULL && PyUnicode_Check(e))
+ addNativePath(PyUnicode_AsUTF8(e)); // returns internal data, don't delete or modify
}
- else
- addNativePath(Py_GetPath());
+ }
+ else
+ {
+ std::string GetPath;
+ g_charsetConverter.wToUTF8(Py_GetPath(), GetPath);
+ addNativePath(GetPath);
+ }
- Py_DECREF(sysMod); // release ref to sysMod
+ Py_DECREF(sysMod); // release ref to sysMod
+
+ // set current directory and python's path.
+ PySys_SetArgv(argc, &argv[0]);
#ifdef TARGET_WINDOWS
- std::string pyPathUtf8;
- g_charsetConverter.systemToUtf8(m_pythonPath, pyPathUtf8, false);
- CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): setting the Python path to %s", GetId(), m_sourceFile.c_str(), pyPathUtf8.c_str());
+ std::string pyPathUtf8;
+ g_charsetConverter.systemToUtf8(m_pythonPath, pyPathUtf8, false);
+ CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): setting the Python path to %s", GetId(), m_sourceFile.c_str(), pyPathUtf8.c_str());
#else // ! TARGET_WINDOWS
- CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): setting the Python path to %s", GetId(), m_sourceFile.c_str(), m_pythonPath.c_str());
+ CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): setting the Python path to %s", GetId(), m_sourceFile.c_str(), m_pythonPath.c_str());
#endif // ! TARGET_WINDOWS
- //! @bug libpython < 3.0 isn't const correct
- PySys_SetPath(const_cast(m_pythonPath.c_str()));
- }
- else
- // swap in my thread m_threadState
- PyThreadState_Swap(m_threadState);
- // set current directory and python's path.
- PySys_SetArgv(argc, &argv[0]);
+ std::wstring pypath;
+ g_charsetConverter.utf8ToW(m_pythonPath, pypath);
+ PySys_SetPath(pypath.c_str());
CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): entering source directory %s", GetId(), m_sourceFile.c_str(), scriptDir.c_str());
PyObject* module = PyImport_AddModule("__main__");
PyObject* moduleDict = PyModule_GetDict(module);
- // when we are done initing we store thread m_threadState so we can be aborted
+ // when we are done initing we store thread state so we can be aborted
PyThreadState_Swap(NULL);
PyEval_ReleaseLock();
// we need to check if we was asked to abort before we had inited
bool stopping = false;
{ CSingleLock lock(m_critical);
+ m_threadState = state;
stopping = m_stop;
}
- PyEval_AcquireLock();
- PyThreadState_Swap(m_threadState);
+ PyEval_AcquireThread(state);
bool failed = false;
std::string exceptionType, exceptionValue, exceptionTraceback;
@@ -289,13 +285,11 @@ bool CPythonInvoker::execute(const std::string &script, const std::vector(nativeFilename.c_str()), const_cast("r"));
- FILE *fp = PyFile_AsFile(file);
+ FILE *fp = _Py_fopen(nativeFilename.c_str(), "r");
if (fp != NULL)
{
- PyObject *f = PyString_FromString(nativeFilename.c_str());
+ PyObject *f = PyUnicode_FromString(nativeFilename.c_str());
PyDict_SetItemString(moduleDict, "__file__", f);
onPythonModuleInitialization(moduleDict);
@@ -303,7 +297,7 @@ bool CPythonInvoker::execute(const std::string &script, const std::vectorinterp->tstate_head, *old = NULL; s;)
+ {
+ if (s == state)
{
- PyThreadState *s = m_threadState->interp->tstate_head;
- for (; s && s == m_threadState;)
- s = s->next;
-
- if (!s)
- break;
+ s = s->next;
+ continue;
+ }
+ if (old != s)
+ {
+ CLog::Log(LOGINFO, "CPythonInvoker(%d, %s): waiting on thread %" PRIu64, GetId(), m_sourceFile.c_str(), (uint64_t)s->thread_id);
+ old = s;
+ }
- if (old != s)
- {
- CLog::Log(LOGINFO, "CPythonInvoker(%d, %s): waiting on thread %" PRIu64, GetId(), m_sourceFile.c_str(), (uint64_t)s->thread_id);
- old = s;
- }
+ CPyThreadState pyState;
+ Sleep(100);
+ pyState.Restore();
- lock.Leave();
- CPyThreadState pyState;
- Sleep(100);
- pyState.Restore();
- lock.Enter();
- }
+ s = state->interp->tstate_head;
}
// pending calls must be cleared out
- XBMCAddon::RetardedAsyncCallbackHandler::clearPendingCalls(m_threadState);
+ XBMCAddon::RetardedAsyncCallbackHandler::clearPendingCalls(state);
PyThreadState_Swap(NULL);
PyEval_ReleaseLock();
+ // set stopped event - this allows ::stop to run and kill remaining threads
+ // this event has to be fired without holding m_critical
+ // also the GIL (PyEval_AcquireLock) must not be held
+ // if not obeyed there is still no deadlock because ::stop waits with timeout (smart one!)
+ m_stoppedEvent.Set();
+
+ { CSingleLock lock(m_critical);
+ m_threadState = NULL;
+ }
+
+ PyEval_AcquireThread(state);
+
+ onDeinitialization();
+
+ // run the gc before finishing
+ //
+ // if the script exited by throwing a SystemExit exception then going back
+ // into the interpreter causes this python bug to get hit:
+ // http://bugs.python.org/issue10582
+ // and that causes major failures. So we are not going to go back in
+ // to run the GC if that's the case.
+ if (!m_stop && languageHook->HasRegisteredAddonClasses() && !systemExitThrown &&
+ PyRun_SimpleString(GC_SCRIPT) == -1)
+ CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): failed to run the gc to clean up after running prior to shutting down the Interpreter", GetId(), m_sourceFile.c_str());
+
+ Py_EndInterpreter(state);
+
+ // If we still have objects left around, produce an error message detailing what's been left behind
+ if (languageHook->HasRegisteredAddonClasses())
+ CLog::Log(LOGWARNING, "CPythonInvoker(%d, %s): the python script \"%s\" has left several "
+ "classes in memory that we couldn't clean up. The classes include: %s",
+ GetId(), m_sourceFile.c_str(), m_sourceFile.c_str(), getListOfAddonClassesAsString(languageHook).c_str());
+
+ // unregister the language hook
+ languageHook->UnregisterMe();
+
+ PyEval_ReleaseLock();
+
setState(stateToSet);
return true;
}
-void CPythonInvoker::executeScript(void *fp, const std::string &script, void *module, void *moduleDict)
+void CPythonInvoker::executeScript(FILE *fp, const std::string &script, PyObject *moduleDict)
{
- if (fp == NULL || script.empty() || module == NULL || moduleDict == NULL)
+ if (fp == NULL || script.empty() || moduleDict == NULL)
return;
int m_Py_file_input = Py_file_input;
- PyRun_FileExFlags(static_cast(fp), script.c_str(), m_Py_file_input, static_cast(moduleDict), static_cast(moduleDict), 1, NULL);
+ PyRun_FileExFlags(fp, script.c_str(), m_Py_file_input, moduleDict, moduleDict, 1, NULL);
+}
+
+FILE* CPythonInvoker::PyFile_AsFileWithMode(PyObject *py_file, const char *mode)
+{
+ PyObject* ret = PyObject_CallMethod(py_file, "flush", "");
+ if (ret == NULL)
+ return NULL;
+ Py_DECREF(ret);
+
+ int fd = PyObject_AsFileDescriptor(py_file);
+ if (fd == -1)
+ return NULL;
+
+ FILE* f = fdopen(fd, mode);
+ if (f == NULL)
+ {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ return f;
}
bool CPythonInvoker::stop(bool abort)
@@ -420,38 +467,28 @@ bool CPythonInvoker::stop(bool abort)
CSingleLock lock(m_critical);
m_stop = true;
- if (!IsRunning() && !m_threadState)
+ if (!IsRunning())
return false;
+ setState(InvokerStateStopping);
+
if (m_threadState != NULL)
{
- if (IsRunning())
- {
- setState(InvokerStateStopping);
-
- lock.Leave();
+ PyEval_AcquireLock();
+ PyThreadState* old = PyThreadState_Swap((PyThreadState*)m_threadState);
- PyEval_AcquireLock();
- PyThreadState* old = PyThreadState_Swap((PyThreadState*)m_threadState);
+ //tell xbmc.Monitor to call onAbortRequested()
+ if (m_addon != NULL)
+ onAbortRequested();
- //tell xbmc.Monitor to call onAbortRequested()
- if (m_addon)
- {
- CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): trigger Monitor abort request", GetId(), m_sourceFile.c_str());
- onAbortRequested();
- }
-
- PyObject *m;
- m = PyImport_AddModule("xbmc");
- if (m == NULL || PyObject_SetAttrString(m, "abortRequested", PyBool_FromLong(1)))
- CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): failed to set abortRequested", GetId(), m_sourceFile.c_str());
+ PyObject *m;
+ m = PyImport_AddModule("xbmc");
+ if (m == NULL || PyObject_SetAttrString(m, "abortRequested", PyBool_FromLong(1)))
+ CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): failed to set abortRequested", GetId(), m_sourceFile.c_str());
- PyThreadState_Swap(old);
- PyEval_ReleaseLock();
- }
- else
- //Release the lock while waiting for threads to finish
- lock.Leave();
+ PyThreadState_Swap(old);
+ old = NULL;
+ PyEval_ReleaseLock();
XbmcThreads::EndTime timeout(PYTHON_SCRIPT_TIMEOUT);
while (!m_stoppedEvent.WaitMSec(15))
@@ -471,22 +508,22 @@ bool CPythonInvoker::stop(bool abort)
}
}
- // grabbing the PyLock while holding the m_critical is asking for a deadlock
- PyEval_AcquireLock();
-
- lock.Enter();
-
- setState(InvokerStateExecutionDone);
-
// Useful for add-on performance metrics
if (!timeout.IsTimePast())
CLog::Log(LOGDEBUG, "CPythonInvoker(%d, %s): script termination took %dms", GetId(), m_sourceFile.c_str(), PYTHON_SCRIPT_TIMEOUT - timeout.MillisLeft());
+ // everything which didn't exit by now gets killed
+ {
+ // grabbing the PyLock while holding the m_critical is asking for a deadlock
+ CSingleExit ex2(m_critical);
+ PyEval_AcquireLock();
+ }
+
// Since we released the m_critical it's possible that the state is cleaned up
// so we need to recheck for m_threadState == NULL
if (m_threadState != NULL)
{
- PyThreadState* old = PyThreadState_Swap((PyThreadState*)m_threadState);
+ old = PyThreadState_Swap((PyThreadState*)m_threadState);
for (PyThreadState* state = ((PyThreadState*)m_threadState)->interp->tstate_head; state; state = state->next)
{
// Raise a SystemExit exception in python threads
@@ -494,71 +531,21 @@ bool CPythonInvoker::stop(bool abort)
state->async_exc = PyExc_SystemExit;
Py_XINCREF(state->async_exc);
}
- PyThreadState_Swap(old);
// If a dialog entered its doModal(), we need to wake it to see the exception
pulseGlobalEvent();
- m_threadState = nullptr;
}
+
+ if (old != NULL)
+ PyThreadState_Swap(old);
+
lock.Leave();
PyEval_ReleaseLock();
-
- setState(InvokerStateFailed);
}
return true;
}
-// Always called from Invoker thread
-void CPythonInvoker::onExecutionDone()
-{
- CSingleLock lock(m_critical);
- if (m_threadState != NULL)
- {
- CLog::Log(LOGDEBUG, "%s(%d, %s)", __FUNCTION__, GetId(), m_sourceFile.c_str());
-
- PyEval_AcquireLock();
- PyThreadState_Swap(m_threadState);
-
- onDeinitialization();
-
- // run the gc before finishing
- //
- // if the script exited by throwing a SystemExit exception then going back
- // into the interpreter causes this python bug to get hit:
- // http://bugs.python.org/issue10582
- // and that causes major failures. So we are not going to go back in
- // to run the GC if that's the case.
- if (!m_stop && m_languageHook->HasRegisteredAddonClasses() && !m_systemExitThrown &&
- PyRun_SimpleString(GC_SCRIPT) == -1)
- CLog::Log(LOGERROR, "CPythonInvoker(%d, %s): failed to run the gc to clean up after running prior to shutting down the Interpreter", GetId(), m_sourceFile.c_str());
-
- Py_EndInterpreter(m_threadState);
-
- // If we still have objects left around, produce an error message detailing what's been left behind
- if (m_languageHook->HasRegisteredAddonClasses())
- CLog::Log(LOGWARNING, "CPythonInvoker(%d, %s): the python script \"%s\" has left several "
- "classes in memory that we couldn't clean up. The classes include: %s",
- GetId(), m_sourceFile.c_str(), m_sourceFile.c_str(), getListOfAddonClassesAsString(m_languageHook).c_str());
-
- // unregister the language hook
- m_languageHook->UnregisterMe();
-
- PyEval_ReleaseLock();
-
- // set stopped event - this allows ::stop to run and kill remaining threads
- // this event has to be fired without holding m_critical
- // also the GIL (PyEval_AcquireLock) must not be held
- // if not obeyed there is still no deadlock because ::stop waits with timeout (smart one!)
- m_stoppedEvent.Set();
-
- m_threadState = nullptr;
-
- setState(InvokerStateExecutionDone);
- }
- ILanguageInvoker::onExecutionDone();
-}
-
void CPythonInvoker::onExecutionFailed()
{
PyThreadState_Swap(NULL);
@@ -573,12 +560,6 @@ void CPythonInvoker::onExecutionFailed()
ILanguageInvoker::onExecutionFailed();
}
-std::map CPythonInvoker::getModules() const
-{
- static std::map modules;
- return modules;
-}
-
void CPythonInvoker::onInitialization()
{
XBMC_TRACE;
@@ -604,11 +585,11 @@ void CPythonInvoker::onPythonModuleInitialization(void* moduleDict)
PyObject *moduleDictionary = (PyObject *)moduleDict;
- PyObject *pyaddonid = PyString_FromString(m_addon->ID().c_str());
+ PyObject *pyaddonid = PyUnicode_FromString(m_addon->ID().c_str());
PyDict_SetItemString(moduleDictionary, "__xbmcaddonid__", pyaddonid);
ADDON::AddonVersion version = m_addon->GetDependencyVersion("xbmc.python");
- PyObject *pyxbmcapiversion = PyString_FromString(version.asString().c_str());
+ PyObject *pyxbmcapiversion = PyUnicode_FromString(version.asString().c_str());
PyDict_SetItemString(moduleDictionary, "__xbmcapiversion__", pyxbmcapiversion);
PyObject *pyinvokerid = PyLong_FromLong(GetId());
@@ -642,11 +623,6 @@ void CPythonInvoker::onError(const std::string &exceptionType /* = "" */, const
}
}
-const char* CPythonInvoker::getInitializationScript() const
-{
- return NULL;
-}
-
void CPythonInvoker::initializeModules(const std::map &modules)
{
for (std::map::const_iterator module = modules.begin(); module != modules.end(); ++module)
@@ -661,8 +637,7 @@ bool CPythonInvoker::initializeModule(PythonModuleInitialization module)
if (module == NULL)
return false;
- module();
- return true;
+ return module() != nullptr;
}
void CPythonInvoker::getAddonModuleDeps(const ADDON::AddonPtr& addon, std::set& paths)
diff --git a/xbmc/interfaces/python/PythonInvoker.h b/xbmc/interfaces/python/PythonInvoker.h
index 3dc1dda4b03a4..faa5960d5f5a2 100644
--- a/xbmc/interfaces/python/PythonInvoker.h
+++ b/xbmc/interfaces/python/PythonInvoker.h
@@ -13,12 +13,10 @@
#include
#include "interfaces/generic/ILanguageInvoker.h"
-#include "interfaces/python/LanguageHook.h"
-#include "interfaces/legacy/Addon.h"
#include "threads/CriticalSection.h"
#include "threads/Event.h"
-struct _ts;
+typedef struct _object PyObject;
class CPythonInvoker : public ILanguageInvoker
{
@@ -30,19 +28,18 @@ class CPythonInvoker : public ILanguageInvoker
bool IsStopping() const override { return m_stop || ILanguageInvoker::IsStopping(); }
- typedef void (*PythonModuleInitialization)();
+ typedef PyObject* (*PythonModuleInitialization)();
protected:
// implementation of ILanguageInvoker
bool execute(const std::string &script, const std::vector &arguments) override;
- virtual void executeScript(void *fp, const std::string &script, void *module, void *moduleDict);
+ virtual void executeScript(FILE *fp, const std::string &script, PyObject* moduleDict);
bool stop(bool abort) override;
- void onExecutionDone() override;
void onExecutionFailed() override;
// custom virtual methods
- virtual std::map getModules() const;
- virtual const char* getInitializationScript() const;
+ virtual std::map getModules() const = 0;
+ virtual const char* getInitializationScript() const = 0;
virtual void onInitialization();
// actually a PyObject* but don't wanna draw Python.h include into the header
virtual void onPythonModuleInitialization(void* moduleDict);
@@ -61,14 +58,13 @@ class CPythonInvoker : public ILanguageInvoker
void addPath(const std::string& path); // add path in UTF-8 encoding
void addNativePath(const std::string& path); // add path in system/Python encoding
void getAddonModuleDeps(const ADDON::AddonPtr& addon, std::set& paths);
+ bool execute(const std::string &script, const std::vector &arguments);
+ FILE* PyFile_AsFileWithMode(PyObject *py_file, const char *mode);
std::string m_pythonPath;
- _ts *m_threadState;
+ void *m_threadState;
bool m_stop;
CEvent m_stoppedEvent;
- XBMCAddon::AddonClass::Ref m_languageHook;
- bool m_systemExitThrown = false;
-
static CCriticalSection s_critical;
};
diff --git a/xbmc/interfaces/python/PythonSwig.cpp.template b/xbmc/interfaces/python/PythonSwig.cpp.template
index f1d0d91f2645c..9e1e4ddb9962c 100644
--- a/xbmc/interfaces/python/PythonSwig.cpp.template
+++ b/xbmc/interfaces/python/PythonSwig.cpp.template
@@ -45,8 +45,8 @@ Helper.setup(this,classes,
* of the native call to be returned to the python caller.
*/
[ 'void' : 'Py_INCREF(Py_None);\n ${result} = Py_None;',
- 'long': '${result} = PyInt_FromLong(${api});',
- 'unsigned long': '${result} = PyInt_FromLong(${api});',
+ 'long': '${result} = PyLong_FromLong(${api});',
+ 'unsigned long': '${result} = PyLong_FromLong(${api});',
'bool': '${result} = Py_BuildValue("b", ${api});',
'long long': '${result} = Py_BuildValue("L", ${api});',
'int': '${result} = Py_BuildValue("i", ${api});',
@@ -54,7 +54,7 @@ Helper.setup(this,classes,
'double': '${result} = PyFloat_FromDouble(${api});',
'float': '${result} = Py_BuildValue("f", ${api});',
'std::string' : new File('typemaps/python.string.outtm'),
- 'p.q(const).char' : '${result} = PyString_FromString(${api});',
+ 'p.q(const).char' : '${result} = PyUnicode_FromString(${api});',
(Pattern.compile('''(p.){0,1}XbmcCommons::Buffer''')) : new File('typemaps/python.buffer.outtm'),
(Pattern.compile('''std::shared_ptr<\\(.*\\)>''')) : new File('typemaps/python.smart_ptr.outtm'),
(Pattern.compile('''std::unique_ptr<\\(.*\\)>''')) : new File('typemaps/python.smart_ptr.outtm'),
@@ -79,15 +79,15 @@ Helper.setup(this,classes,
(Pattern.compile('''(p.){0,1}std::map<\\(.*\\)>''')) : new File('typemaps/python.map.intm'),
(Pattern.compile('''(r.){0,1}XBMCAddon::Dictionary<\\(.*\\)>''')) : new File('typemaps/python.dict.intm'),
(Pattern.compile('''p.void''')) : '${api} = (void*)${slarg};',
- 'bool' : '${api} = (PyInt_AsLong(${slarg}) == 0L ? false : true);',
- 'long' : '${api} = PyInt_AsLong(${slarg});',
+ 'bool' : '${api} = (PyLong_AsLong(${slarg}) == 0L ? false : true);',
+ 'long' : '${api} = PyLong_AsLong(${slarg});',
'unsigned long' : '${api} = PyLong_AsUnsignedLong(${slarg});',
'long long' : '${api} = PyLong_AsLongLong(${slarg});',
'unsigned long long' : '${api} = PyLong_AsUnsignedLongLong(${slarg});',
- 'int' : '${api} = (int)PyInt_AsLong(${slarg});',
+ 'int' : '${api} = (int)PyLong_AsLong(${slarg});',
'double' : '${api} = PyFloat_AsDouble(${slarg});',
'float' : '${api} = (float)PyFloat_AsDouble(${slarg});',
- 'XBMCAddon::StringOrInt' : 'if (${slarg}) PyXBMCGetUnicodeString(${api},${slarg},PyInt_Check(${slarg}) || PyLong_Check(${slarg}) || PyFloat_Check(${slarg}),"${api}","${method.@name}");'
+ 'XBMCAddon::StringOrInt' : 'if (${slarg}) PyXBMCGetUnicodeString(${api},${slarg},PyLong_Check(${slarg}) || PyLong_Check(${slarg}) || PyFloat_Check(${slarg}),"${api}","${method.@name}");'
], '${api} = (${swigTypeParser.SwigType_str(ltype)})retrieveApiInstance(${slarg},"${ltype}","${helper.findNamespace(method)}","${helper.callingName(method)}");')
// ---------------------------------------------------------
@@ -262,7 +262,7 @@ void doMethod(Node method, MethodType methodType)
return result; <% }
else { %>
- self->ob_type->tp_free((PyObject*)self);
+ (((PyObject*)(self))->ob_type)->tp_free((PyObject*)self);
<%
}
%>
@@ -653,22 +653,13 @@ void doClassMethodInfo(Node clazz, List initTypeCalls)
pythonType.tp_name = "${module.@name}.${clazz.@sym_name}";
pythonType.tp_basicsize = sizeof(PyHolder);
pythonType.tp_dealloc = (destructor)${module.@name}_${classNameAsVariable}_Dealloc; <%
- if (doComparator) { %>
- pythonType.tp_compare=${module.@name}_${classNameAsVariable}_cmp;<%
- }
+
if (clazz.@feature_python_rcmp) { %>
pythonType.tp_richcompare=(richcmpfunc)${module.@name}_${classNameAsVariable}_rcmp;<%
} %>
-<%
- if (clazz.@feature_iterator) { %>
- pythonType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER;
-<%
- }
- else { %>
pythonType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
-<%
- } %>
+
pythonType.tp_doc = ${Helper.hasDoc(clazz) ? (classNameAsVariable + '__doc__') : 'NULL' };
pythonType.tp_methods = ${classNameAsVariable}_methods; <%
if (properties.size() > 0) { %>
@@ -829,8 +820,7 @@ namespace PythonBindings
}
%>
XBMCAddon::Python::PyContext pyContext;
- //! @bug libpython < 3.4 isn't const correct
- PyObject_CallMethod(self,const_cast("${Helper.callingName(it)}"),const_cast("(${paramFormatStr})")<%
+ PyObject_CallMethod(self,"${Helper.callingName(it)}","(${paramFormatStr})"<%
params.each {
%>, py${it.@name} <%
}
@@ -896,7 +886,16 @@ namespace PythonBindings
}
}
- void initModule_${module.@name}()
+ static struct PyModuleDef createModule
+ {
+ PyModuleDef_HEAD_INIT,
+ "${module.@name}",
+ "",
+ -1,
+ ${module.@name}_methods
+ };
+
+ PyObject *PyInit_Module_${module.@name}()
{
initTypes();
@@ -907,8 +906,8 @@ namespace PythonBindings
Py_INCREF(&(Ty${it}_Type.pythonType));<%
}%>
- module = Py_InitModule("${module.@name}", ${module.@name}_methods);
- if (module == NULL) return;
+ module = PyModule_Create(&createModule);
+ if (module == NULL) return NULL;
<% classes.each { clazz -> %>
PyModule_AddObject(module, "${clazz.@sym_name}", (PyObject*)(&(Ty${PythonTools.getClassNameAsVariable(clazz)}_Type.pythonType)));<%
@@ -928,6 +927,7 @@ namespace PythonBindings
'PyModule_AddIntConstant' : 'PyModule_AddStringConstant' %>
${pyCall}(module,"${it.@sym_name}",${it.@value}); <%
} %>
+ return module;
}
} // end PythonBindings namespace for python type definitions
diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp
index 81e0d7c55e7d4..93e2043a58ad3 100644
--- a/xbmc/interfaces/python/XBPython.cpp
+++ b/xbmc/interfaces/python/XBPython.cpp
@@ -35,6 +35,8 @@
#include "interfaces/python/PythonInvoker.h"
#include "ServiceBroker.h"
+PyThreadState* savestate;
+
XBPython::XBPython()
{
m_bInitialized = false;
@@ -408,22 +410,6 @@ void XBPython::OnNotification(const std::string &sender, const std::string &meth
}
}
-/**
-* Check for file and print an error if needed
-*/
-bool XBPython::FileExist(const char* strFile)
-{
- if (!strFile)
- return false;
-
- if (!XFILE::CFile::Exists(strFile))
- {
- CLog::Log(LOGERROR, "Python: Cannot find '%s'", strFile);
- return false;
- }
- return true;
-}
-
void XBPython::RegisterExtensionLib(LibraryLoader *pLib)
{
if (!pLib)
@@ -482,8 +468,7 @@ void XBPython::Finalize()
m_mainThreadState = NULL; // clear the main thread state before releasing the lock
{
CSingleExit exit(m_critSection);
- PyEval_AcquireLock();
- PyThreadState_Swap(curTs);
+ PyEval_AcquireThread(curTs);
Py_Finalize();
PyEval_ReleaseLock();
@@ -499,7 +484,7 @@ void XBPython::Finalize()
#endif
#if defined(TARGET_POSIX) && !defined(TARGET_DARWIN) && !defined(TARGET_FREEBSD)
// we can't release it on windows, as this is done in UnloadPythonDlls() for win32 (see above).
- // The implementation for linux needs looking at - UnloadPythonDlls() currently only searches for "python26.dll"
+ // The implementation for linux needs looking at - UnloadPythonDlls() currently only searches for "python36.dll"
// The implementation for osx can never unload the python dylib.
DllLoaderContainer::ReleaseModule(m_pDll);
#endif
@@ -564,21 +549,6 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker)
m_iDllScriptCounter++;
if (!m_bInitialized)
{
- // first we check if all necessary files are installed
-#ifndef TARGET_POSIX
- if (!FileExist("special://xbmc/system/python/DLLs/_socket.pyd") ||
- !FileExist("special://xbmc/system/python/DLLs/_ssl.pyd") ||
- !FileExist("special://xbmc/system/python/DLLs/bz2.pyd") ||
- !FileExist("special://xbmc/system/python/DLLs/pyexpat.pyd") ||
- !FileExist("special://xbmc/system/python/DLLs/select.pyd") ||
- !FileExist("special://xbmc/system/python/DLLs/unicodedata.pyd"))
- {
- CLog::Log(LOGERROR, "Python: Missing files, unable to execute script");
- Finalize();
- return false;
- }
-#endif
-
// Darwin packs .pyo files, we need PYTHONOPTIMIZE on in order to load them.
// linux built with unified builds only packages the pyo files so need it
#if defined(TARGET_DARWIN) || defined(TARGET_LINUX)
@@ -595,8 +565,8 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker)
// check if we are running as real xbmc.app or just binary
if (!CUtil::GetFrameworksPath(true).empty())
{
- // using external python, it's build looking for xxx/lib/python2.6
- // so point it to frameworks which is where python2.6 is located
+ // using external python, it's build looking for xxx/lib/python3.7
+ // so point it to frameworks which is where python3.7 is located
setenv("PYTHONHOME", CSpecialProtocol::TranslatePath("special://frameworks").c_str(), 1);
setenv("PYTHONPATH", CSpecialProtocol::TranslatePath("special://frameworks").c_str(), 1);
CLog::Log(LOGDEBUG, "PYTHONHOME -> %s", CSpecialProtocol::TranslatePath("special://frameworks").c_str());
@@ -606,7 +576,7 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker)
// because the third party build of python is compiled with vs2008 we need
// a hack to set the PYTHONPATH
std::string buf;
- buf = "PYTHONPATH=" + CSpecialProtocol::TranslatePath("special://xbmc/system/python/DLLs") + ";" + CSpecialProtocol::TranslatePath("special://xbmc/system/python/Lib");
+ buf = "PYTHONPATH=" + CSpecialProtocol::TranslatePath("special://xbmc/system/python/Lib");
CEnvironment::putenv(buf);
buf = "PYTHONOPTIMIZE=1";
CEnvironment::putenv(buf);
@@ -620,25 +590,22 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker)
#endif
#endif
- if (PyEval_ThreadsInitialized())
- PyEval_AcquireLock();
- else
- PyEval_InitThreads();
-
Py_Initialize();
- PyEval_ReleaseLock();
// If this is not the first time we initialize Python, the interpreter
// lock already exists and we need to lock it as PyEval_InitThreads
// would not do that in that case.
- PyEval_AcquireLock();
- const char* python_argv[1] = { "" };
+ if (PyEval_ThreadsInitialized() && !PyGILState_Check())
+ PyEval_AcquireLock();
+ else
+ PyEval_InitThreads();
+ const wchar_t* python_argv[1] = { L"" };
//! @bug libpython isn't const correct
- PySys_SetArgv(1, const_cast(python_argv));
+ PySys_SetArgv(1, const_cast(python_argv));
if (!(m_mainThreadState = PyThreadState_Get()))
CLog::Log(LOGERROR, "Python threadstate is NULL.");
- PyEval_ReleaseLock();
+ savestate = PyEval_SaveThread();
m_bInitialized = true;
}
@@ -681,7 +648,7 @@ void XBPython::OnScriptAbortRequested(ILanguageInvoker *invoker)
}
}
-void XBPython::OnExecutionEnded(ILanguageInvoker *invoker)
+void XBPython::OnScriptEnded(ILanguageInvoker *invoker)
{
CSingleLock lock(m_vecPyList);
PyList::iterator it = m_vecPyList.begin();
@@ -690,9 +657,9 @@ void XBPython::OnExecutionEnded(ILanguageInvoker *invoker)
if (it->id == invoker->GetId())
{
if (it->pyThread->IsStopping())
- CLog::Log(LOGINFO, "Python interpreter interrupted by user");
+ CLog::Log(LOGINFO, "Python script interrupted by user");
else
- CLog::Log(LOGINFO, "Python interpreter stopped");
+ CLog::Log(LOGINFO, "Python script stopped");
it->bDone = true;
}
++it;
diff --git a/xbmc/interfaces/python/XBPython.h b/xbmc/interfaces/python/XBPython.h
index 0c922fb71181e..41c5757e01901 100644
--- a/xbmc/interfaces/python/XBPython.h
+++ b/xbmc/interfaces/python/XBPython.h
@@ -91,7 +91,7 @@ class XBPython :
bool OnScriptInitialized(ILanguageInvoker *invoker) override;
void OnScriptStarted(ILanguageInvoker *invoker) override;
void OnScriptAbortRequested(ILanguageInvoker *invoker) override;
- void OnExecutionEnded(ILanguageInvoker *invoker) override;
+ void OnScriptEnded(ILanguageInvoker *invoker) override;
void OnScriptFinalized(ILanguageInvoker *invoker) override;
ILanguageInvoker* CreateInvoker() override;
@@ -105,8 +105,6 @@ class XBPython :
void Finalize();
CCriticalSection m_critSection;
- bool FileExist(const char* strFile);
-
void* m_mainThreadState;
ThreadIdentifier m_ThreadId;
bool m_bInitialized;
diff --git a/xbmc/interfaces/python/swig.cpp b/xbmc/interfaces/python/swig.cpp
index b9d162566a6f3..a2bb3c1b470ba 100644
--- a/xbmc/interfaces/python/swig.cpp
+++ b/xbmc/interfaces/python/swig.cpp
@@ -17,7 +17,7 @@ namespace PythonBindings
{
TypeInfo::TypeInfo(const std::type_info& ti) : swigType(NULL), parentType(NULL), typeIndex(ti)
{
- static PyTypeObject py_type_object_header = { PyObject_HEAD_INIT(NULL) 0};
+ static PyTypeObject py_type_object_header = { PyVarObject_HEAD_INIT(NULL, 0)};
static int size = (long*)&(py_type_object_header.tp_name) - (long*)&py_type_object_header;
memcpy(&(this->pythonType), &py_type_object_header, size);
}
@@ -51,18 +51,14 @@ namespace PythonBindings
// Python unicode objects are UCS2 or UCS4 depending on compilation
// options, wchar_t is 16-bit or 32-bit depending on platform.
// Avoid the complexity by just letting python convert the string.
- PyObject *utf8_pyString = PyUnicode_AsUTF8String(pObject);
- if (utf8_pyString)
- {
- buf = PyString_AsString(utf8_pyString);
- Py_DECREF(utf8_pyString);
+ buf = PyUnicode_AsUTF8(pObject);
return;
}
- }
- if (PyString_Check(pObject))
+
+ if (PyBytes_Check(pObject)) // If pobject is of type Bytes
{
- buf = PyString_AsString(pObject);
+ buf = PyBytes_AsString(pObject);
return;
}
@@ -166,26 +162,24 @@ namespace PythonBindings
// See https://docs.python.org/3/c-api/exceptions.html#c.PyErr_NormalizeException
PyErr_NormalizeException(&exc_type, &exc_value, &exc_traceback);
-#if PY_MAJOR_VERSION > 2
if (exc_traceback != NULL) {
PyException_SetTraceback(exc_value, exc_traceback);
}
-#endif
exceptionType.clear();
exceptionValue.clear();
exceptionTraceback.clear();
- if (exc_type != NULL && (pystring = PyObject_Str(exc_type)) != NULL && PyString_Check(pystring))
+ if (exc_type != NULL && (pystring = PyObject_Str(exc_type)) != NULL && PyUnicode_Check(pystring))
{
- char *str = PyString_AsString(pystring);
+ const char *str = PyUnicode_AsUTF8(pystring);
if (str != NULL)
exceptionType = str;
pystring = PyObject_Str(exc_value);
if (pystring != NULL)
{
- str = PyString_AsString(pystring);
+ str = PyUnicode_AsUTF8(pystring);
exceptionValue = str;
}
@@ -198,7 +192,7 @@ namespace PythonBindings
if (tbList)
{
- PyObject *emptyString = PyString_FromString("");
+ PyObject *emptyString = PyUnicode_FromString("");
char method[] = "join";
char format[] = "O";
PyObject *strRetval = PyObject_CallMethod(emptyString, method, format, tbList);
@@ -206,7 +200,7 @@ namespace PythonBindings
if (strRetval)
{
- str = PyString_AsString(strRetval);
+ str = PyUnicode_AsUTF8(strRetval);
if (str != NULL)
exceptionTraceback = str;
Py_DECREF(strRetval);
diff --git a/xbmc/interfaces/python/typemaps/python.Tuple.intm b/xbmc/interfaces/python/typemaps/python.Tuple.intm
index ee6afce9389fd..c426856373ae7 100644
--- a/xbmc/interfaces/python/typemaps/python.Tuple.intm
+++ b/xbmc/interfaces/python/typemaps/python.Tuple.intm
@@ -17,7 +17,7 @@
bool isTuple = PyObject_TypeCheck(${slarg},&PyTuple_Type);
if (!isTuple && !PyObject_TypeCheck(${slarg},&PyList_Type))
throw WrongTypeException("The parameter \"${api}\" must be either a Tuple or a List.");
- auto vecSize = (isTuple ? PyTuple_Size(${slarg}) : PyList_Size(${slarg}));
+ Py_ssize_t vecSize = (isTuple ? PyTuple_Size(${slarg}) : PyList_Size(${slarg}));
<%
types.eachWithIndex { curType, entryIndex ->
%>
diff --git a/xbmc/interfaces/python/typemaps/python.buffer.intm b/xbmc/interfaces/python/typemaps/python.buffer.intm
index d9bab4560a998..76c09cb783293 100644
--- a/xbmc/interfaces/python/typemaps/python.buffer.intm
+++ b/xbmc/interfaces/python/typemaps/python.buffer.intm
@@ -7,10 +7,10 @@
* See LICENSES/README.md for more information.
*/
%>
- if (PyString_Check(${slarg}))
+ if (PyUnicode_Check(${slarg}))
{
- const char* str = PyString_AsString(${slarg});
- size_t size = (size_t)PyString_Size(${slarg});
+ const char* str = PyUnicode_AsUTF8(${slarg});
+ size_t size = (size_t)PyUnicode_GetLength(${slarg});
${api}.allocate(size);
${api}.put(str,size);
${api}.flip(); // prepare the buffer for reading from
diff --git a/xbmc/interfaces/python/typemaps/python.string.outtm b/xbmc/interfaces/python/typemaps/python.string.outtm
index 6e17f824318fa..93c4971d40dc9 100644
--- a/xbmc/interfaces/python/typemaps/python.string.outtm
+++ b/xbmc/interfaces/python/typemaps/python.string.outtm
@@ -8,4 +8,4 @@
*/
%>${result} = <%
if(method.@feature_python_coerceToUnicode) { %>PyUnicode_DecodeUTF8(${api}.c_str(),${api}.size(),"replace");<% }
- else { %>PyString_FromStringAndSize(${api}.c_str(), ${api}.length());<% } %>
\ No newline at end of file
+ else { %>PyUnicode_FromStringAndSize(${api}.c_str(), ${api}.length());<% } %>
diff --git a/xbmc/interfaces/python/typemaps/python.vector.intm b/xbmc/interfaces/python/typemaps/python.vector.intm
index c4b385e8cb5b7..a479d748b1608 100644
--- a/xbmc/interfaces/python/typemaps/python.vector.intm
+++ b/xbmc/interfaces/python/typemaps/python.vector.intm
@@ -20,7 +20,7 @@
<% if (ispointer) print("${api} = new std::vector<${swigTypeParser.SwigType_str(vectype)}>();") %>
PyObject *pyentry${seq} = NULL;
- auto vecSize = (isTuple ? PyTuple_Size(${slarg}) : PyList_Size(${slarg}));
+ Py_ssize_t vecSize = (isTuple ? PyTuple_Size(${slarg}) : PyList_Size(${slarg}));
for(Py_ssize_t i = 0; i < vecSize; i++)
{
pyentry${seq} = (isTuple ? PyTuple_GetItem(${slarg}, i) : PyList_GetItem(${slarg}, i));
diff --git a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp
index ae487a2d9d362..cb49abec2ac8e 100644
--- a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp
+++ b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp
@@ -6,6 +6,8 @@
* See LICENSES/README.md for more information.
*/
+#include
+
#include "HTTPPythonWsgiInvoker.h"
#include
@@ -40,14 +42,14 @@
#define RUNSCRIPT_SETUPTOOLS_HACK \
"" \
- "import imp,sys\n" \
+ "import types,sys\n" \
"pkg_resources_code = \\\n" \
"\"\"\"\n" \
"def resource_filename(__name__,__path__):\n" \
" return __path__\n" \
"\"\"\"\n" \
- "pkg_resources = imp.new_module('pkg_resources')\n" \
- "exec pkg_resources_code in pkg_resources.__dict__\n" \
+ "pkg_resources = types.ModuleType('pkg_resources')\n" \
+ "exec(pkg_resources_code, pkg_resources.__dict__)\n" \
"sys.modules['pkg_resources'] = pkg_resources\n" \
""
@@ -64,9 +66,9 @@
#endif
namespace PythonBindings {
- void initModule_xbmc(void);
- void initModule_xbmcaddon(void);
- void initModule_xbmcwsgi(void);
+ PyObject* PyInit_Module_xbmc(void);
+ PyObject* PyInit_Module_xbmcaddon(void);
+ PyObject* PyInit_Module_xbmcwsgi(void);
}
using namespace PythonBindings;
@@ -79,15 +81,19 @@ typedef struct
static PythonModule PythonModules[] =
{
- { "xbmc", initModule_xbmc },
- { "xbmcaddon", initModule_xbmcaddon },
- { "xbmcwsgi", initModule_xbmcwsgi }
+ { "xbmc", PyInit_Module_xbmc },
+ { "xbmcaddon", PyInit_Module_xbmcaddon },
+ { "xbmcwsgi", PyInit_Module_xbmcwsgi }
};
CHTTPPythonWsgiInvoker::CHTTPPythonWsgiInvoker(ILanguageInvocationHandler* invocationHandler, HTTPPythonRequest* request)
: CHTTPPythonInvoker(invocationHandler, request),
m_wsgiResponse(NULL)
-{ }
+{
+ PyImport_AppendInittab("xbmc", PyInit_Module_xbmc);
+ PyImport_AppendInittab("xbmcaddon", PyInit_Module_xbmcaddon);
+ PyImport_AppendInittab("xbmcwsgi", PyInit_Module_xbmcwsgi);
+}
CHTTPPythonWsgiInvoker::~CHTTPPythonWsgiInvoker()
{
@@ -107,10 +113,10 @@ HTTPPythonRequest* CHTTPPythonWsgiInvoker::GetRequest()
return m_request;
}
-void CHTTPPythonWsgiInvoker::executeScript(void *fp, const std::string &script, void *module, void *moduleDict)
+void CHTTPPythonWsgiInvoker::executeScript(FILE* fp, const std::string &script, PyObject* moduleDict)
{
if (m_request == NULL || m_addon == NULL || m_addon->Type() != ADDON::ADDON_WEB_INTERFACE ||
- fp == NULL || script.empty() || module == NULL || moduleDict == NULL)
+ fp == NULL || script.empty() || moduleDict == NULL)
return;
ADDON::CWebinterface* webinterface = static_cast(m_addon.get());
@@ -134,7 +140,7 @@ void CHTTPPythonWsgiInvoker::executeScript(void *fp, const std::string &script,
// get the script
std::string scriptName = URIUtils::GetFileName(script);
URIUtils::RemoveExtension(scriptName);
- pyScript = PyString_FromStringAndSize(scriptName.c_str(), scriptName.size());
+ pyScript = PyUnicode_FromStringAndSize(scriptName.c_str(), scriptName.size());
if (pyScript == NULL)
{
CLog::Log(LOGERROR, "CHTTPPythonWsgiInvoker: failed to convert script \"%s\" to python string", script.c_str());
@@ -187,7 +193,7 @@ void CHTTPPythonWsgiInvoker::executeScript(void *fp, const std::string &script,
pyEnviron = PyDict_New();
for (std::map::const_iterator cgiEnv = cgiEnvironment.begin(); cgiEnv != cgiEnvironment.end(); ++cgiEnv)
{
- PyObject* pyEnvEntry = PyString_FromStringAndSize(cgiEnv->second.c_str(), cgiEnv->second.size());
+ PyObject* pyEnvEntry = PyUnicode_FromStringAndSize(cgiEnv->second.c_str(), cgiEnv->second.size());
PyDict_SetItemString(pyEnviron, cgiEnv->first.c_str(), pyEnvEntry);
Py_DECREF(pyEnvEntry);
}
@@ -271,8 +277,7 @@ void CHTTPPythonWsgiInvoker::executeScript(void *fp, const std::string &script,
// Call optional close method on iterator
if (PyObject_HasAttrString(pyResultIterator, "close") == 1)
{
- //! @bug libpython < 3.4 isn't const correct
- if (PyObject_CallMethod(pyResultIterator, const_cast("close"), NULL) == NULL)
+ if (PyObject_CallMethod(pyResultIterator, "close", NULL) == NULL)
CLog::Log(LOGERROR, "CHTTPPythonWsgiInvoker: failed to close iterator object for WSGI script \"%s\"", script.c_str());
}
Py_DECREF(pyResultIterator);
@@ -398,7 +403,7 @@ void CHTTPPythonWsgiInvoker::addWsgiEnvironment(HTTPPythonRequest* request, void
}
{
// wsgi.url_scheme
- PyObject* pyValue = PyString_FromStringAndSize("http", 4);
+ PyObject* pyValue = PyUnicode_FromStringAndSize("http", 4);
PyDict_SetItemString(pyEnviron, "wsgi.url_scheme", pyValue);
Py_DECREF(pyValue);
}
diff --git a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.h b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.h
index ae0ab922f238d..ea85f390a36b2 100644
--- a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.h
+++ b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.h
@@ -34,7 +34,7 @@ class CHTTPPythonWsgiInvoker : public CHTTPPythonInvoker
protected:
// overrides of CPythonInvoker
- void executeScript(void *fp, const std::string &script, void *module, void *moduleDict) override;
+ void executeScript(FILE* fp, const std::string &script, PyObject* moduleDict) override;
std::map getModules() const override;
const char* getInitializationScript() const override;
diff --git a/xbmc/platform/android/activity/XBMCApp.cpp b/xbmc/platform/android/activity/XBMCApp.cpp
index 3a6e6f65c57d4..194dffc852f14 100644
--- a/xbmc/platform/android/activity/XBMCApp.cpp
+++ b/xbmc/platform/android/activity/XBMCApp.cpp
@@ -1297,7 +1297,7 @@ void CXBMCApp::SetupEnv()
setenv("HOME", getenv("KODI_TEMP"), 0);
std::string apkPath = getenv("KODI_ANDROID_APK");
- apkPath += "/assets/python2.7";
+ apkPath += "/assets/python3.7";
setenv("PYTHONHOME", apkPath.c_str(), 1);
setenv("PYTHONPATH", "", 1);
setenv("PYTHONOPTIMIZE","", 1);