kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

PPP3: Pythonのビルド(失敗)

やっと戻ったよ

Chapter 01: Pythonをはじめよう(再開)

01-01 Pythonのセットアップ

どこにPythonをセットアップしようとしているのかが問題だ
ホスト側の環境なのかゲスト側の環境なのか

でもまずdebパッケージを更新するって書いてあるからホスト側かな
ゲスト側はAppendixのほうでもうapt update/upgradeしたし
まあ結局両方やるはずだから

$ python -V
Python 2.7.15rc1
$ python3 -V
Python 3.6.7

本のバージョンに比べると新しいんだけど、ソースからビルドってやつをやってみたい
ビルドの方法ってドキュメントあるんだろうか
本に書いてある通りにやってみるけど
バージョンが違うと違うかもしれないし

必要なdebパッケージのインストール、って11個あらかじめインストールしておくとか
なんとなくでできるもんじゃなさそうだし文書化されてると思うんだけど
ちょっと見つからなかった

まあやってみてから考えようか
snapshotでも取って

ところで現状はどうなってるの

$ apt list build-essential
build-essential/bionic,now 12.4ubuntu1 amd64 [インストール済み、自動]
$ apt list -a python3-dev
python3-dev/bionic-updates 3.6.7-1~18.04 amd64
python3-dev/bionic 3.6.5-3 amd64

build-essentialってやつは入ってるんだな
python3-devで3.6.7とか3.6.5とかついてるけど
単にpython3-devでinstallしたらどんなのが入るんだろう
それに3.7系はどうなるのか
Ubuntuではまだパッケージになっていないっていうことかな
そうするとビルドの手間が増える?
そうすると初心者向けではないかもだなあ
まあ進めてみよう

$ sudo apt -y install build-essential
  :
build-essential はすでに最新バージョン (12.4ubuntu1) です。 build-essential は手動でインストールしたと設定されました。 アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 0 個。 $ sudo apt -y install python3-dev : 以下の追加パッケージがインストールされます: dh-python libexpat1-dev libpython3-dev libpython3.6-dev python3-distutils python3-lib2to3 python3.6-dev 以下のパッケージが新たにインストールされます: dh-python libexpat1-dev libpython3-dev libpython3.6-dev python3-dev python3-distutils python3-lib2to3 python3.6-dev : python3-dev (3.6.7-1~18.04) を設定しています ... $ apt list python3-dev python3-dev/bionic-updates,now 3.6.7-1~18.04 amd64 [インストール済み]

ほかのパッケージも入れていく
最新だったり普通に入ったり
特に問題はなし

そうか
ビルド方法のドキュメントってREADMEになるのか
言われてみれば

でも
基本的にこれしかかいてないんだけど

On Unix, Linux, BSD, macOS, and Cygwin::

    ./configure
    make
    make test
    sudo make install

This will install Python as ``python3``.

ま、公式がそう言ってるんだからそれで

まずはconfigureから

$ ./configure --prefix=/opt/python3.7.3
  :

特に問題なし
makefileが1800行越え なかなかすごいな

お次はmake

$ make
  :
gcc -pthread -c ... -o Python/ceval.o Python/ceval.c
In file included from Python/ceval_gil.h:55:0,
                 from Python/ceval.c:146:
Python/condvar.h: In function ‘PyCOND_TIMEDWAIT’:
Python/condvar.h:60:34: error: too few arguments to function ‘gettimeofday’
 #define PyCOND_GETTIMEOFDAY(ptv) gettimeofday(ptv)
                                  ^
Python/condvar.h:85:5: note: in expansion of macro ‘PyCOND_GETTIMEOFDAY’
     PyCOND_GETTIMEOFDAY(&deadline);
     ^~~~~~~~~~~~~~~~~~~
In file included from ./Include/pyport.h:198:0,
                 from ./Include/Python.h:63,
                 from Python/ceval.c:12:
