2017-09-17 5 views
6

それでは、私は、それは単にcc lex.yy.c scanner.c -o scannerを実行する必要があり、コンパイルにscanner.c呼ばれたsourcefileを取るmake scannerを実行し、その代わりに、それはこれを行い、私はmake lexを実行し、それは私にlex.yy.cファイルを生成し、すべての良いなぜmakefileはコンパイルしたくないものを主張しているのですか?

lex -t scanner.l > scanner.c 
cc lex.yy.c scanner.c -o scanner 

lex -t scanner.lを実行してscanner.cに出力すると、私のコードを上書きするのはなぜですか?邪悪なアイデアはなく、それは私を夢中にしている。

私のメイクファイル:間違って何が起こっている

scanner: scanner.h scanner.c lex.yy.c 
    cc lex.yy.c scanner.c -o scanner 

lex: scanner.l 
    lex scanner.l > lex.yy.c 

clean: 
    rm lex.yy.c 
    rm scanner 

答えて

8

なぜlex -t scanner.lを実行してscanner.cに出力して、自分のコードを上書きするのですか?これはあなたのビルドディレクトリに持って起こるたび

scanner.cscanner.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.cscanner.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.clexer.oscanner.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 
5

makeは、定義した暗黙ルールを定義するデフォルトサフィックスを最も確実に定義しています。

たとえば、この接尾辞の規則について説明しているhowtoを参照してください。あなたのメイクファイルの開始時に

は、次の行を追加することができます。

.SUFFIXES: 

デフォルトの接尾辞規則を望んでいないmakeを伝えるために。

1

さて、あなたは名前のターゲットを作成しません、次の依存関係を、作成している、とそうがそれ

を作成しようとするために、常に呼び出されます
lex: scanner.l   <-- incorrect target name, not created from source. 
    lex scanner.l > lex.yy.c 

この依存関係は、lexという名前のファイルを作成しようとしますが、下のコマンドラインからは作成されません。おそらく、あなたはlex(1)が標準出力にスキャナを生成していないとして、-oオプションを使用します。私は確かだと思いますが、ないところで、LEXを(

lex.yy.c: scanner.l 
    lex scanner.l -olex.yy.c 

あるいは

lex.yy.c: scanner.l 
    lex scanner.l [email protected] 

代わりに、これを望んでいました)のmanページを参照してください、オプション-oに直接接触するオプションの引数を必要と

注1

あなた時間同じ基本名の.lファイルから.cファイルを作成するためのデフォルトルールを実行します。ルールは、同じ名前のLEX入力からソースCファイルを生成する、LFLAGS変数に示されたフラグを有する可変LEXでコマンドを実行するが、.l拡張子を持つ

.l.c: 
    $(LEX) $(LFLAGS) [email protected] $< 

ようなものです。

関連する問題