ラベル GNU toolchain の投稿を表示しています。 すべての投稿を表示
ラベル GNU toolchain の投稿を表示しています。 すべての投稿を表示

2009年11月26日木曜日

【autotools】10(US 11) GNU Libtoolとconfigure.inおよびMakefile.am

Autotoolsの新刊がもうすぐ発売される。

AUTOTOOLS

GNU Autoconf/Automake/Libtoolは、少々古いので、それを補えるかもしれない。楽しみです。


** 10(US 11) GNU Libtoolとconfigure.inおよびMakefile.am
- この章は、Automake&Autoconfと一緒にlibtoolを使
う方法の説明。
- 一通り読み、ソースを追い、サンプルを試してみた。
- しかし、何かを「わかった」という実感はない。
- こういう内容は結局実戦で使うときに、理解が発生
するのだろう。
- 今は、触れておくことによってその準備をしている
と考えておく。
- なお、サンプルは、私の環境では、なぜか
Segmentation fault。。。

convenience-2.0 $ ./convenience
cos (0) => 1
Segmentation fault
convenience-2.0 $


こつこつ。

2009年11月19日木曜日

【autotools】8(US 9) 小規模なGNU Autotoolsプロジェクト

この本は、GNU Autotoolsの本というよりは、GNU Autotoolsプロジェクトの本だということを実感した。「GNU Autotools」をつかったソフトウエアプロジェクトの実践的なノウハウをチュートリアル形式で教えるというものだ。

C言語の書籍とかUnix APIプログラミングの書籍を読んでも、どうも実際のプログラミングとは距離があるなぁ、と感じていた部分がここだったのか、とも感じた。

また、題材が、Unixシェルを作るためのライブラリというのが面白い。これはいいオモチャを見付けた。先々、いろいろいじってみたい。


** 8(US 9) 小規模なGNU Autotoolsプロジェクト
- 今までの章で学んだことを含めて、小規模なサンプ
ルをいじってみるという内容。
- これは楽しみ。

- 本書では、トップレベルをきれいにしておくために
Autotools中間ファイル(install-shなど)をconfig/
に入れておく、と書かれている。small-1.0ではこう
なっているが、small-2.0では違う。config/ を使う
のはすでに時代遅れということか。
- いや、調べてみると、それはmakeが作るものとなっていた。
- さて、small-2.0のトップレベルはこんな感じ。

Makefile.am
bootstrap
config-h.in~
configure.ac
m4/
replace/
sic/
src/

- config-h.in~が、いまのところ謎。とくに'~'が、、、
- GNUのC言語のスタイルでは、

int func(void)



int
func(void)

とするのはソース検索のためだったのか。それだけ
なのかなぁ。
- libibertyとlibitにフォールバック関数のノウハウ
が蓄積されている。
- Sicというプロジェクトをやってみる。このプロジェ
クトは、Unixシェルのベースを提供するポータブルな
ライブラリを提供するのが目的。
- GNU Autotoolsプロジェクトの実戦的な基礎がつまっ
ている。これはいい!
- このサンプルソースは問題なくビルドできた。
- シェルが動いている!

small-2.0 $ ./src/sic
] date
2009年 11月 19日 木曜日 02:59:19 JST
] ls -F
Makefile autom4te.cache/ config-h.in config.status* m4/ stamp-h1
Makefile.am autoscan.log config-h.in~ configure* replace/
Makefile.in bootstrap* config.h configure.ac sic/
aclocal.m4 config/ config.log configure.scan src/
] exit
small-2.0 $


こつこつ。

【autotools】7(US 8) ブートストラップ


** 7(US 8) Bootstrapping
- メタの更新をどうするか、という話題。メタ、とは、
ソースコードの変更ではなく、configure.acや
Makefile.amを変更したときに、build system全体を
どう更新するか、ということ。
- 現状は、autoreconfが成熟してきたのかな、と思える。
AutomakeのInfoがautoreconfを使っているのと、
autoconf --add-missing で追加されるbootstrapの中
身もautoreconfになっているから。


こつこつ。

【autotools】6(US 7) GNU Automake入門

AutomakeのInfoを読んだ後なので、特にさくっと。

** 6(US 7) Introducing GNU Automake
- Automakeが助けてくれるタスク
1. Build
2. Check
3. Clean
4. Install and uninstall
5. Distribution
- この本、多少古い。現在のAutomakeでは解決されて
いることや、違うやり方のものがそこそこある。そ
れでもいろいろ参考になる。
- AutomakeはDejaGNUとも連携する。DejaGNUはPOSIXの
テストハーネス準拠のテストフレームワーク。
DejaGNUも一度調べてみたい。


こつこつ。

2009年11月18日水曜日

【autotools】5(US 6) ポータブルなconfigure.inの作成


