How to build, compile, and install the latest Python 3.11, 3.10, 3.9, 3.8, and 3.7 on Linux CentOS 7, 8, and 9

Do you want to install the latest Python 3.11.2 (resp. 3.10.10, 3.9.16, 3.8.16, or 3.7.16) on Linux CentOS 7, 8, or 9 and don’t want to break up the shipped Python?

You are in the right place.

I have for you a short tutorial on how to build, compile, and install Python 3.11, 3.10, 3.9, 3.8, or 3.7 on Linux CentOS 7 or 8 or 9 and run it without destroying the shipped Python in Centos.

Hint: At the end of the article, you’ll find the cheat sheet, a set of Bash commands that you can copy and paste into your Linux command line and run.

 

What we are going to solve

  • Update your CentOS box and install the needed developer libraries and tools.
  • Download and unpack the latest Python source code.
  • Compile the Python source code.
  • Install Python source code and perform some post-installation tasks to make it easier to use in the Bash command line.
  • Look for Python binaries that have been created.
  • Create and test the Python virtual environment.

At the time of writing this post, Python 3.10.10 (resp. 3.9.16, 3.8.16, or 3.7.16) is the most current stable version of the language, and the most used version in CentOS is version 8, the newest one being version 9. CentOS 8 is shipped with Python 3.6, and CentOS 9 is shipped with Python 3.8.

 


Prerequisites

You will need a functional Linux CentOS 7, 8, or 9 machine, access to the root account, and of course an internet connection.
All of the steps can be completed as a non-root user, but with the help of the sudo command.

 

Step 1: Prepare CentOS for Python compilation.

It is a good idea to have an up-to-date operating system before you start doing anything else. Let’s update your CentOS with the yum command.

sudo yum -y update

You also need some necessary libraries and developer tools to allow you to build and compile software from source code. I chose the minimal amount of packages; those are included in CentOS as well. To install them, use the yum libraries and developer tools to allow you to build and compile software from source code. I chose the minimal amount of packages; those are included in CentOS as well. To install them, use the yum command again.

sudo yum -y install wget yum-utils gcc openssl-devel bzip2-devel libffi-devel

 

Step 2: Download and unpack the Python source code.

We download the source code of the latest Python from the official Python page: https://www.python.org/ftp/python/ and extract Python-3.11.2.tgz to the /tmp directory.

To do that, perform this set of bash commands.

cd /tmp/
wget https://www.python.org/ftp/python/3.11.2/Python-3.11.2.tgz
tar xzf Python-3.11.2.tgz
cd Python-3.11.2

 

Step 3: Compile the Python source code into binaries.

At the moment, we have everything ready for compiling the actual Python source code.

We are going to use the switch --prefix=/opt/python311 to set the root directory for all Python binaries and libraries. Of course, you can choose a folder according to your needs.  For better performance we are going to use a switch --enable-optimizations  for enabling PGO (profile guided optimisation) and so yielding an extra speed boost of Python binaries around 5-10%.

The command make -j "nproc" will ensure the use of all of your CPU cores and will decrease compile time, and the command make altinstall is critical because it preserves the default shipped Python binary /usr/bin/python.

HINT: To get the number of CPU cores in your Linux CentOS box, use these Bash commands: grep "cpu cores" /proc/cpuinfo or nproc.

Now you have two options. How to compile Python: with static libraries or shared libraries? If you don’t know which way to go, then use option a).

Depending on the number of CPU cores, the compilation will take a few minutes.

 

a) compile Python source with STATIC libraries – almost in all of your cases, or if you don´t know, use this option.

sudo ./configure --prefix=/opt/python311 --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions
sudo make -j "$(nproc)"
sudo make altinstall

b) compile Python source with SHARED libraries – you should know why you want this option otherwise use option a).

sudo ./configure --prefix=/opt/python311 --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions --enable-shared LDFLAGS=\"-Wl,-rpath /usr/local/lib\"
sudo make -j "$(nproc)"
sudo make altinstall
ldconfig

We already won’t need the Python source code tarball, so let’s delete it.

sudo rm /tmp/Python-3.11.2.tgz

 

Step 4: Make post-install stuff.

We are going to make some symbolic links that are expected to exist for convenient Python usage.

