2009年11月14日土曜日

【make】4 関数 (2)

教材にしている本の「関数」の章がおわらないとなんかやりかけな感じなので、かけあしでやってしまう。


** 4.1 ユーザ定義関数
- 気になること。makeのinfoでは、

NAME = VALUE

define NAME
...
endef

のどちらもmacroと呼んでいる。しかしこの本は、前
者を変数と呼び、後者のみをmacroと呼ぶ。前者は
VALUEに書けるものに制約があるけれど、それ以外は
機能的な違いは見られれない。

この著者も、前版までは双方ともmacroと書いていた
と訳注にあった。

そのココロは何なんだろう?

** 4.2 組み込み関数
- この節は、infoの内容プラス使いこなしヒントとい
う内容。ヒントはありがたい。が、ここでは割愛。
*** 4.2.1 文字列関数
*** 4.2.2 その他の重要な関数
*** 4.2.3 ファイル名関数
*** 4.2.4 実行制御
*** 4.2.5 比較的重要なその他の関数

** 4.3 高度なユーザ定義関数
- 関数をデバッグするためのinstrumentation。
- 『筆者の知り合いは次のようにいっています。「以
前はmakeがプログラム言語だなんて考えたこともな
かった」と。GNU makeは、いにしえのmakeとは違う
ものになっているのです。』(本書から引用) なるほど。

*** 4.3.1 eval関数と値
- eval関数の使いこなし。割愛。
*** 4.3.2 フック関数
- フック的な使いこなし。割愛。
*** 4.3.3 関数に値を返す
- 割愛。


うむ。すっきりした。
次回は「5 コマンド」。こつこつ

【make】4 関数 (1)

makeは、ちょっとLispの匂いがする。


* 4 関数
- この読書メモ、見出しは本'GNU make'に準拠してい
るが、内容は本そのままではない。
- 本以外にinfoも読んでいる。
- 本とinfoを読んでの自分なりのまとめ。

特にこの節は、Acrobat Readerのプロセスを終了する
例が好みじゃない。

- ということで、まずinfoを中心に関数の基礎を整理す
る。

** 8 Functions for Transforming Text [make.info]
*** 8.1 Function Call Syntax
- 形式
- 変数の似ている
$(FUNCTION ARGUMENTS)
${FUNCTION ARGUMENTS}

- 例1
$(subst ee,EE,feet on the street)
# feet on the street -> fEEt on the strEEt

- 例2 関数の引数に関数をつかう
$(subst ee,EE,$(subst t,T,feet on the street))
# feet on the street -> feeT on The sTreeT -> fEET on The sTrEET

- 例3 関数の引数に変数をつかう
before := ee
after := EE
$(subst $(before),$(after),feet on the street)
# feet on the street -> fEEt on the strEEt

*** 8.2 Functions for String Substitution and Analysis
- 組み込み関数のうち、文字列関係のもの。

- subst
- 形式
$(subst FROM,TO,TEXT)

- 例
上記とおり。

- patsubst
- 形式
$(patsubst PATTERN,REPLACEMENT,TEXT)

- 例
objects = foo.o bar.o baz.o
$(patsubst %.o,%.c,$(objects))
# => foo.c bar.c baz.c

- 例 Substitution referenceという代替手段もある。
objects = foo.o bar.o baz.o
$(objects:.o=.c)
# => foo.c bar.c baz.c

- strip
- 形式
$(strip STRING)

- 例
$(strip " a b c ")
# => " a b c "
$(strip a b c )
# => a b c[行末]

- findstring
- 形式
$(findstring FIND,IN)

- 例
$(findstring a,a b c)
# => a
$(findstring a,b c)
# => [行末]

- filter
- 形式
$(filter PATTERN...,TEXT)

- 例
sources := foo.c bar.c baz.s ugh.h
$(filter %.c %.s,$(sources))
# => foo.c bar.c baz.s

- filter-out
- 形式
$(filter-out PATTERN...,TEXT)

- 例
sources := foo.c bar.c baz.s ugh.h
$(filter-out %.c %.s,$(sources))
# => ugh.h

- sort
- 形式
$(sort LIST)

- 例
$(sort foo bar lose)
# bar foo lose

- word
- 形式
$(word N,TEXT)
- 例
$(word 2, foo bar baz)
# => bar

- wordlist
- 形式
$(wordlist S,E,TEXT)
- 例
$(wordlist 2, 3, foo bar baz)
# => bar baz