** 5(US 6) Writing `configure.in'
- ポータブルなconfigure.inを書くための指針。
- ノウハウ/tips集の趣もあり。
- autoconfを実戦で使うときに役立ちそうな内容。


こつこつ。

【autotools】4(US 5) 最小規模のGNU Autotoolsプロジェクト (3)


** 4(US 5) A Minimal GNU Autotools Project (again)

- flex/bisonの基礎を勉強。

- とりあえず、parser.yの頭に#includeを入れてばよ
いことがわかった。これが解決なのか?

- AutomakeのInfoを勉強。

- 再度、この問題に取り組む。

- まず、automake --add-missingがものたりなかった
のは、サイトから落としたソースが、

AM_INIT_AUTOMAKE([1.9 foreign])

だったからだ。これを、

AM_INIT_AUTOMAKE([1.9 gnu])

とすれば書籍と同じようになる。出版時から方針が変
わったのだろう。

- さて、勉強してわかったのは、Automakeは依存関係
の処理をビルド時に動的にやっておりそれはdepcomp
が実現しているということだ。

- とすると、parser.cがどうなっているのか、という
ことだ。見ると、parser.cにstdio.hはあるが、こ
れはDEBUGがオンのときだけということだろう。

/* Enable debugging if requested. */
#if YYDEBUG

# ifndef YYFPRINTF
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
# define YYFPRINTF fprintf
# endif

- ちなみにbisonのデバッグをonにしても、コンパイルできた。
- するとやはり、単にソースが間違っているのだろうか?
でもfoonly-1.0のときからinclude無いんだよなぁ。
bisonが、昔はデフォルトでincludeしていたのかなぁ。
うーん。これ以上は書いた人に聞かないとわからない。

- とりあえず、原著者の一人に問い合わせてみた。返
事待ち。こういうメールを送って返事が返ってくる
のは稀なので、期待せずに待ってみよう。

2009年11月17日火曜日

【Automake】Infoを読む (1)

結局Infoをごりごり読んでいる。最近このパターンが多い。
教材の本は、Infoを読むモチベーションを与えてくれている、と考えることにする。


* GNU Automake
** 1 Introduction
- Automakeは、'Makefile.am'から'Makefile.in'を生成
するツールである。
- 'Makefile.am'の中身は、makeの変数定義が連なって
いる。
- 'Makefile.in'の中身は、GNU Makefile standardsに
準拠している。
- Automakeは、そのプロジェクトがAutoconfを使用す
ることを前提としている。また、'configure.ac'の
かきぶりについてAutomakeが求めるところもある。
- Automakeはperlを使っている。

** 2 An Introduction to the Autotools
- AutomakeはThe Autotoolsと呼ばれるツールセットの
一部である。
*** 2.1 Introducing the GNU Build System
- Unixでは、makeというbuild systemが使われていた。
それは'Makefile'を読み込んで動作する。
- 'Makefile'はプラットフォーム毎に調整が必要なも
の。
- それを自動でやるのが'configure'というシェルスク
リプト。
- GNU projectは、この2つをThe GNU Coding
Standardsにて標準化した。もっとも単純なシナリオ
では、 ./configure && make && make install でパッ
ケージの導入が完了する。
- このbuild systemを GNU Build System と言う。
- Autotoolsは、ソフトウエアパッケージのためにa
GNU Build Systemをつくるためのツールである。
- Automakeは'Makefile'にフォーカスし、
Autoconfは'configure'にフォーカスする。

*** 2.2 Use Cases for the GNU Build System
- ubuntu(interpid)にはamhelloは存在しない。リポジ
トリから取ってくる。
git clone http://git.sv.gnu.org/r/automake.git
- Autotoolsが実現していることは、GNU Coding
Standardを越えている。ここでは、これこれが越えて
いる機能です、ということを明示しないこともある。
**** 2.2.1 Basic Installation
- 典型的なシーケンス

tar zxf amhello-1.0.tar.gz
cd amhello-1.0
./configure
make
make check
sudo make install
make installcheck

**** 2.2.2 Standard 'Makefile' Targets
- GNU Conding Standardで説明されているターゲット。

make all
make install
make install-strip
make uninstall
make clean
make distclean
make check
make installcheck
make dist

**** 2.2.3 Standard Directory Variables
- GNU Conding Standardで説明されているディレクト
リ。

Directory variable Default value
-------------------------------------------------------
`prefix' `/usr/local'
`exec_prefix' `${prefix}'
`bindir' `${exec_prefix}/bin'
`libdir' `${exec_prefix}/lib'
...
`includedir' `${prefix}/include'
`datarootdir' `${prefix}/share'
`datadir' `${datarootdir}'
`mandir' `${datarootdir}/man'
`infodir' `${datarootdir}/info'
`docdir' `${datarootdir}/doc/${PACKAGE}'
...

**** 2.2.4 Standard Configuration Variables
- GNU Conding Standardで説明されている構成に関す
る変数。

`CC'
C compiler command

`CFLAGS'
C compiler flags

`CXX'
C++ compiler command

`CXXFLAGS'
C++ compiler flags

`LDFLAGS'
linker flags

`CPPFLAGS'
C/C++ preprocessor flags

...

- configureがこれらを適切に自動設定する。
configureの引数で指定することもできる。

**** 2.2.5 Overriding Default Configuration Setting with 'config.site'
- 'PREFIX/share/config.site'が存在すると、
configureは起動直後にそれをsourceする。
- サイトの共有設定を書いたりする。

**** 2.2.6 Parallel Build Trees (a.k.a. VPATH Builds)
- GNU build systemはソースツリーとビルドツリーを
分離できるつくりになっている。これをparallel
buildsとかVPATH buildsと言う。
- top directoryでmakeすると、ソーツとバイナリが混
在する。
- 分けるには次のようにする。

tar zxf ~/amhello-1.0.tar.gz
cd amhello-1.0
mkdir build && cd build
../configure
make

- これを利用するというか、複数のビルドツリーを持
つことによって、ひとつのソースツリーから多様な
ビルドを並列に配置することができる。

**** 2.2.7 Two-Part Installation
- make installは実体としては、2つの部分でできてい
る。
- make install-execとmake install-data。前者は
arichitecture-dependent files、後者は
architecture-independent filesをインストールする。
- dep/indepはパスによって識別される。exec-prefix
配下に入れるものはdependent、それ以外の場所に入
れるものはindependent。

**** 2.2.8 Cross-Compilation
- configureの引数で指定する。targetは
cross-compilerをビルドするときのみ意味がある。

`--build=BUILD'
`--host=HOST'
`--target=TARGET'

**** 2.2.9 Renaming Programs at Install Time
- インストールするexecutablesの名前を変えることが
できる。configureの引数で指定する。

`--program-prefix=PREFIX'
`--program-suffix=SUFFIX'
`--program-transform-name=PROGRAM'

**** 2.2.10 Building Binary Package Using DESTDIR
- make install and make uninstallは何をどこにイン
ストールしたかを完全には管理していない。
- The GNU Build Systemはa package managerにとって
変われるようなものではない。
- DESTDIRをつかうと何をどこに入れるのかの確認はで
きる。例。

make DESTDIR $HOME/inst install

- また、DESTDIRをつかってインストールツリーを構成
し、それをtarで固めることによって、同じプラット
フォームの別ホストにインストールする簡易パッケー
ジみたいにはできる。

**** 2.2.11 Preparing Distributions
- make distで'package-version.tar.gz'をつくること
ができる。
- make distcheckは、できるものは同じだが、いろい
ろなテストを実施してくれる。
- make, make check, make install,
make installcheck, make distをテスト。
- VPATH buildsをテスト。
- make clean, make dist clean, make uninstallを
テスト。
- DESTDIRインストールをテスト。
- すごいな、、、

**** 2.2.12 Automatic Dependecy Tracking
- dependency trackingはコンパイルの際に副作用とし
て実行される。
- ここでDependencyとは、C言語でいうとコンパイルし
ようとしているCソースの中でincludeされている
headersのこと。
- dependency trackingは一回だけしかbuildしないな
ら、意味はない。どうせ全部buildしないといけない
から。
- dependency trackingは二回目以降のbuildを効率化
する。

- configureの引数でon/offできる。

`--disable-dependency-tracking'
`--enable-dependency-tracking'

**** 2.2.13 Nested Packages
- GNU Build Systemsはネストすることができる。
- 一般にはあまり使わないが、GCCはこの機能をヘビー
に使っている。
- くわしくは、configure --help=recursive

*** 2.3 How Autotools Help
- 手で、Autotoolsを使わずに、the GNU Build System
をつくる('Makefile'と'configure'を書く)のは、や
らないほうがいい。