sudo ln -s /opt/python311/bin/python3.11 /opt/python311/bin/python3
sudo ln -s /opt/python311/bin/python3.11 /usr/bin/python311
sudo ln -s /opt/python311/bin/python3.10 /opt/python311/bin/python
sudo ln -s /opt/python311/bin/python3.11-config /opt/python311/bin/python-config
sudo ln -s /opt/python311/bin/pydoc3.11 /opt/python311/bin/pydoc
sudo ln -s /opt/python311/bin/idle3.11 /opt/python311/bin/idle

We are also going to add some symbolic links for the pip binary.

sudo ln -s /opt/python311/bin/pip3.11 /opt/python311/bin/pip3
sudo ln -s /opt/python311/bin/pip3.11 /opt/python311/bin/pip

 

Step 5: Checking Python binaries

The Python interpreter is located at /opt/python311/bin/ after installation.

Let’s do some tests of Python binaries by typing:

/opt/python311/bin/pip -V
>>> pip 22.3 from /opt/python311/lib/python3.11/site-packages/pip (python 3.11.2)

/opt/python311/bin/python -V
>>> Python 3.11.2

which python311
>>> /usr/bin/python311

/usr/bin/python311 -V
>>> Python 3.11.2

/opt/python311/bin/python3.11-config --prefix
>>> /opt/python311

# test out shipped Python 2.x whether it still ok
/usr/bin/python -V
>>> Python 2.7.5

 

Step 6: Setting up the Python virtual environment (venv)

Nowadays, Python’s virtual environment is a great tool and almost necessary for every Python project. It enables you to have more isolated Python spaces on one Linux box. Each Python project has its own set of dependencies and modules.

You can set up as many Python programming environments as you want. Each of them is basically a directory that includes a few scripts and binaries, e.g., Python or Pip.

So let us make one.

sudo /opt/python311/bin/python -m venv /home/hanz/mydjango.cz/env

ls -l /home/hanz/mydjango.eu/env
>>> total 16
>>> drwxr-xr-x 2 root root 4096 Nov  3 18:30 bin
>>> drwxr-xr-x 2 root root 4096 Nov  3 18:30 include
>>> drwxr-xr-x 3 root root 4096 Nov  3 18:30 lib
>>> lrwxrwxrwx 1 root root    3 Nov  3 18:30 lib64 -> lib
>>> -rw-r--r-- 1 root root   78 Nov  3 18:30 pyvenv.cfg

Now that we have the environment created, we have to activate it with the command source /home/hanz/mydjango.cz/env/bin/activate. We will again check Python binaries and run a small inline program, “Hello, World!” The command deactivate will disable the Python environment and restore the shipped Python to our Linux machine.

source /home/hanz/mydjango.cz/env/bin/activate
>>> (env) [hanz@mydjango_cz /]#

(env) [hanz@mydjango_cz /]# pip -V
>>> pip 22.3 from /home/mydjango.cz/env/lib/python3.11/site-packages/pip (python 3.11)
>>> (env) [hanz@mydjango_cz /]#

(env) [hanz@mydjango_cz /]# python -c 'print("Hello, World!")'
>>> (env) [hanz@mydjango_cz /]# Hello, World!

(env) [hanz@mydjango_cz /]# deactivate
>>> [hanz@mydjango_cz /]#

Conclusion

Congratulations!
At this point, you have installed the latest versions of Python (Python 3.11.2, Python 3.10.10, Python 3.9.16, Python 3.8.16, and Python 3.7.16) on your local CentOS machine and for example you can start coding any project with my favorite web framework, Django. Check out my tutorial for setting up a Django runtime environment built on a Nginx web server and a uWSGI Python gateway.

I hope this guide will help you, and if you have any tips for improvements or find a mistake, let me know.

Enjoy!
Hanz


Copy and paste this cheatsheet to install the most recent Python 3.11, 3.10, 3.9, 3.8, or 3.7 on Linux, CentOS 7, 8, and 9.

Just choose your desired version of Python, copy and paste it into your Linux Bash command line and have a cup of coffee. All of this is going to be finished in a few minutes.

INFO: Don’t worry about the shipped Python; it is going to be operational as is.

Installing Python 3.11.2 to the directory /opt/python310

cd /tmp/;
wget https://www.python.org/ftp/python/3.11.2/Python-3.11.2.tgz;
tar xzf Python-3.11.2;

cd Python-3.11.2;
sudo ./configure --prefix=/opt/python310 --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions;
sudo make -j $(nproc);
sudo make altinstall;

