本文记录在 Linux 上源码编译安装 python 的过程.
安装过程比我想象的复杂得多,即使多线程编译也很费时. 在设置安装选项环节有很多没有调查清楚.
如果仅仅是学习和研究,使用包管理工具安装最好,省时省力. 例如 Ubuntu 下安装 python.
在 Linux 平台上源码安装 Python 需要先安装编译工具和相关库文件.
例如,在 Ubuntu 上安装依赖库:
sudo apt-get install gcc make zlib1g-dev
sudo apt-get install libbz2-dev
sudo apt-get install libsqlite3-dev
sudo apt-get install python3-dev libxml2-dev libffi-dev libssl-dev libxslt1-dev
本文以 python2.7.18 为例.
1. 下载 Python-2.7.18.tgz
源码压缩包
cd Downloads
wget -c https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
2. 解压缩
tar -xzvf Python-2.7.18.tgz
3. 进入源码目录
cd Python-2.7.18
4. 建立安装目录
sudo mkdir /usr/local/pyton2.7.18
5. 生成 Makefile 文件
./configure --enable-optimizations --prefix=/usr/local/python2.7.18/
--enable-optimizations
:最优安装--prefix
:指定安装路径. 第4步中建立的目录.6. 修改 Modules/Setup
文件
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto
安装 ssl 依赖库
sudo apt-get install libssl-dev
缺少 ssl 依赖库会导致如下错误:
./Modules/_ssl.c:69:25: fatal error: openssl/rsa.h: No such file or directory
7. 编译
sudo make -j4
-j4
表示多线程编译,如果 8 核可以使用 -j8
.sudo make
得到编译结果 python-2.7.18/python
.8. 安装
sudo make install
--prefix
指定的目录. 如果不指定安装目录,默认安装到 /usr/local/bin/
下.9. 设置软链接
建立安装路径下的 python 可执行文件到 /usr/bin
目录的软连接
sudo ln -s /usr/local/python2.7.18/bin/python2.7 /usr/bin/python2.7.18
本文以 python3.6.10 为例.
1. 下载 Python-3.6.10.tgz
源码压缩包
cd Downloads
wget -c https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tgz
2. 解压缩
tar -xzvf Python-3.6.10.tgz
3. 进入源码目录
cd Python-3.6.10
4. 建立安装目录
sudo mkdir /usr/local/python3.6.10
5. 生成 Makefile 文件
编辑 Python-3.6.10/Modules/Setup.dist
文件. 去掉第270、272、274、276、289、291 和 299 的注释. 并将第 289 行修改为 -ltk8.6 -ltcl8.6 \
,默认是8.2. 这是为了编译 tinker 库,需要先安装 tcl 和 tk.
# *** Always uncomment this (leave the leading underscore in!):
_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
-L/usr/local/lib \
# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
-I/usr/local/include \
# *** Uncomment and edit to reflect where your X11 header files are:
-I/usr/X11R6/include \
# *** Or uncomment this for Solaris:
# -I/usr/openwin/include \
# *** Uncomment and edit for Tix extension only:
# -DWITH_TIX -ltix8.1.8.2 \
# *** Uncomment and edit for BLT extension only:
# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
# *** Uncomment and edit for PIL (TkImaging) extension only:
# (See http://www.pythonware.com/products/pil/ for more info)
# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
# *** Uncomment and edit for TOGL extension only:
# -DWITH_TOGL togl.c \
# *** Uncomment and edit to reflect your Tcl/Tk versions:
-ltk8.6 -ltcl8.6 \
# *** Uncomment and edit to reflect where your X11 libraries are:
-L/usr/X11R6/lib \
# *** Or uncomment this for Solaris:
# -L/usr/openwin/lib \
# *** Uncomment these for TOGL extension only:
# -lGL -lGLU -lXext -lXmu \
# *** Uncomment for AIX:
# -lld \
# *** Always uncomment this; X11 libraries to link with:
-lX11
保存退出
设置共享库环境变量
export LD_LIBRARY_PATH=/usr/local/lib
./configure --enable-optimizations --prefix=/usr/local/python3.6.10/ --enable-shared CFLAGS=-fPIC
--enable-optimizations
:最优安装--prefix
:指定安装路径. 第4步中建立的目录.--enable-shared
:启用共享库,需要设置环境变量 LD_LIBRARY_PATH
. 可以编译动态链接库.CFLAGS=-fPIC
:作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行. 这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的.补充一下:这里加上
--enable-shared
和-fPIC
之后可以将python3的动态链接库编译出来,默认情况编译完lib下面只有python3.xm.a这样的文件,python本身可以正常使用,但是如果编译第三方库需要python接口的比如caffe等,则会报错;所以这里建议按照上面的方式配置.
如果共享库设置不对, 则不要使用上述两个选项. 但是编译得到的结果讲无法使用很多库文件.
6. 编译
sudo make -j4
-j4
表示多线程编译,如果 8 核可以使用 -j8
.sudo make
得到编译结果 python-3.6.10/python
.7. 安装
sudo make install
--prefix
指定的目录. 如果不指定安装目录,默认安装到 /usr/local/bin/
下.如果遇到下列错误,表缺少 lsb_release.py
文件,但是 python3.6 还是安装成功的
subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1.
将系统中自带的 lsb_release.py
复制到相关路径即可
sudo cp /usr/share/pyshared/lsb_release.py /usr/local/python3.6.10/lib/python3.6/lsb_release.py
8. 设置软链接
建立安装路径下的 python 可执行文件到 /usr/bin
目录的软连接
sudo ln -s /usr/local/python3.6.10/bin/python3.6 /usr/bin/python3.6