「stowによるローカルパッケージ管理 」でパッケージのソースコードからのインストール方法について解説した。基本的に,新規でインストールするパッケージはこの方法でソースコードからインストールする。
ソースコードからインスト―ルするにあたって,多数のソフトがビルドに採用しているGNU Makeをソースコードからインストールする。
目次
インストール手順
makeなしでのGNU Makeのインストール
リポジトリーからのビルド
glibc 2.26以上でのコンパイルエラー対策
./make checkの失敗対策
インストール手順
インストール情報
項目
説明
配布元
リポジトリー make.git – make
手順
依存情報
依存先 (必須)
Cコンパイラー(GCC)
依存先 (任意) Autoconf: リポジトリーからのビルドに必要。 Automake: リポジトリーからのビルドに必要。 Make (GNU Make): リポジトリーからのビルドに必要。 GNU Texinfo : リポジトリーからのビルドに必要。wget: リポジトリーからのビルドに必要。 gnulib: make gendocsでマニュアルの生成に必要。 GNU Guile: GNU Make内でのGuile言語の埋め込み対応。
依存元
インストール手順
sh -eux <<-"EOT"
PKG=make VER=4.2.1 TAG=$VER
LOCAL=~/.local J=$(grep -cs '^processor' /proc/cpuinfo || echo 2)
mkdir -p "$LOCAL/src" cd "$LOCAL/src"
if (command -v git && command -v make ) >/dev/null; then
[ -e $PKG ] || git clone --depth 1 git://git.savannah.gnu.org/$PKG.git $PKG
cd $PKG
git fetch --depth 1 origin tag $TAG git checkout -f $TAG git clean -dfX autoreconf -i
else
[ -e $PKG-$VER ] || wget https://ftp.gnu.org/gnu/$PKG/$PKG-$VER.tar.gz
tar -xf $PKG-$VER.*
cd $PKG-$VER
command -v make >/dev/null && make -kj $J distclean clean || : fi
[ $(echo $VER | sed 's/[^0-9]//g') -le 421 ] && patch -N p 1 <<-"EOP" || :
diff --git a/configure.ac b/configure.ac
index 8c72568..4710832 100644
--- a/configure.ac
+++ b/configure.ac
@@ -404,10 +404,9 @@ AC_CACHE_CHECK([if system libc has GNU glob], [make_cv_sys_gnu_glob],
#include <glob.h>
#include <fnmatch.h>
-#define GLOB_INTERFACE_VERSION 1
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
# include <gnu-versions.h>
-# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
+# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2
gnu glob
# endif
#endif],
diff --git a/dir.c b/dir.c
index adbb8a9..c343e4c 100644
--- a/dir.c
+++ b/dir.c
@@ -1299,15 +1299,40 @@ local_stat (const char *path, struct stat *buf)
}
#endif
+/* Similarly for lstat. */
+#if !defined(lstat) && !defined(WINDOWS32) || defined(VMS)
+# ifndef VMS
+# ifndef HAVE_SYS_STAT_H
+int lstat (const char *path, struct stat *sbuf);
+# endif
+# else
+ /* We are done with the fake lstat. Go back to the real lstat */
+# ifdef lstat
+# undef lstat
+# endif
+# endif
+# define local_lstat lstat
+#elif defined(WINDOWS32)
+/* Windows doesn't support lstat(). */
+# define local_lstat local_stat
+#else
+static int
+local_lstat (const char *path, struct stat *buf)
+{
+ int e;
+ EINTRLOOP (e, lstat (path, buf));
+ return e;
+}
+#endif
+
void
dir_setup_glob (glob_t *gl)
{
gl->gl_opendir = open_dirstream;
gl->gl_readdir = read_dirstream;
gl->gl_closedir = free;
+ gl->gl_lstat = local_lstat;
gl->gl_stat = local_stat;
- /* We don't bother setting gl_lstat, since glob never calls it.
- The slot is only there for compatibility with 4.4 BSD. */
}
void
EOP
./configure --prefix="$LOCAL/stow/$PKG-$VER"
if command -v make >/dev/null; then
make -j $J update
make -j $J
else
./build.sh
fi
./make -j $J PERL_USE_UNSAFE_INC=1 check
./make -j $J install
cd "$LOCAL/stow"
if command -v stow >/dev/null; then
echo $PKG-[0-9]* | xargs -n 1 stow --ignore=dir -D
stow --ignore=dir $PKG-$VER
fi
EOT
インストール例
日付 バージョン OS 依存関係
2018-04-07 4.2.1 Ubuntu 16.04 2019-03-13 4.2.1 Ubuntu 18.04 GNU Make 4.2.1, GCC 7.4.0, GNU Texinfo 6.6
GNU Makeのインストールでは,makeコマンドが存在するかどうかでビルド方法が変わる。リポジトリーからのビルドには,makeが必須となる。従って,GNU Makeが存在しない場合,配布用ソースコード (tar.gz) からビルドすることになる。
makeなしでのGNU Makeのインストール GNU MakeもビルドにAutotoolsやMakeを採用しているため,本来ならばGNU Makeのビルド自体にもGNU Makeが必要 だ。しかし,GNU Makeはインストールできていない場合,GNU Makeをインストールできない。この「自分自身を生成するのに自分自身が必要となる問題」をブートストラップ問題 と呼ぶ。
GNU Makeでは,ブートストラップ問題の対策として,GNU Makeが存在しない環境でGNU Makeをビルドするためのシェルスクリプトbuild.sh
が用意されている。
If you need to build GNU Make and
have no other ‘make’ program to use, you can use the shell script
‘build.sh’ instead. To do this, first run ‘configure’ as described in
INSTALL. Then, instead of typing ‘make’ to build the program, type ‘sh
build.sh’. This should compile the program in the current directory.
Then you will have a Make program that you can use for ‘./make install’,
or whatever else.
Some systems’ Make programs cannot process the
Makefile for GNU Make. If you get errors from your system’s Make when
building GNU Make, try using ‘build.sh’ instead.
README.template – make.git – make
GNU Makeの配布用ソースコード (tar.gz) にはbuild.shのテンプレートであるbuild.sh.inが同梱されており,configure実行時にbuild.sh.inからbuild.shが生成される。このbuild.shを使うことで,makeなしでGNU Makeをインストールできる 。インストール手順では,93行目で./build.sh
でGNU Makeをビルドしている。
ただし,このbuild.shは配布用ソースコード (tar.gz) にしか含まれておらず,リポジトリーからのビルドにはmakeが必須 であることに注意する。
リポジトリーからのビルド
GNU MakeをGitリポジトリーからビルドする場合,注意が必要だ。リリース用のtar.gzには,build.sh.inが同梱されているが,リポジトリー上には含まれていない ためだ。build.sh.inを自分で生成する必要があり,build.sh.inの生成にmakeが必要だ。
そのため,6行目のgitリポジトリーを使う際の判定 (command -v
) に,makeコマンドも追加した。リポジトリーからのビルド手順は「README.git – make.git – make 」に記載がある。
ここにある通り,makeの実行前にmake update
が必要だ。インストール手順では,89行目からmakeが存在する場合にmake updateを実行するようにしている。
./make update
を実行しない場合,翻訳関係のファイルが不足するため,./make install
時に以下のエラーが出る。
Making install in po
make[1]: Entering directory '/home/senooken/.local/src/make/po'
test ! -f ./make.pot || \
test -z "be.gmo cs.gmo da.gmo de.gmo es.gmo fi.gmo fr.gmo ga.gmo gl.gmo he.gmo hr.gmo id.gmo it.gmo ja.gmo ko.gmo lt.gmo nl.gmo pl.gmo pt_BR.gmo ru.gmo sv.gmo tr.gmo uk.gmo vi.gmo zh_CN.gmo" || /home/senooken/.local/src/make/./make be.gmo cs.gmo da.gmo de.gmo es.gmo fi.gmo fr.gmo ga.gmo gl.gmo he.gmo hr.gmo id.gmo it.gmo ja.gmo ko.gmo lt.gmo nl.gmo pl.gmo pt_BR.gmo ru.gmo sv.gmo tr.gmo uk.gmo vi.gmo zh_CN.gmo
make[2]: Entering directory '/home/senooken/.local/src/make/po'
make[3]: Entering directory '/home/senooken/.local/src/make/po'
File be.po does not exist. If you are a translator, you can create it through 'msginit'.
make[3]: *** [Makefile:511: be.po-create] Error 1 また,./make update
実行後に./make install
する場合,GNU Texinfo に含まれるmakeinfo
コマンドが必要となる。GNU Texinfoをインストールしていない場合,./make install
実行時に以下のエラーが出てしまう。
make[1]: Entering directory '/home/senooken/.local/src/make/doc'
restore=: && backupdir=".am$$" && \
am__cwd=`pwd` && CDPATH="${ZSH_VERSION+.}:" && cd . && \
rm -rf $backupdir && mkdir $backupdir && \
if (/bin/bash /home/senooken/.local/src/make/config/missing makeinfo --version) >/dev/null 2>&1; then \
for f in make.info make.info-[0-9] make.info-[0-9][0-9] make.i[0-9] make.i[0-9][0-9]; do \
if test -f $f; then mv $f $backupdir; restore=mv; else :; fi; \
done; \
else :; fi && \
cd "$am__cwd"; \
if /bin/bash /home/senooken/.local/src/make/config/missing makeinfo -I . \
-o make.info make.texi; \
then \
rc=0; \
CDPATH="${ZSH_VERSION+.}:" && cd .; \
else \
rc=$?; \
CDPATH="${ZSH_VERSION+.}:" && cd . && \
$restore $backupdir/* `echo "./make.info" | sed 's|[^/]*$||'`; \
fi; \
rm -rf $backupdir; exit $rc
/home/senooken/.local/src/make/config/missing: line 81: makeinfo: command not found
WARNING: 'makeinfo' is missing on your system.
You should only need it if you modified a '.texi' file, or
any other file indirectly affecting the aspect of the manual.
You might want to install the Texinfo package:
<http://www.gnu.org/software/texinfo/>
The spurious makeinfo call might also be the consequence of
using a buggy 'make' (AIX, DU, IRIX), in which case you might
want to install GNU make:
<http://www.gnu.org/software/make/>
make[1]: *** [Makefile:389: make.info] Error 127
make[1]: Leaving directory '/home/senooken/.local/src/make/doc'
make: *** [Makefile:797: install-recursive] Error 1
GNU Makeをリポジトリーからビルドする場合は,依存先が増え手順が複雑になるので注意する。
glibc 2.26以上でのコンパイルエラー対策 GNU Cライブラリーであるglibcのバージョンが2.26以上である場合,./build.shやmakeの実行時に以下のコンパイルエラーが発生する。
glob.o: In function `glob_in_dir':
/home/senooken/.local/src/make/./glob/glob.c:1367: undefined reference to `__alloca'
/home/senooken/.local/src/make/./glob/glob.c:1342: undefined reference to `__alloca'
/home/senooken/.local/src/make/./glob/glob.c:1256: undefined reference to `__alloca'
/home/senooken/.local/src/make/./glob/glob.c:1283: undefined reference to `__alloca'
glob.o: In function `glob':
/home/senooken/.local/src/make/./glob/glob.c:581: undefined reference to `__alloca'
glob.o:/home/senooken/.local/src/make/./glob/glob.c:732: more undefined references to `__alloca' follow
collect2: error: ld returned 1 exit status glibcのバージョンは,glibcの同梱ソフトの一つのlddコマンドを使って以下のとおりに確認できる。
glibcのバージョン確認方法
ldd --version
ldd (Ubuntu GLIBC 2.27-3ubuntu1) 2.27
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
この問題は以下で議論されている通り,2017-08-02にglibcのバージョンが2.26 に上がり,内部のGLOBインターフェイスのバージョンが1から2に上がったことが原因だ。
On Sat, Nov 18, 2017 at 04:48:12PM -0500, Paul Smith wrote: > One way to fix this would be to change the second #if line above to be: > > # if _GNU_GLOB_INTERFACE_VERSION >= GLOB_INTERFACE_VERSION > > and see if that works. Yes! This solves the issue and it also solves the __stat issues as well. > > Is there anywhere documented what the difference is between version 1 > and version 2? Is it just this symlink change? I’m not sure if the > above change is absolutely correct since it means we’ll always accept > the latest libc glob interface, which seems to defeat the purpose of > having a version in the first place. It seems to be a relatively recent change according to `git blame’. https://sourceware.org/git/?p=glibc.git;a=commit;h=ccf970c7a77e86f4f5ef8ecc5e6 Apparently this patch committed in September 2017 to solve this bug report: https://sourceware.org/bugzilla/show_bug.cgi?id=22183 Within it someone mentions this beautiful gem: * Bump _GNU_GLOB_INTERFACE_VERSION to 2 and forcing new GNUmake build to use its internal glob implementation. Well, that sure backfired quite nicely, haha
Eamestly | Gnu – Make – Bugs – undefined reference to `__alloca’
この不具合は,2017-11-19のコミット で以下のように修正された。
glibc 2.26以上でのコンパイルエラー対策パッチ (48c8a116a914a325a0497721f5d8b58d5bba34d4 )
diff --git a/configure.ac b/configure.ac
index 8c72568..4710832 100644
--- a/configure.ac
+++ b/configure.ac
@@ -404,10 +404,9 @@ AC_CACHE_CHECK([if system libc has GNU glob], [make_cv_sys_gnu_glob],
#include <glob.h>
#include <fnmatch.h>
-#define GLOB_INTERFACE_VERSION 1
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
# include <gnu-versions.h>
-# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
+# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2
gnu glob
# endif
#endif],
ただし,GNU Make 4.2.1は2016-06-10リリースである。GNU
Makeの次期リリース (4.2.2 or 4.3) ではこの不具合は解消されると思われる。GNU Make
4.2.1までは上記パッチが必要なので,インストール手順の18行目からインストール対象GNU Makeのバージョンをチェックし,4.2.1以下の場合は上記のパッチを適用している。
./make checkの失敗対策 前述のglib 2.26以上でのコンパイルエラー対策だけでは,実は対策が不十分だ。この場合,./make check
実行時に以下のエラーが発生してテストに失敗する。
./make check実行時のエラー
functions/wildcard ...................................... Error running /home/senooken/.local/src/make/build/tests/../make (expected 0; got 139): /home/senooken/.local/src/make/build/tests/../make -f work/functions/wildcard.mk.1
Caught signal 11!
Error running /home/senooken/.local/src/make/build/tests/../make (expected 0; got 139): /home/senooken/.local/src/make/build/tests/../make -f work/functions/wildcard.mk.2
Caught signal 11!
FAILED (4/6 passed)
先程のglib 2.26以上でのコンパイルエラーと共に,この問題は「Re: Strange errors regarding function ‘__alloca’ on a Debian buster/sid 」で報告されている。
この問題への対策は,GNU MakeのメインテナーであるPaul Smithにより回答 されていた。以下の2017-10-30のコミット を取り込めばよいととのことだ。
./make check実行時エラーの対策パッチ (193f1e81edd6b1b56b0eb0ff8aa4b41c7b4257b4 )
diff --git a/dir.c b/dir.c
index adbb8a9..c343e4c 100644
--- a/dir.c
+++ b/dir.c
@@ -1299,15 +1299,40 @@ local_stat (const char *path, struct stat *buf)
}
#endif
+/* Similarly for lstat. */
+#if !defined(lstat) && !defined(WINDOWS32) || defined(VMS)
+# ifndef VMS
+# ifndef HAVE_SYS_STAT_H
+int lstat (const char *path, struct stat *sbuf);
+# endif
+# else
+ /* We are done with the fake lstat. Go back to the real lstat */
+# ifdef lstat
+# undef lstat
+# endif
+# endif
+# define local_lstat lstat
+#elif defined(WINDOWS32)
+/* Windows doesn't support lstat(). */
+# define local_lstat local_stat
+#else
+static int
+local_lstat (const char *path, struct stat *buf)
+{
+ int e;
+ EINTRLOOP (e, lstat (path, buf));
+ return e;
+}
+#endif
+
void
dir_setup_glob (glob_t *gl)
{
gl->gl_opendir = open_dirstream;
gl->gl_readdir = read_dirstream;
gl->gl_closedir = free;
+ gl->gl_lstat = local_lstat;
gl->gl_stat = local_stat;
- /* We don't bother setting gl_lstat, since glob never calls it.
- The slot is only there for compatibility with 4.4 BSD. */
}
void
こちらもインストール手順の18行目から,インストール対象のGNU Makeが4.2.1以下の場合にパッチを適用することで対応している。
なお,make check実行時にPERL_UNSAFE_INC=1
を指定 (または事前にexport PERL_UNSAFE_INC=1
を実行) しておかないと,以下のエラーが出るので注意する。
make[2]: Entering directory '/home/senooken/.local/src/make'
cd tests && perl ./run_make_tests.pl -srcdir /home/senooken/.local/src/make -make ../make
Can't locate test_driver.pl in @INC (@INC contains: /home/senooken/perl5/lib/perl5 /home/senooken/perl5/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at ./run_make_tests.pl line 61.
make[2]: *** [Makefile:1281: check-regression] Error 2
make[2]: Leaving directory '/home/senooken/.local/src/make'
make[1]: *** [Makefile:1088: check-am] Error 2
make[1]: Leaving directory '/home/senooken/.local/src/make'
make: *** [Makefile:797: check-recursive] Error 1
make checkにPerlを使っているようで,外部ファイルを読み込んでいる。最近のPerlではセキュリティの観点から,環境変数が有効でないと,外部ファイルを読み込まないらしい。
リンク
関連
“インストール: GNU Make | 数多のビルドに必須のビルドツール” に対して15件のコメントがあります。