在64位CentOS 6.5系統上編譯安裝32位Python 2.7

本文的英文版:aresou.net/post/6/compi

也許你會遇到需要在CentOS上安裝一個不同於默認版本的Python的情況。比如,當你的Python程序用到的庫里只有32位編譯版本時,在沒有選擇的情況下,你必須為其安裝一個獨立的32位Python解釋器。接下來我會介紹一下如何在64位CentOS 6.5系統上編譯安裝32位Python 2.7.12。所有的操作都在一個全新安裝的CentOS上測試過。(AWS AMI: CentOS 6.5 x8664(HVM) - 20141008-0 - minimalinstall with cloud helpers plus Intel SRIOV (ami-4dc28f7d

首先,安裝編譯、開發所要用到的庫和工具:

sudo yum groupinstall "Development tools"

請注意,你可能會遇到錯誤,說"Group Development tools does notexist",一般這是你的系統沒有合適的repository造成的,不過在默認情況下,即使是最小安裝的CentOS也能順利找到這個包組。你也可以嘗試安裝EPEL等repository。另外,你的伺服器可能處於內網,這時就需要添加代理伺服器,否則yum將無法正常工作。

接下來,我們安裝編譯Python所需要的庫。由於我們要在64位系統上編譯32位的Python,所有的庫都必須安裝其32位的版本。在CentOS 6上,「名字.i686」就代表該庫的32位版本。

sudo yum install glibc-devel.i686 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

雖然tkinter會安裝libX11,卻不會安裝libX11-devel。現在我們可以到python.org去下載你想要的版本的Python源代碼。假設你將下載回來的包放在home目錄。

wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz

解壓:

unxz Python-2.7.12.tar.xztar xf Python-2.7.12.tar

好了,現在可以開始編譯。進入解壓出來的目錄:

cd Python-2.7.12

創建一個新目錄,用於放置這個新的Python:

mkdir /opt/python-2.7.12.i686

配置編譯器:

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

-prefix 可以讓你選擇一個不同於/usr/local的安裝目錄, --enable-shared 則告訴make,要同時編譯Python的動態與靜態庫。-m32標識會告訴編譯器,使用32位的庫。

還有一點需要注意的是,Python源文件中的ffi.c可能存在bug,編譯_ctype庫時會產生以下錯誤:

/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

出現這個錯誤時,_ctypes庫將無法成功編譯。搜索過後,我發現這是該文件中對於平台(32位或64位)判定的混淆所導致的。有高人在 https://bugs.python.org/issue23042給出了補丁文件。通讀文件中的差異,修正你自己那份Python源文件的邏輯即可。在我下載的Python 2.7.12中,只需要將678行附近的 #ifdef X86_WIN32 往上移至 else if(cif->abi == FFI_FASTCALL) 前面就行了。

編譯Python源文件:

make

有幾個庫可能仍然會提示不能成功編譯。不要緊,這些庫在絕大多數情況下不影響正常使用。 gist.github.com/reorx/4 提到了一些過時的、不再使用的庫:

  • 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 dont develop tkinter programs.

編譯成功後,將Python安裝至我們先前創建的目錄中:

make install altinstall

altinstall 選項會避免替換系統中原有的Python安裝。現在讓我們進入安裝目錄:

cd /opt/python-2.7.12.i686/bin./python

在啟動python時,你可能會碰到以下錯誤:

libpython2.7.so.1.0: cannot open shared object file: No such file or directory

為此,我們要修改 LD_LIBRARY_PATH 路徑,加上 /opt/python-2.7.12.i686/lib 到這個環境變數中:

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

為了在下次登陸時此修改仍然生效,你要將這行命令放進你的bash配置文件中,通常是 ~/.bashrc 。我也建議為新安裝的Python創建一個virtualenv,方便使用。

參考資料

iram.fr/IRAMFR/GILDAS/d

shouro.blogspot.com/201

bugs.python.org/issue23


推薦閱讀:

python如何生成一個日期列表?
新手如何快速學python
【Python3網路爬蟲開發實戰】4-解析庫的使用
Python-Numpy模塊where函數

TAG:Python | CentOS | 編譯 |