*** 2.4 A Small Hello World
- 'amhello-1.0'をゼロから作ってみる。すなわち、
`configure.ac'と`Makefile.am'などを書く。
**** 2.4.1 Creating 'amhello-1.0.tar.gz'
- 次のようなファイルとディレクトリをつくる。

~/amhello % cat src/main.c
#include
#include

int
main (void)
{
puts ("Hello World!");
puts ("This is " PACKAGE_STRING ".");
return 0;
}
~/amhello % cat README
This is a demonstration package for GNU Automake.
Type `info Automake' to read the Automake manual.
~/amhello % cat src/Makefile.am
bin_PROGRAMS = hello
hello_SOURCES = main.c
~/amhello % cat Makefile.am
SUBDIRS = src
dist_doc_DATA = README
~/amhello % cat configure.ac
AC_INIT([amhello], [1.0], [bug-automake@gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
~/amhello %

- 次のように使う。

amhello-selfmade $ autoreconf --install
configure.ac:2: installing `./install-sh'
configure.ac:2: installing `./missing'
src/Makefile.am: installing `./depcomp'
amhello-selfmade $ ls -lR
.:
合計 260
-rw-r--r-- 1 aka aka 37 2009-11-17 00:52 Makefile.am
-rw-r--r-- 1 aka aka 19940 2009-11-17 00:55 Makefile.in
-rw-r--r-- 1 aka aka 100 2009-11-17 00:51 README
-rw-r--r-- 1 aka aka 32230 2009-11-17 00:55 aclocal.m4
drwxr-xr-x 2 aka aka 4096 2009-11-17 00:55 autom4te.cache
-rw-r--r-- 1 aka aka 557 2009-11-17 00:55 config.h.in
-rwxr-xr-x 1 aka aka 131436 2009-11-17 00:55 configure
-rw-r--r-- 1 aka aka 188 2009-11-17 00:53 configure.ac
-rwxr-xr-x 1 aka aka 17867 2009-11-17 00:55 depcomp
-rwxr-xr-x 1 aka aka 13620 2009-11-17 00:55 install-sh
-rwxr-xr-x 1 aka aka 11135 2009-11-17 00:55 missing
drwxr-xr-x 2 aka aka 4096 2009-11-17 00:55 src

./autom4te.cache:
合計 332
-rw-r--r-- 1 aka aka 131773 2009-11-17 00:55 output.0
-rw-r--r-- 1 aka aka 131773 2009-11-17 00:55 output.1
-rw-r--r-- 1 aka aka 5875 2009-11-17 00:55 requests
-rw-r--r-- 1 aka aka 30309 2009-11-17 00:55 traces.0
-rw-r--r-- 1 aka aka 19093 2009-11-17 00:55 traces.1

./src:
合計 24
-rw-r--r-- 1 aka aka 44 2009-11-17 00:52 Makefile.am
-rw-r--r-- 1 aka aka 12428 2009-11-17 00:55 Makefile.in
-rw-r--r-- 1 aka aka 137 2009-11-17 00:51 main.c

amhello-selfmade $ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands
amhello-selfmade $ ls -lR
.:
合計 328
-rw-r--r-- 1 aka aka 20347 2009-11-17 00:58 Makefile
-rw-r--r-- 1 aka aka 37 2009-11-17 00:52 Makefile.am
-rw-r--r-- 1 aka aka 19940 2009-11-17 00:55 Makefile.in
-rw-r--r-- 1 aka aka 100 2009-11-17 00:51 README
-rw-r--r-- 1 aka aka 32230 2009-11-17 00:55 aclocal.m4
drwxr-xr-x 2 aka aka 4096 2009-11-17 00:55 autom4te.cache
-rw-r--r-- 1 aka aka 702 2009-11-17 00:58 config.h
-rw-r--r-- 1 aka aka 557 2009-11-17 00:55 config.h.in
-rw-r--r-- 1 aka aka 7720 2009-11-17 00:58 config.log
-rwxr-xr-x 1 aka aka 29114 2009-11-17 00:58 config.status
-rwxr-xr-x 1 aka aka 131436 2009-11-17 00:55 configure
-rw-r--r-- 1 aka aka 188 2009-11-17 00:53 configure.ac
-rwxr-xr-x 1 aka aka 17867 2009-11-17 00:55 depcomp
-rwxr-xr-x 1 aka aka 13620 2009-11-17 00:55 install-sh
-rwxr-xr-x 1 aka aka 11135 2009-11-17 00:55 missing
drwxr-xr-x 3 aka aka 4096 2009-11-17 00:58 src
-rw-r--r-- 1 aka aka 23 2009-11-17 00:58 stamp-h1

./autom4te.cache:
合計 332
-rw-r--r-- 1 aka aka 131773 2009-11-17 00:55 output.0
-rw-r--r-- 1 aka aka 131773 2009-11-17 00:55 output.1
-rw-r--r-- 1 aka aka 5875 2009-11-17 00:55 requests
-rw-r--r-- 1 aka aka 30309 2009-11-17 00:55 traces.0
-rw-r--r-- 1 aka aka 19093 2009-11-17 00:55 traces.1