- words
- 形式
$(words TEXT)
- 例
$(words foo bar baz)
# => 3

- firstword
- 形式
$(firstword NAMES...)
- 例
$(firstword foo bar)
# => foo

- lastword
- 形式
$(lastword NAMES...)
- 例
$(firstword foo bar)
# => bar

*** 8.3 Functions for File Names
- dir
- 形式
$(dir NAMES...)
- 例
$(dir src/foo.c hacks)
# => src/ ./

- notdir
- 形式
$(notdir NAMES...)
- 例
$(notdir src/foo.c hacks)
# => foo.c hacs

- suffix
- 形式
$(suffix NAMES...)
- 例
$(suffix src/foo.c src-1.0/bar.c hacks)
# => .c .c

- basename
- 形式
$(basename NAMES...)
- 例
$(basename src/foo.c src-1.0/bar.c hacks)
# => src/foo src-1.0/bar hacks

- addsuffix
- 形式
$(addsuffix SUFFIX,NAMES...)
- 例
$(addsuffix .c,foo bar)
# => foo.c bar.c

- addprefix
- 形式
$(addprefix PREFIX,NAMES...)
- 例
$(addprefix src/,foo bar)
# => src/foo src/bar

- join
- 形式
$(join LIST1,LIST2)
- 例
$(join a b,.c .o)
# => a.c b.o

- wildcard
- 形式
$(wildcard PATTERN)
- 例
# touch foo.c foo.o bar.c baz.h ugh.o
# がmakeの第一段階前に為されていることが前提
$(wildcard %.o)
# => foo.o ugh.o

- realpath
- 形式
$(realpath NAMES...)
- 例
$(realpath ./ ../)
# /home/aka/local/work/scratch/make /home/aka/local/work/scratch

- abspath
- 形式
$(abspath NAMES...)
- 例
$(realpath ./ ../)
# /home/aka/local/work/scratch/make /home/aka/local/work/scratch

- realpathとabspathの差異
- abspathはfileが存在するかどうかは関知しない。
realpathは、存在しなければエラー。
- abspathはsymlinkを追わない。realpathは追う。

*** 8.4 Functions for Conditionals
- if
- 形式
$(if CONDITION,THEN-PART[,ELSE-PART])
- 例
$(if "", T, NIL)
# => T
$(if , T, NIL)
# => NIL
$(if "hoge", T, NIL)
# => T
$(if hoge, T, NIL)
# => T

- or
- 形式
$(or CONDITION1[,CONDITION2[,CONDITION3...]])
- 例
$(or first, second, third)
# => first
$(or , second, third)
# => second
$(or , , third)
# => third

- and
- 形式
$(and CONDITION1[,CONDITION2[,CONDITION3...]])
- 例
$(and first, second, third)
# => third
$(and , second, third)
# => [行末]
$(and , , third)
# => [行末]

*** 8.5 The 'foreach' Function
- foreach
- 形式
$(foreach VAR,LIST,TEXT)
- 例
dirs := a b c d
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
# ディレクトリa b c dに含まれているファイルの
# リストをfilesに格納。

*** 8.6 The 'call' Function
- call
- 形式
$(call VARIABLE,PARAM,PARAM,...)
- 例
reverse = $(2) $(1)
$(call reverse,a,b)
# b a

- 補足
$(N)をつかった変数やマクロをcallのパラメータ
で展開する。

*** 8.7 The 'value' Function
- value
- 形式
$(value VARIABLE)
- 例
FOO = $PATH
value:
@echo $(FOO)
@echo $(value FOO)

# => ATH
# => /usr/bin:/usr/local/bin:...

- 補足
値の展開前状態を得る。

*** 8.8 The 'eval' Function
- eval
- 形式
$(eval PARAM)
- 例
define PROC
UNDEFINED += hoge
endef

eval:
# $(UNDEFINED)
# $(eval $(call PROC))
# $(UNDEFINED)

# 最後のUNDIFINEDはhogeになる。

- 補足
引数を展開した上で、それをmakefileの一部であ
るがごとく取り扱う。

*** 8.9 The 'origin' Function
- origine
- 形式
$(origin VARIABLE)
- 例
$(origin LANG)
# => environment

*** 8.10 The 'flavor' Function
- flavor
- 形式
$(flavor VARIABLE)
- 例
SIM := hoge
REC = hoge
$(flavor SIM)
# => simple
$(flavor REC)
# => recursive

