Compile & install 32 bit Python 2.7 on 64 bit CentOS 6.5

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

Note that 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.

wget [https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz](https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz)

Unzip it:

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:

cd Python-2.7.12

Create a folder for your Python installation:

mkdir /opt/python-2.7.12.i686

Configure the compile:

BASECFLAGS=-m32 LDFLAGS=-m32 CFLAGS=-m32 ./configure --prefix=/opt/python-2.7.12.i686 --enable-shared

The -prefix option allows you to install Python in a custom location (instead of /usr/local); --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:

make

Search any library if the make failed on some modules (though it should not happen). You can ignore bsddb185 and 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

The 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

Modify your LD_LIBRARY_PATH, add /opt/python-2.7.12.i686/lib to this environment variable:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/python-2.7.12.i686/lib

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.

REFERENCES

https://www.iram.fr/IRAMFR/GILDAS/doc/html/gildas-python-html/node36.html

http://shouro.blogspot.com/2013/07/compile-python27-on-centos-6.html

https://bugs.python.org/issue23042

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *