これは、なにをしたくて書いたもの?
Pythonは、Linux OSであれば最初からインストールされていたり、比較的新しいバージョンもインストールできたりは
するのですが。
最新かというとそうでもないことが多く、それでも新しいバージョンを使いたい場合はDockerイメージを使うか、
自分でインストールすることになるのではないでしょうか。
環境
今回の環境は、こちらです。Ubuntu Linux 20.04 LTS。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.2 LTS Release: 20.04 Codename: focal $ uname -srvmpio Linux 5.4.0-73-generic #82-Ubuntu SMP Wed Apr 14 17:39:42 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
インストールされているPython 3のバージョンは、こちらです。
$ python3 -V Python 3.8.5
Pythonのコンパイルオプションを確認する
sysconfigというパッケージから取得できるようです。
Python の配布物は、Python 自体のバイナリや、distutils によってコンパイルされる外部の C 拡張をビルドするために必要な、Makefile と pyconfig.h ヘッダーファイルを含んでいます。
sysconfig はこれらのファイルに含まれるすべての変数を辞書に格納し、get_config_vars() や get_config_var() でアクセスできるようにします。
sysconfig --- Python の構成情報にアクセスする — Python 3.8.10 ドキュメント
スクリプトとして動かせるようなので、まずはこちらを試してみましょう。
$ python3 -m sysconfig
実行すると、なにやらたくさん表示されます。
Platform: "linux-x86_64" Python version: "3.8" Current installation scheme: "posix_prefix" Paths: data = "/usr" include = "/usr/include/python3.8" platinclude = "/usr/include/python3.8" platlib = "/usr/lib/python3.8/site-packages" platstdlib = "/usr/lib/python3.8" purelib = "/usr/lib/python3.8/site-packages" scripts = "/usr/bin" stdlib = "/usr/lib/python3.8" Variables: ABIFLAGS = "" AC_APPLE_UNIVERSAL_BUILD = "0" AIX_GENUINE_CPLUSPLUS = "0" ALT_SOABI = "0" ANDROID_API_LEVEL = "0" AR = "x86_64-linux-gnu-gcc-ar" ARFLAGS = "rcs" BASECFLAGS = "-Wno-unused-result -Wsign-compare" BASECPPFLAGS = "-IObjects -IInclude -IPython" BASEMODLIBS = "" 〜省略〜
コンパイルオプションまわりは、このあたりですね。特にCONFIG_ARGS
を見るのが良さそうです。
CC = "x86_64-linux-gnu-gcc -pthread" CCSHARED = "-fPIC" CFLAGS = "-Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 " CFLAGSFORSHARED = "-fPIC" CFLAGS_ALIASING = "" CFLAGS_NODIST = "" CONFIGFILES = "configure configure.ac acconfig.h pyconfig.h.in Makefile.pre.in" CONFIGURE_CFLAGS = "-g -fstack-protector-strong -Wformat -Werror=format-security" CONFIGURE_CFLAGS_NODIST = "-std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration" CONFIGURE_CPPFLAGS = "-Wdate-time -D_FORTIFY_SOURCE=2" CONFIGURE_LDFLAGS = "-Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 " CONFIGURE_LDFLAGS_NODIST = "" CONFIG_ARGS = "'--enable-shared' '--prefix=/usr' '--enable-ipv6' '--enable-loadable-sqlite-extensions' '--with-dbmliborder=bdb:gdbm' '--with-computed-gotos' '--without-ensurepip' '--with-system-expat' '--with-system-libmpdec' '--with-dtrace' '--with-system-ffi' 'CC=x86_64-linux-gnu-gcc' 'CFLAGS=-g -fstack-protector-strong -Wformat -Werror=format-security ' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 ' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'" CONFINCLUDEDIR = "/usr/include" CONFINCLUDEPY = "/usr/include/python3.8"
sysconfigをスクリプトとして実行した時に表示されているのは、get_platform
、get_python_version
、_get_default_scheme
、
get_paths
、get_config_vars
です。
https://github.com/python/cpython/blob/v3.8.5/Lib/sysconfig.py#L696-L707
構成情報はget_config_vars
もしくはget_config_var
を使って取得するので、大量に表示されているのはget_config_vars
の
情報になりますね。
インタプリターでも試してみましょう。
$ python3 Python 3.8.5 (default, Jan 27 2021, 15:41:15) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
こんな感じですね。
>>> import sysconfig >>> print(sysconfig.get_config_var('CONFIG_ARGS')) '--enable-shared' '--prefix=/usr' '--enable-ipv6' '--enable-loadable-sqlite-extensions' '--with-dbmliborder=bdb:gdbm' '--with-computed-gotos' '--without-ensurepip' '--with-system-expat' '--with-system-libmpdec' '--with-dtrace' '--with-system-ffi' 'CC=x86_64-linux-gnu-gcc' 'CFLAGS=-g -fstack-protector-strong -Wformat -Werror=format-security ' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 ' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
One Linerでも。
$ python3 -c 'import sysconfig; print(sysconfig.get_config_var("CONFIG_ARGS"))' '--enable-shared' '--prefix=/usr' '--enable-ipv6' '--enable-loadable-sqlite-extensions' '--with-dbmliborder=bdb:gdbm' '--with-computed-gotos' '--without-ensurepip' '--with-system-expat' '--with-system-libmpdec' '--with-dtrace' '--with-system-ffi' 'CC=x86_64-linux-gnu-gcc' 'CFLAGS=-g -fstack-protector-strong -Wformat -Werror=format-security ' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 ' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
構成情報は、このあたりの情報から成っているようです。
https://github.com/python/cpython/blob/v3.8.5/configure
https://github.com/python/cpython/blob/v3.8.5/configure.ac
https://github.com/python/cpython/blob/v3.8.5/Include/pymacconfig.h
https://github.com/python/cpython/blob/v3.8.5/pyconfig.h.in
https://github.com/python/cpython/blob/v3.8.5/Makefile.pre.in
https://github.com/python/cpython/blob/v3.8.5/Modules/Setup
コンパイルオプションに関するものは、このあたりを見ればよいでしょうか。
https://github.com/python/cpython/blob/v3.8.5/configure#L3016
https://github.com/python/cpython/blob/v3.8.5/configure.ac#L146-L148
https://github.com/python/cpython/blob/v3.8.5/Makefile.pre.in#L206
Pythonを自分でコンパイルしてインストールする
せっかくなので、ここまで見たのならPythonを自分でコンパイルしてインストールしてみましょう。
3.8の最新(3.8.10)をインストールしてみます。
ドキュメントを見ると、make
してインストールする感じで書かれていますね。
2. Unix プラットフォームで Python を使う — Python 3.8.10 ドキュメント
というわけで、まずはbuild-essentialをインストールしておきましょう。あとzlibも必要になるので、こちらもインストールして
おきます。
$ sudo apt install build-essential zlib1g-dev
Python 3.8.10のソースコードをダウンロードして、展開。
$ curl -sLO https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tgz $ tar xf Python-3.8.10.tgz $ cd Python-3.8.10
コンパイルオプションの確認は、こちらで。
$ ./configure --help
今回は、prefix
だけ指定しておきます。
$ ./configure --prefix=/usr/local/python3.8.10
コンパイル&インストール。
$ make && sudo make install
無事、インストールされました。
$ /usr/local/python3.8.10/bin/python3 -V Python 3.8.10
コンパイルオプションを確認してみます。
$ /usr/local/python3.8.10/bin/python3 -c 'import sysconfig; print(sysconfig.get_config_var("CONFIG_ARGS"))' '--prefix=/usr/local/python3.8.10'
見事にprefix
のみしか指定されていません。
ちょっと不安になったので、なにも指定せずに確認したら、空っぽになりました。
$ ./configure $ make && sudo make install $ /usr/local/bin/python3.8 -c 'import sysconfig; print(sysconfig.get_config_var("CONFIG_ARGS"))'
特にデフォルトの値などはなさそうですね。
では、prefix
以外は、パッケージインストールのものにしてみましょう。
$ sudo apt install systemtap-sdt-dev
パッケージインストールされたPythonの結果を使ってconfigure
を実行、
$ ./configure --prefix=/usr/local/python3.8.10 '--enable-shared' '--enable-ipv6' '--enable-loadable-sqlite-extensions' '--with-dbmliborder=bdb:gdbm' '--with-computed-gotos' '--without-ensurepip' '--with-system-expat' '--with-system-libmpdec' '--with-dtrace' '--with-system-ffi' 'CC=x86_64-linux-gnu-gcc' 'CFLAGS=-g -fstack-protector-strong -Wformat -Werror=format-security ' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 ' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
インストール。
$ make && sudo make install
確認。
$ /usr/local/bin/python3.8 -V Python 3.8.10 $ /usr/local/python3.8.10/bin/python3 -c 'import sysconfig; print(sysconfig.get_config_var("CONFIG_ARGS"))' '--prefix=/usr/local/python3.8.10' '--enable-shared' '--enable-ipv6' '--enable-loadable-sqlite-extensions' '--with-dbmliborder=bdb:gdbm' '--with-computed-gotos' '--without-ensurepip' '--with-system-expat' '--with-system-libmpdec' '--with-dtrace' '--with-system-ffi' 'CC=x86_64-linux-gnu-gcc' 'CFLAGS=-g -fstack-protector-strong -Wformat -Werror=format-security ' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 ' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
できました、と。
Ubuntu Linux 20.04 LTSとPython 3.9
ちなみに、パッケージインストールできるPython 3.9のコンパイルオプションは、Python 3.8とはまた違うようです。
$ sudo apt install python3.9 $ python3.9 -c 'import sysconfig; print(sysconfig.get_config_var("CONFIG_ARGS"))' '--enable-shared' '--prefix=/usr' '--enable-ipv6' '--enable-loadable-sqlite-extensions' '--with-dbmliborder=bdb:gdbm' '--with-computed-gotos' '--without-ensurepip' '--with-system-expat' '--with-dtrace' '--with-system-ffi' 'CC=x86_64-linux-gnu-gcc' 'CFLAGS=-g -fstack-protector-strong -Wformat -Werror=format-security ' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 ' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
Python 3.9だと'--with-system-libmpdec'
が増えていました。