|
我遇到了关于 makefile 的问题, 和我正在做的项目有关.
我写了一个编译器, 用来把输入编译成(专用)打印机可以识别的指令. 由于文法的问题, 这个编译器中还要再嵌入另一个解释器(为了方便维护, 这个编译器和解释器都是用 yacc 来翻译成 C 文件的). 现在, 问题出现了. 假设我已有了一个文件 pc.y 以及与它配合的 lex.l, 这是编译器的文件. 我可以这样写 makefile:
- CC = gcc
- CFLAGS = -DYYDEBUG=1 -g
- YFLAGS = -v -d
- LFLAGS = -d
- OBJS = pc.o prop.o error.o lex.o
- pc: $(OBJS)
- $(CC) $(CFLAGS) $(OBJS) -ll -o pc
- lex.o pc.o prop.o error.o: pc.h
- lex.o: x.tab.h
- x.tab.h: y.tab.h
- -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
- clean:
- rm -f $(OBJS) y.output [xy].tab.[ch]
复制代码
make 知道如何从 pc.y 和 lex.l 制造出 pc.o 和 lex.o. 执行是这样的:
- [herbert@localhost pc]$ make
- yacc -v -d pc.y
- mv -f y.tab.c pc.c
- gcc -DYYDEBUG=1 -g -c -o pc.o pc.c
- gcc -DYYDEBUG=1 -g -c -o prop.o prop.c
- gcc -DYYDEBUG=1 -g -c -o error.o error.c
- cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
- lex -d -t lex.l > lex.c
- gcc -DYYDEBUG=1 -g -c -o lex.o lex.c
- gcc -DYYDEBUG=1 -g pc.o prop.o error.o lex.o -ll -o pc
- rm pc.c lex.c
- [herbert@localhost pc]$
复制代码
但是, 当我加入解释器的文件 arg.y 和 arglex.l 时就有问题了. 为了与已有的 pc.y 产生的输出 y.output, y.tab.c, y.tab.h 不同, 我应该使用 -b 选项, 这样, yacc 产生的输出就会以我希望的名字开头. 比如, 如果我用了 -b arg, yacc 就输出 arg.output, arg.tab.c, arg.tab.h. 可是 make 并不知道这些. 当我这样做时, make 出错了:
- [herbert@localhost pc]$ make
- yacc -v -d -b arg -p arg arg.y
- mv -f y.tab.c arg.c
- mv: can't stat source y.tab.c
- make: *** [arg.c] Error 1
- [herbert@localhost pc]$
复制代码
怎样告诉 make 用 arg.tab.c 而不是默认的 y.tab.c 呢?
这里还有另一个解决方案, 就是我把 arg.y 和 arglex.l 放入我现在的项目的子目录里. 可是, yacc 产生的输出都是在当前目录的, 而我又不会告诉 make 进入那个目录. 请问如何告诉 make 在一个合适的时机进入一个子目录并在另外一个合适的时机回来呢? |
|