IT雑記

CentOS 7.2 + PHP 5.6 + MariaDB 10.2 でPHPをソースからビルドしたら大苦戦

投稿日:2018-12-22 更新日:

1. はじめに

先日、とある案件でCent OS 7.2 に PHP 5.6をにインストールする際、がっつりはまってしまいました。ネットで探してもなかなか情報がなかったので、この記事が誰かのお役に立てればと思います。

2. 環境

OS: Cent OS 7.2
DB: MariaDB 10.2
PHP: 5.6

※さらに、PHP 7.2が既にインストールされている状態

モジュール版PHPをビルドする手順に関しては以下の記事から部分部分をかいつまんで実施しています。
同一apache内でモジュール版phpとcgi版phpを共存させる

Raspbianで公式php7をビルド & インストールする

3. 背景

もともと、Cent OS7.2のVMの環境を持っていました。VMwareです。

Cent OS 7.2の標準リポジトリからyumでLAMP環境を構築すると、
普通にやる分には恐らくPHP 5.4 + MariaDB 5.5系がインストールされると思います。

私は開発環境にはあまりこだわりはないので、もっぱらこの構成で開発をしていました。

しかし、先日、とある案件でPHP7.x、MariaDB 10.xでなければならない、という要件が出てきました。

納期が短かったこともあり、環境構築に割ける時間がなかったので、
そのVMのPHPとMariaDBをえいやで最新の状態に上げることで対応しました。

つまり、既存のPHP 5.4と MariaDB 5.5をアンインストールし、
当時(2018/11月)で最新である PHP 7.2, MariaDB 10.2をインストールしたことになります。
(このアップグレードもなかなか大変でしたが、、、)

かくして、最新のPHPとMariaDB(mysql)を手に入れたわけですが、
当たり前な話で、それまで開発してきたPHPのプロジェクトが軒並み動かなくなってしまいました。

そこで、古いPHPと新しいPHPを共存させるための方法を探していたら、
PHPをソースからビルドして、CGIモードで動かせば良い、ということが分かりました。
(複数バージョンのPHPを共存させる方法は他にもありますが、今回は色々悩んでこの方法にしました)

そして、PHPをCGIモードで動かすためには、PHPをソースからビルドする必要がある、と。

そんな背景から、CentOS 7.2 + MariaDB 10.2 にPHP 5.6を入れるという、
普通の人はたぶん絶対やらない道に進むことになったのです。

4. ハマりポイントerror: ‘MYSQL_UNIX_ADDR’ undeclared (first use in this function)

私自身、PHPをソースからビルドするなんて初めての経験だったのですが、
これは何というか、多くの人が口にするように地味に苦痛でした。

どうにかこうにか ./configureコマンドが正常に終わるよう色々なパッケージをインストールして、
やっとのことでmakeまでたどり着いた、と思ったらmakeでこの結果、、、

error: ‘MYSQL_UNIX_ADDR’ undeclared (first use in this function)

文字通り、MYSQL_UNIX_ADDRという定義がされていない、という事のようです。

同時に以下のようなエラーも出ています。

error: ‘MYSQL_PORT’ undeclared (first use in this function)

正直、さすがにこれはお手上げ、と直感しました。

がしかし、ちょっとがんばってみました。

やればできるもんです。

頑張った途中経過は後で説明するとして、最終的には以下のようにC言語のソースコードをいじることで対応しました。

/usr/include/mysql/mariadb_version.h

何をしているかというと、MYSQL_PORTという定義がまだされていなかったら、
MYSQL_PORTをMARIADB_UNIX_ADDRと定義せよ、としています。

MARIADB_UNIX_ADDRは1行目で3306と定義されているため、MYSQL_PORTは最終的に3306に変換されます。

これで無事にmakeが完了しました。

5. 解説

それでは、できる限り詳細に解説を試みます。

まず、エラーの内容をよく見てみます。

エラーメッセージの前に、何やらすごく長いコマンドみたいなものが書かれています。

