I have a grammar I'm writing, called portugol
. The files names are basic, but I chose to call my c program portugol.c
.
So, basically, I have to do:
flex portugol.l ==> lex.yy.c
bison -dy portugol.y ==> y.tab.c and y.tab.h
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly ==> portugol.bin
(I also have portugol.h, but it is irrelevant to the problem)
For long time now, I'm using a shell script I called flexyagcc.sh
that do this. No error in the process.
So now I decided to learn makefile
.
The problem I'm facing is that for some odd reason, "bison -dy
" I called is followed by this command I didn't write: mv -f y.tab.c portugol.c
Well, this destroys my handmade source file!
I've tried all I could, but could not get rid of this "mv
".
I even did a sleep
and tried:
y.tab.c y.tab.h : portugol.y
@echo --- bison -----------------------------------------------
mv -f portugol.c ptg.c
$(BISON) $(BFLAGS) portugol.y
@echo --- bison sleeping --------------------------------------
sleep 5
-mv -f portugol.c y.tab.c
-mv -f ptg.c portugol.c
But for my surprise, I got the following events (in this order):
$ make all o=pequeno
--- bison -----------------------------------------------
mv -f portugol.c ptg.c
bison -dy portugol.y
--- bison sleeping --------------------------------------
sleep 5
mv -f portugol.c y.tab.c
mv: cannot stat `portugol.c': No such file or directory
make: [y.tab.c] Error 1 (ignored)
mv -f ptg.c portugol.c
bison -dy portugol.y
mv -f y.tab.c portugol.c
Surprise! The mv
command is the last one! No matter what I do. I created other rules, just to make it happen last (or first to trick the recursive process). No way! I also used the directive: .NOTPARALLEL.
No way.
I also tried all in the same line, to be sure they execute in the given order:
mv -f portugol.c ptg.c && $(BISON) $(BFLAGS) portugol.y && sleep 5 && mv -f portugol.c y.tab.c && mv -f ptg.c portugol.c
No success.
Well, before I gave up, I decided to use the standard bison output. So, I would have:
flex portugol.l ==> lex.yy.c
bison -d portugol.y ==> portugol.tab.c and y.tab.h
gcc portugol.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly ==> portugol.bin
But I still get this:
--- bison -----------------------------------------------
bison -d portugol.y
bison -y portugol.y
mv -f y.tab.c portugol.c
I also tried to chmod -w
before and +w
after bison, no way.
For now, I run out of ideas.
Is there a way to prevent make to call the second bison? Or to call the mv
command? Or to trick it to not overwrite my file portugol.c
?
Thanks! Beco
PS- Edited. Using:
Ubuntu 10.04.2 LTS
GNU Make 3.81
PPS. Edited. Minor typos.
PPPS. Edited. Answering Ise wisteria:
Thanks for your answer. I've saved your makefile as makefile2 and tried. The answer I got from the make is:
$ make -f makefile2
bison -dy portugol.y
yacc portugol.y
mv -f y.tab.c portugol.c
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly
gcc: y.tab.c: No such file or directory
make: *** [portugol.bin] Error 1
I also noted that "today" the second bison call is not a bison call, but a yacc call. Maybe we are talking about some environment variable here? It also changes with my makefile:
$ make all o=pequeno
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
--- flex ------------------------------------------------
flex portugol.l
yacc portugol.y
mv -f y.tab.c portugol.c
PPPPS. Answering Beta. Your advice works. I called make y.tab.c and got a simple:
$ make y.tab.c
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
$
Here is my complete makefile:
# Compila o compilador Portugol usando lex e yacc,
# e opcionalmente gera o .asm.c e o .bin
# a partir do fonte .ptg usando o novo compilador gerado.
#
#/*
# arquivo: makefile
# Autor: Ruben Carlo Benante
# Email: ***@beco.cc
# Data: 23/04/2009
# Modificado: 22/03/2011
# Versao: Portugol v3q
#*/
#
# Exemplo:
# ./flexyagcc portugol teste
#
# inicia os seguintes processos:
# flex portugol.l (gera lex.yy.c)
# bison -dy portugol.y (gera yy.tab.c e yy.tab.h)
# gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly (gera portugol.bin)
#
# inicia opcionalmente (ultimas linhas descomentadas):
# portugol.bin teste.ptg teste.asm.c (gera teste.asm.c)
# gcc -x c teste.asm.c -o teste.bin -lm (gera teste.bin)
#
#
# entrada:
# portugol.l (arquivo em linguagem lex, analisador lexico)
# portugol.y (arquivo em linguagem yacc, analisador sintatico)
# portugol.c (arquivo em linguagem c, gerador de codigo)
# entrada opcional:
# teste.ptg (arquivo em linguagem portugol)
#
# saida:
# lex.yy.c (saida do lex, em linguagem c)
# y.tab.c (saida do yacc, em linguagem c)
# y.tab.h (saida do yacc, definicoes da linguagem portugol)
# portugol.bin (saida do gcc, arquivo executavel, finalmente o compilador portugol)
# saida opcional:
# teste.asm.c (saida do compilador portugol, arquivo em codigo de quadruplas)
# teste.bin (saida do gcc, arquivo executavel, o fonte .ptg em binario)
#
######################################
LEX = flex
BISON = bison
BFLAGS = --defines=y.tab.h --output=y.tab.c
CC = gcc
#CFLAGS = -g0 -O3 -Wall
CFLAGS = -g0
OBJS = y.tab.o lex.yy.o portugol.o
#OBJS = portugol.tab.o lex.yy.o portugol.o
DEPS = portugol.h y.tab.h
SOURCES = y.tab.c lex.yy.c portugol.c
#SOURCES = portugol.tab.c lex.yy.c portugol.c
.PHONY : clean cleanall cleanptg run all makebug teste
.NOTPARALLEL :
#portugol.bin : lex.yy.c y.tab.c y.tab.h portugol.c portugol.h
portugol.bin : $(SOURCES) $(DEPS) $(OBJS)
@echo --- gcc portugol ----------------------------------------
$(CC) $(CFLAGS) $(OBJS) -o portugol.bin -lm -ly
# gcc lex.yy.c y.tab.c portugol.c -o portugol.bin -lm -ly
# $(CC) $(CFLAGS) $(SOURCES) -o portugol.bin -lm -ly
%.o : %.c
@echo --- gcc objects -----------------------------------------
$(CC) $(CFLAGS) -c $< -o $@
#portugol.tab.c y.tab.h : portugol.y
y.tab.c y.tab.h : portugol.y
@echo --- bison -----------------------------------------------
$(BISON) $(BFLAGS) portugol.y
# @echo --- bison y.tab.c ---------------------------------------
# mv -f portugol.c ptg.c
# sleep 3
# -mv -f portugol.c y.tab.c
# -mv -f ptg.c portugol.c
lex.yy.c : portugol.l
@echo --- flex ------------------------------------------------
$(LEX) $(LFLAGS) portugol.l
teste :
@echo --- testing ---------------------------------------------
@echo $(o)
#Portugol -----------
%.asm.c : %.ptg portugol.bin
@echo --- portugol --------------------------------------------
./portugol.bin $< $@
%.bin : %.asm.c
@echo --- gcc asm ---------------------------------------------
$(CC) -x c $< -o $@ -lm
run : $(o).bin
@echo --- running! --------------------------------------------
./$(o).bin
all : $(o).bin
clean:
-rm lex.yy.c y.tab.c y.tab.h *.o portugol.bin portugol.tab.c
cleanall:
-rm lex.yy.c y.tab.c y.tab.h *.o *.bin
cleanasm:
-rm *.asm.c
VPS. Important edit update. Attention for a possible indication of the real problem:
I changed the name portugol.y
to portugol.syn
and the problem has stoped!
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.syn
---------------------------------------------------------
How is that? This indicates, in my opinion, that make has some default evaluation for files ".y" and now we need, to answer this question, to find out the root of this, and how to disable it. Thanks very much.