在没有被要求的情况下打电话给野牛

Dr *_*eco 1 yacc lex makefile bison

我有一个我正在写的语法,叫做portugol.文件名是基本的,但我选择调用我的c程序portugol.c.

所以,基本上,我必须这样做:

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
Run Code Online (Sandbox Code Playgroud)

(我也有portugol.h,但它与问题无关)

很长一段时间以来,我正在使用我称之为的shell脚本flexyagcc.sh.过程中没有错误.

所以现在我决定学习makefile.

我面临的问题是,由于一些奇怪的原因," bison -dy"我打电话后跟这个命令我没写:mv -f y.tab.c portugol.c

好吧,这破坏了我手工制作的源文件!

我尽我所能,但无法摆脱这个" mv".

我甚至做了一个sleep尝试过:

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
Run Code Online (Sandbox Code Playgroud)

但令我惊讶的是,我得到了以下事件(按此顺序):

$ 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
Run Code Online (Sandbox Code Playgroud)

惊喜!该mv命令是最后一个!不管我做什么.我创建了其他规则,只是为了让它最后发生(或者首先欺骗递归过程).没门!我也使用了指令:.NOTPARALLEL.没办法.

我也尝试了同一行,以确保它们按给定的顺序执行:

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
Run Code Online (Sandbox Code Playgroud)

没有成功.

好吧,在我放弃之前,我决定使用标准的野牛输出.所以,我会:

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
Run Code Online (Sandbox Code Playgroud)

但我仍然得到这个:

--- bison -----------------------------------------------
bison -d portugol.y
bison -y portugol.y 
mv -f y.tab.c portugol.c
Run Code Online (Sandbox Code Playgroud)

我也尝试过野牛chmod -w之前和+w之后,没办法.

现在,我已经没想到了.

有没有办法阻止制作召唤第二个野牛?或者调用mv命令?或者欺骗它不要覆盖我的文件portugol.c

谢谢!贝乔

PS-编辑.使用:

 Ubuntu 10.04.2 LTS
 GNU Make 3.81
Run Code Online (Sandbox Code Playgroud)

PPS.编辑.小错字.

购买力平价.编辑.回答伊势紫藤:

感谢您的回答.我已将您的makefile保存为makefile2并尝试过.我从make中得到的答案是:

$ 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
Run Code Online (Sandbox Code Playgroud)

我还注意到"今天"第二次野牛呼叫不是野牛呼叫,而是yacc呼叫.也许我们在这里谈论一些环境变量?它也随我的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
Run Code Online (Sandbox Code Playgroud)

PPPPS.回答Beta.你的建议有效.我打电话给y.tab.c然后得到一个简单的:

$ make y.tab.c
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
$
Run Code Online (Sandbox Code Playgroud)

这是我的完整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
Run Code Online (Sandbox Code Playgroud)

VPS.重要的编辑更新.注意可能表明真正的问题:

我改变了名称portugol.y,以portugol.syn有这样的问题采空!

--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.syn
---------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

那个怎么样?在我看来,这表明make对文件".y"有一些默认评估,现在我们需要回答这个问题,找出它的根源,以及如何禁用它.非常感谢.

Chr*_*odd 6

问题是make有内置的规则来构建来自.y和.l文件的.c文件,正是这些内置规则被触发并引起你的悲痛.

使用GNU make,您可以通过使用空白规则覆盖它们来禁用这些内置规则.放

%.c: %.y
%.c: %.l
Run Code Online (Sandbox Code Playgroud)

在你的makefile中,你的问题应该消失.

您可以通过运行查看所有GNU make的内置规则 make -p -f /dev/null