sudo rm /tmp/Python-3.11.2.tgz;

# add symbolic links
sudo ln -s /opt/python311/bin/python3.11 /opt/python311/bin/python3;
sudo ln -s /opt/python311/bin/python3.11 /opt/python311/bin/python;
sudo ln -s /opt/python311/bin/python3.11-config /opt/python311/bin/python-config;
sudo ln -s /opt/python311/bin/pydoc3.11 /opt/python311/bin/pydoc;
sudo ln -s /opt/python311/bin/idle3.11 /opt/python311/bin/idle;
sudo ln -s /opt/python311/bin/python3.11 /usr/bin/python311;
sudo ln -s /opt/python311/bin/pip3.11 /opt/python311/bin/pip3;
sudo ln -s /opt/python311/bin/pip3.11 /opt/python311/bin/pip;

Installing Python 3.10.10 to the directory /opt/python310

cd /tmp/;
wget https://www.python.org/ftp/python/3.10.10/Python-3.10.10.tgz;
tar xzf Python-3.10.10;

cd Python-3.10.10;
sudo ./configure --prefix=/opt/python310 --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions;
sudo make -j $(nproc);
sudo make altinstall;

sudo rm /tmp/Python-3.10.10.tgz;

# add symbolic links
sudo ln -s /opt/python310/bin/python3.10 /opt/python310/bin/python3;
sudo ln -s /opt/python310/bin/python3.10 /opt/python310/bin/python;
sudo ln -s /opt/python310/bin/python3.10-config /opt/python310/bin/python-config;
sudo ln -s /opt/python310/bin/pydoc3.10 /opt/python310/bin/pydoc;
sudo ln -s /opt/python310/bin/idle3.10 /opt/python310/bin/idle;
sudo ln -s /opt/python310/bin/python3.10 /usr/bin/python310;
sudo ln -s /opt/python310/bin/pip3.10 /opt/python310/bin/pip3;
sudo ln -s /opt/python310/bin/pip3.10 /opt/python310/bin/pip;

Installing Python 3.9.16 to the directory /opt/python39

cd /tmp/;
wget https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tgz;
tar xzf Python-3.9.16.tgz;

cd Python-3.9.16;
sudo ./configure --prefix=/opt/python39 --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions;
sudo make -j $(nproc);
sudo make altinstall;

sudo rm /tmp/Python-3.9.16.tgz;

# add symbolic links
sudo ln -s /opt/python39/bin/python3.9 /opt/python39/bin/python3;
sudo ln -s /opt/python39/bin/python3.9 /opt/python39/bin/python;
sudo ln -s /opt/python39/bin/python3.9-config /opt/python39/bin/python-config;
sudo ln -s /opt/python39/bin/pydoc3.9 /opt/python39/bin/pydoc;
sudo ln -s /opt/python39/bin/idle3.9 /opt/python39/bin/idle;
sudo ln -s /opt/python39/bin/python3.9 /usr/bin/python39;
sudo ln -s /opt/python39/bin/pip3.9 /opt/python39/bin/pip3;
sudo ln -s /opt/python39/bin/pip3.9 /opt/python39/bin/pip;

Installing Python 3.8.16 to the directory /opt/python38

cd /tmp/;
wget https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tgz;
tar xzf Python-3.8.16.tgz;

cd Python-3.8.16;
sudo ./configure --prefix=/opt/python38 --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions;
sudo make -j $(nproc);
sudo make altinstall;

sudo rm /tmp/Python-3.8.16.tgz;

# add symbolic links
sudo ln -s /opt/python38/bin/python3.8 /opt/python38/bin/python3;
sudo ln -s /opt/python38/bin/python3.8 /opt/python38/bin/python;
sudo ln -s /opt/python38/bin/python3.8-config /opt/python38/bin/python-config;
sudo ln -s /opt/python38/bin/pydoc3.8 /opt/python38/bin/pydoc;
sudo ln -s /opt/python38/bin/idle3.8 /opt/python38/bin/idle;
sudo ln -s /opt/python38/bin/python3.8 /usr/bin/python38;
sudo ln -s /opt/python38/bin/pip3.8 /opt/python38/bin/pip3;
sudo ln -s /opt/python38/bin/pip3.8 /opt/python38/bin/pip;

Installing Python 3.7.16 to the directory /opt/python37

