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

Makefile 在没有被要求的情况下打电话给野牛,makefile,yacc,bison,lex,Makefile,Yacc,Bison,Lex,我正在写一个语法,叫做葡萄牙语。文件名是基本的,但我选择将我的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 我也有葡萄牙语,但这与问题无关 很长一段时间以来,我

我正在写一个语法,叫做葡萄牙语。文件名是基本的,但我选择将我的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
我也有葡萄牙语,但这与问题无关

很长一段时间以来,我一直在使用一个名为flexyagcc.sh的shell脚本来实现这一点。过程中没有错误

所以现在我决定学习makefile

我面临的问题是,出于某种奇怪的原因,我调用的bison-dy后面跟着我没有编写的命令:mv-fy.tab.cportugol.c

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

我已经尽了我所能,但无法摆脱这部mv

我甚至睡了一觉,试着:

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
但令我惊讶的是,我得到了以下事件的顺序:

$ 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
惊喜!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
没有成功

嗯,在我放弃之前,我决定使用标准的bison输出。因此,我会:

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
但我仍然明白这一点:

--- bison -----------------------------------------------
bison -d portugol.y
bison -y portugol.y 
mv -f y.tab.c portugol.c
我也试着在野牛之前和之后使用chmod-w和+w,没有办法

现在,我没有什么想法了

有没有办法防止第二头野牛被叫来?或者调用mv命令?或者欺骗它不覆盖我的文件portugol.c

谢谢! 贝科

PS-编辑。使用:

 Ubuntu 10.04.2 LTS
 GNU Make 3.81
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
我还注意到,今天第二次野牛叫声不是野牛叫声,而是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
# 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
PPPPS。回答测试版。你的建议行得通。我打电话给make y.tab.c,得到了一个简单的:

$ make y.tab.c
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
$
这是我的完整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
# 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

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

基本上,不要试图对抗系统。您需要能够创建portugol.o,并且有三个可能的源文件:portugol.l、portugol.y、portugol.c。这至少多了两个


确保源文件的基名减去扩展名后是唯一的。例如,在对象文件portugoll.o、portugoly.o和portugol.o中使用portugoll.l、portugoly.y和portugol.c。或者使用更长的后缀-葡萄牙语lex.l,葡萄牙语yacc.y。或者portlex.l、portyacc.y或…

基本上,不要试图对抗系统。您需要能够创建portugol.o,并且有三个可能的源文件:portugol.l、portugol.y、portugol.c。这至少多了两个

确保源文件的基名减去扩展名后是唯一的。例如,在对象文件portugoll.o、portugoly.o和portugol.o中使用portugoll.l、portugoly.y和portugol.c。或者使用更长的后缀-葡萄牙语lex.l,葡萄牙语yacc.y。或者portlex.l,portyacc.y,或者…

谢谢你,乔纳森

因此,您可以看到我也看到的一个解决方案:更改文件名。但是,这就是问题的关键。我使用脚本没有问题。如果我从shell脚本flexyagcc.sh中调用bison-dy portugol.y,它会给出y.tab.c和y.tab.h。为什么不从makefile开始,这是中心点

我确实喜欢我的文件名,它使所有的文件都非常连贯:portugol.c:手工例程,portugol.h:头文件,portugol.l:lex scanner和portugol.y:parser。而且,这不是我今天做的项目,多年来一直如此,现在有很多版本是3.0。因此,不能更改文件名。除此之外,我最终还是会选择葡萄牙语.c!但它将是由bison自动生成的文件,也就是y.tab.c。因此,停止使用葡萄牙语.c来创建手工例程,而开始使用相同的名称来创建解析器是非常令人困惑的

我只想知道makefile发生了什么,以及如何使用它来替换脚本。虽然我不能,但很不幸,我将使用脚本。脚本非常简单:

flex portugol.l
bison -dy portugol.y
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly
你看,我甚至都懒得把目标设定在葡萄牙语o,y.tab.o和lex.yy.o上。通过直接在源代码上运行gcc,我跳过了创建它们。我也可以在makefile中这样做,如果在第一次尝试销毁我的portugol.c之后,我手动将创建的文件重命名为y.tab.c

因此,问题在于makefile与上述脚本不同,它试图创建以下内容:

lex相同:对于脚本和makefile,都是portugol.l 野牛:自动从y.tab.c改为葡萄牙语。问题出在这里! c代码:我需要将portugol.c更改为其他内容,比如portugol funcs.c Th 感谢您的关注! 因为谢谢你,乔纳森

因此,您可以看到我也看到的一个解决方案:更改文件名。但是,这就是问题的关键。我使用脚本没有问题。如果我从shell脚本flexyagcc.sh中调用bison-dy portugol.y,它会给出y.tab.c和y.tab.h。为什么不从makefile开始,这是中心点

我确实喜欢我的文件名,它使所有的文件都非常连贯:portugol.c:手工例程,portugol.h:头文件,portugol.l:lex scanner和portugol.y:parser。而且,这不是我今天做的项目,多年来一直如此,现在有很多版本是3.0。因此,不能更改文件名。除此之外,我最终还是会选择葡萄牙语.c!但它将是由bison自动生成的文件,也就是y.tab.c。因此,停止使用葡萄牙语.c来创建手工例程,而开始使用相同的名称来创建解析器是非常令人困惑的

我只想知道makefile发生了什么,以及如何使用它来替换脚本。虽然我不能,但很不幸,我将使用脚本。脚本非常简单:

flex portugol.l
bison -dy portugol.y
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly
你看,我甚至都懒得把目标设定在葡萄牙语o,y.tab.o和lex.yy.o上。通过直接在源代码上运行gcc,我跳过了创建它们。我也可以在makefile中这样做,如果在第一次尝试销毁我的portugol.c之后,我手动将创建的文件重命名为y.tab.c

因此,问题在于makefile与上述脚本不同,它试图创建以下内容:

lex相同:对于脚本和makefile,都是portugol.l 野牛:自动从y.tab.c改为葡萄牙语。问题出在这里! c代码:我需要将portugol.c更改为其他内容,比如portugol funcs.c 谢谢你的关注!
因为奇怪的是,就我用小的即兴文件测试而言,这个问题 没有发生。 我的make版本是gnu3.80。 以下是我使用的makefile,仅供参考


希望这有帮助

奇怪的是,就我用小的即兴文件测试而言,您遇到的问题 没有发生。 我的make版本是gnu3.80。 以下是我使用的makefile,仅供参考


希望这有帮助

问题是make有内置的规则用于从.y和.l文件生成.c文件,而正是这些内置规则触发了make,并使您感到悲伤

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

%.c: %.y
%.c: %.l
在你的makefile中的某个地方,你的问题应该会消失


通过运行make-p-f/dev/null,您可以看到GNU make的所有内置规则。问题是,make有内置规则用于从.y和.l文件中构建.c文件,而正是这些内置规则触发并引起您的悲伤

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

%.c: %.y
%.c: %.l
在你的makefile中的某个地方,你的问题应该会消失


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

您可以尝试make y.tab.c而不是make all o=pequeno吗?亲爱的Beta,您的建议很有效!我想投票赞成你的回答,但你添加了一条评论。如果你能详细说明的话,我相信我们已经找到了问题所在。谢谢你,但我只提出了一个小建议,简化构建并隔离问题。Chris Dodd找到了解决方案。你能试着制作y.tab.c而不是制作所有o=pequeno吗?亲爱的Beta,你的建议很有效!我想投票赞成你的回答,但你添加了一条评论。如果你能详细说明的话,我相信我们已经找到了问题所在。谢谢你,但我只提出了一个小建议,简化构建并隔离问题。克里斯·多德找到了解决办法。亲爱的伊瑟,谢谢!我刚试过你的makefile。我得到的输出是:$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:没有这样的文件或目录\make:**[portugol.bin]错误1\对不起,我会把它放在一个格式化的答案中。亲爱的伊瑟,谢谢!我刚试过你的makefile。我得到的输出是:$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:没有这样的文件或目录\make:**[portugol.bin]错误1\抱歉,我会把它放在一个格式化的答案中。谢谢克里斯!这就彻底解决了这个案子内置程序就是这样:%.c:%.y\执行内置程序的命令:\$YACC.y$<\mv-f y.tab.c$@\我所说的mv出现在您告诉的make-p-f/dev/null中。谢谢Chris,在理解了问题的核心之后,我认为另一个可能的解决方案是让buit运行,并完全删除我为bison编写的规则。但那
这让我想到:$makeall o=pequeno make:**没有规则将目标y.tab.c'设置为葡萄牙语所需的。停止。@Beco博士,如果删除了y.tab.c的规则,make将失败,因为隐式规则只知道如何从y.tab.y中生成y.tab.c。它无法知道您希望y.tab.c由葡萄牙语.y生成。如果您想使用内置规则,您需要按照Jonathan Leffler的建议重命名文件,因为内置规则希望创建一个与.yThanks Chris同名的.c文件!这就彻底解决了这个案子内置程序就是这样:%.c:%.y\执行内置程序的命令:\$YACC.y$<\mv-f y.tab.c$@\我所说的mv出现在您告诉的make-p-f/dev/null中。谢谢Chris,在理解了问题的核心之后,我认为另一个可能的解决方案是让buit运行,并完全删除我为bison编写的规则。但这让我想到:$makeall o=pequeno make:**没有规则将目标y.tab.c'设置为葡萄牙语.bin所需要的。停止。@Beco博士,如果删除了y.tab.c的规则,make将失败,因为隐式规则只知道如何从y.tab.y中生成y.tab.c。它不知道您希望y.tab.c由葡萄牙语.y生成。如果您想使用内置规则,您需要遵循Jonathan Leffler的建议重命名文件,因为内置规则希望创建一个与.yStackOverflow具有相同基本名称的.c文件。yStackOverflow是一个问答网站,而不是论坛。这个空间是为答案保留的,而你在这里发布的内容并不是真正的答案。更多信息:谢谢,罗伯特。在我习惯了这个网站之后,我看到了这一点。这对我来说是新的。我看到“接受答案”按钮后才意识到。我的回答应该是问题的一部分,也许是编辑。现在,我们或我该怎么办?谢谢你的耐心。这是一个太长的问题,所以我们就把这个问题留在这里。StackOverflow是一个问答网站,不是论坛。这个空间是为答案保留的,而你在这里发布的内容并不是真正的答案。更多信息:谢谢,罗伯特。在我习惯了这个网站之后,我看到了这一点。这对我来说是新的。我看到“接受答案”按钮后才意识到。我的回答应该是问题的一部分,也许是编辑。现在,我们或我该怎么办?谢谢你的耐心。这个问题已经很长了,太长了,所以我们就把这个问题留在这里。