./src:
合計 40
-rw-r--r-- 1 aka aka 12491 2009-11-17 00:58 Makefile
-rw-r--r-- 1 aka aka 44 2009-11-17 00:52 Makefile.am
-rw-r--r-- 1 aka aka 12428 2009-11-17 00:55 Makefile.in
-rw-r--r-- 1 aka aka 137 2009-11-17 00:51 main.c
amhello-selfmade $ make
make all-recursive
make[1]: ディレクトリ `/home/aka/local/work/scratch/autotools/amhello-selfmade' に入ります
Making all in src
make[2]: ディレクトリ `/home/aka/local/work/scratch/autotools/amhello-selfmade/src' に入ります
gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -g -O2 -o hello main.o
make[2]: ディレクトリ `/home/aka/local/work/scratch/autotools/amhello-selfmade/src' から出ます
make[2]: ディレクトリ `/home/aka/local/work/scratch/autotools/amhello-selfmade' に入ります
make[2]: `all-am' に対して行うべき事はありません.
make[2]: ディレクトリ `/home/aka/local/work/scratch/autotools/amhello-selfmade' から出ます
make[1]: ディレクトリ `/home/aka/local/work/scratch/autotools/amhello-selfmade' から出ます
amhello-selfmade $ src/hello
Hello World!
This is amhello 1.0.
amhello-selfmade $ make distcheck
{ test ! -d amhello-1.0 || { find amhello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr amhello-1.0; }; }
test -d amhello-1.0 || mkdir amhello-1.0

[snip]

=============================================
amhello-1.0 archives ready for distribution:
amhello-1.0.tar.gz
=============================================
amhello-selfmade $

- autoreconfは、autoconfやautomakeやその他種々の
ツールを適切な順番で呼び出してくれる。

**** 2.4.2 'amhello-1.0' Explained
***** configure.acについて。

AC_INIT([amhello], [1.0], [bug-automake@gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT

- これは、AutoconfもAutomakeも読む。
- これは、M4マクロの連なりである。これらM4マクロ
は、shell codeに展開され、最終的にはconfigureス
クリプトになる。
- `AC_'はAutoconfのマクロ。Autoconfのマニュアルに
説明がある。
- `AM_'はAutomakeのマクロ。Automakeのマニュアルに
説明がある。

- line 1,2

AC_INIT([amhello], [1.0], [bug-automake@gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

- これは、AutoconfとAutomakeの初期化をする。
- `AC_INIT'の引数は、パッケージの名前、バージョン番
号、コンタクトアドレス。
- `AM_INIT_AUTOMAKE'の引数は、`automake'のオプショ
ンのリスト。これはコンパイラのオプションでは無
いことに注意。
- `-Wall' : すべての警告を取扱う
- `-Werror' : 警告をすべてエラーとして扱う
- `foreign' : このパッケージがthe GNU Standard
に準拠していないことを宣言
- GNU packagesはChangeLogとかAUTHORSとかが必
須なのだが、このパッケージには存在しない。
そんなことでautomakeに文句をいわれたくない
ため。

- line 3

AC_PROG_CC

- configureがCコンパイラを探し、それを
CCに設定するようになる。このCCは、Automakeが作っ
たsrc/Makefile.inの中に現われる。

- line 4

AC_CONFIG_HEADERS([config.h])

- configureがconfig.hを作るようになる。
- 具体的には、configure.acの中を知らべて`#define'
によって定義されているもの収集する。この例では、
例えば次のものが含まれる。

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "amhello 1.0"

- main.cはconfig.hをincludeしているので、これを使
うことができる。

- line 5

AC_CONFIG_FILES([
Makefile
src/Makefile
])

- configureが`*.in'テンプレートから生成すべきファ
イルを指定する。
- また、Automakeもこれをscanする。処理すべき
Makefile.amをここで特定するのだ。

- line 6

AC_OUTPUT

- ファイル生成処理を開始する。
- 具体的には、AC_CONFIG_FILESとAC_CONFIG_HEADERS
で指定したものを作る。

- これでcounfigure.acはおしまい。
- 実戦でも、このくらいの簡単なものから徐々に育て
るのがよい。
- autoscanを使うのもよい。必要なテストをいろいろ
提案してくれる。

***** Makefile.amについて。
- src/Makefile.am

bin_PROGRAMS = hello
hello_SOURCES = main.c

- これはhelloをコンパイルする。
- Makefile.amの構文はMakefileと一緒。
- Makefile.amの内容は、そのまま、全て、
Makefile.inに含まれる。
- ただしそれだけではない。automakeは、build rules
や他の変数定義を追加する。
- _PROGRAMSで終わる変数は、Makefileがbuildすべき
programsを格納する。
- この`_PROGRAMS'というサフィックスをAutomakeでは
"primary"と言う。他のprimariesとして、
`_SCRIPTS'、`_DATA'、`_LIBRARIES'などなどがある。
- `bin_PROGRAMS'の`bin'は、成果物をBINDIRにインス
トールすべきことを示す。
- PROG_SOURCESは前項をbuildするためのsource files
を指定する。

- Makefile.am

SUBDIRS = src
dist_doc_DATA = README