*** 8.11 The 'shell' Function
- shell
- 形式
$(shell COMMAND[ ARGS ...])
- 例
shell:
# $(shell date)
# $(shell sleep 5)
# $(shell date)

# 結果
# 2009年 11月 14日 土曜日 00:06:46 JST
#
# 2009年 11月 14日 土曜日 00:06:51 JST

*** 8.12 Functions That Control Make
- error
- 形式
$(error TEXT...)
- 例
$(error found an error!)
# => found an error!

- 補足
makeはexitする。

- warning
- 形式
$(warning TEXT...)
- 例
$(warning found an error)
# => found an error

- 補足
makeはexitしない。

- info
- 形式
$(info TEXT...)
- 例
$(info info printed)
# 標準出力に"info printed"を出力


うひー。こつこつ。

2009年11月11日水曜日

【LPL】9章 限量入門 (5)


  • 9.6 複合名詞句の翻訳

    • この節は、自然言語の文をFOLに翻訳する練習。
    • 特に限量表現が絡むもの。
    • 会話の含みと限量についての説明あり。
    • まず、「空疎に真な一般文」について。
    • 例えば、
      ∀y(Tet(y) → Small(y)).
      これは四面体が存在していて、それらが全てSmallならば真である。しかし真になるのはそれだけではない。四面体がまったく存在しない談話領域でも真である。四面体がまったく存在しないという単純な事実によって真となる、ということを空疎に真という。
    • 続いて、「本質的に空疎」について。
    • 例えば、
      ∀y(Tet(y) → Cube(y))
      も談話領域によっては真となる。ただし、これが真となりえるのは、空疎な真のときだけだ。こういう場合を「本質的に空疎」と言う。



さあ、練習問題。7問、トータル70文くらいの翻訳。のんびりいこう。

こつこつ。

【make】3 変数とマクロ

Unixシェルでものたりなかった部分をmakeがもっている、というか、shell+makeというのは2つで一人前と考えたほうがいいのかもしれない。bashのシェルスクリプトでなんだかなぁ、と思っていた部分をmakeが補完している感じ。


* 3 変数とマクロ
- makeは2つの言語で構成されていると言える。
- ターゲットと前提条件とがつくる依存関係グラフ
- マクロ言語(テキストの置換を行う)
- 変数の形式
- 変数名につかえない文字は、':'、'#'、'='の三文
字。
- case sensitive
- 値の参照は、$(変数名)または${変数名}。ただし
変数名が一文字なら、$変数名もOK。
- 変数への値の束縛/代入において、後続の空白も値
とみなされる点に注意。例

------
CC := gcc # gccの定義
------

この場合、CCの値は、"gcc "となる。

** 3.1 変数を何に使うべきか
- ポータビリティおよびセキュリティのために、コマ
ンドゾーンのプログラム名を変数化するのはよくあ
ること。

** 3.2 変数の種類
- 単純展開変数と再帰展開変数の2種類がある。
- 詳細は3.4を参照
- 単純展開変数
- :=代入演算子で値を代入した変数のこと。
- 再帰展開変数
- =代入演算子で値を代入した変数のこと。

*** 3.2.1 その他の代入
- ?= 条件付き代入演算子
変数に値が無いときだけ代入が実行される。
- += アペンド
変数の値に文字列を追加していく。
** 3.3 マクロ
- =代入演算子の複数行版かな。

------
define print-info
@echo execuring $@ ...
pwd
uname -a
ls -l
endef
------

** 3.4 変数はいつ展開されるか
- makeの二段階処理
1. 第一段階 (read-in phase):
依存関係グラフの作成

makefile及びそれがincludeしているファイルを読
み込み、依存関係グラフを作成する。

依存関係グラフの作成にあたって、全ての変数と
値とルールとを内部に取り込む。

2. 第二段階(target-update phase):
ルール連鎖特定とコマンド実行

存在するファイルの情報と依存関係グラフから構
築に必要なルール連鎖を特定し、それに従ってコ
マンドを実行する。

- makeの変数を展開する2つの文脈
1. 即時文脈(IMMEDIATE):即時文脈にあるとき変数は
第一段階で展開される。

2. 遅延文脈(DEFERRED):遅延文脈にあるとき変数は展
開されずそのままとなる。ただし第一段階の処理
を進めていった結果、それがIMMEDIATEの位置に現
れたら、そのときに展開される。IMMEDIATEの位置
に現れないものは、第二段階で展開される。

