apxsコマンドでUse of uninitialized value…のエラー

Linux

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.

Apache License2.0の日本語訳

タイトルとURLをコピーしました