- SUBDIRSは、再帰すべきディレクトリのリスト。
- dist_doc_DATA = READMEは、READMEを配布物と認識
し、DOCDIRにインストールすることを示す。
- `_DATA' primaryに属するファイルは、デフォルトで
は配布物にならない。なので、このような指定をす
る。


こつこつ。

2009年11月16日月曜日

【autotools】4(US 5) 最小規模のGNU Autotoolsプロジェクト (2)

この段階で一回解決にトライ。
まず、flexとbisonのかきぶりがわかったので、単純に言えば、次のようにparser.yに追記をしてしまえばmake allは通るようになる。(%{から%}を追加)

%{
# include <stdio.h>
%}
%%
x : '\n' ;
%%
yyerror (s)
char *s;
{
fprintf (stderr, "%s\n", s);
}

しかしこのプロジェクトどのソースもincludeが存在しない。なので、includeすべきものをなんらかの機構で自動構成しようとしていると思える。だとすれば、この追記は解決ではない。

さて、これを切り分けるにはAutotoolsの仕組みについてもう少し知識が必要。なんだか卵と鶏になっている。。。

本意ではないが、InfoのAutomake/Autoconfを少し掘ってみよう。

こつこつ。

【flex&bison】1 Introducing Flex and Bison


* flex & bison
- ソースは公開されている。
ftp://ftp.iecc.com/pub/file/flexbison.zip
- はじめのうちは慣れるためにソースを写経する。また
このメモにも掲載する。先々は公開ソースをそのまま
使う。その場合は公開ソースのファイル名だけ掲載し
て、ソース自体は掲載しないこともある。
- ソースコードの著作権は次のとおり。

------
Copyright (c) 2009, Taughannock Networks. All rights reserved.
------

** 1 Introducing Flex and Bison
- Flex and Bison はコンパイラやインタプリタのため
のものだが、入力のパターンを取り扱うようなソフ
トウエア開発一般に使える。
- いろいろなDSLにも使われている。

*** Lexical Analysis and Parsing
- コンパイラの研究によって、syntax analysisという
のはwell-understoodとなった。
- そこで重要なアイデアは、処理を次の2つにわけると
いうこと。
1. lexical analysis (lexing,scanning or 字句解析)
2. syntax analysis (parsing or 構文解析)
- scanningは、入力をぶつ切りにする。ただしそれぞ
れの塊が意味をもつように。この塊をtokensと呼ぶ。
- parsingは、tokensが御互いにどういう関係にあるか
を決定する。

*** Regular Expressions and Scanning
- flexは通常、入力から文字の並びのパターンを探す。
- a flex programは基本的には、正規表現とan action
との組のリストである。actionsは、その正規表現に
マッチしたときに何をすべきかを記述している。

*** Our First Flex Program
- flexのプログラムの大部分はCである。
- %%行で3つの部分に区切られている。
1. 宣言とオプション設定。%{と%}の間は、生成する
Cのコードの先頭付近にそのまま採用される。
2. パターンとアクションの組のリスト
3. Cのコード。生成するCのコードにそのまま採用さ
れる。

- 例

/* file: fb1-1.l */
/* just like Unix wc */
%{
int chars = 0;
int words = 0;
int lines = 0;
%}

%%

[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n { chars++; lines++; }
. { chars++; }

%%

main(int argc, char **argv)
{
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
}
/* end of file */

- 使ってみる

flex&bison $ flex fb1-1.l
flex&bison $ cc lex.yy.c -lfl
flex&bison $ ./a.out
The boy stood on the burning deck
chelling peanuts by the peck
2 12 63
flex&bison $

*** Programs in Plain Flex
- 単純なアプリケーションは、flexだけで書ける。
flexだけ、というのはCのコードを含まない、という
こと。
- 例

/* file: fb1-2.l */
/* English -> American */
%%
"colour" { printf("color"); }
"flavour" { printf("flavor"); }
"clever" { printf("smart"); }
"conservative" { printf("liveral"); }
. { printf("%s", yytext); }
%%
/* end of file */

- 使ってみる。

flex&bison $ flex fb1-2.l
flex&bison $ cc lex.yy.c -lfl
flex&bison $ ./a.out
He is clever and conservative
He is smart and liberal
flex&bison $

*** Putting Flex and Bison Together
- この節からflexとbisonの両方を使う例を構築してい
くようだ。お題は算術計算。
- とりあえずflex。

/* file: fb1-3.l */
/* recognize tokens for the calculator and print them out */
%%
"+" { printf("PLUS\n"); }
"-" { printf("MINUS\n"); }
"*" { printf("TIMES\n"); }
"/" { printf("DIVIDE\n"); }
"|" { printf("ABS\n"); }
[0-9]+ { printf("NUMBER %s\n",yytext); }
\n { printf("NEWLINE\n"); }
[ \t] { }
. { printf("Mystery chracter %s\n",yytext); }
%%
/* end of file */

- 使ってみる

flex&bison $ flex fb1-3.l
flex&bison $ cc lex.yy.c -lfl
flex&bison $ ./a.out
12+34
NUMBER 12
PLUS
NUMBER 34
NEWLINE
5 6 / 7q
NUMBER 5
NUMBER 6
DIVIDE
NUMBER 7
Mystery chracter q
NEWLINE
flex&bison $

*** The Scanner as Coroutine
- yylex()はcoroutine。
- coroutineはどこまで処理をしたか覚えていて、再度
呼ばれるとそこから処理を再開する。
- actionがreturnするなら、yylex()はそこでいったん
returnし待機する。
- 違う言い方をすると、actionがreturnするまで、
yylex()は処理(マッチ)を続ける。
- coroutineは、継続のクロージャみたいなものかな。

*** Tokens and Values
-

/* file: fb1-4.l */
/* recognize tokens for the calculator and print them out */

%{
enum yytokentype {
NUMBER = 258,
ADD = 259,
SUB = 260,
MUL = 261,
DIV = 262,
ABS = 263,
EOL = 264 /* end of line */
};

int yylval;

%}

%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
[ \t] { /* ignore white space */ }
. { printf("Mystery character %c\n", *yytext); }
%%
main()
{
int tok;

while(tok = yylex()) {
printf("%d", tok);
if(tok == NUMBER) printf(" = %d\n", yylval);
else printf("\n");
}
}
/* end of file */

*** Grammars and Parsing
- parserの仕事は、tokensの関係を決定することだっ
た。
- 関係の表現は、通常、parse treeにて行う。
- bisonは、tokensのstreamから逐次処理をしていく。
bisonプログラムのかきぶりによって、parse treeを
メモリ上のデータとして現出させることもできるし、
逐次処理=具体的な操作として、データとして保持
しなこともある。

*** BNF Grammars
- CFGとBNFの簡単な説明。
*** Bison's Rule Input Language
- bisonのプログラムのかきぶりについて。
- まず、大枠の構造はflexと同じ。
- flexのpattern-actionの部分が、BNFチックになる。
- bisonにもactionがあり、ここにCコードを書くのが
意味の定義になる。
- 例

/* file: fb1-5.y */
/* simplest version of calculator */
%{
# include
%}

/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL

%%

calclist: /* noshing */
| calclist exp EOL { printf("= %d\n", $2); }
;

exp: factor
| exp ADD exp { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
| exp ABS factor { $$ = $1 | $3; }
;

factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;

term: NUMBER
| ABS term { $$ = $2 >=0? $2 : - $2; }
;
%%
main(int argc, char **argv)
{
yyparse();
}

yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
/* end of file */

- 宣言部の%tokenは、それらsymbolsがこのプログラム
のなかでtokensであることを宣言している。
- tokensとなるsymbolは大文字にするのが慣例。
- tokensではないsymbolはBNFの左側にくるべき。(変
項ということだろう)
- bisonのルールにでてくるsymbolsはそれぞれ値を持
つ。左側(ターゲット)のsymbolの値は$$で表す。右
側のsymbolsの値は、$1,$2,...で表す。

*** Compiling Flex and Bison Programs Together
- flexプログラムをbisonと協調するように変更。

/* file: fb1-5.l */
/* recognize tokens for the calculator and print them out */

%{
# include "fb1-5.tab.h"
%}

%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
[ \t] { /* ignore white space */ }
. { printf("Mystery character %c\n", *yytext); }
%%
/* end of file */

- コンパイルが若干複雑になるのでMakefileを用意す
る。該当ルールは次のとおり。

fb1-5: fb1-5.l fb1-5.y
bison -d fb1-5.y
flex fb1-5.l
cc -o $@ fb1-5.tab.c lex.yy.c -lfl

- 使ってみる。

1-5 $ make fb1-5
bison -d fb1-5.y
fb1-5.y: conflicts: 3 shift/reduce
flex fb1-5.l
cc -o fb1-5 fb1-5.tab.c lex.yy.c -lfl
1-5 $ ./fb1-5
3 * 2
= 6
55 + 3 * 5
= 70
1-5 $

*** Ambiguous Grammars: Not Quite
- bisonもprologのようにbinary operatorsに対する
operator precedenceの指定ができるようだ。

*** Adding a Few More Rules
- 括弧を取り扱えるようにする。
- プロンプトを出す。

*** Flex and Bison vs. Handwritten Scanners and Parsers
- (flexの)パターンマッチは記述力が強力なので、Cで
scannerを書くよりメリットがある。とくに拡張性な
ど。

*** Exercise
- 割愛


もしかして、Chapter 1だけでスタックから抜けられるかも?
せっかくだからChapter 2 Using FlexとChapter 3 Using Bisonもやっておこうかどうしようか。

こつこつ。

flex & bison を勉強する

flex & bison の基礎を勉強する。
あまり深掘りしないようにしたい。

教材は、

flex & bison

とする。これ、いつか読みたいなぁと思って買っておいたら、こんなに早く手をつけることになるとは。。。

こつこつ。

【autotools】4(US 5) 最小規模のGNU Autotoolsプロジェクト


** 4(US 5) A Minimal GNU Autotools Project
- 書籍ではconfigure.inだがソースはconfigure.ac。
- 現在はconfigure.acが推奨されているらしい。.inと
いう拡張子がautoconfと紐付いていることを明示し
てないかららしい。

- お、書籍にあるような"not found"は出てこない。

foonly-2.0 $ automake --add-missing
configure.ac:7: installing `./install-sh'
configure.ac:7: installing `./missing'
Makefile.am: installing `./depcomp'
configure.ac: installing `./ylwrap'
foonly-2.0 $

- しかも、'make all'が失敗する。

foonly-2.0 $ make all
gcc -DPACKAGE_NAME=\"foonly\" -DPACKAGE_TARNAME=\"foonly\" -DPACKAGE_VERSION=\"2.0\" -DPACKAGE_STRING=\"foonly\ 2.0\" -DPACKAGE_BUGREPORT=\"gary@gnu.org\" -DPACKAGE=\"foonly\" -DV$
parser.y: In function ‘yyerror’:
parser.y:7: 警告: incompatible implicit declaration of built-in function ‘fprintf’
parser.y:7: error: ‘stderr’ undeclared (first use in this function)
parser.y:7: error: (Each undeclared identifier is reported only once
parser.y:7: error: for each function it appears in.)
make: *** [parser.o] エラー 1
foonly-2.0 $

- これ、ヘッダが読めてないのかな? 原因はわからな
いが、CLで言えば、シンボルの検索に失敗している
のだろう。
- しばらくconfigure.logなどを探ってみるが、どこの
誰がこのヘッダの面倒をみるべきで、それをやって
いないのかがわからない。
- そもそも、lex/yacc(flex/bison)を知らない。
- しょうがない、まずそっちを勉強しよう。。。

スタックが深くなってきた。
Emacs22 -> Debian -> make -> Autotools -> lex/yacc(flex/bison)
戻れるかなぁ。

こつこつ。

【autotools】3(US 4) Makefile入門


** 3(US 4) Introducing `Makefile's
- 拡張されていないmake文法。
- なので、Suffix rulesもold style。
- さすがに"GNU make"を読んだ直後なので理解に困難は無い。
- オンラインの英語版と書籍で章番号がずれていること
に気がついた。英語版の方が1多い。USの章番号を括
弧で書くことにする。