- 変数の展開の要点
- 変数代入

IMMEDIATE = DEFERRED
IMMEDIATE ?= DEFERRED
IMMEDIATE := IMMEDIATE
IMMEDIATE += DEFERRED or IMMEDIATE

define IMMEDIATE
DEFERRED
endef

- +=について

左辺が以前に:=で代入されているならIMMEDIATE
になり、それ以外はDEFERREDになる。

- ルール

IMMEDIATE : IMMEDIATE ; DEFERRED
DEFERRED

- 実証用makefile

------
###
### =、?=、:= の基本
###

A1 = $(X1)
B1 := $(X1)

C1 ?= $(Y1)
A1 ?= $(Y1)

X1 := value1
Y1 := value2

.PHONY: all test-1 test-2 test-3 test-4 test-5 test-6
all: test-1 test-2 test-3 test-4 test-5 test-6

test-1:
# =、?=、:= の基本
# A1=$(A1), B1=$(B1), C1=$(C1)
#

# 実行結果
# A1=value1, B1=, C1=value2


###
### += の基本
###

A2 = $(X2)
B2 := $(X2)

A2 += - $(Y2)
B2 += - $(Y2)

X2 := value1
Y2 := value2

test-2:
# += の基本
# A2=$(A2)#
# B2=$(B2)#
#

###
### defineの基本
###

define A3
$(X3)
endef

X3 := value1

test-3:
# defineの基本
# $(A3)
#

###
### DEFFEREDが実行時の値であることの明示的確認
###

X4 := value1
A4 = $(X4)
X4 := value2

test-4:
# DEFFEREDが実行時の値であることの明示的確認
# A4=$(A4)
#

###
### DEFERREDの文脈だったものがIMMEDIATEに移る例
###

X5 := value1
A5 = $(X5)
B5 := $(A5)
X5 := value2

test-5:
# DEFERREDの文脈だったものがIMMEDIATEに移る例
# A5=$(A5), B5=$(B5)
#

###
### 左辺が即時であることの確認
###

VAR_NAME := A6
$(VAR_NAME) := value1

test-6:
# 左辺が即時であることの確認
# A6=$(A6)
#
------

実行結果
------
# =、?=、:= の基本
# A1=value1, B1=, C1=value2
#
# += の基本
# A2=value1 - value2#
# B2= - #
#
# defineの基本
# value1
#
# DEFFEREDが実行時の値であることの明示的確認
# A4=value2
#
# DEFERREDの文脈だったものがIMMEDIATEに移る例
# A5=value2, B5=value1
#
# 左辺が即時であることの確認
# A6=value1
#
------

** 3.5 ターゲットとパターンに固有の変数

- これ、節題が多少わかりにくいのですが、個別ター
ゲットや個別パターンにて変数の値をカスタマイズ
する、ということ。例。

------
SHEBANG = "\#!/bin/sh"

%: %.sh
echo $(SHEBANG) > $@
cat $< >> $@
chmod a+x $@

hoge: SHEBANG += -
------

これを'make hoge'したときと'make piyo'したとき
ではSHEBANGの値は異なる。

** 3.6 変数はどこからくるのか
- ファイル

makefile本体やincludeしたもの

- コマンドライン

例。

------
make CFLAG=-g
------

- 環境

いわゆる環境変数はmakeの変数として取り込まれる。

- 自動変数

ルールのコマンドゾーン実行直前に、自動変数とそ
の値を作成する。

** 3.7 条件判断とinclude命令
- 条件判断命令によって、makeの読み込みを制御でき
る。
- 形式は次のとおり。

CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
endif

CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
else
TEXT-IF-FALSE
endif

CONDITIONAL-DIRECTIVE
TEXT-IF-ONE-IS-TRUE
else CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
else
TEXT-IF-FALSE
endif

- CONDITIONAL-DIRECTIVE

`ifeq (ARG1, ARG2)'
`ifeq 'ARG1' 'ARG2''
`ifeq "ARG1" "ARG2"'
`ifeq "ARG1" 'ARG2''
`ifeq 'ARG1' "ARG2"'

`ifneq (ARG1, ARG2)'
`ifneq 'ARG1' 'ARG2''
`ifneq "ARG1" "ARG2"'
`ifneq "ARG1" 'ARG2''
`ifneq 'ARG1' "ARG2"'

`ifdef VARIABLE-NAME'

`ifndef VARIABLE-NAME'

*** 3.7.1 include命令
- 他のファイルを取り込むことができる。
例。

------
include header.mk
------

- ファイル指定部分は、ワイルドカードや変数を使う
ことができる。

*** 3.7.2 includeと依存関係
- includeファイル自身をターゲットとすることができ
る。このことは、
- makefileをはじめて読んだときは、include対象ファ
イルは存在しないかもしれない。
- makefileを読んだときにinclude対象ファイルは存
在するが、それを読み込んで処理を進めていった
ら、それ自身がターゲットになっており更新対象
であった。
というケースを発生させる。

- makeではこれらの状況に備えて次の処理手順となっ
ている。
- include対象ファイルが存在しない場合
- include行はスキップして処理を進める。
- include対象ファイルのターゲットが存在する場

- ターゲットを構築する。
- makeの内部データベースをクリアする。
- 始めから処理をする。(このときには、
include対象ファイルが存在する。)
- include対象ファイルのターゲットが存在しない
場合

- include対象ファイルが存在する場合
- include行でファイルを取り込む。
- include対象ファイルのターゲットが存在する場

- ターゲットの再構築が必要な場合
- ターゲットを再構築する。
- makeの内部データベースをクリアする。
- 始めから処理をする。(このときには、
include対象ファイルが存在する。)
- ターゲットの再構築が不要な場合
- そのまま処理をすすめる。
- include対象ファイルのターゲットが存在しない
場合
- そのまま処理をすすめる。

** 3.8 標準的なmake変数
- MAKE_VERSIONなどのmakeのメタ情報を保持する変数
が定義済みである。
- 組み込みルールはカスタマイズに備えて変数を多用
している。変数の命名則は次のとおり。

ACTION.suffix

- C/C++の例

COMPILE.c
COMPILE.cpp
LINK.o
...


こつこつ。

2009年11月10日火曜日

【make】2 ルール (その2)

TT#4、近山先生のお話に「シェルはバッチ処理由来のジョブコントロールを引きつぎすぎていて使いづらい。全部は無理だけど、そういうこともLispの中でやって、自分の世界にひきこもれたら幸せです。」という趣旨のことがあった。いわゆるキッチンシンクのことだ。自分にとってそれはEmacs + Emacs Lisp + Common Lispになるのかなぁ。近山先生もEmacsがあれば、まあEmacsを使ってたかな、という話でもあった。

さて、make。進むにつれ、これPAIPの冒頭にあるGPS(General Problem Solver)すなわちmeans-ends analysisそのものじゃん、ということに気がついた。これは結構強力。ASDF、Rake、Antとかはこれよりさらに強力な機能をもっているのか?だとしたら、すごいな。。。


** 2.4 パターンルール
- パターン(マッチ)をつかったルール。
- 拡張子がポイント。MS Windowsとちがって、Unixで
拡張子はナンセンスと思っていたが、浅はかだった。
- 組み込み暗黙ルールというものあり。makeにあらかじ
めパターンルールが組み込まれている。

例1 .oファイルを作るルール。
------
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
------

例2 .lファイルから.cファイルを作るルール。
------
%.c: %.l
@$(RM) $@
$(LEX.l) $< > $@
------

例3 サフィックス無し(実行ファイル)を作るルール。
------
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
------

*** 2.4.1 パターン
- '%'はシェルの'*'みたいなもの。これをつかってパ
ターンを記述する。ただし一つの単語の中で、'%'は
一回しかつかえない。
- パターンマッチの制御は次のとおり。

まず、ターゲットに着目し、マッチするファイル名が
あるかどうか探索する。マッチがあれば、マッチ部で
前提条件の'%' を置換する。置換後のファイル名が存
在するかを探索する。存在しない場合は、そのファイ
ル名がターゲットで存在するかどうか探索する。これ
ら探索で、ターゲットにマッチしたファイル名を構築
するための連鎖が特定されれば、それを実行する。こ
の連鎖をルール連鎖と呼ぶ。

ターゲットに着目したマッチが全部終わったら、前
提条件に着目したマッチを行う。前提条件のパター
ンにマッチするファイル名が存在するなら、マッチ
部でターゲットの'%'を置換する。マッチするファイ
ル名が無い場合は、ターゲットでマッチするものを
探し、連鎖をつくっていく。連鎖が終端されればそ
れを実行する。もちろんこれもルール連鎖と呼ぶ。

例。

------
%: %.sh
cat $< >$@
chmod a+x $@
------

探索対象ディレクトリに'hoge.sh'があれば、前提条
件部がマッチして'hoge'が構築される。

*** 2.4.2 静的バターンルール
- パターンルールの一種であり、特定のターゲットリ
ストのみを対象とする。

------
$(OBJECTS): %.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
------

この場合、OBJECTSに含まれているファイル名だけを
対象に、%.oのパターンマッチが実施される。


*** 2.4.3 サフィックスルール
- 'GNU make'ではない'make'で使われている古い記法。
- ポータビリティのために、現在でもこれを使うことも
ある。

例1。
------
.c.o:
$(COMPILE.c) $(OUTPUT_OPTION) $<
------

これはダブルサフィックスルールという。
これは、次のバターンルールと同じ。

------
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
------

例2。
------
.p:
$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@
------

これはシングルサフィックスルールという。
これは、次のバターンルールと同じ。

------
%: %.p
$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@
------

- サフィックスルールの管理は、.SUFFIXESで行う。

------
.SUFFIXES: .pdf .p
------

などとすると、自分で定義したサフィックスルール
を有効にできる。

makeでデフォルト定義されているルールを無効化す
るには次のようにする。

------
.SUFFIXES:
------

** 2.5 暗黙ルールのデータベース
- 'make -p' で一覧が出力される。

**** make -p の一覧
--------
~ $ make -p
# GNU Make 3.81
# Copyright (C) 2006 Free Software Foundation, Inc.
# これはフリーソフトウェアです. 利用許諾についてはソースを
# ご覧ください.
# 商業性や特定の目的への適合性の如何に関わらず, 無保証です.

# This program built for x86_64-pc-linux-gnu
make: *** ターゲットが指定されておらず, makefile も見つかりません. 中止.

# Make データベース出力 Tue Nov 10 02:39:19 2009

# 変数

# 自動変数
<D = $(patsubst %/,%,$(dir $<))
# 自動変数
?F = $(notdir $?)
# 環境変数
DESKTOP_SESSION = default
# デフォルト
CWEAVE = cweave
# 自動変数
?D = $(patsubst %/,%,$(dir $?))

[snip]

# 環境変数
PORTABLE_ENVIRONMENT_TYPE = ubuntu
# 環境変数
SESSION_MANAGER = local/adonis:/tmp/.ICE-unix/5548
# デフォルト
COMPILE.mod = $(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)
# デフォルト
ARFLAGS = rv
# デフォルト
LINK.r = $(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)
# 環境変数
WINDOWID = 4194362
# デフォルト
COMPILE.f = $(FC) $(FFLAGS) $(TARGET_ARCH) -c
# デフォルト
LINT.c = $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)
# デフォルト
LINT = lint

[snip]

# 変数セットのハッシュテーブルの状態:
# Load=137/1024=13%, Rehash=0, Collisions=13/161=8%

# Pattern-specific Variable Values

# パターン指定変数の値なし.

# ディレクトリ

# SCCS: 状態を調べられませんでした.
# . (device 2049, inode 1286082): 109 個のファイル, 51 個の適用不能ファイル名.
# RCS: 状態を調べられませんでした.

# 109 個のファイル, 51 個の適用不能ファイル名 (3 個のディレクトリ内).

# 暗黙ルール

%.out:

%.a:

%.ln:

%.o:

%: %.o
# 実行するコマンド (ビルトイン):
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

%.c:

%: %.c
# 実行するコマンド (ビルトイン):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@

%.ln: %.c
# 実行するコマンド (ビルトイン):
$(LINT.c) -C$* $<

%.o: %.c
# 実行するコマンド (ビルトイン):
$(COMPILE.c) $(OUTPUT_OPTION) $<

%.cc:

%: %.cc
# 実行するコマンド (ビルトイン):
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@

%.o: %.cc
# 実行するコマンド (ビルトイン):
$(COMPILE.cc) $(OUTPUT_OPTION) $<

%.C:

%: %.C
# 実行するコマンド (ビルトイン):
$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@

%.o: %.C
# 実行するコマンド (ビルトイン):
$(COMPILE.C) $(OUTPUT_OPTION) $<

%.cpp:

%: %.cpp
# 実行するコマンド (ビルトイン):
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@

%.o: %.cpp
# 実行するコマンド (ビルトイン):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<

[snip]

%:: %,v
# 実行するコマンド (ビルトイン):
$(CHECKOUT,v)

%:: RCS/%,v
# 実行するコマンド (ビルトイン):
$(CHECKOUT,v)

%:: RCS/%
# 実行するコマンド (ビルトイン):
$(CHECKOUT,v)

%:: s.%
# 実行するコマンド (ビルトイン):
$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<

%:: SCCS/s.%
# 実行するコマンド (ビルトイン):
$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<

# 86 個の暗黙ルール, 5 (5.8%) 以上.

# ファイル

# ターゲットではありません:
.web.p:
# 暗黙ルールの探索は行われませんでした.
# 修正時刻がチェックされることはありません.
# ファイルは更新されていません.
# 実行するコマンド (ビルトイン):
$(TANGLE) $<

# ターゲットではありません:
.l.r:
# 暗黙ルールの探索は行われませんでした.
# 修正時刻がチェックされることはありません.
# ファイルは更新されていません.
# 実行するコマンド (ビルトイン):
$(LEX.l) $< > $@
mv -f lex.yy.r $@

# ターゲットではありません:
.dvi:
# 暗黙ルールの探索は行われませんでした.
# 修正時刻がチェックされることはありません.
# ファイルは更新されていません.

# ターゲットではありません:
.F.o:
# 暗黙ルールの探索は行われませんでした.
# 修正時刻がチェックされることはありません.
# ファイルは更新されていません.
# 実行するコマンド (ビルトイン):
$(COMPILE.F) $(OUTPUT_OPTION) $<

[snip]

# ファイルハッシュテーブルの状態:
# Load=69/1024=7%, Rehash=0, Collisions=276/1520=18%
# VPATH 探索パス

# `vpath' 探索パスはありません

# 一般の (`VPATH' 変数) 探索パスなし.

# # of strings in strcache: 0
# # of strcache buffers: 0
# strcache size: total = 0 / max = 0 / min = 4096 / avg = 0
# strcache free: total = 0 / max = 0 / min = 4096 / avg = 0

# Make データベース終了 Tue Nov 10 02:39:19 2009

~ $
--------

*** 2.5.1 暗黙ルールを活用する
- makefileを書かずとも暗黙ルールだけでかなりやっ
てくれる。

例。これはすごい。
------
2.5.1 $ touch foo.y
2.5.1 $ ci foo.y
foo.y,v <-- foo.y
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>> .
initial revision: 1.1
done
2.5.1 $ ls
foo.y,v
2.5.1 $ make --just-print foo
co foo.y,v foo.y
foo.y,v --> foo.y
revision 1.1
done
yacc foo.y
mv -f y.tab.c foo.c
cc -c -o foo.o foo.c
cc foo.o -o foo
rm foo.c foo.o foo.y
2.5.1 $
------

- ルール連鎖の中で作成されたファイルを中間ファイ
ルと呼ぶ。中間ファイルはmakeが終了前に削除する。

- 暗黙ルールが害をおよぼすこともある。その場合、
コマンドが空のパターンルールを書けばよい。

例。

------
%.o: %.c
------

*** 2.5.2 ルールの構造
- 暗黙ルールはカスタマイズしやすいように、典型的
には次のような構造をもっている。

------
%.o: %.c
# 実行するコマンド (ビルトイン):
$(COMPILE.c) $(OUTPUT_OPTION) $<
------

ここで変数の定義は次のとおり。

------
# デフォルト
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
# デフォルト
CC = cc
# デフォルト
OUTPUT_OPTION = -o $@
------

** 2.6 特殊ターゲット

- .PHONYがその一種。makeの動作に指示を与えるもの。
- 全部で12種類ある。
- フォーマットは、コマンドなしルール。

------
ターゲット: 前提条件
------

** 2.7 自動的な依存関係の修正

- まず、コンパイラはソースを読んで、ライブラリの
依存関係をmakefileの形式で書き出してくれる。

------
2.7 $ cat hoge.c
#include <stdio.h>

2.7 $ gcc -M hoge.c
hoge.o: hoge.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
/usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
/usr/lib/gcc/x86_64-linux-gnu/4.3.2/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/typesizes.h \
/usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/x86_64-linux-gnu/4.3.2/include/stdarg.h \
/usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
2.7 $
------

- おお、これは便利。
- これを自動的に自分のmakefileに取り込む方法がい
くつかあり。ここでは割愛。(本には記載あり)

** 2.8 ライブラリ管理
- ライブラリの基礎
- ライブラリは、正式にはアーカイブライブラリ、
と言う。
- 包含しているファイルをメンバと呼ぶ。
- 関連するオブジェクトファイルを、まとめて、管
理する。
- アーカイブの作成・変更はarで行う。以下、例。

------
2.8 $ ls
count_words count_words.o counter.o include lexer.o makefile src
2.8 $ ar rv libcounter.a counter.o lexer.o
ar: creating libcounter.a
a - counter.o
a - lexer.o
2.8 $
------

- ライブラリを使うにはライブラリファイルをコマ
ンドラインで指定する。コンパイラやリンカは、
その取扱いを知っており、拡張子で判断して適用
する。具体的にはソースの中の未解決のシンボル
をライブラリから探す。以下、例。

------
cc hoge.o libpiyo.a /lib/libfl.a -o hoge
------

-lオプションを使う方法。

------
cc hoge.o libpiyo.a -lfl -o hoge
------

- アーカイブライブラリは、オブジェクトファイル
だけでなく、シンボルのインデックスももつこと
ができる。GNUのarはこのインデックスの作成と
更新を自動的にやってくれる。自動的にやってく
れない古いarをつかっている場合はranlibを使う。

*** 2.8.1 ライブラリの作成と更新
- makefileでライブラリを作成する典型。

------
libhoge.a: hoge.o piyo.o
$(AR) $(ARFLAG) $@ $?
------

- 既出だが、ライブラリのメンバをターゲットにする
方法。

------
libhoge.a(piyo.o): piyo.o
$(AR) $(ARFLAG) $@ $<
------

- ranlibが必要な場合は次のようにする。

------
libhoge.a: hoge.o piyo.o
$(RM) $@
$(AR) $(ARFLAG) $@ $^
$(RANLIB) $@
------

*** 2.8.2 ライブラリを必須項目として使う
- かきぶりは2つあった。

------
hoge: hoge.o /lib/libfl.a
$(LINK) $^ -o $@
------
------
hoge: hoge.o -lfl
$(LINK) $^ -o $@
------

- 後者の方がすぐれている。理由は次のとおり。

- 前者は絶対パスになっているので、配置を変えた
らmakefileの修正が必要。後者はライブラリの探
索パスだけ変えればよい。
- 後者だとmakeはシェアードライブラリの方がこの
ましいと判断し、それがあるならそれを優先する。

*** 2.8.3 二重コロンルール

- 二重コロンは、前提条件毎にコマンドを変えるとき
に使う。暗黙ルールからの例。

------
%:: RCS/%
# 実行するコマンド (ビルトイン):
$(CHECKOUT,v)

%:: SCCS/s.%
# 実行するコマンド (ビルトイン):
$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<
------


こつこつ。

【LPL】9章 限量入門 (4)

9.5節の問題を5問やる。あせらないよう自分にいいきかせる。
次回は、9.6節 複合名詞句の翻訳。

こつこつ。

2009年11月9日月曜日

【LPL】9章 限量入門 (3)

FOLの勉強を再開できるぐらいに復活してきた。あせらず刻んでいこう。


  • 9.5 4つのアリストテレス文型

    • 4つのアリストテレス文型はFOLで表現できる。

      • All P's are Q's.
        ∀x(P(x) → Q(x))
      • Some P's are Q's.
        ∃x(P(x) ∧ Q(x))
      • No P's are Q's.
        ∀x(P(x) → ¬Q(x))
      • Some P's are not Q's.
        ∃x(P(x) ∧ ¬Q(x))




10月体調を崩したのは、どうも夏場に論理に根を詰めすぎたのも原因な気がする。で、一カ月休んだのですが、一カ月休むと、論理について以前にやったものをほとんど忘れている自分がいたり。論理の勉強は、他の勉強とくらべて特にむずかしい気がする。。。

ちょっとスタンスを変えて、まずは「ことば」としてのFOLを使いこなすことに重点を置いてみることにする。「言語」としてのFOLの詳細を理解する、というのは、根を詰めないとできないし、根を詰めてやってもすぐに忘れる。。。「ことば」としての使いこなしの方が忘れにくい気がするし、それがあれば言語としての詳細の探求のスタートポイントをいつも持っていることになる気がする。気がするだけかも。

こつこつ。