在make文件中使用$$?

时间:2012-10-21 16:11:39

标签: shell makefile

我有以下结构

home
|-- Makefile
|-- H1
|   |-- Makefile
|   `-- h1.c
|-- H2
|   |-- Makefile
|   `-- h2.c
|-- main.c

H1 /生成文件

h1.o:h1.c
        gcc -c h1.c

H 2 /生成文件

h2.o:h2.c
        gcc -c h2.c

主/生成文件

DIR = h1 h2
main.out:main.o
        for i in $(DIR);\
        do (cd $$i; make);\ //1.why () used here to encolose 2 commands and $$ before the i
        done
        gcc -o main.out main.o ./h1/h1.o ./h1/h1.o

main.o:main.c
        gcc -c main.c

以上工作正常并给我输出文件,但我怀疑这是进行此编译的有效方式或其他任何方式。

我的问题在代码的评论中提到,并且也在

之后
I have tried like 
do(cd $i;make;)//this showing error
also do(cd $$i;)make;//this also sowing error

,请给我一些想法。这里发生了什么。 我浏览了一些书籍,我发现$$表示当前的进程ID,但是在i之前有什么用途。

使用()包含两个命令[cdmake]的原因是什么。

请帮我解答一下我的怀疑。

2 个答案:

答案 0 :(得分:1)

make在规则的操作中展开所有 make-variables (如$(CFLAGS)$@),然后使用shell执行它。 $$扩展为$。所以shell在$i循环中看到for。如果您只在规则中编写$i,则会在调用shell之前将其$(i)展开为make为空(因为 make don没有绑定i 生成变量)。

使用GNU remake作为remake -x来解决发生的事情。

顺便说一句,我相信你的Makefile错了:(cd $$i; make)应为$(MAKE) -C $$i (因为GNU 制作流程非常特别$(MAKE),例如当你开始make -j 2时)

答案 1 :(得分:1)

1:正如@BasileStarynkevitch所说,Make扩展了这个:

for i in $(DIR); do (cd $$i; make); done

进入这个:

for i in h1 h2; do (cd $i; make); done

并将其传递给shell。

2:括号不是必需的。这同样有效:

for i in $(DIR); do cd $$i; make; done

<击> [正如Virgile指出的那样,我对这一点的看法是错误的。]

3:正如@BasileStarynkevitch所说,$(MAKE) -C $$i优于cd $$i; make

4:你可以完全没有循环(从而正确处理依赖关系):

h1/h1.o: h1/h1.c
    $(MAKE) -C h1

h2/h2.o: h2/h2.c
    $(MAKE) -C h2

main.out:main.o h1/h2.o h1/h2.o
    gcc -o main.out main.o ./h1/h1.o ./h2/h2.o

5:你可以完全没有递归:

h1/h1.o: h1/h1.c
    gcc -c h1/h1.c -o h1/h1.o

h2/h2.o: h2/h2.c
    gcc -c h2/h2.c -o h2/h2.o

5:您可以使用automatic variables让规则更清晰:

h1/h1.o: h1/h1.c
    gcc -c $< -o $@

h2/h2.o: h2/h2.c
    gcc -c $< -o $@

main.out:main.o h1/h2.o h1/h2.o
    gcc -o $@ $^

您可以进行更多简化,但对于这样一个简单的makefile,它是不值得的。