こつこつ。

2009年11月15日日曜日

【autotools】2 configureとmakeの実行方法


2 How to run configure and make

- mmalloc-1.0.tar.gzがどこにもころがってなさそう。
- host-build-targetの関係がわからないので、調べた。
- host: コンパイルしたプログラムが動く計算機
- build: プログラムをコンパイルする計算機
- target: コンパイルしたプログラムがバイナリを
出力するとき、そのバイナリが動く計算機 (クロ
スコンパイラなど)


一章1エントリだと更新頻度が高くなるかも。
まあいいか。

こつこつ。

【autotools】1 歴史

英語版がオンラインで読める!
しかも更新されている!

GNU AUTOCONF, AUTOMAKE AND LIBTOOL

ありがたい。

一章完了。

こつこつ。

GNU Autotools を勉強

makeをかじったので、この際GNU Autotoolsをざっと概観しよう。

Autotoolsは、主にAutoconf/Automake/Libtoolの3つで構成されている。

教材は、

GNU Autoconf/Automake/Libtool

にする。この本、メモ的にまとまっている本のようなので、学習ブログとして書くことが無いかも(本文そのままになってしまう。。。)

とりあえず、進捗と気づいた点があれば書くことにしよう。

こつこつ。

【make】8 CとC++

ノウハウ的な内容なので、概要のみ記述。
実際にC/C++のプロジェクトを自分でやるときには、テンプレとして重宝すると思う。


* 8 CとC++
** 8.1 ソースとバイナリの分離
- makeはもともと単一ディレクトリにファイルがまとめ
てあるときにうまく機能するように作られている。
- なので、ソースツリーとバイナリツリーを分けると
きには工夫が必要。
*** 8.1.1 簡単な方法
- makeをバイナリツリーディレクトリから起動する方
法。
*** 8.1.2 難しい方法
- makeをソースツリーディレクトリから起動する方法。
** 8.2 読み出し専用のソース
- yaccなどでソースを生成する場合は、ソースツリーを
読み出し専用にするには困難がある場合がある。
- 古いパッケージはソースツリーにそれら生成ソース
を配置するようにしていることがあるからだ。
- それらに対処するために、リファレンスとして複数の
ソースツリーを持つというのもあり。
** 8.3 依存関係の生成
- 動的に生成する依存関係に関する回避策。
*** 8.3.1 Tromeyの手法
- トリッキーなノウハウ。割愛。
*** 8.3.2 makedependプログラム
- 依存関係を生成するプログラムはいくつかある。Xの
開発の際にはmakedependというプログラムが作られ
た。
- gccは、依存関係生成のスイスアーミーナイフ。実際
にコンパイルに使うプログラムがgccじゃないとして
も、gccを依存関係生成に使うというのもあり。
** 8.4 複数のバイナリツリーを利用する
- ソースツリーとバイナリツリーの分離ができてしま
えば、バイナリツリーを複数化するのは簡単。
** 8.5 部分的なソースツリー
- 大きなプロジェクトでは、個別開発者がプロジェク
ト全体をチェックアウトして作業するのは負担。
- リファレンスをシステム上にひとつ置き、プログラ
マは担当部分のみをチェックアウトする。
- これを実現するには担当しているcomponentについて、
それ以外のヘッダファイルやライブラリファイルは
リファレンスツリーを参照するようにmakefileを調
整する必要がある。
- しかし、この手法はかなり複雑になり、実用性には
疑問もある。
** 8.6 リファレンスビルド、ライブラリ、インストーラ
- SCMについて、CVSを前提としているところが、なんだ
か。せめてSubversionも対象として欲しいところ。


おお、これでmakeを読めるようになるという所期の目的は達成できたような。
次はなにを勉強しようか。せっかくだからもうちょいGNUを掘ってみるかなぁ。

こつこつ。

【make】7 ポータブルなmakefile

この章、短い。


* 7 ポータブルなmakefile
- 最小公倍数方式:2つある。
- 対象となるすべてのプラットフォームで共通に利用
可能なツールだけをつかう。
- 使いたいツールを選び、対象となるすべてのプラッ
トフォームでそれが使えるように、必要に応じて
移植する。
- makeで差異を吸収:
- マクロや関数でプラットフォームの差異を吸収。

** 7.1 移植における問題点
- ここでの「移植」とはmakefileの移植というか自分
が作っているパッケージの移植のことだと思う。
- ポイントは次のもの
- プログラム名
- パス名
- オプション
- シェル機能
- プログラムの挙動
- OS

