Makefile automatically call `yacc`

Hi I have a makefile like this:

# Variables =====================================================================================
PHONY           = 
proj            = 

ALL_FILES   := $(filter $(proj).%,$(shell ls | grep "^$(proj)\.[a-z]*$$"))
LEX_FILE    := $(filter %.l, $(ALL_FILES))
BISON_FILE  := $(filter %.y, $(ALL_FILES))
C_FILE      := $(filter %.c, $(ALL_FILES))
H_FILE      := $(filter %.h, $(ALL_FILES))

BISON_OUT_H := $(subst .y,.tab.h,$(BISON_FILE)) 
BISON_OUT_C := $(subst .y,.tab.c,$(BISON_FILE))
LEX_OUT     := $(subst .l,.yy.c,$(LEX_FILE))
LEX_TRG     := $(LEX_FILE)

CFLAGS      = -g
    @echo $(proj)
    @echo $(ALL_FILES)
    @echo $(LEX_FILE)
    @echo $(BISON_FILE)
    @echo $(C_FILE)
    @echo $(BISON_OUT_C)
    @echo $(LEX_OUT)
    @echo $(GCC_TRG)
    @echo $(GCC_DEP)
# Flex ==========================================================================================
ifneq (,$(LEX_TRG))
    flex --outfile=$@ $(LEX_TRG)

# Bison =========================================================================================
ifneq (,$(BISON_FILE))
    bison -d $<

# Run ===========================================================================================
ifneq (,$(GCC_TRG))
    gcc $(CFLAGS) $(GCC_TRG) -o $@


    @echo "Please type in file names: "; \
    read file; \
    ./$< $$file

PHONY += run run_wc run_lex
# Clean =========================================================================================
    -rm *.out *.lex *.yy.c *.tab.h *.tab.c *.s
    -rm $(proj).out $(proj).lex $(BISON_OUT) $(LEX_OUT)

PHONY += clean cleansp
# GitHub ========================================================================================
commit: clean
    git add -A
    @echo "Please type in commit comment: "; \
    read comment; \
    git commit -m"$$comment"
sync: commit 
    git push -u origin master

PHONY += commit sync
# PHONY =========================================================================================

In the current folder I have

[shore@shore-82b6 flex-bison]$ ls
calc2.c  calc2.h  calc2.l  calc2.y  calc2.yy.c  calc.l  calc.y  ccr.l  lc.l  makefile  samples  st.l  wc.l

The thing vary confused me is that when I run make run proj=calc2, if calc.y is changed then the make file will run extra instructions and output to calc.c as a result. The following is the shell output:

[shore@shore-82b6 flex-bison]$ make run proj=calc2
bison -d calc2.y
flex --outfile=calc2.yy.c calc2.l
yacc  calc2.y 
mv -f calc2.c
calc2.yy.c calc2.c

Notice this will only happen if calc.y is changed.

So how should I fix this and letting the makefile run the instructions suppose to be in my makefile.


  • You are being bitten by one of make's built-in rules:

    %.c: %.y
    #  recipe to execute (built-in):
             $(YACC.y) $<
             mv -f $@

    This says, "if I have a file foo.y and I want to build a file foo.c, here's how to do it". This is the normal naming convention for building yacc files.

    In your situation you have a file calc2.y which is the yacc file and another file calc2.c which is a normal source file, but make doesn't know that it's a normal source file.

    If you want to have your calc2.y not be related to your calc2.c, and instead have calc2.y be related only to, you'll have to cancel the built-in rule by declaring it without any recipe like this:

    %.c: %.y