phpのインストールでapxsコマンドのエラーが表示された。以下のようなエラー。これの原因と対策について記載します。
phpのインストールやapxsコマンド打った時に、Use of uninitialized value…っていうエラーが出ている人が対象かと。
Installing PHP SAPI module: apache2handler
Use of uninitialized value $localstatedir in concatenation (.) or string at (eval 3) line 1.
Use of uninitialized value in concatenation (.) or string at /usr/bin/apxs line 232.
apxsコマンドのエラー確認
apxsとはapacheに同梱されているapacheのモジュールをインストールしたりするときに使うコマンド。phpをソースからインストールしているときにこのエラーに遭遇しました。
本当にapxsでエラーが出るのかコマンド打って確認しました。同じエラーがでますね。
[root@mackii ~]# apxs -q ENABLED_DSO_MODULES
Use of uninitialized value $localstatedir in concatenation (.) or string at (eval 3) line 1.
Use of uninitialized value in concatenation (.) or string at /usr/bin/apxs line 232.
,authn_file,authn_core,authz_host,authz_groupfile,authz_user,authz_core,access_compat,auth_basic,reqtimeout,filter,mime,log_config,env,headers,setenvif,version,unixd,status,autoindex,dir,alias
エラー発生までの経緯
apache2.4なのになぜ今頃php5.6なのかという突っ込みはさておき(古いサーバーのメンテナンスなのです)、経緯は以下の通りです。
apache2.4をソースからインストール
[mackii@mackii httpd-2.4.53]$ ./configure --enable-layout=RPM --enable-ssl --with-apr-util=/usr --with-apr=/usr --with-mpm=prefork
[mackii@mackii httpd-2.4.53]$ make
[mackii@mackii httpd-2.4.53]$ sudo /usr/bin/make install
のような感じで最低限のビルド~インストールを実施したわけです。
–enable-layoutというのはインストール先のフォルダを設定ファイルで指定するオプション。ソースに同梱されているconfig.layoutに実際の設定が記載されています。
指定したRPMのlayoutは以下の感じ。
<Layout RPM>
prefix: /usr
exec_prefix: ${prefix}
bindir: ${prefix}/bin
sbindir: ${prefix}/sbin
libdir: ${prefix}/lib
libexecdir: ${libdir}/httpd/modules
mandir: ${prefix}/share/man
sysconfdir: /etc/httpd/conf
installbuilddir: ${libdir}/httpd/build
includedir: ${prefix}/include/httpd
localstatedir: /var
datadir: ${localstatedir}/www
errordir: ${datadir}/error
iconsdir: ${datadir}/icons
htdocsdir: ${datadir}/html
manualdir: ${datadir}/manual
cgidir: ${datadir}/cgi-bin
runtimedir: ${localstatedir}/run
logfiledir: ${localstatedir}/log/httpd
proxycachedir: ${localstatedir}/cache/httpd/cache-root
</Layout>
この${prefix}とか${localstatedir}は変数というもので、configureスクリプトの中で自動で事前に定義した値を埋め込んでくれます。
php5.6のインストール、エラー発生!
[mackii@mackii php-5.6.40]$ ./configure --prefix=/usr --exec-prefix=/usr --bind ir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --include dir=/usr/include --libdir=/usr/lib --libexecdir=/usr/libexec --localstatedir=/va r --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info -- cache-file=../config.cache --with-libdir=lib --with-config-file-path=/etc --with -config-file-scan-dir=/etc/php.d --disable-debug --enable-mbstring --with-apxs2=/usr/bin/apxs
[mackii@mackii php-5.6.40]$ make
・・・・・
Build complete.
Don't forget to run 'make test'.(はい忘れてました!)
[mackii@mackii php-5.6.40]$ sudo /usr/bin/make install
Installing PHP SAPI module: apache2handler
Use of uninitialized value $localstatedir in concatenation (.) or string at (eval 3) line 1.
Use of uninitialized value in concatenation (.) or string at /usr/bin/apxs line 232.
apxs:Error: no config variable LIBEXECDIR
configure、makeと無事に終了したらほぼタスク完了も同然と思ってた安心してたところに見たこともないエラー発生!
エラー原因
ネットで調べても大して情報見当たらず。いまさらphp5.6だからか?とか嘆いていましたが、とにかく何とかしないと、本番機のウェブサーバーが停止しています。メンテナンス時間中に何とかしないといけません!とりあえず、apxsって何者?と中身をテキストエディタで見てみました。開けてみるとperlのスクリプトです!本職はプログラマーなんで、perlならなんとかなるかも!
apxsコマンドの環境設定ファイル
apxsを解析したところ、以下で環境設定ファイルを読みこんでいるらしい。
my $installbuilddir = "/usr/lib/httpd/build";
get_config_vars($destdir . "$installbuilddir/config_vars.mk",\%config_vars);
環境設定ファイルは/usr/lib/httpd/buildディレクトリのconfig_vars.mkファイルだな。見てみよう。
(抜粋)
bindir = ${prefix}/bin
sbindir = ${prefix}/sbin
cgidir = ${datadir}/cgi-bin
logfiledir = ${localstatedir}/log/httpd
exec_prefix = ${prefix}
datadir = ${localstatedir}/www
localstatedir = /var
mandir = ${prefix}/share/man
libdir = ${prefix}/lib
libexecdir = ${libdir}/httpd/modules
htdocsdir = ${datadir}/html
manualdir = ${datadir}/manual
includedir = ${prefix}/include/httpd
errordir = ${datadir}/error
iconsdir = ${datadir}/icons
sysconfdir = /etc/httpd/conf
installbuilddir = ${libdir}/httpd/build
runtimedir = ${localstatedir}/run
proxycachedir = ${localstatedir}/cache/httpd/cache-root
other_targets =
progname = httpd
prefix = /usr
なんか見覚えがあると思ったら、config.layoutの指定と同じ。configureで指定したオプションがそのまま記載されています。
apxsコマンドの初期処理
続きのソースを以下に抜粋する。
# read the configuration variables once
my $prefix = get_vars("prefix");
my $CFG_PREFIX = $prefix;
my $exec_prefix = get_vars("exec_prefix");
my $datadir = get_vars("datadir");
my $localstatedir = get_vars("localstatedir");
my $CFG_TARGET = get_vars("progname");
my $CFG_SYSCONFDIR = get_vars("sysconfdir");
my $CFG_CFLAGS = join ' ', map { get_vars($_) }
qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS);
my $CFG_LDFLAGS = join ' ', map { get_vars($_) }
qw(LDFLAGS NOTEST_LDFLAGS SH_LDFLAGS);
my $includedir = $destdir . get_vars("includedir");
my $CFG_INCLUDEDIR = eval qq("$includedir");
my $CFG_CC = get_vars("CC");
my $libexecdir = $destdir . get_vars("libexecdir");
my $CFG_LIBEXECDIR = eval qq("$libexecdir");
my $sbindir = get_vars("sbindir");
my $CFG_SBINDIR = eval qq("$sbindir");
my $ltflags = $ENV{'LTFLAGS'};
問題は、
my $datadir = get_vars("datadir");
my $libexecdir = $destdir . get_vars("libexecdir");
の2行(赤マーカーのところ)
get_varsサブルーチンで先ほどのconfig_vars.mkファイルから、引数で指定されているキー情報に対応する値を設定ファイルから読み取って変数に格納する、っていう処理をしているのだが、datadirが環境設定ファイルconfig_vars.mkでどうなっているか見てみると・・・
datadir = ${localstatedir}/www
${localstatedir}の値を読み込んで定義するとなっているが、肝心のlocalstatedirの初期設定がdatadirの次の行になってる!(黄色マーカーのところ)。datadirの定義をしようとした時にはlocalstatedirの定義処理が実行されていないのでそりゃ出た通りのエラーになりますね。どうやらこれが原因で間違いないっぽい。
対応方法
対処法は2通り考えられます。どちらか一方を実施すればOK。
対処法1 config_vars.mkの修正
apacheをビルドしたときのconfigureのオプションとapxsの処理があっておらず、変数に定義した値がうまく読み込めていないのが原因なので変数ではなく値を指定すれば良いです。
${prefix} → /usr
${datadir}→/var/www
のように置き換えてしまいましょう(バックアップを忘れずに!)。下記のようになります。
(抜粋)
bindir = /usr/bin
sbindir = /usr/sbin
cgidir = /var/www/cgi-bin
logfiledir = /var/log/httpd
exec_prefix = /usr
datadir = /var/www
localstatedir = /var
mandir = /usr/share/man
libdir = /usr/lib
libexecdir = /usr/lib/httpd/modules
htdocsdir = /var/www/html
manualdir = /var/www/manual
includedir = /usr/include/httpd
errordir = /var/www/error
iconsdir = /var/www/icons
sysconfdir = /etc/httpd/conf
installbuilddir = /usr/lib/httpd/build
runtimedir = /var/run
proxycachedir = /var/cache/httpd/cache-root
other_targets =
progname = httpd
prefix = /usr
書き換え後、再確認すると見事エラーが解消されていました!
[root@mit04 build]# apxs -q ENABLED_DSO_MODULES
,authn_file,authn_core,authz_host,authz_groupfile,authz_user,authz_core,access_compat,auth_basic,reqtimeout,filter,mime,log_config,env,headers,setenvif,version,unixd,status,autoindex,dir,alias
対処法2 apxsの修正
apxsの変数の初期化順が問題なのであれば、初期化順を変えてしまえばよいです(バックアップを忘れずに!)。
$localstatedirと$datadirの順番を入れ替え、$libdirの初期化処理を追記しました。
・・・(抜粋)・・・
my $prefix = get_vars("prefix");
my $CFG_PREFIX = $prefix;
my $exec_prefix = get_vars("exec_prefix");
my $localstatedir = get_vars("localstatedir");
my $datadir = get_vars("datadir");
my $CFG_TARGET = get_vars("progname");
my $CFG_SYSCONFDIR = get_vars("sysconfdir");
my $CFG_CFLAGS = join ' ', map { get_vars($_) }
qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS);
my $CFG_LDFLAGS = join ' ', map { get_vars($_) }
qw(LDFLAGS NOTEST_LDFLAGS SH_LDFLAGS);
my $includedir = $destdir . get_vars("includedir");
my $CFG_INCLUDEDIR = eval qq("$includedir");
my $CFG_CC = get_vars("CC");
my $libdir = get_vars("libdir");
my $libexecdir = $destdir . get_vars("libexecdir");
・・・
修正後、確認するとエラーが解消されてました。
エラー解消後、phpのインストール
apxsのエラー解消後、phpインストール作業は、
make distclean
を実施して、configureからやり直してください。apxsコマンドのエラー解消後、うまくインストールできました。
apxsコマンドはApache License 2.0で配布されています
Apacheライセンスの2.0バージョンのもとに配布されてます。apxsに付与されているライセンス条文を載せておきます。今回修正、再配布したコードも同じApache License 2.0とします。適用するしないはすべて自己責任においてお願いします。
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.