在Ubuntu 16.04.3 LTS上安裝Python 3.6.3的脫坑指南
心血來潮,想要裝一個Python+Tensorflow玩一玩,於是從官網下了一個Python3.6.3的源代碼包,解壓,configure,make,make install,一切正常.
直到pip3 install tensorflow-gpu,出錯了.
Collecting tensorflow-gpu Could not fetch URL https://pypi.python.org/simple/tensorflow-gpu/: There was a problem confirming the ssl certificate: Cant connect to HTTPS URL because the SSL module is not available. - skipping
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
最坑的是,StackOverflow到處都是錯誤的教程,不外乎讓你安裝libssl-dev,或者是在CentOS 下面安裝openssl-devel,或者修改Setup. 本人親測,這種方法對於標題所述的環境(再加上openssl 1.1.0g)沒有作用. 後來經過一晚上的debug,四方尋找,終於從各種信息中拼湊出合適的方案.
直接debug pip.main(["install","tensorflow-gpu"])的執行過程,終於找到了關鍵的代碼:
# If we dont have TLS enabled, then WARN if anyplace were lookingn# relies on TLS.nif not HAS_TLS:n for link in itertools.chain(self.index_urls, self.find_links):n parsed = urllib_parse.urlparse(link)n if parsed.scheme == "https":n logger.warning(n "pip is configured with locations that require "n "TLS/SSL, however the ssl module in Python is not "n "available."n )n breakn
而HAS_LTS的定義是
try:n import ssl # noqan HAS_TLS = Truenexcept ImportError:n HAS_TLS = Falsen
於是我手動執行import ssl,果然出錯了
Traceback (most recent call last):n import ssln File "/.../ssl.py", line 97, in <module>n import _ssl # if we cant import it, let the error propagatenImportError: No module named _ssl n
原來是沒有安裝_ssl模塊.但是如何安裝呢?網上有教程說看源代碼的根目錄下面的Setup.py文件.於是,裡面有這麼幾行:
# Detect SSL support for the socket module (via _ssl)n search_for_ssl_incs_in = [n /usr/local/ssl/include,n /usr/contrib/ssl/include/n ]n ssl_incs = find_file(openssl/ssl.h, inc_dirs,n search_for_ssl_incs_inn )n if ssl_incs is not None:n krb5_h = find_file(krb5.h, inc_dirs,n [/usr/kerberos/include])n if krb5_h:n ssl_incs += krb5_hn ssl_libs = find_library_file(self.compiler, ssl, lib_dirs,n [/usr/local/ssl/lib,n /usr/contrib/ssl/lib/,n ])nn if (ssl_incs is not None andn ssl_libs is not None):n exts.append(Extension(_ssl, [_ssl.c],n include_dirs=ssl_incs,n library_dirs=ssl_libs,n libraries=[ssl, crypto],n depends=[socketmodule.h]), )n else:n missing.append(_ssl)n
去/usr/local/ssl下面找了一下,根本沒有include這個文件夾.問題很有可能出在這裡.我又去翻了openssl的readme,裡面是這麼說的:
4. If everything tests ok, install OpenSSL with
$ make install # Unix $ mms install ! OpenVMS $ nmake install # Windows This will install all the software components in this directorytree under PREFIX (the directory given with --prefix or its
default): Unix: bin/ Contains the openssl binary and a few other utility scripts. include/openssl Contains the header files needed if you want to build your own programs that use libcrypto or libssl. lib Contains the OpenSSL library files.lib/engines Contains the OpenSSL dynamically loadable engines.
......
所以說include應該在/usr/local/include或者/usr/include裡面.於是,往search_for_ssl_incs_in裡面加一個/usr/include或者/usr/local/include(前者是系統自帶的openssl的地址),然後按照其他教程的說法把Python-3.6.3/Modules/Setup裡面的這麼幾行的注釋去掉:(按下面所示的這樣修改代碼)
# Socket module helper for socket(2)
_socket socketmodule.c# Socket module helper for SSL support; you must comment out the other# socket line above, and possibly edit the SSL variable:SSL=/usr/local/ssl_ssl _ssl.c t-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl t-L$(SSL)/lib -lssl -lcrypto
重新make&&sudo make install,之後檢查import ssl是否報錯,如果不報錯應該就能正常使用pip了.(撒花)
至於問我為什麼不用系統自帶的Python 2.7的話,我只有說,我就是看不慣Python 2,來打我呀
另外,Ubuntu 的repo裡面貌似只到Python 3.5....
附教程:
用Python-3.6.3表示源代碼所在的根目錄,首先修改Python-3.6.3/setup.py,將相關部分的代碼改成下面這樣:
search_for_ssl_incs_in = [n /usr/local/ssl/include,n /usr/contrib/ssl/include/,n /usr/local/include,n /usr/includen ]n
然後cd Python-3.6.3,運行
./configure --enable-optimizations --enable-ipv6n
然後修改Python-3.6.3/Modules/Setup,將相關部分改成下面這樣:
# Socket module helper for socket(2)
_socket socketmodule.c# Socket module helper for SSL support; you must comment out the other# socket line above, and possibly edit the SSL variable:
SSL=/usr/local/ssl_ssl _ssl.c t-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl t-L$(SSL)/lib -lssl -lcrypto
然後make.在make的輸出之中如果能夠看到
The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:_socket _ssl atexit pwd time
說明_ssl模塊一定是被成功編譯了的,之後sudo make install,親測有效.
然後如果想要換安裝的DIR和PREFIX,可自便.
然後就能開心的用pip了.不用pip自己手動安裝module實在是很頭疼...
推薦閱讀:
※有沒有中英文均有,且有字重和斜體的等寬字體?
※OO 的設計理念對 Python 來說是重點嗎?
※NBA首次舉辦編程馬拉松,深度數據已成球隊新寵
※如何評價 2015 年 CCPC ?
TAG:编程 | Python | ubuntu1604 |