/bin/sh //usr/local/src/php-5.6.32/php-5.6.32/libtool --silent --preserve-dup-deps --mode=compile cc -Iext/mysql/ -I//usr/local/src/php-5.6.32/php-5.6.32/ext/mysql/ -DPHP_ATOM_INC -I//usr/local/src/php-5.6.32/php-5.6.32/include -I//usr/local/src/php-5.6.32/php-5.6.32/main -I//usr/local/src/php-5.6.32/php-5.6.32 -I//usr/local/src/php-5.6.32/php-5.6.32/ext/date/lib -I//usr/local/src/php-5.6.32/php-5.6.32/ext/ereg/regex -I/usr/include/libxml2 -I/usr/X11 -I/usr/include/freetype2 -I/usr/include/libpng15 -I//usr/local/src/php-5.6.32/php-5.6.32/ext/mbstring/oniguruma -I//usr/local/src/php-5.6.32/php-5.6.32/ext/mbstring/libmbfl -I//usr/local/src/php-5.6.32/php-5.6.32/ext/mbstring/libmbfl/mbfl -I/usr/include/mysql -I/usr/include/mysql/mysql -I//usr/local/src/php-5.6.32/php-5.6.32/ext/sqlite3/libsqlite -I/usr/include/pspell -I//usr/local/src/php-5.6.32/php-5.6.32/ext/zip/lib -I//usr/local/src/php-5.6.32/php-5.6.32/TSRM -I//usr/local/src/php-5.6.32/php-5.6.32/Zend -I/usr/include/mysql/server -I/usr/include -g -O2 -fvisibility=hidden -c //usr/local/src/php-5.6.32/php-5.6.32/ext/mysql/php_mysql.c -o ext/mysql/php_mysql.lo

よく見ると、途中に「cc」とか「php_mysql.c」とか「-o」とか書かれています。

なるほど、これはC言語のソースコードをコンパイルするときのコマンドパターンです。

つまり、/usr/local/src/php-5.6.32/php-5.6.32/ext/mysql/php_mysql.cというC言語のコードをコンパイルしている時にエラーが出ていることが分かります。

もう一度エラーメッセージを見てみます。

error: ‘MYSQL_UNIX_ADDR’ undeclared (first use in this function)

これはつまり、php_mysql.cをコンパイルするにあたって、MYSQL_UNIX_ADDRが定義されていないよ、と怒られているのですね。

一見、そんなのどうしようもないじゃないか、とも思います。

確かに。

ダメもとでGoogle先生に聞いてみます。

すると、以下のような記事が見つかりました。

PHP mysqli extension cannot be build with MariaDB >= 10.2.10

この記事の内容を見てみると、どうも今回のケースとは少し違う現象のようですが、原因は恐らく同じです。

試しに、この記事に書かれている通り、./configure時に以下のオプションを付けてみます。

CPPFLAGS="-I/usr/include/mysql/server"

でもダメでした。

エラーの内容が変わりません。

もう本当にダメだと思いましたが、もう少し粘ってみることに。

上の記事に書かれているように、関係する定義は/usr/include/mysql/配下にありそうです。

そこで、このフォルダ以下でgrepしてみると、以下の定義が見つかります。

server/mysql_version.h:#define MYSQL_UNIX_ADDR "/var/lib/mysql/mysql.sock"
server/mysql_version.h:#define MYSQL_PORT 3306

うーん。

ここまでわかったのなら、とりあえずはこの二つの定義をphp_mysql.cに直書きしてやれば、
少なくともエラーが出ている件に関してはクリアできそうですが、そんな無茶をしてビルドしたPHPなんて信用できます?

ちょっとできません、、、

せめて、どうしてコンパイルが失敗しているのか突き止めたい所です。

今回のケースの問題は、つまり、mysql_version.hというヘッダファイルを読み込めていない事と言えます。

上であげた記事で説明されていますが、いくつかのヘッダファイルは/usr/include/mysql/から/usr/include/mysql/serverに移動したようですね。

そのあたりの構成の変更のせいで、インクルードファイルの構成にも影響が出てしまったと思われます。

C言語プロジェクトの開発ではよくある事です。

仕方がないのでphp_mysql.cの中身を覗いてみることにします。

解析してみると、どうもmysql.hをインクルードする時に、MYSQL_UNIX_ADDRが定義されていてほしいはずが、そうなっていないものと思われます。

