You might want to compile a version of Python other than shipped one on your CentOS system. For example, running a Python script using a library that only has a 32bit build. Here are the steps on how to compile & install Python 2.7.12 from source code on CentOS 6.5. All operations tested on a clean CentOS 6.5 (AWS AMI: CentOS 6.5 x86_64(HVM) — 20141008–0 — minimal install with cloud helpers plus Intel SRIOV (ami-4dc28f7d))
Firstly, prepare your system for development and compilation:
sudo yum groupinstall "Development tools"
Please note that you might receive “Group Development tools does not exist” warning if you don’t have proper repositories. Try to install EPEL, CentOS-base or other necessary repositories. Also remember to setup proxies on if your server is in an internal network, otherwise
yum will not work to get external resources.
Then, install the libraries required for compiling Python. As we are compiling a 32bit application on a 64bit system, we need to grab 32bit version of all these libraries. On CentOS 6, append ‘.i686’ to the package name for 32bit versions.
sudo yum install glibc-devel.i686 glibc-devel zlib-devel.i686 bzip2-devel.i686 openssl-devel.i686 ncurses-devel.i686 sqlite-devel.i686 readline-devel.i686 tk-devel.i686 gdbm-devel.i686 db4-devel.i686 libX11-devel.i686
libX11 library will be installed by
tkinter but not
libX11-devel, so we have to install it separately. Now download satisfied version of Python from python.org. Let’s say put it in your home directory.
unxz Python-2.7.12.tar.xz tar xf Python-2.7.12.tar
OK, we are set to start the compilation process. Change directory:
Create a folder for your Python installation:
Configure the compile:
BASECFLAGS=-m32 LDFLAGS=-m32 CFLAGS=-m32 ./configure --prefix=/opt/python-2.7.12.i686 --enable-shared
-prefix option allows you to install Python in a custom location (instead of
--enable-shared option tells
make to build both static and dynamic Python libraries. The
-m32 flags tells the compiler to use 32bit libraries for building. By default, gcc will use 64bit libraries on a 64bit platform.
Make the Python source files:
Search any library if the
make failed on some modules (though it should not happen). You can ignore
sunaudiodev if you don’t need them. But other modules should be built for a complete functioning Python installation. From https://gist.github.com/reorx/4067217 we know these libraries are undocumented or deprecated:
bsddb185: Older version of Oracle Berkeley DB. Undocumented. Install version 4.8 instead.
dl: For 32-bit machines. Deprecated. Use ctypes instead.
imageop: For 32-bit machines. Deprecated. Use PIL instead.
sunaudiodev: For Sun hardware. Deprecated.
_tkinter: For tkinter graphy library, unnecessary if you don’t develop tkinter programs.
Another consideraion is, there a bug in ffi.c in Python source code. When I was compiling, make returned an error message like this:
/opt/python-3.4.2/Python-3.4.2/Modules/_ctypes/libffi/src/x86/ffi.c:679: undefined reference to `ffi_closure_FASTCALL' /usr/bin/ld: build/temp.linux-x86_64-3.4/opt/python-3.4.2/Python-3.4.2/Modules/_ctypes/libffi/src/x86/ffi.o: relocation R_386_GOTOFF against undefined hidden symbol `ffi_closure_FASTCALL' can not be used when making a shared object
This will prevent you from successfully building
_ctypes module. Through a little bit search, I found out this is caused by the mixed definition of calls for different platforms (x86 and x64). Some awesome guys provided a patch at https://bugs.python.org/issue23042. Read through the patch file (https://bugs.python.org/file39321/ffi.patch) and fix the logic in your
ffi.c. In my case, I just need to move one line of
#ifdef X86_WIN32 upper, before the line
else if (cif->abi == FFI_FASTCALL) near line 678.
After make is succeed, install Python binary into the folder we created before:
make install altinstall
altinstall option make sure the new installation will not replace the current version shipped with your system. Now let’s head to the installation folder and run the new built Python:
cd /opt/python-2.7.12.i686/bin ./python
You might encounter this error message when starting up:
libpython2.7.so.1.0: cannot open shared object file: No such file or directory
/opt/python-2.7.12.i686/lib to this environment variable:
You will want to save this export statement into your own bash configure file (usually
~/.bashrc) to make the change permanent. I also suggest to create a virtualenv for the new Python installation for further use.