** 7.2 Cygwin
- Cygwinは当面関わることはないので、この章割愛。
*** 7.2.1 行末文字
*** 7.2.2 ファイルシステム
*** 7.2.3 プログラムの衝突

** 7.3 プログラムとファイルを管理する
- プログラム名は変数に格納する。
- ifdefなどをつかって、プラットフォーム毎に値を変
える。
- プラットフォーム毎に設定べきものが大量にある場合
は、別途定義ファイルに記述する。unameになどに因
んだファイル名とし、includeする。

** 7.4 ポータビリティのないツールで作業する
- まず、GNUのプログラムはポータビリティがあると考
えているようだ。
- 次に、perlやpythonはGNUのプログラムではないが、
同等のポータビリティがあると考えているようだ。
- それ以外のものの中に、ポータビリティが無いもの
がある。
- それを使う場合には、関数を作って、その呼び出し
の引数でそれぞれのプラットフォーム毎のプログラ
ムを指定するようにする。
- この節、何が主題なのか、ちょっとわかりずらい。

*** 7.4.1 標準シェル
- /bin/shにも非互換性がある。
- 自分のプロジェクトなら、これを/bin/bashなど、他
のシェルに固定するのもあり。

** 7.5 automake
- automakeは、昔ながらのmakefileを生成する。すな
わち互換性を重視して、"GNU make"の拡張機能はア
ペンド(+=)以外は使わない。
- すなわち最小公倍数型である。
- 最小公倍数型で行く場合は、automakeの使用を検討
するのもよい。


さあ、次は(自分としての)最終章!
こつこつ。

【make】6 大きなプロジェクトの管理

ゴールが見えてきた!


* 6 大きなプロジェクトの管理
- まず、大きなソフトウエアは、それを書くことにお
いてもコンポーネントへの分割が重要となる。
- makeによる構築もそれに従う。コンポーネント毎の構
築を行うmakefileを作ることになる。そしてトップ
レベルにそれらmakefilesを管理するmakefileを置く。
- この手法を再帰的makeと呼ぶ。
- 再帰的makeはいくつか課題をもつ。
- それを回避するために、トップレベルのmakefileが
各コンポーネントディレクトリを調べることによっ
て、すべての構築処理を管理するという非再帰的
makeという手法もある。
- コンポーネント分割の他に、次のようなトピックが
ある。
- 複数バージョンの取扱い
- マルチプラットフォームの取扱い
- ディレクトリ構成の工夫

** 6.1 再帰的make
- 再帰はシェルスクリプトではなく、makeで書いたほ
うがよい。

- makeで書いた例

------
components := lib/a lib/c hoge piyo

all: $(components)

$(components):
$(MAKE) --directory=$@
------

- シェルスクリプトで書いた例

------
components := lib/a lib/c hoge piyo

all:
for d in $(components); \
do \
$(MAKE) --directory=$$d; \
done
------

- なぜか?
- 呼び出し元のmakeにエラーが返らない。
- 並列化ができない。

- 前提条件について、GNU makeは左から右へ実行して
いく。また、あるターゲットの前提条件が複数行に
かかれていたときどうなるかは実装依存である。前
提条件の実施順について構築上必須の部分があるな
ら、それにケアして前提条件を並べるべきである。

*** 6.1.1 コマンドラインオプション
- makeはMAKEFLAGS変数を通じて、下位のmakeにコマン
ドラインオプションを引き継ぐ。
- 一部のコマンドラインオプションは特別扱いとなる。
例えば、--touch、--just-print、--question。
- makeを呼ぶルール自体はPHONYなので、これらオプショ
ンでは実行されないのが基本。これを実行させるよ
うにmakeが振る舞う。

*** 6.1.2 値を渡す
- makeの間で値を渡すには環境変数を使う。
- makeのexport/unexport命令で制御する。
- --environment-overridesを使うと、下位のmakefile
で環境変数由来の変数に代入していても、それを無
視して環境変数の値を使う。
- overrideを使うと、--environment-overridesがあっ
たとしても、変数の代入を実行する。例。

------
override TMPDIR = ~/tmp
------

*** 6.1.3 エラー処理
- 下位のmakeのエラーは、上位へ伝搬し、トップの
makeの処理が止まる。
- --keep-goingをトップで指定しているなら、それは
全てのmakeに渡される。

*** 6.1.4 その他のターゲットの構築
- cleanとかinstallとかのPHONYなターゲットを再帰的
にするにはどう書くか。こう書く。

------
$(components):
$(MAKE) --directory=$@ $(TARGET)
$(if $(TARGET), $(MAKE) $(TARGET))
------

- これによって、任意のターゲットを再帰的に渡すこ
とができる。

*** 6.1.5 makefileの相互依存
- ヘッダファイルなどについてコンポーネント間で依
存関係が発生することがある。
- 特にコードジェネレータを使っている場合、先に一方
のコンポーネントを構築しないと、適切なハッダファ
イルが存在しないことになる。
- これはトップレベルで地道に依存関係を作り込むし
かない。

*** 6.1.6 コードの重複を回避する
- makefile間でのコードの重複を避けるには、共用ファ
イルをつくりincludeする。
- ちなみに、こういうファイルの拡張子は.mk。

** 6.2 非再帰的make
- 各componentのディレクトリには、component.mkを置
く。そこには、そのcomponentに関する変数定義とルー
ル定義をおこなう。
- トップレベルのmakefileはそれらをincludeする。ま
た、このmakefileには各componentからの情報を集積
する変数を定義しておく
- component.mkには、集積する変数に自分が定義した
ものを投入していく。

** 6.3 巨大システムのコンポーネント
- ビルドシステムの構成に関する一般則
- ソースとバイナリの置き場所は分けるべき。
- それぞれのディレクトリ構造をソースツリー・バ
イナリツリーと呼ぶ。
- リファレンスを運用すべき。
- リポジトリからチェックアウトした状態のソース
と、それをそのままビルドしたバイナリを、あわ
せてリファレンスという。
- それぞれツリーを成している場合、それぞれリファ
レンスソースツリー・リファレンスバイナリツリー
と呼ぶ。
- リファレンスソースツリーは読み出し専用にす
べき。

** 6.4 ファイルシステムの配置
- バイナリツリーの配置に注意すべし。
- 名前の付け方の工夫が有効。
- 構築パラメータをパスに含める。
例。

------
vendor-architecture-os-memo

dell-386-linux-debug
------

** 6.5 構築とテストの自動化
- 構築の自動化は大事。
- テストの自動化も大事。
- テストの自動化はグラフィカルかそうじゃないかで
大別。
- グラフィカル(X): Xvfb
- 非グラフィカル: devaGnu, JUnit