その原因は、mysql.hが二つ存在するからです。

一つ目は
/usr/include/mysql/mysql.h

二つ目は
/usr/include/mysql/server/mysql.h

です。

一つ目のmysql.hをインクルードした場合は、以下のようにインクルードされ、定義がない状態となる。
/usr/include/mysql/mysql.h
-> mariadb_version.hをインクルード
-> MYSQL_UNIX_ADDRがない!

二つ目のmysql.hをインクルードした場合は、以下のようインクルードされ、定義がある状態となる(結果コンパイルできるはず
/usr/include/mysql/server/mysql.h
-> mysql_version.hをインクルード
-> MYSQL_UNIX_ADDRがある!

そして、今回の現象では一つ目のmysql.hをインクルードしています。
なぜかというと、あの長いコマンドをよくよく見てみると、中に-I/usr/include/mysqlと書いてあるじゃありませんか。

-I/usr/include/mysql/serverも書いてありますが、-I/usr/include/mysqlが先に書かれているので
こちらが優先されるのでしょう(-Iはインクルードパスを追加するオプション)。

というわけで、うまくインクルードできていない原因が分かりました。

それでは次はどう直そうか、という問題です。

色々選択肢はあります。

i. php_mysql.cにそれぞれのdefineを直書きする
ii. インクルードしてほしくない方のmysql.hの名前を変える
→すると自動的に/usr/include/mysql/serverの方のmysql.hを見に行く
iii. mariadb_version.hにdefine定義を追加する

どの方法でもビルドは成功するでしょうし、ビルドされた結果も全く同一になるでしょう。

ここではできるだけ影響を小さくし、.cファイルを触りたくないという理由から、iiiを採用しました。

6. 終わりに

ワラゴンは、今はもっぱらWeb系のプログラマですが、昔はCもかじっていました。
今回は、そんな経験が少し役に立つ形となりました。

本当、色々とやってみるもんです。

それにしても、改めてPHPはCで書かれているんだなぁと実感する出来事でした。

そして、こんなに苦戦するんだったら、最初からDockerでPHP 5.6の環境を作った方が早かっただろうな、と少し後悔しました、、、

おまけ
※makeが途中でコケた場合、念のためmake cleanコマンドを使ってゴミを掃除してからもう一度makeしましょう。念のため。

おすすめ記事

1

こんにちは。ワラゴンです。 今日は、アメリカで見つけた、日本ではあまり知られていないけど超絶おいしいお菓子を紹介したいと思います。 その名も Loacker Quadratini。 なんて読むのかは分 ...

2

こんにちは。ワラゴンです。 アメリカに在住することのひとつのデメリットは、「日本への一時帰国が簡単ではない」という点です。 特に、子供が小さいうちはなるべく親に孫を見せてあげたいと思うのが心情なのでは ...

3

こんにちは。ワラゴンです。 みなさん、Netflix(ネットフリックス)って知っていますか? アメリカ発の動画配信サービスなんですが、これが英語の勉強をするのにとても便利なのです。 英語学習では、映画 ...

4

0. はじめに こんばんわ。ワラゴンです。 さて、今日は久しぶりにアメリカ生活について、 特にロサンゼルスの賃貸事情について少しお話したいと思います。 これからロサンゼルス周辺に駐在でいらっしゃる皆様 ...

5

どうもワラゴンです。 今日は、タイトルにもあるように、一歩進んだバックアップのプラグイン、 UpdraftPlusを紹介したいと思います 1. はじめに みなさん、Wordpressのバックアップを取 ...

6

0. はじめに こんにちは。ワラゴンです。 調べ物をしている最中、すごいサイトを発見したので紹介したいと思います。 そのサイトというのは、以下になります。 副業クエスト100 もう、何というか、アフィ ...

7

前回、アメリカ生活のここがイヤ!移住して後悔したこと 前編 3つという記事を書きました。 今回はその続きになります。 シリーズを最初から読みたい方は以下の目次ページが便利です エンジニアのアメリカ進出 ...

-IT雑記

Copyright© 40歳から始める資産ブログ , 2020 All Rights Reserved Powered by STINGER.