cd /tmp/;
wget https://www.python.org/ftp/python/3.7.16/Python-3.7.16.tgz;
tar xzf Python-3.7.16.tgz;

cd Python-3.7.16;
sudo ./configure --prefix=/opt/python37 --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions;
sudo make -j $(nproc);
sudo make altinstall;

sudo rm /tmp/Python-3.7.16.tgz;

# add symbolic links
sudo ln -s /opt/python37/bin/python3.7 /opt/python37/bin/python3;
sudo ln -s /opt/python37/bin/python3.7 /opt/python37/bin/python;
sudo ln -s /opt/python37/bin/python3.7-config /opt/python37/bin/python-config;
sudo ln -s /opt/python37/bin/pydoc3.7 /opt/python37/bin/pydoc;
sudo ln -s /opt/python37/bin/idle3.7 /opt/python37/bin/idle;
sudo ln -s /opt/python37/bin/python3.7 /usr/bin/python37;
sudo ln -s /opt/python37/bin/pip3.7 /opt/python37/bin/pip3;
sudo ln -s /opt/python37/bin/pip3.7 /opt/python37/bin/pip;

18 thoughts on “How to build, compile, and install the latest Python 3.11, 3.10, 3.9, 3.8, and 3.7 on Linux CentOS 7, 8, and 9”

  1. This is sad… Python was a first class citizen on Linux, and now Windows has a newer version of python prepackaged, while we need to compile latest python on Linux…

  2. How do I also install python3.x-devel so I can build and link C/C++ modules?

    • Hi,
      you can get all your needs with command

      "/opt/python39/bin/python3.9-config --help"

      e.g. try to run

      "/opt/python39/bin/python3.9-config --includes"

      Hope it helps.
      Hanz

  3. I follow the steps to install 3.9b1

    I have:
    root@192 /h/h/A/Python-3.9# sqlite3
    SQLite version 3.26.0 2018-12-01 12:34:55
    Enter “.help” for usage hints.
    Connected to a transient in-memory database.
    Use “.open FILENAME” to reopen on a persistent database.

    Got this error:

    Traceback (most recent call last):
    File “/media/test.py”, line 2, in
    import sqlite3
    File “/opt/python39/lib/python3.9/sqlite3/__init__.py”, line 23, in
    from sqlite3.dbapi2 import *
    File “/opt/python39/lib/python3.9/sqlite3/dbapi2.py”, line 27, in
    from _sqlite3 import *
    ModuleNotFoundError: No module named ‘_sqlite3’

    • Hello,
      before Python compilation you have to install SQlite into your Linux box.
      I hope that helps.
      Hanz

  4. I followed all the steps to install Python 3.7.7 onto my Centos 8 server machine. However when I type python3 -V it returns “Command not found”.

    Any ideas what is missing, steps 5 and 6 all work?

    • Hi,
      there is no python3 in my howto. You can fix it with another simlink

      "sudo ln -s /opt/python37/bin/python3.7 /usr/bin/python3;"

      Hanz

  5. Hi Hanz.

    Now that was really useful.
    It worked within some minutes (compiling does take some time)

    Thanks.
    Andy

  6. Hello,

    I followed the steps to configure python3.8 on my machine and ran into this error:
    sudo: unable to execute ./configure: Permission denied

    Can someone help me fix thus error ?

    • Hello,
      you have to own the execution permission in the script ” ./configure” , you can try something like chmod 777 -R /tmp/python-3.8.2 before run the script.
      I houpe that it helps you.
      Hanz

    • Cool. That is good one. When i have a time, I am going to incorporate a few goods ideas from your script to my page. Thanks.

  7. That’s great! Thanks for sharing!

    I think it’s awesome when I find a guide like this with this kind of details.

    One thing, to future: If I want to remove (uninstall), I just need to remove the symbolic links and the installation folder in /opt/ ?

  8. Hi,
    Thanks for guide, but I have some problem.
    I already have python 2.7 and 3.4
    I wanted to install 3.8 in my /opt/python38
    I followed your guide, but I cannot use pip in any way:
    WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
    I don’t have this problem with other python and I already had all the libraries for ssl installed (updated) before the configure.
    What’s wrong?
    Thanks

    • Hi,
      to compile Python with ssl support you have to installed in your Linux box openssl devel libraries “yum install openssl-devel openssl-static” before the compilation.
      I houpe that it helps you.
      Hanz

Comments are closed.