Why does the makefile insist on compiling things that it shouldn't do?

So, I run make lexand generate a file for me lex.yy.c, all good

then I run make scanner, which takes the source file with the name scanner.cinto compilation, it should just run cc lex.yy.c scanner.c -o scanner, but instead, it does this:

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

Why does he decide to run lex -t scanner.land display it on scanner.c, effectively overwriting my code? No damn idea, and it drives me crazy.

my makefile:

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

What will go wrong?

+6
source share
3 answers

Why does he decide to run lex -t scanner.l and output it to scanner.c, effectively overwriting my code?

, , scanner.c a scanner.l, , scanner.c

make scanner, :

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) $@ 
     $(LEX.l) $< > $@

file.c file.l, :

rm file.c   # Not echoed
lex  -t file.l > file.c

, - %.c: %.l - scanner.c, scanner.l , scanner.c. , scanner.c uptodate:

lex  -t scanner.l > scanner.c

scanner.c.

, - , , :

%.c: %.l

makefile .

, --no-builtin-rules make commandline.

, make , , , makefile. :

%.<target-type>: %.<prereq-type>
    <command>
    ...

<target-type> <prereq-type> make, . , C ++, GNU make , .o .c .cpp , , make , .

%.c: %.l file.c a file.l. : 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;
}

scanner.h

#ifndef SCANNER_H
#define SCANNER_H

extern int yylex(void);

#endif

make :

Makefile

SRCS := scanner.c lexer.c
OBJS := $(SRCS:.c=.o)
LDLIBS := -lfl

.PHONY: all clean

all: scanner

scanner: $(OBJS)
    $(LINK.o) -o $@ $^ $(LDLIBS)

scanner.o: scanner.h

clean:
    rm -f scanner *.o

:

$ 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

, make :

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

lexer.c, lexer.o scanner.o , , . lexer.c - , , lexer.l lexer.o - :

rm lexer.c

.

:

$ ./scanner 
hello
Found a string: [hello]

42
Found an integer: [42]

42.42
Found a floating-point number: [42.42]

^C
+8

make, , , , , .

., , howto, .

make :

.SUFFIXES:

make, .

+5

, , , ,

lex: scanner.l           <-- incorrect target name, not created from source.
    lex scanner.l > lex.yy.c

lex, . , ,

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

lex.yy.c: scanner.l
    lex scanner.l -o$@

( -o, lex(1) . , , , lex , -o, . )

1

.c .l .

.l.c:
    $(LEX) $(LFLAGS) -o$@ $<

which executes a command in a variable lexwith the flags specified in the variable LFLAGS, generating the source C file from input with the same name but with the extension .l.

+1
source

All Articles