/usr/include/x86_64-linux-gnu/sys/time.h:68:12: note: declared here
 extern int gettimeofday (struct timeval *__restrict __tv,
            ^~~~~~~~~~~~
Makefile:1641: recipe for target 'Python/ceval.o' failed
make: *** [Python/ceval.o] Error 1

ぐふ
こういう場合ってどうしたらいいの

わからんからとりあえずソースの該当箇所を見る
このへん

Py_LOCAL_INLINE(int)
PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us)
{
    :
    PyCOND_GETTIMEOFDAY(&deadline);
    :

PyCOND_GETTIMEOFDAY(&deadline)を展開したら
gettimeofday(ptv)になって
これが引数不足って言ってるんだよな

マクロ定義はこのあたり
今はgettimeofday(ptv)と定義されている

#ifdef GETTIMEOFDAY_NO_TZ
#define PyCOND_GETTIMEOFDAY(ptv) gettimeofday(ptv)
#else
#define PyCOND_GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
#endif

gettimeofdayの定義はここだと言っている

extern int gettimeofday (struct timeval *__restrict __tv,
             __timezone_ptr_t __tz) __THROW __nonnull ((1));

当然引数が不足する
うーん
configureがとちってんのかなあ

ログを見てみる

$ grep gettimeofday build.log
checking for gettimeofday... yes

ある、ということはわかってるようだけどどっちのgettimeofdayかは
判定されているんだろうか

GETTIMEOFDAY_NO_TZはどこで定義されているのか

$ find . -type f -exec grep -Hn --context=2 GETTIMEOFDAY_NO_TZ {} \;
./config.status-1121-D["HAVE_SETPGRP"]=" 1"
./config.status-1122-D["HAVE_GETTIMEOFDAY"]=" 1"
  :
./pyconfig.h-40-/* Define if gettimeofday() does not have second (timezone) argument This is
./pyconfig.h-41-   the case on Motorola V4 (R40V4.2) */
./pyconfig.h:42:#define GETTIMEOFDAY_NO_TZ 1
./pyconfig.h-43-
./pyconfig.h-44-/* Define to 1 if you have the `accept4' function. */
  :

GETTIMEOFDAY_NO_TZを定義しているのはpyconfig.hだけみたい
しかしコメントからして定義されてるのはおかしい
わからんけどディレクトリごと消してtar xfからやり直してみよう

今度は定義されてないようだ
さっきはなにかおかしかったんだろうか

/* Define if gettimeofday() does not have second (timezone) argument This is
   the case on Motorola V4 (R40V4.2) */
/* #undef GETTIMEOFDAY_NO_TZ */

makeする

vagrant@vagrant:~/study/PPP3/python/Python-3.7.3$ make
gcc -pthread -c ... -o Programs/python.o ./Programs/python.c
gcc -pthread -c ... -o Parser/acceler.o Parser/acceler.c
  :
sed -e "s,@EXENAME@,/opt/python3.7.3/bin/python3.7m," < ./Misc/python-config.in >python-config.py
LC_ALL=C sed -e 's,\$(\([A-Za-z0-9_]*\)),\$\{\1\},g' < Misc/python-config.sh >python-config

静かに終わった
これでいいのかな

本にはmake testしろとは書いてないけどここまでの流れからし
不安もあるのでやってみる

$ make test
  :
== Tests result: FAILURE then FAILURE ==

354 tests OK.

35 tests failed:
    test_aifc test_bufio test_bz2 test_cmd_line_script test_dbm
    test_dbm_dumb test_dbm_gnu test_glob test_imp test_import test_io
    test_macpath test_mailbox test_marshal test_mmap test_netrc
    test_ntpath test_os test_pathlib test_posix test_posixpath
    test_shelve test_shutil test_socket test_stat test_support
    test_tarfile test_unicode_file test_unicode_file_functions
    test_urllib test_uu test_wave test_xml_etree_c test_zipfile
    test_zipimport

17 tests skipped:
    test_ctypes test_curses test_dbm_ndbm test_devpoll test_gdb
    test_kqueue test_lzma test_msilib test_ossaudiodev test_startfile
    test_tix test_tk test_ttk_guionly test_winconsoleio test_winreg
    test_winsound test_zipfile64

45 re-run tests:
    test_aifc test_asyncore test_bufio test_bz2 test_cmd_line_script
    test_concurrent_futures test_dbm test_dbm_dumb test_dbm_gnu
    test_fileinput test_fileio test_gettext test_glob test_imp
    test_import test_importlib test_io test_macpath test_mailbox
    test_marshal test_mmap test_netrc test_ntpath test_os test_pathlib
    test_pipes test_posix test_posixpath test_shelve test_shutil
    test_socket test_socketserver test_stat test_sunau test_support
    test_tarfile test_unicode_file test_unicode_file_functions
    test_univnewlines test_urllib test_uu test_wave test_xml_etree_c
    test_zipfile test_zipimport

Total duration: 34 min 26 sec
Tests result: FAILURE then FAILURE
Makefile:1074: recipe for target 'test' failed
make: *** [test] Error 2

ぐぬぬ
何がよくないのか
いちばんありそうなのはソースが3.7.3でpython3-devが3.6.7ってとこだな
3.6.7のソースからビルドすれば成功するのか