我有以下结构
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之前有什么用途。
使用()
包含两个命令[cd
和make
]的原因是什么。
请帮我解答一下我的怀疑。
答案 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,它是不值得的。