GNU gperfのインストール

完全ハッシュ関数 (perfect hash function) を生成するGNU gperfをソースコードからインストールする。

GNU gperfはC/C++でハッシュを実装するためのライブラリーとなっている。

インストール手順

インストール情報
項目 説明
配布元
リポジトリー gperf.git – gperf
手順 INSTALL – gperf.git – gperf
依存情報 configure.ac – gperf.git – gperf
依存先 (必須) Make (GNU Make), Perl
依存先 (任意) リポジトリーからのビルド: Autoconf 2.63+
依存元 ccache
インストールコマンド
sh -eux <<-"EOT"
PKG=gperf VER=3.1 TAG=v$VER
LOCAL=~/.local J=$(grep -cs '^processor' /proc/cpuinfo || echo 2)
mkdir -p "$LOCAL/src"
cd "$LOCAL/src"

if command -v git >/dev/null; then
  [ -e $PKG ] || git clone --depth 1 git://git.savannah.gnu.org/gperf.git $PKG
  cd $PKG
  git fetch --depth 1 origin tag $TAG
  git checkout -f $TAG
  git clean -dfX
  [ -e .gitmodules ] && git submodule foreach --recursive git clean -dfX
  GNULIB_TOOL=$(command -v gnulib-tool) ./autogen.sh
else
  [ -e $PKG-$VER ] || wget http://ftp.gnu.org/pub/gnu/gperf/$PKG-$VER.tar.gz
  tar -xf $PKG-$VER.*
  cd $PKG-$VER
  make -kj $J distclean clean || :
fi

[ $(echo $VER | sed 's/[^0-9]//g') -le 31 ] && patch -lNp 1 <<-"EOP" || :
diff --git a/doc/texi2html b/doc/texi2html diff --git a/doc/texi2html b/doc/texi2html index d423c2f..5ada126 100755 --- a/doc/texi2html +++ b/doc/texi2html @@ -1561,7 +1561,7 @@ sub update_sec_num { $level--; # here we start at 0 if ($name =~ /^appendix/) { # appendix style - if (defined(@appendix_sec_num)) { + if (@appendix_sec_num) { &incr_sec_num($level, @appendix_sec_num); } else { @appendix_sec_num = ('A', 0, 0, 0); @@ -1569,7 +1569,7 @@ sub update_sec_num { return(join('.', @appendix_sec_num[0..$level])); } else { # normal style - if (defined(@normal_sec_num)) { + if (@normal_sec_num) { &incr_sec_num($level, @normal_sec_num); } else { @normal_sec_num = (1, 0, 0, 0); diff --git a/doc/texi2html b/doc/texi2html index 5ada126..ca8b5fc 100755 --- a/doc/texi2html +++ b/doc/texi2html @@ -879,7 +879,7 @@ while ($_ = &next_line) { s/\@refill\s+//g; # other substitutions &simple_substitutions; - s/\@value{($VARRE)}/$value{$1}/eg; + s/\@value\{($VARRE)\}/$value{$1}/eg; s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4 # # analyze the tag again @@ -1204,7 +1204,7 @@ while (@lines) { # # xref # - while (/\@(x|px|info|)ref{($XREFRE)(}?)/o) { + while (/\@(x|px|info|)ref\{($XREFRE)(\}?)/o) { # note: Texinfo may accept other characters ($type, $nodes, $full) = ($1, $2, $3); ($before, $after) = ($`, $'); @@ -1810,7 +1810,7 @@ sub substitute_style { while ($changed) { $changed = 0; $done = ''; - while (/\@(\w+|"|\~|,|\^){([^\{\}]+)}/) { + while (/\@(\w+|"|\~|,|\^)\{([^\{\}]+)\}/) { $text = &apply_style($1, $2); if ($text) { $_ = "$`$text$'"; EOP
./configure --prefix="$LOCAL/stow/$PKG-$VER" make -j $J make -j $J check make -j $J install cd "$LOCAL/stow" echo $PKG-[0-9]* | xargs -n 1 stow --ignore=dir -D stow --ignore=dir $PKG-$VER EOT
インストール例
日付 バージョン OS 依存関係
2019-06-22 3.1 Ubuntu 18.04 GNU Make 4.2.1, GCC 7.4.0, Autoconf 2.69, Perl 5.26.1

gperfはGnulibを使っており,リポジトリーからのビルドでは,autogen.sh実行時にGNULIB_TOOL環境変数で指定したgnulib-toolが存在しなければ,リポジトリーからgnulib-toolをダウンロードする。

そのため,実行前にローカルにGnulibがインストールされていれば,以下のコマンドでそれを使うようにした。

  GNULIB_TOOL=$(command -v gnulib-tool) ./autogen.sh

また,gperf 3.1のビルド時に,エラーがでたのでエラー対応のためのパッチを適用している。

Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?)

