Python3.10 source build on CentOS 7.6
The above posts were very helpful to guide me to my solution. I want to share in case someone else could use this:
First the development libs
sudo yum groupinstall "Development Tools" -ysudo yum install openssl11-devel libffi-devel bzip2-devel xz-devel -y- for static linking use
openssl11-static
- for static linking use
Then configure
So for some reason CentOS ships openssl1.1.1 but it is installed in a way that doesn't jive with Python's configure script.
# note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in
# an 'openssl' subdirectory
if ! $found; then
OPENSSL_INCLUDES=
for ssldir in $ssldirs; do
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl/ssl.h in $ssldir" >&5
$as_echo_n "checking for openssl/ssl.h in $ssldir... " >&6; }
if test -f "$ssldir/include/openssl/ssl.h"; then
OPENSSL_INCLUDES="-I$ssldir/include"
OPENSSL_LDFLAGS="-L$ssldir/lib"
OPENSSL_LIBS="-lssl -lcrypto"
Since Python is including headers a subfolder is desired: $ssldir/include/openssl/ssl.h
I just created a new folder with the correct layout:
/opt/openssl111/
├── include
│ └── openssl
│ └── *.h
└── lib
├── libcrypto.so
└── libssl.so
Once in place, the trifecta:
./configure --enable-optimizations --with-lto --with-openssl=/opt/openssl111/ltois link time optimization
make -j8make altinstall(installs in/usr/local/not to overwrite system python)
I've tried a few didnt online guides but nothing seems to be helping me achieve what I'm looking for. I have a Linux machine for my network environment that I use for automation. I'm trying to upgrade my python 3.6.8 to some version of 3.9.x. I want to remove python 3.6.8, install 3.9, and then put 3.9 as the default for every user on the box.
Current Version of Linux 3.10.0-1160.6.1.el7.x86_64
I'm not a linux pro but I know some things.
Is there any alternative way to install python 3.9 in Centos 7 instead of using source code (tar.gz/tgz)
On CentOS, how do I build Python 3.9 from source while incorporating my openssl module? - Stack Overflow
Problem installing Python 3.9 RPM with yum on Centos 7
centos7 - Is there any way to install Python 3.9 on Centos 7 without using source code (tar.gz/tgz)? - Stack Overflow
Videos
Python3.10 source build on CentOS 7.6
The above posts were very helpful to guide me to my solution. I want to share in case someone else could use this:
First the development libs
sudo yum groupinstall "Development Tools" -ysudo yum install openssl11-devel libffi-devel bzip2-devel xz-devel -y- for static linking use
openssl11-static
- for static linking use
Then configure
So for some reason CentOS ships openssl1.1.1 but it is installed in a way that doesn't jive with Python's configure script.
# note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in
# an 'openssl' subdirectory
if ! $found; then
OPENSSL_INCLUDES=
for ssldir in $ssldirs; do
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl/ssl.h in $ssldir" >&5
$as_echo_n "checking for openssl/ssl.h in $ssldir... " >&6; }
if test -f "$ssldir/include/openssl/ssl.h"; then
OPENSSL_INCLUDES="-I$ssldir/include"
OPENSSL_LDFLAGS="-L$ssldir/lib"
OPENSSL_LIBS="-lssl -lcrypto"
Since Python is including headers a subfolder is desired: $ssldir/include/openssl/ssl.h
I just created a new folder with the correct layout:
/opt/openssl111/
├── include
│ └── openssl
│ └── *.h
└── lib
├── libcrypto.so
└── libssl.so
Once in place, the trifecta:
./configure --enable-optimizations --with-lto --with-openssl=/opt/openssl111/ltois link time optimization
make -j8make altinstall(installs in/usr/local/not to overwrite system python)
When you compile Python, you need to tell it which OpenSSL headers and libraries to use.
First, install openssl11-devel:
sudo yum install --assumeyes openssl11-devel
Second, before running "./configure" set CFLAGS and LDFLAGS from the values emitted by pkg-config
export CFLAGS="$CFLAGS $(pkg-config --cflags openssl11)"
export LDFLAGS="$LDFLAGS $(pkg-config --libs openssl11)"
Third, configure and build as normal:
./configure --prefix=/some/where/dir
# ... etc ...
This is the most reliable way to get the correct flags passed to the compiler and linker. It's also worth checking that there aren't any conflicting values being passed into the CFLAGS / LDFLAGS environment variables, which might stymie your efforts.
This assumes that you have the openssl-devel package installed, obviously. :-)
... but not rpm. Which has left me stumped.
I built Python 3.9.16 from source, and then packaged that as an RPM (using Gradle ospackage library).
./configure
make
make altinstall DESTDIR=${PWD}/fakeroot
If I try to yum install on Centos 7.9, I get a whole load of errors relating to python(abi) and it ultimately refuses to install as there's a requirement to uninstall system Python 2.7.
But if I rpm -i the same file, it installs no problem.
Querying the RPM I built (rpm -qlvp) there are no references to /usr/bin/python.
Why's Yum finding blocking dependencies and rpm is not?
SOLVED: Error/ignorance on my part!
When creating the RPM package, the following fields must be set exactly so:
-
Name: python3
-
Release: n.el7 (where n can be incremented to force Yum to treat it as an upgrade version)
I had "python" and "1" respectively... which I suspect rpm ignores, but Yum uses to work out the dependency chain, and my values were too ambiguous.
Changing them to the values above allowed me to install via yum with no errors whatsoever (and completely unaffecting the system installation of Python).
You can safely install Python as a Local / Non-root user by executing the below code with the required Python Version defined in the variable "PYTHON_VER"
Note: This installs Python in your $HOME directory. You can modify the PATH if needed for a different installation location.
# Install Python3 and Libraries as a local user.
python_config() {
export PYTHON_VER="3.12.4"
export PYTHON_VER_SHORT="$(echo ${PYTHON_VER} | cut -d '.' -f1,2)"
export PYTHON_REQ="/tmp/requirements.txt"
cd ~
rm -rf ~/python && mkdir -p ~/python
echo "" >> ~/.bashrc
echo "export PATH=~/python/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
wget --quiet --no-check-certificate "https://www.python.org/ftp/python/${PYTHON_VER}/Python-${PYTHON_VER}.tgz"
tar -zxvf ~/Python-${PYTHON_VER}.tgz 1>/dev/null
cd ~/Python-${PYTHON_VER}/
echo "Python ${PYTHON_VER} - Installing in current logged-in user - $(whoami)"
echo "Python ${PYTHON_VER} - Installation in-progress. Please wait..."
./configure --enable-optimizations --prefix=$HOME/python > /dev/null 2>&1;
echo "Python ${PYTHON_VER} - ETA: upto 5mins. Please wait..."
make altinstall > /dev/null 2>&1;
ln -s ~/python/bin/python${PYTHON_VER_SHORT} ~/python/bin/python3
ln -s ~/python/bin/pip${PYTHON_VER_SHORT} ~/python/bin/pip3
# Install PIP3
wget --quiet --no-check-certificate https://bootstrap.pypa.io/get-pip.py -O - | python3 - --prefix=$HOME/python
source ~/.bashrc
~/python/bin/pip3 install --upgrade pip
~/python/bin/pip3 install --upgrade --no-cache-dir -r ${PYTHON_REQ} --use-pep517
cd ~ && rm -rf ~/Python-${PYTHON_VER}*
~/python/bin/python3 --version
~/python/bin/pip3 --version
echo "Python ${PYTHON_VER} - Setup Completed!"
}
# Function Call
python_config
Ubuntu 20.04 and later has the python3.9 package in its default repositories. It can be installed alongside the default python3.8 package with sudo apt update && sudo apt install python3.9 Installing the python3.9 package from the default Ubuntu repositories simplifies package management.
If you are using Ubuntu 20.04 keep Python 3.8 as the default Python 3.x version and switch to Python 3.9 only when necessary using update-alternatives. After you are done using Python 3.9 you can switch the it back to the default Python 3 version.
List installed versions of Python:
update-alternatives --list pythonSwitch between Python versions:
update-alternatives --config pythonFrom the terminal command-line Press <enter> to keep the current choice[*], or type selection number: