なぜlex -t scanner.lを実行してscanner.cに出力して、自分のコードを上書きするのですか?これはあなたのビルドディレクトリに持って起こるたび
scanner.c
と scanner.c
あなたがmake scanner
実行し、レシピよりも、より新しいscanner.l
:
scanner: scanner.h scanner.c lex.yy.c
cc lex.yy.c scanner.c -o scanner
をする必要がありその前提条件scanner.c
を更新する。あなたは にレシピを提供していないので、組み込みレシピのデータベースに を戻してください。
make -p
を実行することにより、これらの組み込みのレシピを調べて、あなたは見つけることができます:
%.c: %.l
# recipe to execute (built-in):
@$(RM) [email protected]
$(LEX.l) $< > [email protected]
この組み込みレシピが実行することにより、マッチングfile.l
からfile.c
を行います:
rm file.c # Not echoed
lex -t file.l > file.c
メイクパターンことを発見このレシピのルール - %.c: %.l
- が によってscanner.c
に設定されています。これはscanner.l
が存在し、最近はscanner.c
。
lex -t scanner.l > scanner.c
は、それによってあなたの
scanner.c
をつかう: は、だから、
scanner.c
uptodateを作るためにこのレシピを使用しています。
あなたはこの組み込みレシピを適用するには、これまで作りたくない場合は、明示的 だけルール書き込むことによって、それを取り消すことができます任意のレシピなしであなたのメイクファイルで
%.c: %.l
を。
また メイクコマンドラインで--no-builtin-rules
を渡すことによってすべて組み込みのレシピを無効にすることができます。メイクファイル の動作についてのあなたの期待が、あなたの期待 は、入力ファイル からの出力ファイルを作成する通常の方法にとしてよく知らされていないことを強く示唆している組み込みのレシピによって妨害されるたびに
しかし、あなたのmakefileが呼び出すツールを使用します。 メイクのCatalogue of Built-In Rules:あなたは あなたのメイクファイルでこのレシピを自分で書いて維持する必要がないように
%.<target-type>: %.<prereq-type>
<command>
...
は、メイクと<prereq-type>
ファイルから<target-type>
ファイルを作る標準的な方法を具現化。彼らは道のmakeがそれを行うだろうことを知っているので、GNUと能力がある例CおよびC++プログラマのために自動的に 通常は、 コーナーの場合を除き、.c
ファイルまたは.cpp
ファイルから.o
ファイルを作るためのレシピを書いていない を作ります彼らが望む方法。 %.c: %.l
ルールがfile.l
与えfile.c
を作る の標準的な方法を表現するため
メイクの組み込みレシピ。そう自問してみてください:あなたはscanner.c
がscanner.l
からそのように作られたくないん、そしてあなたがlex.yy.c
にはscanner.l
から作ることがしたいの代わりにあれば、それはあなたがする scanner.l
を求めているファイルのために必要または有用な場合にはあなたはまた、全く独立したソースファイル をscanner.c
と呼んでいます。
lexer.l
%{
#include <stdio.h>
%}
%%
[ \t] ;
[0-9]+\.[0-9]+ { printf("Found a floating-point number: [%s]\n",yytext); }
[0-9]+ { printf("Found an integer: [%s]\n",yytext); }
[a-zA-Z0-9]+ { printf("Found a string: [%s]\n",yytext); }
%%
scanner.c
#include "scanner.h"
int main(void) {
yylex();
return 0;
}
スキャナ:
は、このおもちゃの例のようにmakeの組み込みレシピの利点を取ったとします。時間
#ifndef SCANNER_H
#define SCANNER_H
extern int yylex(void);
#endif
次に、あなたのメイクファイルはただのようになります。すべてのこれらのコマンドを実行します作る
$ make
cc -c -o scanner.o scanner.c
lex -t lexer.l > lexer.c
cc -c -o lexer.o lexer.c
cc -o scanner scanner.o lexer.o -lfl
rm lexer.c
注:
のように実行します Makefileの
SRCS := scanner.c lexer.c
OBJS := $(SRCS:.c=.o)
LDLIBS := -lfl
.PHONY: all clean
all: scanner
scanner: $(OBJS)
$(LINK.o) -o [email protected] $^ $(LDLIBS)
scanner.o: scanner.h
clean:
rm -f scanner *.o
あなたはどのようにそうするように、それを伝える 書かれた任意のレシピを持たずにlexer.c
、lexer.o
とscanner.o
を作るために
cc -c -o scanner.o scanner.c
lex -t lexer.l > lexer.c
cc -c -o lexer.o lexer.c
。 だけlexer.l
からlexer.o
に到達するために存在する必要があることを、生成されたファイル - - それはまた、自動的に はlexer.c
が中間ファイルであることに気づくので、それが最後に それを削除します。
rm lexer.c
に言われずに。
このスキャナは次のように実行します:
$ ./scanner
hello
Found a string: [hello]
42
Found an integer: [42]
42.42
Found a floating-point number: [42.42]
^C