こつこつ。

2009年11月14日土曜日

【make】5 コマンド(2)

教材本をさくっと。


** 5.1 コマンドの構文解析
- 教材をさくっとやる。
- ここはrule contextのお話。
- Infoの内容を理解していればOK。

*** 5.1.1 長いコマンド
- backslashの取扱い。
- Infoの内容を理解していればOK。

*** 5.1.2 コマンド修飾子
- '@'、'-'、'+'の3つ。'+'だけここに書く。
- '+'
--just-printでmakeを起動したときもこのcommandを
実行する。

*** 5.1.3 エラーと中断
- '-'を使うのはあまりよくない。該当commandの
optionで対応できるなら、その方がベター。
- エラーを返しても続行させる場合のノウハウいくつ
か。

** 5.2 空のコマンド
- Infoとほぼ同じ。

** 5.3 コマンド環境
- makeが実行するコマンドは、(アタリマエだが)make
自身の実行環境を継承する。

** 5.4 コマンドを評価する
- 既出。

** 5.5 コマンドラインの制限
- 例えばRedhat 9では、コマンド行長のshellの上限は
128K文字。
- 文字数が上限を越えないように、処理を分割するノ
ウハウをいくつか。


次回は、「6 大きなプロジェクトの管理」。

その後、「7 ポータブルなmakefile」を経て「8 CとC++」にてmakeの基礎勉強は終了にしようと思う。それ以降の章は応用なので、必要に応じて参照することにしたい。

こつこつ。

【make】5 コマンド(1)

makeのInfoが良く書けている。入門はこれだけでいけると思う。書籍"GNU make"は、Infoを参照しつつ、使いこなしのtipsをこの本から得るという位置付けがよいかも。


* 5 コマンド
- うーん。この章もいまひとつわかりにくい。
- infoの方がわかりやすい気がする。
- もしかしたら、infoがけっこうちゃんと書かれてい
るので、それとは違うことを書こうとしてこういう
風になっていのかなぁ。
- いずれにしても、infoをやった方がよさそうだ。

** 5 Writing the Commands in Rules
- makeによるコマンドゾーンの取扱い
- 一行毎に取扱うのが基本
- 書かれた順に、一行毎に実行される。
- デフォルトのシェルは/bin/sh
- これは環境変数のSHELLをみているのではなく、
make独自管理。
*** 5.1 Command Syntax
- makefileというのは、make構文とshell構文という2
つの言語が入り乱れるものである。
- makeはshell構文を基本的には理解しない。よって、
その文字列に必要な処理を加えた上で、シェルにわ
たすだけである。

- rule context とは
- target-and-prerequistes行で始まる。
- 次のtarget-and-prerequistes行がでてきたら終わ
る。
- また、変数定義がでてきても終わる。
- command line とは
- rule contextにあり、行頭文字がタブの行は、
command line for that ruleと呼ばれる。

**** 5.1.1 Splitting Command Lines
- makeはcommand lineのかきぶりに応じて多少振る舞
いをかえる。これはそのひとつ。
- command lineの行末のbackslashを、makeは認識する。
makeは行末がbackslashの間は同一のシェルに
command lineを渡しつづける。

あくまで単一のシェルで処理をするということだけ
がmakeの所作。backslash含めて、各行はそのままシェ
ルに送られる。backslashの行の次の行では、タブか
ら始まっていなくともcommand lineとみなし、シェ
ルにおくる。

------
all :
@echo no\
space
@echo no\
space
@echo one \
space
@echo one\
space
------

結果
------
nospace
nospace
one space
one space
------

**** 5.1.2 Using Variables in Commands
- makeはcommand lineのかきぶりに応じて多少振る舞
いをかえる。これもそのひとつ。
- makeはcommand lineの中の変数参照と関数参照を展開
する。
- 例。

------
LIST = one two three
all:
for i in $(LIST); do \
echo $$i; \
done

# 結果
#for i in one two three; do \
# echo $i; \
#done
#
#one
#two
#three
------

- $が先頭にある文字列について、makeに展開させずに
シェルにそのまま渡したい場合は、$を頭につける。
すなわちシェルに$iをわたしたければ、$$iとする。

*** 5.2 Command Echoing
- makeはcommand lineをシェルに渡す前に、その
command lineを出力する。これによって、どんな
commandが実行されているのかが見てとれる。これを
Echoingと言う。
- command lineのcommandの先頭を'@'にすると、この
Echoingが抑制される。

- 例は既出。

*** 5.3 Command Execution
- 各command line毎に別のsubshellで実行するのが基
本。(実際には結果が変わらない範囲で、同一の
subshellを使いつづける。これは効率のためのmake
の工夫)
- なので、例えば、作業ディレクトリといてcdすると
きなどは注意が必要。そのcdは、そのcommand line
のみで有効だからだ。
- そういう場合は、command lineのシェルとしてのか
きぶりで対応する。

cd $(@D) && gobble $(@F) > ../$@

など。

**** 5.3.1 Choosing the Shell
- makefileで設定したSHELL変数はデフォルトではエキ
スポートされない。

*** 5.4 Parallel Execution
- デフォルトでは、makeはcommandをシーケンシャルに
実行する。
- '-j'をmakeにつけると、複数commandsを並行実行す
るようになる。
- '-j N'とすると同時に最大N個のcommandsを並行実行
する。
- 難点
- makeからのメッセージが混乱して、読みにくい。
- 標準入力を扱うcommandsは、競合し、エラーとな
ることがある。
- '-l R'によって(Rは実数)、makeが並行プロセスを追
加で立ち上げる際に、load averageを確認するように
なる。R以上なら追加しない。

*** 5.5 Errors in Commands
- まず、makeは各command lineの終了時にexit status
を確認する。正常終了であれば、先に進み、エラー
であれば、makeの処理を停止する。これが基本。
- エラーになっても処理を停止したくないcommand
linesには、commandの頭に'-'をつける。

- 例。

------
clean:
-rm -f *.o
------

*** 5.6 Interrupting or Killing 'make'
- C-cなどでmakeを中断した場合、makeを開始したとき
よりも最新の日付にかわっているターゲットは、
makeによって削除される。これは壊れたターゲット
が存在することを避けるためです。
- ターゲットを'.PRECIOUS'で指定すると、この自動削
除は実施されない。

*** 5.7 Recursive Use of 'make'
- これは後の章にて。

*** 5.8 Defining Canned Command Sequences
- defineマクロのこと。

*** 5.9 Using Empty Commands
- Empty Commandsは、

------
target: ;
------

と書いた方がよい。tabだけcommand lineは、見にく
いから。

- これは、暗黙ルールからターゲットを除外するため
に使う。


こつこつ。