make-python.sh 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #!/bin/bash
  2. #
  3. # Copyright (c) Contributors to the Open 3D Engine Project.
  4. # For complete copyright and license terms please see the LICENSE at the root of this distribution.
  5. #
  6. # SPDX-License-Identifier: Apache-2.0 OR MIT
  7. #
  8. #
  9. SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
  10. cd $SCRIPT_DIR
  11. echo ""
  12. echo "--------------- PYTHON PACKAGE BUILD SCRIPT ----------------"
  13. echo ""
  14. echo "BASIC REQUIREMENTS in case something goes wrong:"
  15. echo " - git installed and in PATH"
  16. echo " - packages installed: apt-get dev-essential tk8.6-dev python3 libssl-dev tcl8.6-dev libgdbm-compat-dev liblzma-dev libsqlite3-dev libreadline-dev texinfo"
  17. echo " - python3 with pip in PATH! (i.e. sudo apt install python3 and sudo apt install python3-pip"
  18. echo " - Note: This script is currently written for buildng on Ubuntu Linux only."
  19. echo " - Note: installing binaries with pip must result with them being on PATH."
  20. echo ""
  21. # Make sure we have all the required dev packages
  22. REQUIRED_DEV_PACKAGES="tk8.6-dev python3 libssl-dev tcl8.6-dev libgdbm-compat-dev liblzma-dev libsqlite3-dev libreadline-dev texinfo"
  23. ALL_PACKAGES=`apt list 2>/dev/null`
  24. for req_package in $REQUIRED_DEV_PACKAGES
  25. do
  26. PACKAGE_COUNT=`echo $ALL_PACKAGES | grep $req_package | wc -l`
  27. if [[ $PACKAGE_COUNT -eq 0 ]]; then
  28. echo Missing required package $req_package
  29. exit 1
  30. fi
  31. done
  32. if [[ ${PACKAGE_CLEAR_TEMP_FOLDERS} -gt 0 ]]; then
  33. echo " - PACKAGE_CLEAR_TEMP_FOLDERS env var is set > 0, will clear temp folders."
  34. else
  35. echo " - PACKAGE_CLEAR_TEMP_FOLDERS env var not set or = 0, will not clear temp."
  36. fi
  37. echo " ... this will take about one and a half hours ..."
  38. echo ""
  39. mkdir -p temp
  40. echo ""
  41. echo "--------------- Cloning python 3.10.13 from git ---------------"
  42. echo ""
  43. cd temp
  44. git clone https://github.com/python/cpython.git --branch v3.10.13 --depth 1
  45. if [[ ! -d "cpython" ]]; then
  46. echo "Was unable to create cpython dir via git clone. Is git installed?"
  47. exit 1
  48. fi
  49. echo ""
  50. echo "--------------- Cloning libexpat 2.4.6 from git and applying update ---------------"
  51. echo ""
  52. git clone https://github.com/libexpat/libexpat.git --branch "R_2_4_6" --depth 1
  53. if [[ ! -d "libexpat" ]]; then
  54. echo "Was unable to create libexpat dir via git clone. Is git installed?"
  55. exit 1
  56. fi
  57. cp -f -v libexpat/expat/lib/*.h cpython/Modules/expat/
  58. cp -f -v libexpat/expat/lib/*.c cpython/Modules/expat/
  59. echo ""
  60. echo "--------------- Cloning libffi 3.4.2 and building static version ---------------"
  61. echo ""
  62. git clone https://github.com/libffi/libffi.git --branch "v3.4.2" --depth 1
  63. if [[ ! -d "libffi" ]]; then
  64. echo "Was unable to create libffi dir via git clone."
  65. exit 1
  66. fi
  67. pushd libffi
  68. # According to the README.md for libffi, we need to run autogen.sh first
  69. ./autogen.sh
  70. retVal=$?
  71. if [ $retVal -ne 0 ]; then
  72. echo "Error running autogen.sh for libffi"
  73. exit $retVal
  74. fi
  75. ./configure --prefix=$SCRIPT_DIR/temp/ffi_lib --enable-shared=no CFLAGS='-fPIC' CPPFLAGS='-fPIC'
  76. retVal=$?
  77. if [ $retVal -ne 0 ]; then
  78. echo "Error running configuring for libffi"
  79. exit $retVal
  80. fi
  81. make install
  82. retVal=$?
  83. if [ $retVal -ne 0 ]; then
  84. echo "Error building libffi"
  85. exit $retVal
  86. fi
  87. popd
  88. echo ""
  89. echo "--------------- Cloning openssl 1.1.1w and building it externally ---------------"
  90. echo ""
  91. git clone https://github.com/openssl/openssl.git --branch "OpenSSL_1_1_1w" --depth 1
  92. if [[ ! -d "openssl" ]]; then
  93. echo "Was unable to create openssl dir via git clone."
  94. exit 1
  95. fi
  96. pushd openssl
  97. echo ./config --prefix=$SCRIPT_DIR/temp/openssl-local/build --openssldir=/etc/ssl LDFLAGS='-Wl,-rpath=\$$ORIGIN'
  98. ./config --prefix=$SCRIPT_DIR/temp/openssl-local/build --openssldir=/etc/ssl LDFLAGS='-Wl,-rpath=\$$ORIGIN'
  99. retVal=$?
  100. if [ $retVal -ne 0 ]; then
  101. echo "Error building openssl"
  102. exit $retVal
  103. fi
  104. echo make
  105. make
  106. if [ $retVal -ne 0 ]; then
  107. echo "Error building openssl (build failure)"
  108. exit $retVal
  109. fi
  110. echo make test
  111. if [ $retVal -ne 0 ]; then
  112. echo "Error building openssl (test failure)"
  113. exit $retVal
  114. fi
  115. echo make install
  116. make install
  117. if [ $retVal -ne 0 ]; then
  118. echo "Error building openssl (install failure)"
  119. exit $retVal
  120. fi
  121. popd
  122. cd cpython
  123. echo ""
  124. echo "--------------- Building cpython from source ---------------"
  125. echo ""
  126. # Build from the source with optimizations and shared libs enabled , and override the RPATH and bzip include/lib paths
  127. ./configure --prefix=$SCRIPT_DIR/package/python --enable-optimizations --with-openssl=$SCRIPT_DIR/temp/openssl-local/build --enable-shared LDFLAGS='-Wl,-rpath=\$$ORIGIN:\$$ORIGIN/../lib:\$$ORIGIN/../.. -L../ffi_lib/lib' CPPFLAGS='-I../ffi_lib/include' CFLAGS='-I../ffi_lib/include'
  128. retVal=$?
  129. if [ $retVal -ne 0 ]; then
  130. echo "Error running configuring optimized build"
  131. exit $retVal
  132. fi
  133. make
  134. retVal=$?
  135. if [ $retVal -ne 0 ]; then
  136. echo "Error compiling optimized build"
  137. exit $retVal
  138. fi
  139. # Prepare the package folder
  140. cd $SCRIPT_DIR
  141. # Install the newly built python 3.10.13 to the package/python folder
  142. cd $SCRIPT_DIR
  143. cd temp
  144. cd cpython
  145. make install
  146. retVal=$?
  147. if [ $retVal -ne 0 ]; then
  148. echo "Error installing python to the package folder"
  149. exit $retVal
  150. fi
  151. cd $SCRIPT_DIR
  152. mkdir -p package
  153. cd package
  154. cp $SCRIPT_DIR/temp/cpython/LICENSE ./python/LICENSE
  155. cp $SCRIPT_DIR/PackageInfo.json .
  156. cp $SCRIPT_DIR/*.cmake .
  157. cd $SCRIPT_DIR/package/python/bin
  158. ln -s python3 python
  159. cd $SCRIPT_DIR/package
  160. # Move the openssl libraries to the local cpython build for portability
  161. pushd $SCRIPT_DIR/package/python/lib
  162. cp $SCRIPT_DIR/temp/openssl-local/build/lib/libssl.so.1.1 .
  163. ln -s libssl.so.1.1 libssl.so.1
  164. cp $SCRIPT_DIR/temp/openssl-local/build/lib/libcrypto.so.1.1 .
  165. ln -s libcrypto.so.1.1 libcrypto.so.1
  166. popd
  167. # Copy the openssl license
  168. cp $SCRIPT_DIR/temp/openssl/LICENSE $SCRIPT_DIR/package/python/LICENSE.OPENSSL
  169. echo ""
  170. echo "--------------- Upgrading pip ---------------"
  171. echo ""
  172. # the pip that may come from the above repo can be broken, so we'll use get-pip
  173. # and then upgrade it.
  174. curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
  175. ./python/bin/python3 get-pip.py
  176. rm get-pip.py
  177. PYTHONNOUSERSITE=1 ./python/bin/python3 -m pip install --upgrade pip
  178. # installing pip causes it to put absolute paths to python
  179. # in the pip files (in bin). For example, pip will have
  180. # a line at the top that starts with #!/full/path/to/python
  181. # so we fix those up too.
  182. # We want to change it from and absolute path to python
  183. # to a multi-line #! that runs python from the same folder as the file is being called from:
  184. #!/bin/sh
  185. #"exec" "`dirname $0`/python" "$0" "$@"
  186. sed -i "1s+.*+\#\!/bin/sh+" ./python/bin/pip*
  187. sed -i "2i\\
  188. \"exec\" \"\`dirname \$0\`/python\" \"\$0\" \"\$\@\" " ./python/bin/pip*
  189. echo ""
  190. echo "--------------- PYTHON WAS BUILT FROM SOURCE ---------------"
  191. echo ""
  192. echo "Package has completed building, and is now in $SCRIPT_DIR/package"
  193. if [[ ${PACKAGE_CLEAR_TEMP_FOLDERS} -gt 0 ]]
  194. then
  195. echo "Deleting temp folders because PACKAGE_CLEAR_TEMP_FOLDERS is set to > 0"
  196. rm -rf $SCRIPT_DIR/temp
  197. else
  198. echo "PACKAGE_CLEAR_TEMP_FOLDERS is unset or zero, temp folder retained."
  199. echo "Running this script again without deleting temp will just update the package without"
  200. echo "The two hour wait time to build everything from scratch..."
  201. fi
  202. exit 0