gperf 3.1のmakeで以下のエラーが発生した。

make[1]: Entering directory '/home/senooken/.local/src/gperf/doc'
cd . && perl ./texi2html -number -monolithic gperf.texi
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at ./texi2html line 1564.
make[1]: *** [Makefile:103: gperf.html] Error 255

エラー内容を調べると,どうやらPerlの廃止予定の文法によるエラーのようだ。

defined(@array) and defined(%hash) are now fatal errors

These have been deprecated since v5.6.1 and have raised deprecation warnings since v5.16.

defined(@array) and defined(%hash) are now fatal errors | perl5220delta – perldoc.perl.org

defined(@array)の構文がPerl 5.20からエラー扱うになったようだ。

Perl v5.6.0から廃止予定扱いの記述が以下にあった。

30
defined(@array) is deprecated

(D)
defined() is not usually useful on arrays because it checks for an
undefined scalar value. If you want to see if the array is empty, just
use if (@array) { # not empty } for example.
30
defined(%hash) is deprecated

(D) defined() is not usually useful on hashes because it checks for an
undefined scalar value. If you want to see if the hash is empty, just
use if (%hash) { # not empty } for example.

New or Changed Diagnostics | perl56delta – perldoc.perl.org

上記の記載がある通り,defined(@array)ではなく,単に@arrayに書き換えればいいようだ。

master上は2017-03-31のコミットで以下のように修正されていた。

diff --git a/doc/texi2html b/doc/texi2html
index d423c2f..5ada126 100755
--- a/doc/texi2html
+++ b/doc/texi2html
@@ -1561,7 +1561,7 @@ sub update_sec_num {
     $level--; # here we start at 0
     if ($name =~ /^appendix/) {
 	# appendix style
-	if (defined(@appendix_sec_num)) {
+	if (@appendix_sec_num) {
 	    &incr_sec_num($level, @appendix_sec_num);
 	} else {
 	    @appendix_sec_num = ('A', 0, 0, 0);
@@ -1569,7 +1569,7 @@ sub update_sec_num {
 	return(join('.', @appendix_sec_num[0..$level]));
     } else {
 	# normal style
-	if (defined(@normal_sec_num)) {
+	if (@normal_sec_num) {
 	    &incr_sec_num($level, @normal_sec_num);
 	} else {
 	    @normal_sec_num = (1, 0, 0, 0);

このパッチをv3.1以下の場合は当ててビルドする。

Unescaped left brace in regex is deprecated here (and will be fatal in Perl 5.30), passed through in regex

gperf v3.1のビルドで,Can’t use ‘defined(@array)’のエラーに対応したら,今度はmake実行時に次のビルドエラーがでてしまった。

make[1]: Entering directory '/home/senooken/.local/src/gperf/doc'
cd . && perl ./texi2html -number -monolithic gperf.texi
Unescaped left brace in regex is deprecated here (and will be fatal in Perl 5.30), passed through in regex; marked by <-- HERE in m/\@(\w+|"|\~|,|\^){ <-- HERE ([^\{\}]+)}/ at ./texi2html line 1813.
Unescaped left brace in regex is illegal here in regex; marked by <-- HERE in m/\@value{ <-- HERE ([^\s\{\}]+)}/ at ./texi2html line 882, <FH001> line 3.
make[1]: *** [Makefile:103: gperf.html] Error 25

Perl 5.30で正規表現内のリテラル開き波括弧はエスケープが必須になったらしい。

Some formerly deprecated uses of an unescaped left brace “{” in regular expression patterns are now illegal

But
to avoid breaking code unnecessarily, most instances that issued a
deprecation warning, remain legal and now have a non-deprecation warning
raised. See Unescaped left braces in regular expressions in
perldeprecation.

Some
formerly deprecated uses of an unescaped left brace “{” in regular
expression patterns are now illegal | perl5300delta – perldoc.perl.org

「See Unescaped left braces in regular expressions in perldeprecation」のリンクが切れていた。恐らく「perldeprecation – list Perl deprecations – metacpan.org」へのリンクだろう。こちらに経緯が書かれている。

Unescaped left braces in regular expressions

The
simple rule to remember, if you want to match a literal { character
(U+007B LEFT CURLY BRACKET) in a regular expression pattern, is to
escape each literal instance of it in some way. Generally easiest is to
precede it with a backslash, like \{ or enclose it in square brackets
([{]). If the pattern delimiters are also braces, any matching right
brace (}) should also be escaped to avoid confusing the parser, for
example,

qr{abc\{def\}ghi}

Forcing literal { characters to
be escaped will enable the Perl language to be extended in various ways
in future releases. To avoid needlessly breaking existing code, the
restriction is is not enforced in contexts where there are unlikely to
ever be extensions that could conflict with the use there of { as a
literal. A non-deprecation warning that the left brace is being taken
literally is raised in contexts where there could be confusion about it.

Literal
uses of { were deprecated in Perl 5.20, and some uses of it started to
give deprecation warnings since. These cases were made fatal in Perl
5.26. Due to an oversight, not all cases of a use of a literal { got a
deprecation warning. Some cases started warning in Perl 5.26, and were
made fatal in Perl 5.30. Other cases started in Perl 5.28, and will be
made fatal in 5.32.

perldeprecation – list Perl deprecations – metacpan.org

正規表現内で,開き波括弧 ({) へのマッチは,バックスラッシュを直前につけてエスケープするか,角括弧 ([]) で囲むかする。将来のPerlの言語拡張のためにこのような扱いになったようだ。

Perl 5.20で廃止予定になり,5.26から警告扱いになり,5.30でエラー扱いになったようだ。

このビルドエラーは2018-09-16のコミットで修正されていた。

diff --git a/doc/texi2html b/doc/texi2html
index 5ada126..ca8b5fc 100755
--- a/doc/texi2html
+++ b/doc/texi2html
@@ -879,7 +879,7 @@ while ($_ = &next_line) {
     s/\@refill\s+//g;
     # other substitutions
     &simple_substitutions;
-    s/\@value{($VARRE)}/$value{$1}/eg;
+    s/\@value\{($VARRE)\}/$value{$1}/eg;
     s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
     #
     # analyze the tag again
@@ -1204,7 +1204,7 @@ while (@lines) {
     #
     # xref
     #
-    while (/\@(x|px|info|)ref{($XREFRE)(}?)/o) {
+    while (/\@(x|px|info|)ref\{($XREFRE)(\}?)/o) {
 	# note: Texinfo may accept other characters
 	($type, $nodes, $full) = ($1, $2, $3);
 	($before, $after) = ($`, $');
@@ -1810,7 +1810,7 @@ sub substitute_style {
     while ($changed) {
 	$changed = 0;
 	$done = '';
-	while (/\@(\w+|"|\~|,|\^){([^\{\}]+)}/) {
+	while (/\@(\w+|"|\~|,|\^)\{([^\{\}]+)\}/) {
 	    $text = &apply_style($1, $2);
 	    if ($text) {
 		$_ = "$`$text$'";

インデントにタブが混在していた。端末に貼り付ける際に都合が悪いので,インストール手順ではタブをスペースに置換し,patchの-lオプションでスペースの違いを無視してパッチを適用している。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です