Voo*_*Voo 6 c assembly makefile
我有几个包含c或asm文件的子目录的目录,我希望它们全部编译/组装然后链接.我不是特别挑剔目标文件的位置(例如一个特殊的bin文件夹或在src文件夹中),只要make clean将它们全部删除.
结构看起来像这样:
/src
/dir1
/dir1_1
+file1_1.s
+file1_2.s
+file1.s
/dir2
+file2.c
Run Code Online (Sandbox Code Playgroud)
我确信有一些简单的方法来创建一个编译所有文件的makefile而不必指定它应该看的位置(编译一个目录中的所有文件都可以使用通配符,但那么呢?).
谷歌搜索"递归使被认为有害".你会发现原始的文章假设递归制作程序是一种糟糕的做生意的方式,你会发现一些链接到其他地方辩论命题的有效性.
基本上,有两种方法可以在目录层次结构中进行构建(使用make).
我经常在一个产品上工作,其中主构建序列由混合系统驱动,该系统使用shell脚本和每个目录的一个makefile.产品的一部分由'RMCH'makefile管理; 大部分都不是.构建脚本处理构建的各个阶段,并对目录进行排序,并在需要时make在每个目录中运行.(源代码是20k +文件,分布在众多目录中 - 这是一个很大的项目/产品.)
我还转换了一个中小项目(大约20个相关目录,大约400个源文件)来使用RMCH(来自脚本+ makefile-per-directory系统).起初它有点令人兴奋,但现在它已经完成了.我是否正确地做了它是开放的辩论; 它主要是一个学习练习,虽然我也做了一些工作修改代码,以使用现代curses库而不是作为代码的一部分使用的古老BSD库(古老,如1982年复古 - 代码是最后在1986年左右开发并且通常升级到现代(标准C)标准.这也是一个合作的机会git- 总而言之,这是一次非常广泛的学习经历.
如果你可以将你的大脑包裹在RMCH周围,这是一个很好的系统.如果正确完成,通过完整和准确的依赖关系跟踪,它会从构建序列中删除猜测,并且运行速度很快.但是,将中等规模的项目迁移到它是相当困难的工作 - 在我工作的主要产品上进行这项工作将是一项艰巨的任务,尽管系统可能会从中受益.
另一种方法是看其他的替代品make,如cmake,rake,scons,bras,imake,或ant或其他任何需要你的想象.其中大部分都可以通过谷歌搜索轻松发现; 困难的是bras,它基于Tcl(如在Tcl/Tk中),但现在可能基本上已经死了.并且imake提到完整性而不是严肃的建议.你也可以看一下GNU Autotools.那些不放弃make; 他们建立在顶上make.
如果您的项目足够小,则可以使用单个手工制作的文件而不是更复杂的构建系统:查看转换函数的手册页,以了解可能的方法。
您的示例项目可以使用以下非递归makefile进行编译:
targets = $(patsubst %$(1),%$(2),$(foreach dir,$(3),$(wildcard $(dir)/*$(1))))
asmdirs := src/dir1 src/dir1/dir1_1
cdirs := src/dir2
asmobjects := $(call targets,.s,.o,$(asmdirs))
cobjects := $(call targets,.c,.o,$(cdirs))
.PHONY : all clean
all : $(asmobjects) $(cobjects)
clean :
rm -f $(asmobjects) $(cobjects)
$(cobjects) : %.o : %.c
gcc -o $@ -c $<
$(asmobjects) : %.o : %.s
gcc -o $@ -c $<
Run Code Online (Sandbox Code Playgroud)
但是,由于make可以访问该外壳程序,因此您也可以使用标准的unix工具,例如,find而不是某些有限的内置函数,例如
asmsources := $(shell find src -name '*.s')
csources := $(shell find src -name '*.c')
asmobjects := $(asmsources:.s=.o)
cobjects := $(csources:.c=.o)
Run Code Online (Sandbox Code Playgroud)